Skip to content

Commit 4068c74

Browse files
author
Christian Westgaard
committed
Support nested data when importing, and support fragment and text component in ContentConnection
1 parent 840c8bf commit 4068c74

File tree

9 files changed

+483
-205
lines changed

9 files changed

+483
-205
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
/enonic-mock-xp-*.tgz
66
/yarn-error.log
77
.idea
8+
.DS_store

src/implementation/Branch.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import {
2828
isFilter,
2929
isHasValueFilter,
3030
isQueryDsl,
31-
toStr
3231
} from '@enonic/js-utils';
3332
import {flatten} from '@enonic/js-utils/array/flatten';
3433
import {forceArray} from '@enonic/js-utils/array/forceArray';
@@ -286,7 +285,7 @@ export class Branch {
286285
)
287286
)) {
288287
if (this.repo.server.indexWarnings) {
289-
this.log.warning('mock-xp is only able to (index for quering) boolean and string properties, skipping rootProp:%s with value:%s', rootProp, toStr(rootPropValue));
288+
this.log.warning('mock-xp is only able to (index for quering) boolean and string properties, skipping rootProp:%s with value:%s', rootProp, rootPropValue);
290289
}
291290
continue RestKeys;
292291
}
@@ -377,7 +376,7 @@ export class Branch {
377376

378377
if (!isString(rootPropValue)) {
379378
if (this.repo.server.indexWarnings) {
380-
this.log.warning('mock-xp is not able to handle non-string properties yet, skipping rootProp:%s with value:%s', rootPropKey, toStr(rootPropValue));
379+
this.log.warning('mock-xp is not able to handle non-string properties yet, skipping rootProp:%s with value:%s', rootPropKey, rootPropValue);
381380
}
382381
continue RootProps;
383382
}
@@ -588,7 +587,7 @@ export class Branch {
588587
) {
589588
for (const value of values) {
590589
if (!supportedValueType(value)) {
591-
this.log.error('query: Unsupported value type:%s', toStr(value));
590+
this.log.error('query: Unsupported value type:%s', value);
592591
} else {
593592
if (
594593
// @ts-ignore Object is possibly 'undefined'.ts(2532)

src/implementation/ContentConnection.ts

Lines changed: 93 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,33 @@ import {
4242
getIn,
4343
// deleteIn,
4444
setIn,
45-
// toStr // log mock does not support need toStr, but throwing Errors does.
45+
toStr // log mock does not support need toStr, but throwing Errors does.
4646
} from '@enonic/js-utils';
4747
import { sha512 } from 'node-forge';
4848
import { sync as probeSync } from 'probe-image-size';
4949
import {
5050
INDEX_CONFIG_DEFAULT,
5151
PERMISSIONS_DEFAULT,
5252
} from './node/constants';
53-
import {NodeAlreadyExistAtPathException} from './node/NodeAlreadyExistAtPathException';
54-
import {NodeNotFoundException} from './node/NodeNotFoundException';
53+
import { NodeAlreadyExistAtPathException } from './node/NodeAlreadyExistAtPathException';
54+
import { NodeNotFoundException } from './node/NodeNotFoundException';
5555

5656

57+
declare interface NodeComponenFragment {
58+
fragment: {
59+
id: string;
60+
};
61+
path: string;
62+
type: 'fragment';
63+
}
64+
5765
declare interface NodeComponentLayout {
5866
layout: {
5967
config?: NestedRecord
6068
descriptor: ComponentDescriptor
6169
}
62-
path: string
63-
type: 'layout'
70+
path: string;
71+
type: 'layout';
6472
}
6573

6674
declare interface NodeComponentPage {
@@ -69,20 +77,33 @@ declare interface NodeComponentPage {
6977
customized: boolean
7078
descriptor: ComponentDescriptor
7179
}
72-
path: string
73-
type: 'page'
80+
path: string;
81+
type: 'page';
7482
}
7583

7684
declare interface NodeComponentPart {
7785
part: {
7886
config?: NestedRecord
7987
descriptor: ComponentDescriptor
8088
}
81-
path: string
82-
type: 'part'
89+
path: string;
90+
type: 'part';
91+
}
92+
93+
declare interface NodeComponentText {
94+
path: string;
95+
text: {
96+
value: string;
97+
};
98+
type: 'text';
8399
}
84100

85-
declare type NodeComponent = NodeComponentLayout | NodeComponentPage | NodeComponentPart;
101+
declare type NodeComponent =
102+
| NodeComponenFragment
103+
| NodeComponentLayout
104+
| NodeComponentPage
105+
| NodeComponentPart
106+
| NodeComponentText;
86107

87108
declare interface ContentProperties<Data, Type> {
88109
createdTime: string
@@ -137,6 +158,14 @@ declare type ContentToNode<
137158
const CHILD_ORDER_DEFAULT = 'displayname ASC'; // NOTE: With small n is actually what Content Studio does.
138159
const USER_DEFAULT: UserKey = 'user:system:su';
139160

161+
const COMPONENT_TYPE = {
162+
FRAGMENT: 'fragment',
163+
LAYOUT: 'layout',
164+
PAGE: 'page',
165+
PART: 'part',
166+
TEXT: 'text',
167+
} as const;
168+
140169

141170
export class ContentConnection {
142171
readonly branch: Branch;
@@ -626,8 +655,6 @@ export class ContentConnection {
626655
const {
627656
path,
628657
type,
629-
// part,
630-
// layout
631658
} = component;
632659
if (type === 'page' && path === '/') {
633660
const {
@@ -660,65 +687,87 @@ export class ContentConnection {
660687
});
661688
}
662689

663-
const pageRegion = fragmentOrPage.regions[pageRegionName]
664-
// this.log.debug('pageRegion: %s', pageRegion)
690+
const pageRegion = fragmentOrPage.regions[pageRegionName];
691+
// this.log.debug('pageRegion: %s', pageRegion);
665692

666-
if (type === 'layout') {
693+
if (type === COMPONENT_TYPE.LAYOUT) {
667694
const {
668695
layout: {
669696
config,
670-
descriptor
697+
descriptor,
671698
}
672699
} = component;
673-
const [app, componentName] = descriptor.split(':');
700+
const [ app, componentName ] = descriptor.split(':');
674701
const dashedApp = app.replace(/\./g, '-');
675702
const layout = {
676703
config: config?.[dashedApp]?.[componentName],
677704
descriptor,
678705
path,
706+
// NOTE: component contains no information about which regions it has.
679707
regions: {},
680-
type
708+
type,
681709
};
682710
pageRegion.components.push(layout);
683-
} else if (type === 'part') {
684-
const {
685-
part: {
686-
config,
687-
descriptor
688-
}
689-
} = component;
690-
const [app, componentName] = descriptor.split(':');
691-
const dashedApp = app.replace(/\./g, '-');
692-
const part = {
693-
config: config?.[dashedApp]?.[componentName],
694-
descriptor,
695-
path,
696-
type
697-
};
711+
} else { // fragment, part, text
712+
let components;
698713
if (pathParts.length === 2) {
699-
pageRegion.components.push(part);
714+
components = pageRegion.components;
700715
} else if (pathParts.length === 4) {
716+
// this.log.debug('component: %s', component);
701717
const pageComponentRegionIndex = pathParts[1];
702-
// this.log.debug('pageComponentRegionIndex: %s', pageComponentRegionIndex)
703-
718+
// this.log.debug('pageComponentRegionIndex: %s', pageComponentRegionIndex);
719+
// this.log.debug('pageRegion: %s', pageRegion);
704720
const layoutComponent = pageRegion.components[pageComponentRegionIndex];
705-
// this.log.debug('layoutComponent: %s', layoutComponent)
706-
721+
// this.log.debug('layoutComponent1: %s', layoutComponent);
707722
const layoutRegionName = pathParts[2];
708-
// this.log.debug('layoutRegionName: %s', layoutRegionName)
709-
723+
// this.log.debug('layoutRegionName: %s', layoutRegionName);
710724
if (!layoutComponent.regions[layoutRegionName]) {
711725
layoutComponent.regions[layoutRegionName] = {
712726
components: [],
713727
name: layoutRegionName,
728+
};
729+
}
730+
// this.log.debug('layoutComponent2: %s', layoutComponent);
731+
components = layoutComponent.regions[layoutRegionName].components;
732+
} else {
733+
throw new Error(`pathParts.length !== 2 or 4 component:${toStr(component)}`);
734+
}
735+
if (type === COMPONENT_TYPE.PART) {
736+
const {
737+
part: {
738+
config,
739+
descriptor
714740
}
715-
};
716-
layoutComponent.regions[layoutRegionName].components.push(part);
741+
} = component;
742+
const [ app, componentName ] = descriptor.split(':');
743+
const dashedApp = app.replace(/\./g, '-');
744+
components.push({
745+
config: config?.[dashedApp]?.[componentName],
746+
descriptor,
747+
path,
748+
type
749+
});
750+
} else if (type === COMPONENT_TYPE.TEXT) {
751+
const { text: { value: text } } = component;
752+
components.push({
753+
path,
754+
text,
755+
type,
756+
});
757+
} else if (type === COMPONENT_TYPE.FRAGMENT) {
758+
const { fragment: { id: fragment } } = component;
759+
components.push({
760+
fragment,
761+
path,
762+
type,
763+
});
764+
} else {
765+
throw new Error(`type !== fragment, part nor text! type:${type}`);
717766
}
718-
}
767+
} // if componentType[...]
719768
}
720769
} // for components
721-
}
770+
} // if components
722771

723772
return content as C;
724773
} // nodeToContent

0 commit comments

Comments
 (0)