mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-02-23 14:39:32 +08:00
feat(build): Remove support for nested contexts on a page.
This commit is contained in:
parent
6bc03c86b8
commit
b003b76182
@ -1,44 +1,38 @@
|
||||
{
|
||||
"id": "404",
|
||||
"type": "Context",
|
||||
"type": "Result",
|
||||
"style": {
|
||||
"minHeight": "100vh"
|
||||
},
|
||||
"blocks": [
|
||||
{
|
||||
"id": "404_result",
|
||||
"type": "Result",
|
||||
"properties": {
|
||||
"status": 404,
|
||||
"title": "404",
|
||||
"subTitle": "Sorry, the page you are visiting does not exist."
|
||||
},
|
||||
"areas": {
|
||||
"extra": {
|
||||
"blocks": [
|
||||
{
|
||||
"id": "home",
|
||||
"type": "Button",
|
||||
"properties": {
|
||||
"title": "Go to home page",
|
||||
"properties": {
|
||||
"status": 404,
|
||||
"title": "404",
|
||||
"subTitle": "Sorry, the page you are visiting does not exist."
|
||||
},
|
||||
"areas": {
|
||||
"extra": {
|
||||
"blocks": [
|
||||
{
|
||||
"id": "home",
|
||||
"type": "Button",
|
||||
"properties": {
|
||||
"title": "Go to home page",
|
||||
"type": "Link",
|
||||
"icon": "HomeOutlined"
|
||||
},
|
||||
"events": {
|
||||
"onClick": [
|
||||
{
|
||||
"id": "home",
|
||||
"type": "Link",
|
||||
"icon": "HomeOutlined"
|
||||
},
|
||||
"events": {
|
||||
"onClick": [
|
||||
{
|
||||
"id": "home",
|
||||
"type": "Link",
|
||||
"params": {
|
||||
"home": true
|
||||
}
|
||||
}
|
||||
]
|
||||
"params": {
|
||||
"home": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,48 +35,42 @@ test('addDefaultPages, no pages array', async () => {
|
||||
expect(res).toEqual({
|
||||
pages: [
|
||||
{
|
||||
blocks: [
|
||||
{
|
||||
areas: {
|
||||
extra: {
|
||||
blocks: [
|
||||
{
|
||||
events: {
|
||||
onClick: [
|
||||
{
|
||||
id: 'home',
|
||||
params: {
|
||||
home: true,
|
||||
},
|
||||
type: 'Link',
|
||||
},
|
||||
],
|
||||
},
|
||||
id: 'home',
|
||||
properties: {
|
||||
icon: 'HomeOutlined',
|
||||
title: 'Go to home page',
|
||||
type: 'Link',
|
||||
},
|
||||
type: 'Button',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
id: '404_result',
|
||||
properties: {
|
||||
status: 404,
|
||||
subTitle: 'Sorry, the page you are visiting does not exist.',
|
||||
title: '404',
|
||||
},
|
||||
type: 'Result',
|
||||
},
|
||||
],
|
||||
id: '404',
|
||||
type: 'Result',
|
||||
style: {
|
||||
minHeight: '100vh',
|
||||
},
|
||||
type: 'Context',
|
||||
properties: {
|
||||
status: 404,
|
||||
subTitle: 'Sorry, the page you are visiting does not exist.',
|
||||
title: '404',
|
||||
},
|
||||
areas: {
|
||||
extra: {
|
||||
blocks: [
|
||||
{
|
||||
events: {
|
||||
onClick: [
|
||||
{
|
||||
id: 'home',
|
||||
params: {
|
||||
home: true,
|
||||
},
|
||||
type: 'Link',
|
||||
},
|
||||
],
|
||||
},
|
||||
id: 'home',
|
||||
properties: {
|
||||
icon: 'HomeOutlined',
|
||||
title: 'Go to home page',
|
||||
type: 'Link',
|
||||
},
|
||||
type: 'Button',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -88,105 +82,93 @@ test('addDefaultPages, empty pages array', async () => {
|
||||
expect(res).toEqual({
|
||||
pages: [
|
||||
{
|
||||
blocks: [
|
||||
{
|
||||
areas: {
|
||||
extra: {
|
||||
blocks: [
|
||||
{
|
||||
events: {
|
||||
onClick: [
|
||||
{
|
||||
id: 'home',
|
||||
params: {
|
||||
home: true,
|
||||
},
|
||||
type: 'Link',
|
||||
},
|
||||
],
|
||||
},
|
||||
id: 'home',
|
||||
properties: {
|
||||
icon: 'HomeOutlined',
|
||||
title: 'Go to home page',
|
||||
type: 'Link',
|
||||
},
|
||||
type: 'Button',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
id: '404_result',
|
||||
properties: {
|
||||
status: 404,
|
||||
subTitle: 'Sorry, the page you are visiting does not exist.',
|
||||
title: '404',
|
||||
},
|
||||
type: 'Result',
|
||||
},
|
||||
],
|
||||
id: '404',
|
||||
type: 'Result',
|
||||
style: {
|
||||
minHeight: '100vh',
|
||||
},
|
||||
type: 'Context',
|
||||
properties: {
|
||||
status: 404,
|
||||
subTitle: 'Sorry, the page you are visiting does not exist.',
|
||||
title: '404',
|
||||
},
|
||||
areas: {
|
||||
extra: {
|
||||
blocks: [
|
||||
{
|
||||
events: {
|
||||
onClick: [
|
||||
{
|
||||
id: 'home',
|
||||
params: {
|
||||
home: true,
|
||||
},
|
||||
type: 'Link',
|
||||
},
|
||||
],
|
||||
},
|
||||
id: 'home',
|
||||
properties: {
|
||||
icon: 'HomeOutlined',
|
||||
title: 'Go to home page',
|
||||
type: 'Link',
|
||||
},
|
||||
type: 'Button',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('addDefaultPages, pages without 404 page', async () => {
|
||||
const components = { pages: [{ id: 'page1', type: 'Context' }] };
|
||||
const components = { pages: [{ id: 'page1', type: 'PageHeaderMenu' }] };
|
||||
const res = await addDefaultPages({ components, context });
|
||||
expect(res).toEqual({
|
||||
pages: [
|
||||
{
|
||||
id: 'page1',
|
||||
type: 'Context',
|
||||
type: 'PageHeaderMenu',
|
||||
},
|
||||
{
|
||||
blocks: [
|
||||
{
|
||||
areas: {
|
||||
extra: {
|
||||
blocks: [
|
||||
{
|
||||
events: {
|
||||
onClick: [
|
||||
{
|
||||
id: 'home',
|
||||
params: {
|
||||
home: true,
|
||||
},
|
||||
type: 'Link',
|
||||
},
|
||||
],
|
||||
},
|
||||
id: 'home',
|
||||
properties: {
|
||||
icon: 'HomeOutlined',
|
||||
title: 'Go to home page',
|
||||
type: 'Link',
|
||||
},
|
||||
type: 'Button',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
id: '404_result',
|
||||
properties: {
|
||||
status: 404,
|
||||
subTitle: 'Sorry, the page you are visiting does not exist.',
|
||||
title: '404',
|
||||
},
|
||||
type: 'Result',
|
||||
},
|
||||
],
|
||||
id: '404',
|
||||
type: 'Result',
|
||||
style: {
|
||||
minHeight: '100vh',
|
||||
},
|
||||
type: 'Context',
|
||||
properties: {
|
||||
status: 404,
|
||||
subTitle: 'Sorry, the page you are visiting does not exist.',
|
||||
title: '404',
|
||||
},
|
||||
areas: {
|
||||
extra: {
|
||||
blocks: [
|
||||
{
|
||||
events: {
|
||||
onClick: [
|
||||
{
|
||||
id: 'home',
|
||||
params: {
|
||||
home: true,
|
||||
},
|
||||
type: 'Link',
|
||||
},
|
||||
],
|
||||
},
|
||||
id: 'home',
|
||||
properties: {
|
||||
icon: 'HomeOutlined',
|
||||
title: 'Go to home page',
|
||||
type: 'Link',
|
||||
},
|
||||
type: 'Button',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -195,8 +177,8 @@ test('addDefaultPages, pages without 404 page', async () => {
|
||||
test('addDefaultPages, pages with 404 page, should not overwrite', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{ id: 'page1', type: 'Context' },
|
||||
{ id: '404', type: 'Context' },
|
||||
{ id: 'page1', type: 'PageHeaderMenu' },
|
||||
{ id: '404', type: 'PageHeaderMenu' },
|
||||
],
|
||||
};
|
||||
const res = await addDefaultPages({ components, context });
|
||||
@ -204,11 +186,11 @@ test('addDefaultPages, pages with 404 page, should not overwrite', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page1',
|
||||
type: 'Context',
|
||||
type: 'PageHeaderMenu',
|
||||
},
|
||||
{
|
||||
id: '404',
|
||||
type: 'Context',
|
||||
type: 'PageHeaderMenu',
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -216,7 +198,7 @@ test('addDefaultPages, pages with 404 page, should not overwrite', async () => {
|
||||
|
||||
test('addDefaultPages, pages not an array', async () => {
|
||||
const components = {
|
||||
pages: { id: 'page1', type: 'Context' },
|
||||
pages: { id: 'page1', type: 'PageHeaderMenu' },
|
||||
};
|
||||
await expect(addDefaultPages({ components, context })).rejects.toThrow(
|
||||
'lowdefy.pages is not an array.'
|
||||
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { set, type } from '@lowdefy/helpers';
|
||||
import buildRequests from './buildRequests';
|
||||
import setBlockMeta from './setBlockMeta';
|
||||
|
||||
async function buildBlock(block, blockContext) {
|
||||
if (!type.isObject(block)) {
|
||||
throw new Error(
|
||||
`Expected block to be an object on ${blockContext.pageId}. Received ${JSON.stringify(block)}`
|
||||
);
|
||||
}
|
||||
if (!type.isString(block.id)) {
|
||||
if (type.isUndefined(block.id)) {
|
||||
throw new Error(`Block id missing at page "${blockContext.pageId}".`);
|
||||
}
|
||||
throw new Error(
|
||||
`Block id is not a string at page "${blockContext.pageId}". Received ${JSON.stringify(
|
||||
block.id
|
||||
)}.`
|
||||
);
|
||||
}
|
||||
block.blockId = block.id;
|
||||
block.id = `block:${blockContext.pageId}:${block.id}`;
|
||||
await setBlockMeta(block, blockContext);
|
||||
|
||||
let newBlockContext = blockContext;
|
||||
if (block.meta.category === 'context') {
|
||||
newBlockContext = {
|
||||
auth: blockContext.auth,
|
||||
contextId: block.blockId,
|
||||
getMeta: blockContext.getMeta,
|
||||
pageId: blockContext.pageId,
|
||||
requests: [],
|
||||
};
|
||||
}
|
||||
buildRequests(block, newBlockContext);
|
||||
if (block.meta.category === 'context') {
|
||||
block.requests = newBlockContext.requests;
|
||||
}
|
||||
|
||||
if (block.events) {
|
||||
Object.keys(block.events).map((key) => {
|
||||
if (type.isArray(block.events[key])) {
|
||||
block.events[key] = {
|
||||
try: block.events[key],
|
||||
catch: [],
|
||||
};
|
||||
}
|
||||
if (!type.isArray(block.events[key].try)) {
|
||||
throw new Error(
|
||||
`Events must be an array of actions at ${block.blockId} in events ${key} on page ${
|
||||
newBlockContext.pageId
|
||||
}. Received ${JSON.stringify(block.events[key].try)}`
|
||||
);
|
||||
}
|
||||
if (!type.isArray(block.events[key].catch) && !type.isNone(block.events[key].catch)) {
|
||||
throw new Error(
|
||||
`Catch events must be an array of actions at ${block.blockId} in events ${key} on page ${
|
||||
newBlockContext.pageId
|
||||
}. Received ${JSON.stringify(block.events[key].catch)}`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!type.isNone(block.blocks)) {
|
||||
if (!type.isArray(block.blocks)) {
|
||||
throw new Error(
|
||||
`Blocks at ${block.blockId} on page ${
|
||||
newBlockContext.pageId
|
||||
} is not an array. Received ${JSON.stringify(block.blocks)}`
|
||||
);
|
||||
}
|
||||
set(block, 'areas.content.blocks', block.blocks);
|
||||
delete block.blocks;
|
||||
}
|
||||
if (type.isObject(block.areas)) {
|
||||
let promises = [];
|
||||
Object.keys(block.areas).forEach((key) => {
|
||||
if (type.isNone(block.areas[key].blocks)) {
|
||||
block.areas[key].blocks = [];
|
||||
}
|
||||
if (!type.isArray(block.areas[key].blocks)) {
|
||||
throw new Error(
|
||||
`Expected blocks to be an array at ${block.blockId} in area ${key} on page ${
|
||||
newBlockContext.pageId
|
||||
}. Received ${JSON.stringify(block.areas[key].blocks)}`
|
||||
);
|
||||
}
|
||||
const blockPromises = block.areas[key].blocks.map(async (blk) => {
|
||||
await buildBlock(blk, newBlockContext);
|
||||
});
|
||||
promises = promises.concat(blockPromises);
|
||||
});
|
||||
await Promise.all(promises);
|
||||
}
|
||||
}
|
||||
|
||||
export default buildBlock;
|
37
packages/build/src/build/buildPages/buildBlock/buildBlock.js
Normal file
37
packages/build/src/build/buildPages/buildBlock/buildBlock.js
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import buildEvents from './buildEvents';
|
||||
import buildRequests from './buildRequests';
|
||||
import buildSubBlocks from './buildSubBlocks';
|
||||
import getOperators from './getOperators';
|
||||
import moveSubBlocksToArea from './moveSubBlocksToArea';
|
||||
import setBlockId from './setBlockId';
|
||||
import setBlockMeta from './setBlockMeta';
|
||||
import validateBlock from './validateBlock';
|
||||
|
||||
async function buildBlock(block, pageContext) {
|
||||
validateBlock(block, pageContext);
|
||||
getOperators(block, pageContext);
|
||||
setBlockId(block, pageContext);
|
||||
await setBlockMeta(block, pageContext);
|
||||
buildEvents(block, pageContext);
|
||||
buildRequests(block, pageContext);
|
||||
moveSubBlocksToArea(block, pageContext);
|
||||
await buildSubBlocks(block, pageContext);
|
||||
}
|
||||
|
||||
export default buildBlock;
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { type } from '@lowdefy/helpers';
|
||||
|
||||
function buildEvents(block, pageContext) {
|
||||
if (block.events) {
|
||||
Object.keys(block.events).map((key) => {
|
||||
if (type.isArray(block.events[key])) {
|
||||
block.events[key] = {
|
||||
try: block.events[key],
|
||||
catch: [],
|
||||
};
|
||||
}
|
||||
if (!type.isArray(block.events[key].try)) {
|
||||
throw new Error(
|
||||
`Events must be an array of actions at "${block.blockId}" in event "${key}" on page "${
|
||||
pageContext.pageId
|
||||
}". Received ${JSON.stringify(block.events[key].try)}`
|
||||
);
|
||||
}
|
||||
if (!type.isArray(block.events[key].catch) && !type.isNone(block.events[key].catch)) {
|
||||
throw new Error(
|
||||
`Catch events must be an array of actions at "${
|
||||
block.blockId
|
||||
}" in event "${key}" on page "${pageContext.pageId}". Received ${JSON.stringify(
|
||||
block.events[key].catch
|
||||
)}`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default buildEvents;
|
@ -0,0 +1,322 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import { get } from '@lowdefy/helpers';
|
||||
import buildPages from '../buildPages';
|
||||
import testContext from '../../../test/testContext';
|
||||
|
||||
const mockLogWarn = jest.fn();
|
||||
const mockLog = jest.fn();
|
||||
|
||||
const logger = {
|
||||
warn: mockLogWarn,
|
||||
log: mockLog,
|
||||
};
|
||||
|
||||
const blockMetas = {
|
||||
Container: {
|
||||
category: 'container',
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Container',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
schema: {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'https://example.com/Container.json',
|
||||
},
|
||||
},
|
||||
List: {
|
||||
category: 'list',
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'List',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
schema: {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'https://example.com/Container.json',
|
||||
},
|
||||
},
|
||||
Input: {
|
||||
category: 'input',
|
||||
valueType: 'string',
|
||||
loading: {
|
||||
type: 'SkeletonInput',
|
||||
},
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Input',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
schema: {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'https://example.com/Container.json',
|
||||
},
|
||||
},
|
||||
Display: {
|
||||
category: 'display',
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Display',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
schema: {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'https://example.com/Container.json',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const outputMetas = {
|
||||
Container: {
|
||||
category: 'container',
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Container',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
},
|
||||
List: {
|
||||
category: 'list',
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'List',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
valueType: 'array',
|
||||
},
|
||||
Input: {
|
||||
category: 'input',
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Input',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
valueType: 'string',
|
||||
loading: {
|
||||
type: 'SkeletonInput',
|
||||
},
|
||||
},
|
||||
Display: {
|
||||
category: 'display',
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Display',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const auth = {
|
||||
public: true,
|
||||
};
|
||||
|
||||
const getMeta = (type) => {
|
||||
const meta = blockMetas[type];
|
||||
if (!meta) {
|
||||
return null;
|
||||
}
|
||||
return Promise.resolve(meta);
|
||||
};
|
||||
|
||||
const context = testContext({ logger, getMeta });
|
||||
|
||||
beforeEach(() => {
|
||||
mockLogWarn.mockReset();
|
||||
mockLog.mockReset();
|
||||
});
|
||||
|
||||
test('block events actions array should map to try catch', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Input',
|
||||
events: {
|
||||
onClick: [
|
||||
{
|
||||
id: 'action_1',
|
||||
type: 'Reset',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(get(res, 'pages.0.areas.content.blocks.0.events.onClick.try')).toEqual([
|
||||
{
|
||||
id: 'action_1',
|
||||
type: 'Reset',
|
||||
},
|
||||
]);
|
||||
expect(get(res, 'pages.0.areas.content.blocks.0.events.onClick.catch')).toEqual([]);
|
||||
});
|
||||
|
||||
test('block events actions as try catch arrays', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Input',
|
||||
events: {
|
||||
onClick: {
|
||||
try: [
|
||||
{
|
||||
id: 'action_1',
|
||||
type: 'Reset',
|
||||
},
|
||||
],
|
||||
catch: [
|
||||
{
|
||||
id: 'action_1',
|
||||
type: 'Retry',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(get(res, 'pages.0.areas.content.blocks.0.events.onClick.try')).toEqual([
|
||||
{
|
||||
id: 'action_1',
|
||||
type: 'Reset',
|
||||
},
|
||||
]);
|
||||
expect(get(res, 'pages.0.areas.content.blocks.0.events.onClick.catch')).toEqual([
|
||||
{
|
||||
id: 'action_1',
|
||||
type: 'Retry',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test('block events actions try not an array', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Input',
|
||||
events: {
|
||||
onClick: {
|
||||
try: {
|
||||
id: 'action_1',
|
||||
type: 'Reset',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Events must be an array of actions at "block_1" in event "onClick" on page "page_1". Received {"id":"action_1","type":"Reset"}'
|
||||
);
|
||||
});
|
||||
|
||||
test('block events actions not an array', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Input',
|
||||
events: {
|
||||
onClick: {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Events must be an array of actions at "block_1" in event "onClick" on page "page_1". Received undefined'
|
||||
);
|
||||
});
|
||||
|
||||
test('block events actions catch not an array', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Input',
|
||||
events: {
|
||||
onClick: {
|
||||
try: [],
|
||||
catch: {
|
||||
id: 'action_1',
|
||||
type: 'Reset',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Catch events must be an array of actions at "block_1" in event "onClick" on page "page_1". Received {"id":"action_1","type":"Reset"}'
|
||||
);
|
||||
});
|
@ -16,8 +16,8 @@
|
||||
|
||||
import { type } from '@lowdefy/helpers';
|
||||
|
||||
function buildRequest(request, blockContext) {
|
||||
const { auth, contextId, pageId } = blockContext;
|
||||
function buildRequest(request, pageContext) {
|
||||
const { auth, pageId } = pageContext;
|
||||
if (!type.isString(request.id)) {
|
||||
if (type.isUndefined(request.id)) {
|
||||
throw new Error(`Request id missing at page "${pageId}".`);
|
||||
@ -40,25 +40,16 @@ function buildRequest(request, blockContext) {
|
||||
|
||||
request.auth = auth;
|
||||
request.requestId = request.id;
|
||||
request.contextId = contextId;
|
||||
request.id = `request:${pageId}:${contextId}:${request.id}`;
|
||||
blockContext.requests.push(request);
|
||||
request.pageId = pageId;
|
||||
request.id = `request:${pageId}:${request.id}`;
|
||||
pageContext.requests.push(request);
|
||||
}
|
||||
|
||||
function buildRequests(block, blockContext) {
|
||||
if (!type.isNone(block.requests)) {
|
||||
if (!type.isArray(block.requests)) {
|
||||
throw new Error(
|
||||
`Requests is not an array at ${block.blockId} on page ${
|
||||
blockContext.pageId
|
||||
}. Received ${JSON.stringify(block.requests)}`
|
||||
);
|
||||
}
|
||||
block.requests.forEach((request) => {
|
||||
buildRequest(request, blockContext);
|
||||
});
|
||||
delete block.requests;
|
||||
}
|
||||
function buildRequests(block, pageContext) {
|
||||
(block.requests || []).forEach((request) => {
|
||||
buildRequest(request, pageContext);
|
||||
});
|
||||
delete block.requests;
|
||||
}
|
||||
|
||||
export default buildRequests;
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { type } from '@lowdefy/helpers';
|
||||
|
||||
import buildBlock from './buildBlock';
|
||||
|
||||
async function buildSubBlocks(block, pageContext) {
|
||||
if (type.isObject(block.areas)) {
|
||||
let promises = [];
|
||||
Object.keys(block.areas).forEach((key) => {
|
||||
if (type.isNone(block.areas[key].blocks)) {
|
||||
block.areas[key].blocks = [];
|
||||
}
|
||||
if (!type.isArray(block.areas[key].blocks)) {
|
||||
throw new Error(
|
||||
`Expected blocks to be an array at ${block.blockId} in area ${key} on page ${
|
||||
pageContext.pageId
|
||||
}. Received ${JSON.stringify(block.areas[key].blocks)}`
|
||||
);
|
||||
}
|
||||
const blockPromises = block.areas[key].blocks.map(async (blk) => {
|
||||
await buildBlock(blk, pageContext);
|
||||
});
|
||||
promises = promises.concat(blockPromises);
|
||||
});
|
||||
await Promise.all(promises);
|
||||
}
|
||||
}
|
||||
|
||||
export default buildSubBlocks;
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { type } from '@lowdefy/helpers';
|
||||
|
||||
function getOperators(block, pageContext) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { requests, blocks, areas, ...webBlock } = block;
|
||||
|
||||
function getOperatorsReviver(_, value) {
|
||||
if (type.isObject(value) && Object.keys(value).length === 1) {
|
||||
const key = Object.keys(value)[0];
|
||||
const [op] = key.split('.');
|
||||
const operator = op.replace(/^(_+)/gm, '_');
|
||||
if (operator.length > 1 && operator[0] === '_') {
|
||||
pageContext.operators.add(operator);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
JSON.parse(JSON.stringify(webBlock), getOperatorsReviver);
|
||||
|
||||
(requests || []).forEach((request) => {
|
||||
JSON.parse(JSON.stringify(request.payload || {}), getOperatorsReviver);
|
||||
});
|
||||
}
|
||||
|
||||
export default getOperators;
|
@ -0,0 +1,246 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import { get } from '@lowdefy/helpers';
|
||||
import buildPages from '../buildPages';
|
||||
import testContext from '../../../test/testContext';
|
||||
|
||||
const mockLogWarn = jest.fn();
|
||||
const mockLog = jest.fn();
|
||||
|
||||
const logger = {
|
||||
warn: mockLogWarn,
|
||||
log: mockLog,
|
||||
};
|
||||
|
||||
const blockMetas = {
|
||||
Container: {
|
||||
category: 'container',
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Container',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
schema: {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'https://example.com/Container.json',
|
||||
},
|
||||
},
|
||||
List: {
|
||||
category: 'list',
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'List',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
schema: {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'https://example.com/Container.json',
|
||||
},
|
||||
},
|
||||
Input: {
|
||||
category: 'input',
|
||||
valueType: 'string',
|
||||
loading: {
|
||||
type: 'SkeletonInput',
|
||||
},
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Input',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
schema: {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'https://example.com/Container.json',
|
||||
},
|
||||
},
|
||||
Display: {
|
||||
category: 'display',
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Display',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
schema: {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'https://example.com/Container.json',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const auth = {
|
||||
public: true,
|
||||
};
|
||||
|
||||
const getMeta = (type) => {
|
||||
const meta = blockMetas[type];
|
||||
if (!meta) {
|
||||
return null;
|
||||
}
|
||||
return Promise.resolve(meta);
|
||||
};
|
||||
|
||||
const context = testContext({ logger, getMeta });
|
||||
|
||||
beforeEach(() => {
|
||||
mockLogWarn.mockReset();
|
||||
mockLog.mockReset();
|
||||
});
|
||||
|
||||
test('set empty operators array if no operators on page', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Container',
|
||||
},
|
||||
{
|
||||
id: 'block_2',
|
||||
type: 'Container',
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_3',
|
||||
type: 'Display',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'block_4',
|
||||
type: 'Display',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'block_5',
|
||||
type: 'Display',
|
||||
auth,
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(get(res, 'pages.0.operators')).toEqual([]);
|
||||
});
|
||||
|
||||
test('set all operators for the page', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Container',
|
||||
auth,
|
||||
properties: {
|
||||
a: { _op_1: {} },
|
||||
},
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Display',
|
||||
visible: {
|
||||
__op_2: {},
|
||||
},
|
||||
properties: {
|
||||
a: { _op_1: {} },
|
||||
b: { _op_1: {} },
|
||||
c: { _op_3: { __op_4: { ___op_5: {} } } },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(new Set(get(res, 'pages.0.operators'))).toEqual(
|
||||
new Set(['_op_1', '_op_2', '_op_3', '_op_4', '_op_5'])
|
||||
);
|
||||
});
|
||||
|
||||
test('exclude requests operators', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Container',
|
||||
auth,
|
||||
requests: [
|
||||
{
|
||||
id: 'request_1',
|
||||
properties: {
|
||||
a: { _r_op_1: {} },
|
||||
},
|
||||
},
|
||||
],
|
||||
properties: {
|
||||
a: { _op_1: {} },
|
||||
},
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Display',
|
||||
visible: {
|
||||
_op_2: {},
|
||||
},
|
||||
properties: {
|
||||
a: { _op_3: {} },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(new Set(get(res, 'pages.0.operators'))).toEqual(new Set(['_op_1', '_op_2', '_op_3']));
|
||||
});
|
||||
|
||||
test('include request payload operators', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Container',
|
||||
auth,
|
||||
requests: [
|
||||
{
|
||||
id: 'request_1',
|
||||
payload: {
|
||||
a: { _r_op_1: {} },
|
||||
},
|
||||
properties: {
|
||||
a: { _r_op_2: {} },
|
||||
},
|
||||
},
|
||||
],
|
||||
properties: {
|
||||
a: { _op_1: {} },
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(new Set(get(res, 'pages.0.operators'))).toEqual(new Set(['_op_1', '_r_op_1']));
|
||||
});
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { set, type } from '@lowdefy/helpers';
|
||||
|
||||
function moveSubBlocksToArea(block, pageContext) {
|
||||
if (!type.isNone(block.blocks)) {
|
||||
if (!type.isArray(block.blocks)) {
|
||||
throw new Error(
|
||||
`Blocks at ${block.blockId} on page ${
|
||||
pageContext.pageId
|
||||
} is not an array. Received ${JSON.stringify(block.blocks)}`
|
||||
);
|
||||
}
|
||||
set(block, 'areas.content.blocks', block.blocks);
|
||||
delete block.blocks;
|
||||
}
|
||||
}
|
||||
|
||||
export default moveSubBlocksToArea;
|
22
packages/build/src/build/buildPages/buildBlock/setBlockId.js
Normal file
22
packages/build/src/build/buildPages/buildBlock/setBlockId.js
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
function setBlockId(block, { pageId }) {
|
||||
block.blockId = block.id;
|
||||
block.id = `block:${pageId}:${block.id}`;
|
||||
}
|
||||
|
||||
export default setBlockId;
|
@ -14,25 +14,13 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { type } from '@lowdefy/helpers';
|
||||
|
||||
async function setBlockMeta(block, { getMeta, pageId }) {
|
||||
if (type.isNone(block.type)) {
|
||||
throw new Error(`Block type is not defined at ${block.blockId} on page ${pageId}.`);
|
||||
}
|
||||
if (!type.isString(block.type)) {
|
||||
throw new Error(
|
||||
`Block type is not a string at ${block.blockId} on page ${pageId}. Received ${JSON.stringify(
|
||||
block.type
|
||||
)}`
|
||||
);
|
||||
}
|
||||
const meta = await getMeta(block.type);
|
||||
if (!meta) {
|
||||
throw new Error(
|
||||
`Invalid Block type at ${block.blockId} on page ${pageId}. Received ${JSON.stringify(
|
||||
`Invalid block type at "${block.blockId}" on page "${pageId}". Received ${JSON.stringify(
|
||||
block.type
|
||||
)}`
|
||||
)}.`
|
||||
);
|
||||
}
|
||||
const { category, loading, moduleFederation, valueType } = meta;
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { type } from '@lowdefy/helpers';
|
||||
|
||||
function validateBlock(block, { pageId }) {
|
||||
if (!type.isObject(block)) {
|
||||
throw new Error(
|
||||
`Expected block to be an object on page "${pageId}". Received ${JSON.stringify(block)}.`
|
||||
);
|
||||
}
|
||||
if (!type.isString(block.id)) {
|
||||
if (type.isUndefined(block.id)) {
|
||||
throw new Error(`Block id missing at page "${pageId}".`);
|
||||
}
|
||||
throw new Error(
|
||||
`Block id is not a string at page "${pageId}". Received ${JSON.stringify(block.id)}.`
|
||||
);
|
||||
}
|
||||
if (type.isNone(block.type)) {
|
||||
throw new Error(`Block type is not defined at "${block.id}" on page "${pageId}".`);
|
||||
}
|
||||
if (!type.isString(block.type)) {
|
||||
throw new Error(
|
||||
`Block type is not a string at "${block.id}" on page "${pageId}". Received ${JSON.stringify(
|
||||
block.type
|
||||
)}.`
|
||||
);
|
||||
}
|
||||
if (!type.isNone(block.requests)) {
|
||||
if (!type.isArray(block.requests)) {
|
||||
throw new Error(
|
||||
`Requests is not an array at "${block.id}" on page "${pageId}". Received ${JSON.stringify(
|
||||
block.requests
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default validateBlock;
|
48
packages/build/src/build/buildPages/buildPage.js
Normal file
48
packages/build/src/build/buildPages/buildPage.js
Normal file
@ -0,0 +1,48 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { type } from '@lowdefy/helpers';
|
||||
import buildBlock from './buildBlock/buildBlock';
|
||||
|
||||
async function buildPage({ page, index, context }) {
|
||||
if (!type.isString(page.id)) {
|
||||
if (type.isUndefined(page.id)) {
|
||||
throw new Error(`Page id missing at page ${index}.`);
|
||||
}
|
||||
throw new Error(
|
||||
`Page id is not a string at at page ${index}. Received ${JSON.stringify(page.id)}.`
|
||||
);
|
||||
}
|
||||
page.pageId = page.id;
|
||||
const requests = [];
|
||||
const operators = new Set();
|
||||
await buildBlock(page, {
|
||||
auth: page.auth,
|
||||
getMeta: context.getMeta,
|
||||
operators,
|
||||
pageId: page.pageId,
|
||||
requests,
|
||||
});
|
||||
// set page.id since buildBlock sets id as well.
|
||||
page.id = `page:${page.pageId}`;
|
||||
|
||||
page.requests = requests;
|
||||
page.operators = [...operators];
|
||||
}
|
||||
|
||||
export default buildPage;
|
@ -17,48 +17,11 @@
|
||||
*/
|
||||
|
||||
import { type } from '@lowdefy/helpers';
|
||||
import buildBlock from './buildBlock';
|
||||
import checkPageIsContext from './checkPageIsContext';
|
||||
import fillContextOperators from './fillContextOperators';
|
||||
|
||||
/* Page and block build steps
|
||||
|
||||
Pages:
|
||||
- set pageId = id
|
||||
- set id = `page:${page.id}`
|
||||
|
||||
Blocks:
|
||||
- set blockId = id
|
||||
- set id = `block:${pageId}:${block.id}` if not a page
|
||||
- set request ids
|
||||
- set block meta
|
||||
- set blocks to areas.content
|
||||
- set operators list on context blocks
|
||||
*/
|
||||
import buildPage from './buildPage';
|
||||
|
||||
async function buildPages({ components, context }) {
|
||||
const pages = type.isArray(components.pages) ? components.pages : [];
|
||||
const pageBuildPromises = pages.map(async (page, i) => {
|
||||
if (!type.isString(page.id)) {
|
||||
if (type.isUndefined(page.id)) {
|
||||
throw new Error(`Page id missing at page ${i}.`);
|
||||
}
|
||||
throw new Error(
|
||||
`Page id is not a string at at page ${i}. Received ${JSON.stringify(page.id)}.`
|
||||
);
|
||||
}
|
||||
page.pageId = page.id;
|
||||
await checkPageIsContext(page, context);
|
||||
await buildBlock(page, {
|
||||
auth: page.auth,
|
||||
pageId: page.pageId,
|
||||
requests: [],
|
||||
getMeta: context.getMeta,
|
||||
});
|
||||
// set page.id since buildBlock sets id as well.
|
||||
page.id = `page:${page.pageId}`;
|
||||
fillContextOperators(page);
|
||||
});
|
||||
const pageBuildPromises = pages.map((page, index) => buildPage({ page, index, context }));
|
||||
await Promise.all(pageBuildPromises);
|
||||
return components;
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import { get } from '@lowdefy/helpers';
|
||||
import buildPages from './buildPages';
|
||||
import testContext from '../../test/testContext';
|
||||
|
||||
@ -26,21 +25,6 @@ const logger = {
|
||||
};
|
||||
|
||||
const blockMetas = {
|
||||
Context: {
|
||||
category: 'context',
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Context',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
schema: {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'https://example.com/Container.json',
|
||||
},
|
||||
},
|
||||
Container: {
|
||||
category: 'container',
|
||||
loading: {
|
||||
@ -105,17 +89,6 @@ const blockMetas = {
|
||||
};
|
||||
|
||||
const outputMetas = {
|
||||
Context: {
|
||||
category: 'context',
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Context',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
},
|
||||
Container: {
|
||||
category: 'container',
|
||||
moduleFederation: {
|
||||
@ -203,7 +176,7 @@ test('page does not have an id', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
},
|
||||
],
|
||||
@ -216,7 +189,7 @@ test('page id is not a string', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: true,
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
},
|
||||
],
|
||||
@ -231,7 +204,7 @@ test('block does not have an id', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
@ -251,7 +224,7 @@ test('block id is not a string', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
@ -277,7 +250,7 @@ test('page type missing', async () => {
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Page type is not defined at page1.'
|
||||
'Block type is not defined at "page1" on page "page1".'
|
||||
);
|
||||
});
|
||||
|
||||
@ -286,7 +259,7 @@ test('block type missing', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
@ -297,7 +270,7 @@ test('block type missing', async () => {
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Block type is not defined at blockId on page page1.'
|
||||
'Block type is not defined at "blockId" on page "page1".'
|
||||
);
|
||||
});
|
||||
|
||||
@ -312,7 +285,7 @@ test('invalid page type', async () => {
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Invalid block type at page page1. Received "NotABlock"'
|
||||
'Invalid block type at "page1" on page "page1". Received "NotABlock".'
|
||||
);
|
||||
});
|
||||
|
||||
@ -321,7 +294,7 @@ test('invalid block type', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
@ -333,7 +306,7 @@ test('invalid block type', async () => {
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Invalid Block type at blockId on page page1. Received "NotABlock"'
|
||||
'Invalid block type at "blockId" on page "page1". Received "NotABlock".'
|
||||
);
|
||||
});
|
||||
|
||||
@ -348,7 +321,7 @@ test('page type not a string', async () => {
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Page type is not a string at page1. Received 1'
|
||||
'Block type is not a string at "page1" on page "page1". Received 1.'
|
||||
);
|
||||
});
|
||||
|
||||
@ -357,7 +330,7 @@ test('block type not a string', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
@ -369,22 +342,7 @@ test('block type not a string', async () => {
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Block type is not a string at blockId on page page1. Received 1'
|
||||
);
|
||||
});
|
||||
|
||||
test('page type is not of category context', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page1',
|
||||
type: 'Container',
|
||||
auth,
|
||||
},
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Page page1 is not of category "context". Received "Container"'
|
||||
'Block type is not a string at "blockId" on page "page1". Received 1.'
|
||||
);
|
||||
});
|
||||
|
||||
@ -393,7 +351,7 @@ test('no blocks on page', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: '1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
},
|
||||
],
|
||||
@ -407,8 +365,8 @@ test('no blocks on page', async () => {
|
||||
operators: [],
|
||||
pageId: '1',
|
||||
blockId: '1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [],
|
||||
},
|
||||
],
|
||||
@ -420,7 +378,7 @@ test('blocks not an array', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
blocks: 'block_1',
|
||||
},
|
||||
],
|
||||
@ -435,13 +393,13 @@ test('block not an object', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
blocks: ['block_1'],
|
||||
},
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Expected block to be an object on page1. Received "block_1"'
|
||||
'Expected block to be an object on page "page1". Received "block_1".'
|
||||
);
|
||||
});
|
||||
|
||||
@ -450,7 +408,7 @@ test('block meta should include all meta fields', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
@ -478,8 +436,8 @@ test('block meta should include all meta fields', async () => {
|
||||
operators: [],
|
||||
pageId: 'page_1',
|
||||
blockId: 'page_1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [],
|
||||
areas: {
|
||||
content: {
|
||||
@ -515,7 +473,7 @@ test('nested blocks', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
@ -541,8 +499,8 @@ test('nested blocks', async () => {
|
||||
operators: [],
|
||||
pageId: 'page_1',
|
||||
blockId: 'page_1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [],
|
||||
areas: {
|
||||
content: {
|
||||
@ -579,7 +537,7 @@ describe('block areas', () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
areas: {
|
||||
content: {
|
||||
@ -599,7 +557,7 @@ describe('block areas', () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
areas: {
|
||||
content: {},
|
||||
@ -616,8 +574,8 @@ describe('block areas', () => {
|
||||
blockId: 'page1',
|
||||
operators: [],
|
||||
pageId: 'page1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [],
|
||||
areas: {
|
||||
content: {
|
||||
@ -634,7 +592,7 @@ describe('block areas', () => {
|
||||
pages: [
|
||||
{
|
||||
id: '1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
areas: {
|
||||
content: {
|
||||
@ -658,8 +616,8 @@ describe('block areas', () => {
|
||||
blockId: '1',
|
||||
operators: [],
|
||||
pageId: '1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [],
|
||||
areas: {
|
||||
content: {
|
||||
@ -683,7 +641,7 @@ describe('block areas', () => {
|
||||
pages: [
|
||||
{
|
||||
id: '1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
areas: {
|
||||
content: {
|
||||
@ -708,8 +666,8 @@ describe('block areas', () => {
|
||||
pageId: '1',
|
||||
operators: [],
|
||||
blockId: '1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [],
|
||||
areas: {
|
||||
content: {
|
||||
@ -734,7 +692,7 @@ describe('block areas', () => {
|
||||
pages: [
|
||||
{
|
||||
id: '1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
areas: {
|
||||
content: {
|
||||
@ -766,8 +724,8 @@ describe('block areas', () => {
|
||||
operators: [],
|
||||
pageId: '1',
|
||||
blockId: '1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [],
|
||||
areas: {
|
||||
content: {
|
||||
@ -801,7 +759,7 @@ describe('block areas', () => {
|
||||
pages: [
|
||||
{
|
||||
id: '1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
@ -831,8 +789,8 @@ describe('block areas', () => {
|
||||
operators: [],
|
||||
pageId: '1',
|
||||
blockId: '1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [],
|
||||
areas: {
|
||||
content: {
|
||||
@ -866,7 +824,7 @@ describe('block areas', () => {
|
||||
pages: [
|
||||
{
|
||||
id: '1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
@ -904,8 +862,8 @@ describe('block areas', () => {
|
||||
operators: [],
|
||||
pageId: '1',
|
||||
blockId: '1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [],
|
||||
areas: {
|
||||
content: {
|
||||
@ -939,7 +897,7 @@ describe('block areas', () => {
|
||||
pages: [
|
||||
{
|
||||
id: '1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
@ -993,8 +951,8 @@ describe('block areas', () => {
|
||||
operators: [],
|
||||
pageId: '1',
|
||||
blockId: '1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [],
|
||||
areas: {
|
||||
content: {
|
||||
@ -1063,7 +1021,7 @@ test('add user defined loading to meta', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
loading: {
|
||||
custom: true,
|
||||
@ -1089,15 +1047,15 @@ test('add user defined loading to meta', async () => {
|
||||
operators: [],
|
||||
pageId: 'page_1',
|
||||
blockId: 'page_1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
loading: {
|
||||
custom: true,
|
||||
},
|
||||
meta: {
|
||||
category: 'context',
|
||||
category: 'container',
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Context',
|
||||
module: 'Container',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
loading: {
|
||||
@ -1135,365 +1093,3 @@ test('add user defined loading to meta', async () => {
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
describe('web operators', () => {
|
||||
test('set empty operators array for every context', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'context_1',
|
||||
type: 'Context',
|
||||
},
|
||||
{
|
||||
id: 'context_2',
|
||||
type: 'Context',
|
||||
blocks: [
|
||||
{
|
||||
id: 'context_2_1',
|
||||
type: 'Context',
|
||||
},
|
||||
{
|
||||
id: 'block_2_2',
|
||||
type: 'Display',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'block_3',
|
||||
type: 'Display',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'page_2',
|
||||
type: 'Context',
|
||||
auth,
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(get(res, 'pages.0.operators')).toEqual([]);
|
||||
expect(get(res, 'pages.0.areas.content.blocks.0.operators')).toEqual([]);
|
||||
expect(get(res, 'pages.0.areas.content.blocks.1.areas.content.blocks.0.operators')).toEqual([]);
|
||||
expect(get(res, 'pages.1.operators')).toEqual([]);
|
||||
});
|
||||
|
||||
test('set all operators for context', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
properties: {
|
||||
a: { _c_op_1: {} },
|
||||
},
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Display',
|
||||
visible: {
|
||||
_v_1: {},
|
||||
},
|
||||
properties: {
|
||||
a: { _op_1: {} },
|
||||
b: { _op_1: {} },
|
||||
c: { _op_2: { __op_3: { ___op_4: {} } } },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(get(res, 'pages.0.operators')).toEqual([
|
||||
'_c_op_1',
|
||||
'_v_1',
|
||||
'_op_1',
|
||||
'_op_4',
|
||||
'_op_3',
|
||||
'_op_2',
|
||||
]);
|
||||
});
|
||||
|
||||
test('exclude requests operators', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
requests: [
|
||||
{
|
||||
id: 'request_1',
|
||||
properties: {
|
||||
a: { _r_op_1: {} },
|
||||
},
|
||||
},
|
||||
],
|
||||
properties: {
|
||||
a: { _c_op_1: {} },
|
||||
},
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Display',
|
||||
visible: {
|
||||
_v_1: {},
|
||||
},
|
||||
properties: {
|
||||
a: { _op_1: {} },
|
||||
b: { _op_1: {} },
|
||||
c: { _op_2: { __op_3: { ___op_4: {} } } },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(get(res, 'pages.0.operators')).toEqual([
|
||||
'_c_op_1',
|
||||
'_v_1',
|
||||
'_op_1',
|
||||
'_op_4',
|
||||
'_op_3',
|
||||
'_op_2',
|
||||
]);
|
||||
});
|
||||
|
||||
test('include request payload operators', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
requests: [
|
||||
{
|
||||
id: 'request_1',
|
||||
payload: {
|
||||
a: { _r_op_1: {} },
|
||||
},
|
||||
properties: {
|
||||
a: { _r_op_2: {} },
|
||||
},
|
||||
},
|
||||
],
|
||||
properties: {
|
||||
a: { _op_1: {} },
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(get(res, 'pages.0.operators')).toEqual(['_op_1', '_r_op_1']);
|
||||
});
|
||||
|
||||
test('set operators specific to multiple contexts', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
properties: {
|
||||
a: { _c_op_1: {} },
|
||||
},
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Context',
|
||||
visible: {
|
||||
_v_1: {},
|
||||
},
|
||||
properties: {
|
||||
a: { _op_1: {} },
|
||||
b: { _op_1: {} },
|
||||
c: { _op_2: { __op_3: { ___op_4: {} } } },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(get(res, 'pages.0.operators')).toEqual(['_c_op_1']);
|
||||
expect(get(res, 'pages.0.areas.content.blocks.0.operators')).toEqual([
|
||||
'_v_1',
|
||||
'_op_1',
|
||||
'_op_4',
|
||||
'_op_3',
|
||||
'_op_2',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
test('block events actions array should map to try catch', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Input',
|
||||
events: {
|
||||
onClick: [
|
||||
{
|
||||
id: 'action_1',
|
||||
type: 'Reset',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(get(res, 'pages.0.areas.content.blocks.0.events.onClick.try')).toEqual([
|
||||
{
|
||||
id: 'action_1',
|
||||
type: 'Reset',
|
||||
},
|
||||
]);
|
||||
expect(get(res, 'pages.0.areas.content.blocks.0.events.onClick.catch')).toEqual([]);
|
||||
});
|
||||
|
||||
test('block events actions as try catch arrays', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Input',
|
||||
events: {
|
||||
onClick: {
|
||||
try: [
|
||||
{
|
||||
id: 'action_1',
|
||||
type: 'Reset',
|
||||
},
|
||||
],
|
||||
catch: [
|
||||
{
|
||||
id: 'action_1',
|
||||
type: 'Retry',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(get(res, 'pages.0.areas.content.blocks.0.events.onClick.try')).toEqual([
|
||||
{
|
||||
id: 'action_1',
|
||||
type: 'Reset',
|
||||
},
|
||||
]);
|
||||
expect(get(res, 'pages.0.areas.content.blocks.0.events.onClick.catch')).toEqual([
|
||||
{
|
||||
id: 'action_1',
|
||||
type: 'Retry',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test('block events actions try not an array', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Input',
|
||||
events: {
|
||||
onClick: {
|
||||
try: {
|
||||
id: 'action_1',
|
||||
type: 'Reset',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Events must be an array of actions at block_1 in events onClick on page page_1. Received {"id":"action_1","type":"Reset"}'
|
||||
);
|
||||
});
|
||||
|
||||
test('block events actions not an array', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Input',
|
||||
events: {
|
||||
onClick: {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Events must be an array of actions at block_1 in events onClick on page page_1. Received undefined'
|
||||
);
|
||||
});
|
||||
|
||||
test('block events actions catch not an array', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'block_1',
|
||||
type: 'Input',
|
||||
events: {
|
||||
onClick: {
|
||||
try: [],
|
||||
catch: {
|
||||
id: 'action_1',
|
||||
type: 'Reset',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Catch events must be an array of actions at block_1 in events onClick on page page_1. Received {"id":"action_1","type":"Reset"}'
|
||||
);
|
||||
});
|
||||
|
@ -25,21 +25,6 @@ const logger = {
|
||||
};
|
||||
|
||||
const blockMetas = {
|
||||
Context: {
|
||||
category: 'context',
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Context',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
schema: {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'https://example.com/Container.json',
|
||||
},
|
||||
},
|
||||
Container: {
|
||||
category: 'container',
|
||||
loading: {
|
||||
@ -104,17 +89,6 @@ const blockMetas = {
|
||||
};
|
||||
|
||||
const outputMetas = {
|
||||
Context: {
|
||||
category: 'context',
|
||||
moduleFederation: {
|
||||
scope: 'blocks',
|
||||
module: 'Context',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
},
|
||||
Container: {
|
||||
category: 'container',
|
||||
moduleFederation: {
|
||||
@ -188,13 +162,13 @@ test('requests not an array', async () => {
|
||||
{
|
||||
id: 'page_1',
|
||||
auth,
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
requests: 'requests',
|
||||
},
|
||||
],
|
||||
};
|
||||
await expect(buildPages({ components, context })).rejects.toThrow(
|
||||
'Requests is not an array at page_1 on page page_1. Received "requests"'
|
||||
'Requests is not an array at "page_1" on page "page_1". Received "requests"'
|
||||
);
|
||||
});
|
||||
|
||||
@ -204,7 +178,7 @@ test('request id missing', async () => {
|
||||
{
|
||||
id: 'page_1',
|
||||
auth,
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
requests: [{ type: 'Request' }],
|
||||
},
|
||||
],
|
||||
@ -220,7 +194,7 @@ test('request id not a string', async () => {
|
||||
{
|
||||
id: 'page_1',
|
||||
auth,
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
requests: [{ id: true, type: 'Request' }],
|
||||
},
|
||||
],
|
||||
@ -236,7 +210,7 @@ test('request id contains a "."', async () => {
|
||||
{
|
||||
id: 'page_1',
|
||||
auth,
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
requests: [{ id: 'my.request', type: 'Request' }],
|
||||
},
|
||||
],
|
||||
@ -252,7 +226,7 @@ test('request payload not an object', async () => {
|
||||
{
|
||||
id: 'page_1',
|
||||
auth,
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
requests: [{ id: 'my_request', type: 'Request', payload: 'payload' }],
|
||||
},
|
||||
],
|
||||
@ -267,7 +241,7 @@ test('give request an id', async () => {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
requests: [
|
||||
{
|
||||
@ -286,14 +260,14 @@ test('give request an id', async () => {
|
||||
operators: [],
|
||||
pageId: 'page_1',
|
||||
blockId: 'page_1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page_1:page_1:request_1',
|
||||
id: 'request:page_1:request_1',
|
||||
auth: { public: true },
|
||||
requestId: 'request_1',
|
||||
contextId: 'page_1',
|
||||
pageId: 'page_1',
|
||||
payload: {},
|
||||
},
|
||||
],
|
||||
@ -302,72 +276,12 @@ test('give request an id', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('request on a context block not at root', async () => {
|
||||
test('request on a sub-block', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'context',
|
||||
type: 'Context',
|
||||
requests: [
|
||||
{
|
||||
id: 'request_1',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(res).toEqual({
|
||||
pages: [
|
||||
{
|
||||
id: 'page:page_1',
|
||||
auth: { public: true },
|
||||
operators: [],
|
||||
pageId: 'page_1',
|
||||
blockId: 'page_1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
requests: [],
|
||||
areas: {
|
||||
content: {
|
||||
blocks: [
|
||||
{
|
||||
id: 'block:page_1:context',
|
||||
blockId: 'context',
|
||||
type: 'Context',
|
||||
operators: [],
|
||||
meta: outputMetas.Context,
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page_1:context:request_1',
|
||||
auth: { public: true },
|
||||
requestId: 'request_1',
|
||||
contextId: 'context',
|
||||
payload: {},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('request on a non-context block', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
@ -392,14 +306,14 @@ test('request on a non-context block', async () => {
|
||||
blockId: 'page_1',
|
||||
operators: [],
|
||||
pageId: 'page_1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page_1:page_1:request_1',
|
||||
id: 'request:page_1:request_1',
|
||||
auth: { public: true },
|
||||
requestId: 'request_1',
|
||||
contextId: 'page_1',
|
||||
pageId: 'page_1',
|
||||
payload: {},
|
||||
},
|
||||
],
|
||||
@ -420,212 +334,12 @@ test('request on a non-context block', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('request on a non-context block below a context block not at root', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'context',
|
||||
type: 'Context',
|
||||
blocks: [
|
||||
{
|
||||
id: 'box',
|
||||
type: 'Container',
|
||||
requests: [
|
||||
{
|
||||
id: 'request_1',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(res).toEqual({
|
||||
pages: [
|
||||
{
|
||||
id: 'page:page_1',
|
||||
auth: { public: true },
|
||||
operators: [],
|
||||
pageId: 'page_1',
|
||||
blockId: 'page_1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
requests: [],
|
||||
areas: {
|
||||
content: {
|
||||
blocks: [
|
||||
{
|
||||
id: 'block:page_1:context',
|
||||
blockId: 'context',
|
||||
type: 'Context',
|
||||
operators: [],
|
||||
meta: outputMetas.Context,
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page_1:context:request_1',
|
||||
auth: { public: true },
|
||||
requestId: 'request_1',
|
||||
contextId: 'context',
|
||||
payload: {},
|
||||
},
|
||||
],
|
||||
areas: {
|
||||
content: {
|
||||
blocks: [
|
||||
{
|
||||
id: 'block:page_1:box',
|
||||
blockId: 'box',
|
||||
meta: outputMetas.Container,
|
||||
type: 'Container',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('request on a non-context block below a context block and at root', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
auth,
|
||||
blocks: [
|
||||
{
|
||||
id: 'context',
|
||||
type: 'Context',
|
||||
blocks: [
|
||||
{
|
||||
id: 'box-inner',
|
||||
type: 'Container',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'box',
|
||||
type: 'Container',
|
||||
requests: [
|
||||
{
|
||||
id: 'request_1',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const res = await buildPages({ components, context });
|
||||
expect(res).toEqual({
|
||||
pages: [
|
||||
{
|
||||
id: 'page:page_1',
|
||||
auth: { public: true },
|
||||
blockId: 'page_1',
|
||||
type: 'Context',
|
||||
meta: {
|
||||
category: 'context',
|
||||
loading: { type: 'Spinner' },
|
||||
moduleFederation: {
|
||||
module: 'Context',
|
||||
scope: 'blocks',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
},
|
||||
operators: [],
|
||||
pageId: 'page_1',
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page_1:page_1:request_1',
|
||||
auth: { public: true },
|
||||
contextId: 'page_1',
|
||||
requestId: 'request_1',
|
||||
payload: {},
|
||||
},
|
||||
],
|
||||
areas: {
|
||||
content: {
|
||||
blocks: [
|
||||
{
|
||||
id: 'block:page_1:context',
|
||||
blockId: 'context',
|
||||
operators: [],
|
||||
type: 'Context',
|
||||
requests: [],
|
||||
areas: {
|
||||
content: {
|
||||
blocks: [
|
||||
{
|
||||
blockId: 'box-inner',
|
||||
id: 'block:page_1:box-inner',
|
||||
meta: {
|
||||
category: 'container',
|
||||
loading: {
|
||||
type: 'Spinner',
|
||||
},
|
||||
moduleFederation: {
|
||||
module: 'Container',
|
||||
scope: 'blocks',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
},
|
||||
type: 'Container',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
meta: {
|
||||
category: 'context',
|
||||
loading: { type: 'Spinner' },
|
||||
moduleFederation: {
|
||||
module: 'Context',
|
||||
scope: 'blocks',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'block:page_1:box',
|
||||
blockId: 'box',
|
||||
type: 'Container',
|
||||
meta: {
|
||||
category: 'container',
|
||||
loading: { type: 'Spinner' },
|
||||
moduleFederation: {
|
||||
module: 'Container',
|
||||
scope: 'blocks',
|
||||
url: 'https://example.com/remoteEntry.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('multiple requests', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page_1',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth,
|
||||
requests: [
|
||||
{
|
||||
@ -647,21 +361,21 @@ test('multiple requests', async () => {
|
||||
operators: [],
|
||||
pageId: 'page_1',
|
||||
blockId: 'page_1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page_1:page_1:request_1',
|
||||
id: 'request:page_1:request_1',
|
||||
auth: { public: true },
|
||||
requestId: 'request_1',
|
||||
contextId: 'page_1',
|
||||
pageId: 'page_1',
|
||||
payload: {},
|
||||
},
|
||||
{
|
||||
id: 'request:page_1:page_1:request_2',
|
||||
id: 'request:page_1:request_2',
|
||||
auth: { public: true },
|
||||
requestId: 'request_2',
|
||||
contextId: 'page_1',
|
||||
pageId: 'page_1',
|
||||
payload: {},
|
||||
},
|
||||
],
|
||||
@ -676,7 +390,7 @@ test('set auth to request', async () => {
|
||||
{
|
||||
id: 'page_1',
|
||||
auth: { public: true },
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
requests: [
|
||||
{
|
||||
id: 'request_1',
|
||||
@ -685,7 +399,7 @@ test('set auth to request', async () => {
|
||||
},
|
||||
{
|
||||
id: 'page_2',
|
||||
type: 'Context',
|
||||
type: 'Container',
|
||||
auth: { public: false },
|
||||
requests: [
|
||||
{
|
||||
@ -704,14 +418,14 @@ test('set auth to request', async () => {
|
||||
operators: [],
|
||||
pageId: 'page_1',
|
||||
blockId: 'page_1',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page_1:page_1:request_1',
|
||||
id: 'request:page_1:request_1',
|
||||
auth: { public: true },
|
||||
requestId: 'request_1',
|
||||
contextId: 'page_1',
|
||||
pageId: 'page_1',
|
||||
payload: {},
|
||||
},
|
||||
],
|
||||
@ -722,14 +436,14 @@ test('set auth to request', async () => {
|
||||
operators: [],
|
||||
pageId: 'page_2',
|
||||
blockId: 'page_2',
|
||||
type: 'Context',
|
||||
meta: outputMetas.Context,
|
||||
type: 'Container',
|
||||
meta: outputMetas.Container,
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page_2:page_2:request_2',
|
||||
id: 'request:page_2:request_2',
|
||||
auth: { public: false },
|
||||
requestId: 'request_2',
|
||||
contextId: 'page_2',
|
||||
pageId: 'page_2',
|
||||
payload: {},
|
||||
},
|
||||
],
|
||||
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { type } from '@lowdefy/helpers';
|
||||
|
||||
async function checkPageIsContext(page, { getMeta }) {
|
||||
if (type.isNone(page.type)) {
|
||||
throw new Error(`Page type is not defined at ${page.pageId}.`);
|
||||
}
|
||||
if (!type.isString(page.type)) {
|
||||
throw new Error(
|
||||
`Page type is not a string at ${page.pageId}. Received ${JSON.stringify(page.type)}`
|
||||
);
|
||||
}
|
||||
const meta = await getMeta(page.type);
|
||||
if (!meta) {
|
||||
throw new Error(
|
||||
`Invalid block type at page ${page.pageId}. Received ${JSON.stringify(page.type)}`
|
||||
);
|
||||
}
|
||||
if (meta.category !== 'context') {
|
||||
throw new Error(
|
||||
`Page ${page.pageId} is not of category "context". Received ${JSON.stringify(page.type)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default checkPageIsContext;
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { get, type } from '@lowdefy/helpers';
|
||||
|
||||
function getContextOperators(block) {
|
||||
const stripContext = (_, value) => {
|
||||
if (get(value, 'meta.category') === 'context') {
|
||||
return null;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
const { requests, ...webBlock } = block;
|
||||
webBlock.areas = JSON.parse(JSON.stringify(webBlock.areas || {}), stripContext);
|
||||
const operators = new Set();
|
||||
const pushOperators = (_, value) => {
|
||||
if (type.isObject(value) && Object.keys(value).length === 1) {
|
||||
const key = Object.keys(value)[0];
|
||||
const [op] = key.split('.');
|
||||
const operator = op.replace(/^(_+)/gm, '_');
|
||||
if (operator.length > 1 && operator[0] === '_') {
|
||||
operators.add(operator);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
};
|
||||
JSON.parse(JSON.stringify(webBlock), pushOperators);
|
||||
requests.forEach((request) => {
|
||||
JSON.parse(JSON.stringify(request.payload), pushOperators);
|
||||
});
|
||||
return [...operators];
|
||||
}
|
||||
|
||||
function fillContextOperators(block) {
|
||||
if (get(block, 'meta.category') === 'context') {
|
||||
block.operators = getContextOperators(block);
|
||||
}
|
||||
Object.keys(block.areas || {}).forEach((key) => {
|
||||
block.areas[key].blocks.map((blk) => {
|
||||
fillContextOperators(blk);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export default fillContextOperators;
|
@ -14,62 +14,29 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { serializer, type } from '@lowdefy/helpers';
|
||||
import { type } from '@lowdefy/helpers';
|
||||
|
||||
function getRequestsOnBlock({ block, requests, pageId }) {
|
||||
if (!type.isObject(block)) {
|
||||
throw new Error(`Block is not an object on page "${pageId}".`);
|
||||
}
|
||||
if (!type.isNone(block.requests)) {
|
||||
if (!type.isArray(block.requests)) {
|
||||
throw new Error(`Requests is not an array on page "${pageId}".`);
|
||||
}
|
||||
block.requests.forEach((request) => {
|
||||
requests.push(serializer.copy(request));
|
||||
async function writeRequestsOnPage({ page, context }) {
|
||||
return Promise.all(
|
||||
page.requests.map(async (request) => {
|
||||
await context.writeBuildArtifact({
|
||||
filePath: `pages/${page.pageId}/requests/${request.requestId}.json`,
|
||||
content: JSON.stringify(request, null, 2),
|
||||
});
|
||||
delete request.properties;
|
||||
delete request.type;
|
||||
delete request.connectionId;
|
||||
delete request.auth;
|
||||
});
|
||||
}
|
||||
if (type.isObject(block.areas)) {
|
||||
Object.keys(block.areas).forEach((key) => {
|
||||
if (!type.isArray(block.areas[key].blocks)) {
|
||||
throw new Error(
|
||||
`Blocks is not an array on page "${pageId}", block "${block.blockId}", area "${key}".`
|
||||
);
|
||||
}
|
||||
block.areas[key].blocks.forEach((blk) => {
|
||||
getRequestsOnBlock({ block: blk, requests, pageId });
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function writeRequestsOnPage({ page, context }) {
|
||||
if (!type.isObject(page)) {
|
||||
throw new Error(`Page is not an object.`);
|
||||
}
|
||||
const requests = [];
|
||||
getRequestsOnBlock({ block: page, requests, pageId: page.pageId });
|
||||
|
||||
return requests.map(async (request) => {
|
||||
await context.writeBuildArtifact({
|
||||
filePath: `pages/${page.pageId}/requests/${request.contextId}/${request.requestId}.json`,
|
||||
content: JSON.stringify(request, null, 2),
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async function writeRequests({ components, context }) {
|
||||
if (type.isNone(components.pages)) return;
|
||||
if (!type.isArray(components.pages)) {
|
||||
throw new Error(`Pages is not an array.`);
|
||||
}
|
||||
const writePromises = components.pages.map((page) => writeRequestsOnPage({ page, context }));
|
||||
return Promise.all(writePromises);
|
||||
}
|
||||
|
||||
export { getRequestsOnBlock };
|
||||
// export { getRequestsOnBlock };
|
||||
|
||||
export default writeRequests;
|
||||
|
@ -33,10 +33,13 @@ test('writeRequests write request', async () => {
|
||||
pageId: 'page1',
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page1:page1:request1',
|
||||
id: 'request:page1:request1',
|
||||
requestId: 'request1',
|
||||
contextId: 'page1',
|
||||
pageId: 'page1',
|
||||
connectionId: 'connection1',
|
||||
auth: { public: true },
|
||||
type: 'Request',
|
||||
payload: {},
|
||||
properties: { key: 'value' },
|
||||
},
|
||||
],
|
||||
@ -47,12 +50,17 @@ test('writeRequests write request', async () => {
|
||||
expect(mockWriteBuildArtifact.mock.calls).toEqual([
|
||||
[
|
||||
{
|
||||
filePath: 'pages/page1/requests/page1/request1.json',
|
||||
filePath: 'pages/page1/requests/request1.json',
|
||||
content: `{
|
||||
"id": "request:page1:page1:request1",
|
||||
"id": "request:page1:request1",
|
||||
"requestId": "request1",
|
||||
"contextId": "page1",
|
||||
"pageId": "page1",
|
||||
"connectionId": "connection1",
|
||||
"auth": {
|
||||
"public": true
|
||||
},
|
||||
"type": "Request",
|
||||
"payload": {},
|
||||
"properties": {
|
||||
"key": "value"
|
||||
}
|
||||
@ -62,31 +70,34 @@ test('writeRequests write request', async () => {
|
||||
]);
|
||||
});
|
||||
|
||||
test('writeRequests write nested request', async () => {
|
||||
test('writeRequests write multiple requests on a page', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page:page1',
|
||||
pageId: 'page1',
|
||||
areas: {
|
||||
content: {
|
||||
blocks: [
|
||||
{
|
||||
id: 'block:block1',
|
||||
blockId: 'block1',
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page1:page1:request1',
|
||||
requestId: 'request1',
|
||||
contextId: 'page1',
|
||||
connectionId: 'connection1',
|
||||
properties: { key: 'value' },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page1:request1',
|
||||
requestId: 'request1',
|
||||
pageId: 'page1',
|
||||
connectionId: 'connection1',
|
||||
auth: { public: true },
|
||||
type: 'Request',
|
||||
payload: {},
|
||||
properties: { key: 'value' },
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'request:page1:request2',
|
||||
requestId: 'request2',
|
||||
pageId: 'page1',
|
||||
connectionId: 'connection1',
|
||||
auth: { public: true },
|
||||
type: 'Request',
|
||||
payload: {},
|
||||
properties: { key: 'value' },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
@ -94,12 +105,36 @@ test('writeRequests write nested request', async () => {
|
||||
expect(mockWriteBuildArtifact.mock.calls).toEqual([
|
||||
[
|
||||
{
|
||||
filePath: 'pages/page1/requests/page1/request1.json',
|
||||
filePath: 'pages/page1/requests/request1.json',
|
||||
content: `{
|
||||
"id": "request:page1:page1:request1",
|
||||
"id": "request:page1:request1",
|
||||
"requestId": "request1",
|
||||
"contextId": "page1",
|
||||
"pageId": "page1",
|
||||
"connectionId": "connection1",
|
||||
"auth": {
|
||||
"public": true
|
||||
},
|
||||
"type": "Request",
|
||||
"payload": {},
|
||||
"properties": {
|
||||
"key": "value"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
filePath: 'pages/page1/requests/request2.json',
|
||||
content: `{
|
||||
"id": "request:page1:request2",
|
||||
"requestId": "request2",
|
||||
"pageId": "page1",
|
||||
"connectionId": "connection1",
|
||||
"auth": {
|
||||
"public": true
|
||||
},
|
||||
"type": "Request",
|
||||
"payload": {},
|
||||
"properties": {
|
||||
"key": "value"
|
||||
}
|
||||
@ -109,19 +144,84 @@ test('writeRequests write nested request', async () => {
|
||||
]);
|
||||
});
|
||||
|
||||
test('writeRequests requests is not an array', async () => {
|
||||
test('writeRequests write requests on a for multiple pages', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page:page1',
|
||||
pageId: 'page1',
|
||||
requests: 'requests',
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page1:request1',
|
||||
requestId: 'request1',
|
||||
pageId: 'page1',
|
||||
connectionId: 'connection1',
|
||||
auth: { public: true },
|
||||
type: 'Request',
|
||||
payload: {},
|
||||
properties: { key: 'value' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'page:page2',
|
||||
pageId: 'page2',
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page2:request1',
|
||||
requestId: 'request1',
|
||||
pageId: 'page2',
|
||||
connectionId: 'connection1',
|
||||
auth: { public: true },
|
||||
type: 'Request',
|
||||
payload: {},
|
||||
properties: { key: 'value' },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
await expect(writeRequests({ components, context })).rejects.toThrow(
|
||||
'Requests is not an array on page "page1"'
|
||||
);
|
||||
await writeRequests({ components, context });
|
||||
expect(mockWriteBuildArtifact.mock.calls).toEqual([
|
||||
[
|
||||
{
|
||||
filePath: 'pages/page1/requests/request1.json',
|
||||
content: `{
|
||||
"id": "request:page1:request1",
|
||||
"requestId": "request1",
|
||||
"pageId": "page1",
|
||||
"connectionId": "connection1",
|
||||
"auth": {
|
||||
"public": true
|
||||
},
|
||||
"type": "Request",
|
||||
"payload": {},
|
||||
"properties": {
|
||||
"key": "value"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
filePath: 'pages/page2/requests/request1.json',
|
||||
content: `{
|
||||
"id": "request:page2:request1",
|
||||
"requestId": "request1",
|
||||
"pageId": "page2",
|
||||
"connectionId": "connection1",
|
||||
"auth": {
|
||||
"public": true
|
||||
},
|
||||
"type": "Request",
|
||||
"payload": {},
|
||||
"properties": {
|
||||
"key": "value"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test('writeRequests empty pages array', async () => {
|
||||
@ -138,60 +238,6 @@ test('writeRequests no pages array', async () => {
|
||||
expect(mockWriteBuildArtifact.mock.calls).toEqual([]);
|
||||
});
|
||||
|
||||
test('writeRequests pages not an array', async () => {
|
||||
const components = {
|
||||
pages: 'pages',
|
||||
};
|
||||
await expect(writeRequests({ components, context })).rejects.toThrow('Pages is not an array.');
|
||||
});
|
||||
|
||||
test('writeRequests page is not a object', async () => {
|
||||
const components = {
|
||||
pages: ['page'],
|
||||
};
|
||||
await expect(writeRequests({ components, context })).rejects.toThrow('Page is not an object.');
|
||||
});
|
||||
|
||||
test('writeRequests to throw when blocks is not a array', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page:page1',
|
||||
pageId: 'page1',
|
||||
blockId: 'page1',
|
||||
areas: {
|
||||
content: {
|
||||
blocks: 'blocks',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
await expect(writeRequests({ components, context })).rejects.toThrow(
|
||||
'Blocks is not an array on page "page1", block "page1", area "content".'
|
||||
);
|
||||
});
|
||||
|
||||
test('writeRequests to throw when block is not an object', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
{
|
||||
id: 'page:page1',
|
||||
pageId: 'page1',
|
||||
blockId: 'page1',
|
||||
areas: {
|
||||
content: {
|
||||
blocks: ['block'],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
await expect(writeRequests({ components, context })).rejects.toThrow(
|
||||
'Block is not an object on page "page1".'
|
||||
);
|
||||
});
|
||||
|
||||
test('writeRequests deletes request properties', async () => {
|
||||
const components = {
|
||||
pages: [
|
||||
@ -200,11 +246,20 @@ test('writeRequests deletes request properties', async () => {
|
||||
pageId: 'page1',
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page1:page1:request1',
|
||||
id: 'request:page1:request1',
|
||||
requestId: 'request1',
|
||||
type: 'RequestType',
|
||||
connectionId: 'connection1',
|
||||
payload: { payload: true },
|
||||
payload: { payload: 1 },
|
||||
auth: { public: true },
|
||||
properties: { key: 'value' },
|
||||
},
|
||||
{
|
||||
id: 'request:page1:request2',
|
||||
requestId: 'request2',
|
||||
type: 'RequestType',
|
||||
connectionId: 'connection1',
|
||||
payload: { payload: 2 },
|
||||
auth: { public: true },
|
||||
properties: { key: 'value' },
|
||||
},
|
||||
@ -215,17 +270,6 @@ test('writeRequests deletes request properties', async () => {
|
||||
{
|
||||
id: 'block:block1',
|
||||
blockId: 'block1',
|
||||
requests: [
|
||||
{
|
||||
id: 'request:request2',
|
||||
requestId: 'request1',
|
||||
type: 'RequestType',
|
||||
connectionId: 'connection1',
|
||||
payload: { payload: true },
|
||||
auth: { public: true },
|
||||
properties: { key: 'value' },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -241,9 +285,14 @@ test('writeRequests deletes request properties', async () => {
|
||||
pageId: 'page1',
|
||||
requests: [
|
||||
{
|
||||
id: 'request:page1:page1:request1',
|
||||
id: 'request:page1:request1',
|
||||
requestId: 'request1',
|
||||
payload: { payload: true },
|
||||
payload: { payload: 1 },
|
||||
},
|
||||
{
|
||||
id: 'request:page1:request2',
|
||||
requestId: 'request2',
|
||||
payload: { payload: 2 },
|
||||
},
|
||||
],
|
||||
areas: {
|
||||
@ -252,13 +301,6 @@ test('writeRequests deletes request properties', async () => {
|
||||
{
|
||||
id: 'block:block1',
|
||||
blockId: 'block1',
|
||||
requests: [
|
||||
{
|
||||
id: 'request:request2',
|
||||
requestId: 'request1',
|
||||
payload: { payload: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user