@next-core/brick-utils 2.44.7 → 2.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -605,271 +605,616 @@
605
605
  }
606
606
 
607
607
  // Ref https://github.com/lodash/lodash/blob/4.17.11/lodash.js#L11744
608
- function isObject(value) {
608
+ function isObject$1(value) {
609
609
  var type = typeof value;
610
610
  return value != null && (type == "object" || type == "function");
611
611
  }
612
612
 
613
- /**
614
- * Scan bricks and custom apis in storyboard.
615
- *
616
- * @param storyboard - Storyboard.
617
- * @param options - If options is a boolean, it means `isUniq` or `de-duplicate`.
618
- */
619
- function scanStoryboard(storyboard) {
620
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
621
- var {
622
- keepDuplicates,
623
- ignoreBricksInUnusedCustomTemplates
624
- } = isObject(options) ? options : {
625
- keepDuplicates: !options
613
+ /** Parse storyboard as AST. */
614
+
615
+ function parseStoryboard(storyboard) {
616
+ var _storyboard$meta;
617
+
618
+ return {
619
+ type: "Root",
620
+ raw: storyboard,
621
+ routes: parseRoutes(storyboard.routes),
622
+ templates: parseTemplates((_storyboard$meta = storyboard.meta) === null || _storyboard$meta === void 0 ? void 0 : _storyboard$meta.customTemplates)
626
623
  };
627
- var collection = [];
628
- collectBricksInRouteConfs(storyboard.routes, collection);
629
- var selfDefined = new Set(["form-renderer.form-renderer"]);
624
+ }
625
+ /** Parse storyboard routes as AST. */
630
626
 
631
- if (ignoreBricksInUnusedCustomTemplates) {
632
- var _storyboard$meta;
627
+ function parseRoutes(routes, options) {
628
+ if (Array.isArray(routes)) {
629
+ return routes.map(route => _objectSpread__default["default"](_objectSpread__default["default"]({
630
+ type: "Route",
631
+ raw: route
632
+ }, options !== null && options !== void 0 && options.routesOnly ? null : {
633
+ context: parseContext(route.context),
634
+ redirect: parseResolvable(route.redirect),
635
+ menu: parseMenu(route.menu),
636
+ providers: parseRouteProviders(route.providers),
637
+ defineResolves: Array.isArray(route.defineResolves) ? route.defineResolves.map(item => parseResolvable(item)).filter(Boolean) : undefined
638
+ }), {}, {
639
+ children: route.type === "routes" ? parseRoutes(route.routes, options) : parseBricks(route.bricks, options)
640
+ }));
641
+ }
642
+
643
+ return [];
644
+ }
645
+ /** Parse storyboard templates as AST. */
633
646
 
634
- // Only collect bricks in used custom templates.
635
- var collectionByTpl = collectBricksByCustomTemplates((_storyboard$meta = storyboard.meta) === null || _storyboard$meta === void 0 ? void 0 : _storyboard$meta.customTemplates);
647
+ function parseTemplates(templates) {
648
+ if (Array.isArray(templates)) {
649
+ return templates.map(parseTemplate);
650
+ }
636
651
 
637
- for (var item of collection) {
638
- if (collectionByTpl.has(item) && !selfDefined.has(item)) {
639
- selfDefined.add(item);
640
- collection.push(...collectionByTpl.get(item));
641
- }
642
- }
643
- } else {
644
- var _storyboard$meta2;
652
+ return [];
653
+ }
654
+ /** Parse a storyboard template as AST. */
645
655
 
646
- collectBricksInCustomTemplates((_storyboard$meta2 = storyboard.meta) === null || _storyboard$meta2 === void 0 ? void 0 : _storyboard$meta2.customTemplates, collection, selfDefined);
656
+ function parseTemplate(tpl) {
657
+ return {
658
+ type: "Template",
659
+ raw: tpl,
660
+ bricks: parseBricks(tpl.bricks),
661
+ context: parseContext(tpl.state)
662
+ };
663
+ }
664
+
665
+ function parseBricks(bricks, options) {
666
+ if (Array.isArray(bricks)) {
667
+ return bricks.map(brick => parseBrick(brick, options));
647
668
  }
648
669
 
649
- var bricks = [];
650
- var customApis = [];
651
- collection.forEach(item => {
652
- if (item.includes("@")) {
653
- customApis.push(item);
654
- } else {
655
- if (item.includes("-") && !selfDefined.has(item)) {
656
- bricks.push(item);
657
- }
658
- }
670
+ return [];
671
+ }
672
+ /** Parse a storyboard brick as AST. */
673
+
674
+
675
+ function parseBrick(brick, options) {
676
+ return _objectSpread__default["default"](_objectSpread__default["default"]({
677
+ type: "Brick",
678
+ raw: brick,
679
+ isUseBrick: options === null || options === void 0 ? void 0 : options.isUseBrick
680
+ }, options !== null && options !== void 0 && options.routesOnly ? null : _objectSpread__default["default"](_objectSpread__default["default"]({
681
+ if: parseCondition(brick.if),
682
+ events: parseEvents(brick.events),
683
+ lifeCycle: parseLifeCycles(brick.lifeCycle)
684
+ }, parseBrickProperties(brick.properties)), {}, {
685
+ context: parseContext(brick.context)
686
+ })), {}, {
687
+ children: parseSlots(brick.slots, options)
659
688
  });
689
+ }
690
+
691
+ function parseCondition(condition) {
692
+ if (isObject(condition)) {
693
+ return {
694
+ type: "ResolvableCondition",
695
+ resolve: parseResolvable(condition)
696
+ };
697
+ }
698
+
660
699
  return {
661
- bricks: keepDuplicates ? bricks : lodash.uniq(bricks),
662
- customApis: keepDuplicates ? customApis : lodash.uniq(customApis)
700
+ type: "LiteralCondition"
663
701
  };
664
702
  }
665
- function collectBricksInBrickConf(brickConf, collection) {
666
- if (brickConf.brick) {
667
- collection.push(brickConf.brick);
668
- }
669
703
 
670
- if (brickConf.slots) {
671
- Object.values(brickConf.slots).forEach(slotConf => {
672
- if (slotConf.type === "routes") {
673
- collectBricksInRouteConfs(slotConf.routes, collection);
704
+ function parseBrickProperties(props) {
705
+ var useBrick = [];
706
+ var useBackend = [];
707
+
708
+ function walkBrickProperties(value) {
709
+ if (Array.isArray(value)) {
710
+ for (var item of value) {
711
+ walkBrickProperties(item);
712
+ }
713
+ } else if (isObject(value)) {
714
+ if (value.useBrick || value.useBackend) {
715
+ var _value$useBackend;
716
+
717
+ if (value.useBrick) {
718
+ useBrick.push({
719
+ type: "UseBrickEntry",
720
+ rawContainer: value,
721
+ rawKey: "useBrick",
722
+ children: parseBricks([].concat(value.useBrick), {
723
+ isUseBrick: true
724
+ })
725
+ });
726
+ }
727
+
728
+ var provider = (_value$useBackend = value.useBackend) === null || _value$useBackend === void 0 ? void 0 : _value$useBackend.provider;
729
+
730
+ if (typeof provider === "string") {
731
+ useBackend.push({
732
+ type: "UseBackendEntry",
733
+ rawContainer: value,
734
+ rawKey: "useBackend",
735
+ children: [parseBrick({
736
+ brick: provider
737
+ })]
738
+ });
739
+ }
674
740
  } else {
675
- collectBricksInBrickConfs(slotConf.bricks, collection);
741
+ for (var _item of Object.values(value)) {
742
+ walkBrickProperties(_item);
743
+ }
744
+ }
745
+ }
746
+ }
747
+
748
+ walkBrickProperties(props);
749
+ return {
750
+ useBrick,
751
+ useBackend
752
+ };
753
+ }
754
+
755
+ function parseLifeCycles(lifeCycle) {
756
+ if (isObject(lifeCycle)) {
757
+ return Object.entries(lifeCycle).map(_ref => {
758
+ var [name, conf] = _ref;
759
+
760
+ switch (name) {
761
+ case "useResolves":
762
+ return {
763
+ type: "ResolveLifeCycle",
764
+ rawContainer: lifeCycle,
765
+ rawKey: name,
766
+ resolves: Array.isArray(conf) ? conf.map(item => parseResolvable(item, true)).filter(Boolean) : undefined
767
+ };
768
+
769
+ case "onPageLoad":
770
+ case "onPageLeave":
771
+ case "onAnchorLoad":
772
+ case "onAnchorUnload":
773
+ case "onMessageClose":
774
+ case "onBeforePageLoad":
775
+ case "onBeforePageLeave":
776
+ case "onMediaChange":
777
+ return {
778
+ type: "SimpleLifeCycle",
779
+ name,
780
+ rawContainer: lifeCycle,
781
+ rawKey: name,
782
+ handlers: parseEventHandlers(conf)
783
+ };
784
+
785
+ case "onMessage":
786
+ case "onScrollIntoView":
787
+ return {
788
+ type: "ConditionalLifeCycle",
789
+ name,
790
+ events: [].concat(conf).filter(Boolean).map(item => ({
791
+ type: "ConditionalEvent",
792
+ rawContainer: item,
793
+ rawKey: "handlers",
794
+ handlers: parseEventHandlers(item.handlers)
795
+ }))
796
+ };
797
+
798
+ default:
799
+ return {
800
+ type: "UnknownLifeCycle"
801
+ };
676
802
  }
677
803
  });
678
804
  }
805
+ }
679
806
 
680
- if (Array.isArray(brickConf.internalUsedBricks)) {
681
- brickConf.internalUsedBricks.forEach(brick => {
682
- collection.push(brick);
807
+ function parseSlots(slots, options) {
808
+ if (isObject(slots)) {
809
+ return Object.entries(slots).map(_ref2 => {
810
+ var [slot, conf] = _ref2;
811
+ return {
812
+ type: "Slot",
813
+ raw: conf,
814
+ slot,
815
+ childrenType: conf.type === "routes" ? "Route" : "Brick",
816
+ children: conf.type === "routes" ? parseRoutes(conf.routes, options) : parseBricks(conf.bricks, options)
817
+ };
683
818
  });
684
819
  }
685
820
 
686
- if (brickConf.lifeCycle) {
687
- var {
688
- useResolves,
689
- onPageLoad,
690
- onPageLeave,
691
- onAnchorLoad,
692
- onAnchorUnload,
693
- onMessage,
694
- onMessageClose,
695
- onBeforePageLoad,
696
- onBeforePageLeave,
697
- onMediaChange,
698
- onScrollIntoView
699
- } = brickConf.lifeCycle;
700
-
701
- if (Array.isArray(useResolves)) {
702
- useResolves.forEach(useResolve => {
703
- var useProvider = useResolve.useProvider;
704
-
705
- if (useProvider) {
706
- collection.push(useProvider);
707
- }
708
- });
709
- }
821
+ return [];
822
+ }
710
823
 
711
- var specialHandlers = [].concat(onMessage, onScrollIntoView).filter(Boolean).reduce((previousValue, currentValue) => previousValue.concat(currentValue.handlers), []);
712
- collectUsedBricksInEventHandlers({
713
- onPageLoad,
714
- onPageLeave,
715
- onAnchorLoad,
716
- onAnchorUnload,
717
- onMessageClose,
718
- onBeforePageLoad,
719
- onBeforePageLeave,
720
- onMediaChange,
721
- specialHandlers
722
- }, collection);
824
+ function parseEvents(events) {
825
+ if (isObject(events)) {
826
+ return Object.entries(events).map(_ref3 => {
827
+ var [eventType, handlers] = _ref3;
828
+ return {
829
+ type: "Event",
830
+ rawContainer: events,
831
+ rawKey: eventType,
832
+ handlers: parseEventHandlers(handlers)
833
+ };
834
+ });
723
835
  }
724
-
725
- collectUsedBricksInEventHandlers(brickConf.events, collection);
726
- collectBricksInResolvable(brickConf.if, collection);
727
- collectBricksInContext(brickConf.context, collection);
728
- collectUsedBricksInProperties(brickConf.properties, collection);
729
836
  }
730
837
 
731
- function collectBricksInResolvable(resolvable, collection) {
732
- if (isObject(resolvable) && resolvable.useProvider) {
733
- collection.push(resolvable.useProvider);
838
+ function parseContext(contexts) {
839
+ if (Array.isArray(contexts)) {
840
+ return contexts.map(context => ({
841
+ type: "Context",
842
+ raw: context,
843
+ resolve: parseResolvable(context.resolve),
844
+ onChange: parseEventHandlers(context.onChange)
845
+ }));
734
846
  }
735
847
  }
736
848
 
737
- function collectBricksInContext(context, collection) {
738
- if (Array.isArray(context)) {
739
- for (var ctx of context) {
740
- collectBricksInResolvable(ctx.resolve, collection);
849
+ function parseMenu(menu) {
850
+ if (menu === false) {
851
+ return {
852
+ type: "FalseMenu"
853
+ };
854
+ }
741
855
 
742
- if (ctx.onChange) {
743
- collectUsedBricksInEventHandlers({
744
- onChange: ctx.onChange
745
- }, collection);
746
- }
747
- }
856
+ if (!menu) {
857
+ return;
858
+ }
859
+
860
+ switch (menu.type) {
861
+ case "brick":
862
+ return {
863
+ type: "BrickMenu",
864
+ raw: menu,
865
+ brick: parseBrick(menu)
866
+ };
867
+
868
+ case "resolve":
869
+ return {
870
+ type: "ResolvableMenu",
871
+ resolve: parseResolvable(menu.resolve)
872
+ };
873
+
874
+ default:
875
+ return {
876
+ type: "StaticMenu"
877
+ };
748
878
  }
749
879
  }
750
880
 
751
- function collectUsedBricksInEventHandlers(events, collection) {
752
- if (isObject(events)) {
753
- Object.values(events).filter(Boolean).forEach(handlers => {
754
- [].concat(handlers).forEach(handler => {
755
- if (handler.useProvider) {
756
- collection.push(handler.useProvider);
757
- }
881
+ function parseResolvable(resolve, isConditional) {
882
+ if (isObject(resolve)) {
883
+ return {
884
+ type: "Resolvable",
885
+ raw: resolve,
886
+ isConditional
887
+ };
888
+ }
889
+ }
758
890
 
759
- if (handler.callback) {
760
- collectUsedBricksInEventHandlers(handler.callback, collection);
761
- }
762
- });
891
+ function parseEventHandlers(handlers) {
892
+ return [].concat(handlers).filter(Boolean).map(handler => ({
893
+ type: "EventHandler",
894
+ callback: parseEventCallback(handler.callback),
895
+ raw: handler
896
+ }));
897
+ }
898
+
899
+ function parseEventCallback(callback) {
900
+ if (isObject(callback)) {
901
+ return Object.entries(callback).map(_ref4 => {
902
+ var [callbackType, handlers] = _ref4;
903
+ return {
904
+ type: "EventCallback",
905
+ rawContainer: callback,
906
+ rawKey: callbackType,
907
+ handlers: parseEventHandlers(handlers)
908
+ };
763
909
  });
764
910
  }
765
911
  }
766
912
 
767
- function collectUsedBricksInProperties(value, collection) {
768
- if (Array.isArray(value)) {
769
- value.forEach(item => {
770
- collectUsedBricksInProperties(item, collection);
771
- });
772
- } else if (isObject(value)) {
773
- if (value.useBrick || value.useBackend) {
774
- if (value.useBrick) {
775
- [].concat(value.useBrick).forEach(useBrickConf => {
776
- if (typeof (useBrickConf === null || useBrickConf === void 0 ? void 0 : useBrickConf.brick) === "string") {
777
- collection.push(useBrickConf.brick);
778
- collectUsedBricksInProperties(useBrickConf.properties, collection);
779
- collectUsedBricksInEventHandlers(useBrickConf.events, collection);
780
-
781
- if (useBrickConf.slots) {
782
- Object.values(useBrickConf.slots).forEach(slotConf => {
783
- collectBricksInBrickConfs(slotConf.bricks, collection);
784
- });
785
- }
786
- }
787
- });
788
- }
913
+ function parseRouteProviders(providers) {
914
+ if (Array.isArray(providers)) {
915
+ return providers.map(provider => parseBrick(typeof provider === "string" ? {
916
+ brick: provider
917
+ } : provider));
918
+ }
919
+ } // Ref https://github.com/lodash/lodash/blob/4.17.11/lodash.js#L11744
789
920
 
790
- if (value.useBackend) {
791
- var _value$useBackend;
792
921
 
793
- if (typeof ((_value$useBackend = value.useBackend) === null || _value$useBackend === void 0 ? void 0 : _value$useBackend.provider) === "string") {
794
- var _value$useBackend2;
922
+ function isObject(value) {
923
+ var type = typeof value;
924
+ return value != null && (type == "object" || type == "function");
925
+ }
795
926
 
796
- collection.push((_value$useBackend2 = value.useBackend) === null || _value$useBackend2 === void 0 ? void 0 : _value$useBackend2.provider);
797
- }
798
- }
799
- } else {
800
- Object.values(value).forEach(item => {
801
- collectUsedBricksInProperties(item, collection);
802
- });
803
- }
927
+ /** Traverse a storyboard AST. */
928
+ function traverseStoryboard(ast, callback) {
929
+ traverseNode(ast, callback);
930
+ }
931
+ /** Traverse any node(s) in storyboard AST. */
932
+
933
+ function traverse(nodeOrNodes, callback) {
934
+ if (Array.isArray(nodeOrNodes)) {
935
+ traverseNodes(nodeOrNodes, callback);
936
+ } else {
937
+ traverseNode(nodeOrNodes, callback);
804
938
  }
805
939
  }
806
940
 
807
- function collectBricksInBrickConfs(bricks, collection) {
808
- if (Array.isArray(bricks)) {
809
- bricks.forEach(brickConf => {
810
- collectBricksInBrickConf(brickConf, collection);
811
- });
941
+ function traverseNodes(nodes, callback) {
942
+ if (!nodes) {
943
+ return;
944
+ }
945
+
946
+ for (var _node of nodes) {
947
+ traverseNode(_node, callback);
812
948
  }
813
949
  }
814
950
 
815
- function scanBricksInProviderConfs(providers, collection) {
816
- if (Array.isArray(providers)) {
817
- providers.forEach(providerConf => {
818
- collection.push(typeof providerConf === "string" ? providerConf : providerConf.brick);
819
- });
951
+ function traverseNode(node, callback) {
952
+ if (!node) {
953
+ return;
954
+ }
955
+
956
+ callback(node);
957
+
958
+ switch (node.type) {
959
+ case "Root":
960
+ traverseNodes(node.routes, callback);
961
+ traverseNodes(node.templates, callback);
962
+ break;
963
+
964
+ case "Route":
965
+ traverseNodes(node.context, callback);
966
+ traverseNode(node.redirect, callback);
967
+ traverseNode(node.menu, callback);
968
+ traverseNodes(node.providers, callback);
969
+ traverseNodes(node.defineResolves, callback);
970
+ traverseNodes(node.children, callback);
971
+ break;
972
+
973
+ case "Template":
974
+ traverseNodes(node.bricks, callback);
975
+ traverseNodes(node.context, callback);
976
+ break;
977
+
978
+ case "Brick":
979
+ traverseNode(node.if, callback);
980
+ traverseNodes(node.events, callback);
981
+ traverseNodes(node.lifeCycle, callback);
982
+ traverseNodes(node.useBrick, callback);
983
+ traverseNodes(node.useBackend, callback);
984
+ traverseNodes(node.context, callback);
985
+ traverseNodes(node.children, callback);
986
+ break;
987
+
988
+ case "Slot":
989
+ case "UseBrickEntry":
990
+ case "UseBackendEntry":
991
+ traverseNodes(node.children, callback);
992
+ break;
993
+
994
+ case "Context":
995
+ traverseNode(node.resolve, callback);
996
+ traverseNodes(node.onChange, callback);
997
+ break;
998
+
999
+ case "ResolvableCondition":
1000
+ case "ResolvableMenu":
1001
+ traverseNode(node.resolve, callback);
1002
+ break;
1003
+
1004
+ case "ResolveLifeCycle":
1005
+ traverseNodes(node.resolves, callback);
1006
+ break;
1007
+
1008
+ case "Event":
1009
+ case "EventCallback":
1010
+ case "SimpleLifeCycle":
1011
+ case "ConditionalEvent":
1012
+ traverseNodes(node.handlers, callback);
1013
+ break;
1014
+
1015
+ case "EventHandler":
1016
+ traverseNodes(node.callback, callback);
1017
+ break;
1018
+
1019
+ case "ConditionalLifeCycle":
1020
+ traverseNodes(node.events, callback);
1021
+ break;
1022
+
1023
+ case "BrickMenu":
1024
+ traverseNode(node.brick, callback);
1025
+ break;
1026
+
1027
+ case "Resolvable":
1028
+ case "FalseMenu":
1029
+ case "StaticMenu":
1030
+ case "UnknownLifeCycle":
1031
+ case "LiteralCondition":
1032
+ break;
1033
+
1034
+ default:
1035
+ // istanbul ignore if
1036
+ if (process.env.NODE_ENV === "development") {
1037
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1038
+ // @ts-expect-error
1039
+ throw new Error("Unhandled storyboard node type: ".concat(node.type));
1040
+ }
1041
+
820
1042
  }
821
1043
  }
822
1044
 
823
- function collectBricksInRouteConfs(routes, collection) {
824
- if (Array.isArray(routes)) {
825
- routes.forEach(routeConf => {
826
- scanBricksInProviderConfs(routeConf.providers, collection);
827
- collectBricksInContext(routeConf.context, collection);
828
- collectBricksInResolvable(routeConf.redirect, collection);
1045
+ /**
1046
+ * Scan bricks and custom apis in storyboard.
1047
+ *
1048
+ * @param storyboard - Storyboard.
1049
+ * @param options - If options is a boolean, it means `isUniq` or `de-duplicate`.
1050
+ */
1051
+ function scanStoryboard(storyboard) {
1052
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
1053
+ var ast = parseStoryboard(storyboard);
1054
+ return scanStoryboardAst(ast, options);
1055
+ }
1056
+ /**
1057
+ * Scan bricks and custom apis in storyboard.
1058
+ *
1059
+ * @param storyboard - Storyboard.
1060
+ * @param options - If options is a boolean, it means `isUniq` or `de-duplicate`.
1061
+ */
1062
+
1063
+ function scanStoryboardAst(ast) {
1064
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
1065
+ var {
1066
+ keepDuplicates,
1067
+ ignoreBricksInUnusedCustomTemplates
1068
+ } = isObject$1(options) ? options : {
1069
+ keepDuplicates: !options
1070
+ };
1071
+ var selfDefined = new Set(["form-renderer.form-renderer"]);
1072
+ var collection;
1073
+
1074
+ if (ignoreBricksInUnusedCustomTemplates) {
1075
+ collection = collect(ast.routes, keepDuplicates);
1076
+
1077
+ if (Array.isArray(ast.templates)) {
1078
+ var tplMap = new Map();
1079
+
1080
+ for (var tpl of ast.templates) {
1081
+ tplMap.set(tpl.raw.name, tpl);
1082
+ }
1083
+
1084
+ for (var _item of collection) {
1085
+ if (tplMap.has(_item) && !selfDefined.has(_item)) {
1086
+ selfDefined.add(_item);
1087
+ var collectionByTpl = collect(tplMap.get(_item));
1088
+
1089
+ if (keepDuplicates) {
1090
+ collection.push(_item);
1091
+ collection.push(...collectionByTpl);
1092
+ } else {
1093
+ collection.add(_item);
829
1094
 
830
- if (Array.isArray(routeConf.defineResolves)) {
831
- for (var def of routeConf.defineResolves) {
832
- collectBricksInResolvable(def, collection);
1095
+ for (var i of collectionByTpl) {
1096
+ collection.add(i);
1097
+ }
1098
+ }
833
1099
  }
834
1100
  }
1101
+ }
1102
+ } else {
1103
+ collection = collect(ast, keepDuplicates, selfDefined);
1104
+ }
835
1105
 
836
- if (routeConf.type === "routes") {
837
- collectBricksInRouteConfs(routeConf.routes, collection);
1106
+ if (keepDuplicates) {
1107
+ var bricks = [];
1108
+ var customApis = [];
1109
+
1110
+ for (var _item2 of collection) {
1111
+ if (_item2.includes("@")) {
1112
+ customApis.push(_item2);
838
1113
  } else {
839
- collectBricksInBrickConfs(routeConf.bricks, collection);
1114
+ if (_item2.includes("-") && !selfDefined.has(_item2)) {
1115
+ bricks.push(_item2);
1116
+ }
840
1117
  }
1118
+ }
841
1119
 
842
- if (routeConf.menu) {
843
- if (routeConf.menu.type === "brick" && routeConf.menu.brick) {
844
- collection.push(routeConf.menu.brick);
845
- } else if (routeConf.menu.type === "resolve") {
846
- collectBricksInResolvable(routeConf.menu.resolve, collection);
1120
+ return {
1121
+ bricks,
1122
+ customApis
1123
+ };
1124
+ } else {
1125
+ var _bricks = new Set();
1126
+
1127
+ var _customApis = new Set();
1128
+
1129
+ for (var _item3 of collection) {
1130
+ if (_item3.includes("@")) {
1131
+ _customApis.add(_item3);
1132
+ } else {
1133
+ if (_item3.includes("-") && !selfDefined.has(_item3)) {
1134
+ _bricks.add(_item3);
847
1135
  }
848
1136
  }
849
- });
1137
+ }
1138
+
1139
+ return {
1140
+ bricks: [..._bricks],
1141
+ customApis: [..._customApis]
1142
+ };
850
1143
  }
851
1144
  }
852
1145
 
853
- function collectBricksInCustomTemplates(customTemplates, collection, selfDefined) {
854
- if (Array.isArray(customTemplates)) {
855
- customTemplates.forEach(tpl => {
856
- selfDefined.add(tpl.name);
857
- collectBricksInBrickConfs(tpl.bricks, collection);
858
- collectBricksInContext(tpl.state, collection);
859
- });
1146
+ function collect(nodeOrNodes, keepDuplicates, definedTemplates) {
1147
+ var collection;
1148
+ var add;
1149
+
1150
+ if (keepDuplicates) {
1151
+ collection = [];
1152
+
1153
+ add = item => {
1154
+ collection.push(item);
1155
+ };
1156
+ } else {
1157
+ collection = new Set();
1158
+
1159
+ add = item => {
1160
+ collection.add(item);
1161
+ };
860
1162
  }
1163
+
1164
+ traverse(nodeOrNodes, node => {
1165
+ switch (node.type) {
1166
+ case "Brick":
1167
+ if (node.raw.brick) {
1168
+ add(node.raw.brick);
1169
+ }
1170
+
1171
+ break;
1172
+
1173
+ case "Resolvable":
1174
+ {
1175
+ var _node$raw;
1176
+
1177
+ var useProvider = (_node$raw = node.raw) === null || _node$raw === void 0 ? void 0 : _node$raw.useProvider;
1178
+
1179
+ if (useProvider) {
1180
+ add(useProvider);
1181
+ }
1182
+
1183
+ break;
1184
+ }
1185
+
1186
+ case "EventHandler":
1187
+ {
1188
+ var _node$raw2;
1189
+
1190
+ var _useProvider = (_node$raw2 = node.raw) === null || _node$raw2 === void 0 ? void 0 : _node$raw2.useProvider;
1191
+
1192
+ if (_useProvider) {
1193
+ add(_useProvider);
1194
+ }
1195
+
1196
+ break;
1197
+ }
1198
+
1199
+ case "Template":
1200
+ definedTemplates === null || definedTemplates === void 0 ? void 0 : definedTemplates.add(node.raw.name);
1201
+ break;
1202
+ }
1203
+ });
1204
+ return collection;
861
1205
  }
862
1206
 
1207
+ function collectBricksInBrickConf(brickConf) {
1208
+ var node = parseBrick(brickConf);
1209
+ return [...collect(node)];
1210
+ }
863
1211
  function collectBricksByCustomTemplates(customTemplates) {
864
1212
  var collectionByTpl = new Map();
1213
+ var templates = parseTemplates(customTemplates);
865
1214
 
866
- if (Array.isArray(customTemplates)) {
867
- customTemplates.forEach(tpl => {
868
- var collection = [];
869
- collectionByTpl.set(tpl.name, collection);
870
- collectBricksInBrickConfs(tpl.bricks, collection);
871
- collectBricksInContext(tpl.state, collection);
872
- });
1215
+ for (var tpl of templates) {
1216
+ var collection = collect(tpl, false);
1217
+ collectionByTpl.set(tpl.raw.name, [...collection]);
873
1218
  }
874
1219
 
875
1220
  return collectionByTpl;
@@ -887,11 +1232,9 @@
887
1232
  return scanStoryboard(storyboard, options).bricks;
888
1233
  }
889
1234
  function scanBricksInBrickConf(brickConf) {
890
- var isUniq = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
891
- var collection = [];
892
- collectBricksInBrickConf(brickConf, collection);
1235
+ var collection = collectBricksInBrickConf(brickConf);
893
1236
  var result = collection.filter(item => !item.includes("@") && item.includes("-"));
894
- return isUniq ? lodash.uniq(result) : result;
1237
+ return result;
895
1238
  }
896
1239
 
897
1240
  class ExecutionContext {
@@ -21185,7 +21528,7 @@
21185
21528
  } else {
21186
21529
  visitNonExpressionString === null || visitNonExpressionString === void 0 ? void 0 : visitNonExpressionString(value);
21187
21530
  }
21188
- } else if (isObject(value)) {
21531
+ } else if (isObject$1(value)) {
21189
21532
  // Avoid call stack overflow.
21190
21533
  if (memo.has(value)) {
21191
21534
  return;
@@ -22032,34 +22375,12 @@
22032
22375
 
22033
22376
  function scanRouteAliasInStoryboard(storyboard) {
22034
22377
  var collection = new Map();
22035
- collectRouteAliasInRouteConfs(storyboard.routes, collection);
22036
- return collection;
22037
- }
22038
-
22039
- function collectRouteAliasInBrickConf(brickConf, collection) {
22040
- if (brickConf.slots) {
22041
- Object.values(brickConf.slots).forEach(slotConf => {
22042
- if (slotConf.type === "bricks") {
22043
- collectRouteAliasInBrickConfs(slotConf.bricks, collection);
22044
- } else {
22045
- collectRouteAliasInRouteConfs(slotConf.routes, collection);
22046
- }
22047
- });
22048
- }
22049
- }
22050
-
22051
- function collectRouteAliasInBrickConfs(bricks, collection) {
22052
- if (Array.isArray(bricks)) {
22053
- bricks.forEach(brickConf => {
22054
- collectRouteAliasInBrickConf(brickConf, collection);
22055
- });
22056
- }
22057
- }
22058
-
22059
- function collectRouteAliasInRouteConfs(routes, collection) {
22060
- if (Array.isArray(routes)) {
22061
- routes.forEach(routeConf => {
22062
- var alias = routeConf.alias;
22378
+ var routes = parseRoutes(storyboard.routes, {
22379
+ routesOnly: true
22380
+ });
22381
+ traverse(routes, node => {
22382
+ if (node.type === "Route") {
22383
+ var alias = node.raw.alias;
22063
22384
 
22064
22385
  if (alias) {
22065
22386
  if (collection.has(alias)) {
@@ -22069,17 +22390,12 @@
22069
22390
 
22070
22391
  collection.set(alias, {
22071
22392
  alias,
22072
- path: routeConf.path
22393
+ path: node.raw.path
22073
22394
  });
22074
22395
  }
22075
-
22076
- if (routeConf.type === "routes") {
22077
- collectRouteAliasInRouteConfs(routeConf.routes, collection);
22078
- } else {
22079
- collectRouteAliasInBrickConfs(routeConf.bricks, collection);
22080
- }
22081
- });
22082
- }
22396
+ }
22397
+ });
22398
+ return collection;
22083
22399
  }
22084
22400
 
22085
22401
  var I18N = "I18N";
@@ -23392,185 +23708,128 @@
23392
23708
  * `FLAGS["your-feature-flag"]` is falsy.
23393
23709
  */
23394
23710
  function removeDeadConditions(storyboard, options) {
23395
- var _storyboard$meta;
23396
-
23397
23711
  if (storyboard.$$deadConditionsRemoved) {
23398
23712
  return;
23399
23713
  }
23400
23714
 
23401
- removeDeadConditionsInRoutes(storyboard.routes, options);
23402
- var {
23403
- customTemplates
23404
- } = (_storyboard$meta = storyboard.meta) !== null && _storyboard$meta !== void 0 ? _storyboard$meta : {};
23405
-
23406
- if (Array.isArray(customTemplates)) {
23407
- for (var tpl of customTemplates) {
23408
- removeDeadConditionsInTpl(tpl, options);
23409
- }
23410
- }
23411
-
23715
+ var ast = parseStoryboard(storyboard);
23716
+ removeDeadConditionsByAst(ast, options);
23412
23717
  storyboard.$$deadConditionsRemoved = true;
23413
23718
  }
23414
- /**
23415
- * Like `removeDeadConditions` but applied to a custom template.
23416
- */
23417
-
23418
- function removeDeadConditionsInTpl(tplConstructor, options) {
23419
- removeDeadConditionsInBricks(tplConstructor.bricks, options);
23420
- }
23421
23719
 
23422
- function removeDeadConditionsInRoutes(routes, options) {
23423
- removeDeadConditionsInArray(routes, options, route => {
23424
- removeDeadConditionsInContext(route.context, options);
23425
-
23426
- if (route.type === "routes") {
23427
- removeDeadConditionsInRoutes(route.routes, options);
23428
- } else {
23429
- removeDeadConditionsInBricks(route.bricks, options);
23430
- }
23431
- });
23432
- }
23720
+ function removeDeadConditionsByAst(ast, options) {
23721
+ // First, we mark constant conditions.
23722
+ traverse(ast, node => {
23723
+ switch (node.type) {
23724
+ case "Route":
23725
+ case "Brick":
23726
+ case "EventHandler":
23727
+ case "Context":
23728
+ computeConstantCondition(node.raw, options);
23729
+ break;
23433
23730
 
23434
- function removeDeadConditionsInBricks(bricks, options) {
23435
- removeDeadConditionsInArray(bricks, options, brick => {
23436
- if (brick.slots) {
23437
- for (var slot of Object.values(brick.slots)) {
23438
- if (slot.type === "routes") {
23439
- removeDeadConditionsInRoutes(slot.routes, options);
23440
- } else {
23441
- removeDeadConditionsInBricks(slot.bricks, options);
23731
+ case "Resolvable":
23732
+ if (node.isConditional) {
23733
+ computeConstantCondition(node.raw, options);
23442
23734
  }
23443
- }
23444
- }
23445
-
23446
- removeDeadConditionsInLifeCycle(brick.lifeCycle, options);
23447
- removeDeadConditionsInEvents(brick.events, options);
23448
- removeDeadConditionsInContext(brick.context, options);
23449
- removeDeadConditionsInProperties(brick.properties, options);
23450
- });
23451
- }
23452
23735
 
23453
- function removeDeadConditionsInProperties(value, options) {
23454
- if (Array.isArray(value)) {
23455
- for (var _item of value) {
23456
- removeDeadConditionsInProperties(_item, options);
23457
- }
23458
- } else if (isObject(value)) {
23459
- if (value.useBrick) {
23460
- if (Array.isArray(value.useBrick)) {
23461
- // For useBrick as array, just remove dead items.
23462
- removeDeadConditionsInArray(value.useBrick, options, useBrick => {
23463
- removeDeadConditionsInUseBrick(useBrick, options);
23464
- });
23465
- } else {
23466
- // For useBrick as single one, we have to keep it,
23467
- // and we change it to an empty <div>.
23468
- computeConstantCondition(value.useBrick, options);
23469
-
23470
- if (value.useBrick.if === false) {
23471
- value.useBrick = {
23472
- brick: "div",
23473
- if: false
23474
- };
23475
- } else {
23476
- removeDeadConditionsInUseBrick(value.useBrick, options);
23477
- }
23478
- }
23479
- } else {
23480
- for (var _item2 of Object.values(value)) {
23481
- removeDeadConditionsInProperties(_item2, options);
23482
- }
23736
+ break;
23483
23737
  }
23484
- }
23485
- }
23738
+ }); // Then, we remove dead conditions accordingly.
23486
23739
 
23487
- function removeDeadConditionsInUseBrick(useBrick, options) {
23488
- removeDeadConditionsInProperties(useBrick.properties, options);
23489
- removeDeadConditionsInEvents(useBrick.events, options);
23740
+ traverse(ast, node => {
23741
+ var rawContainer;
23742
+ var conditionalNodes;
23743
+ var rawKey;
23744
+ var deleteEmptyArray = false;
23490
23745
 
23491
- if (useBrick.slots) {
23492
- for (var slot of Object.values(useBrick.slots)) {
23493
- removeDeadConditionsInBricks(slot.bricks, options);
23494
- }
23495
- }
23496
- }
23497
-
23498
- function removeDeadConditionsInEvents(events, options) {
23499
- if (isObject(events)) {
23500
- for (var eventType of Object.keys(events)) {
23501
- removeDeadConditionsInEvent(events, eventType, options);
23502
- }
23503
- }
23504
- }
23746
+ switch (node.type) {
23747
+ case "Root":
23748
+ conditionalNodes = node.routes;
23749
+ rawContainer = node.raw;
23750
+ rawKey = "routes";
23751
+ break;
23505
23752
 
23506
- function removeDeadConditionsInEvent(events, eventType, options) {
23507
- var handlers = events[eventType];
23753
+ case "Template":
23754
+ conditionalNodes = node.bricks;
23755
+ rawContainer = node.raw;
23756
+ rawKey = "bricks";
23757
+ break;
23508
23758
 
23509
- if (!handlers) {
23510
- return;
23511
- }
23759
+ case "Route":
23760
+ case "Slot":
23761
+ conditionalNodes = node.children;
23762
+ rawContainer = node.raw;
23763
+ rawKey = node.raw.type === "routes" ? "routes" : "bricks";
23764
+ break;
23512
23765
 
23513
- if (Array.isArray(handlers)) {
23514
- removeDeadConditionsInArray(handlers, options, handler => {
23515
- if (handler.callback) {
23516
- removeDeadConditionsInEvents(handler.callback, options);
23517
- }
23518
- });
23519
- } else {
23520
- computeConstantCondition(handlers, options);
23766
+ case "Event":
23767
+ case "EventCallback":
23768
+ case "SimpleLifeCycle":
23769
+ case "ConditionalEvent":
23770
+ conditionalNodes = node.handlers;
23771
+ rawContainer = node.rawContainer;
23772
+ rawKey = node.rawKey;
23773
+ deleteEmptyArray = true;
23774
+ break;
23521
23775
 
23522
- if (handlers.if === false) {
23523
- delete events[eventType];
23524
- return;
23525
- }
23776
+ case "ResolveLifeCycle":
23777
+ conditionalNodes = node.resolves;
23778
+ rawContainer = node.rawContainer;
23779
+ rawKey = node.rawKey;
23780
+ deleteEmptyArray = true;
23781
+ break;
23526
23782
 
23527
- if (handlers.callback) {
23528
- removeDeadConditionsInEvents(handlers.callback, options);
23783
+ case "UseBrickEntry":
23784
+ conditionalNodes = node.children;
23785
+ rawContainer = node.rawContainer;
23786
+ rawKey = node.rawKey;
23787
+ break;
23529
23788
  }
23530
- }
23531
- }
23532
-
23533
- function removeDeadConditionsInContext(context, options) {
23534
- removeDeadConditionsInArray(context, options);
23535
- }
23536
-
23537
- function removeDeadConditionsInArray(list, options, callback) {
23538
- if (Array.isArray(list)) {
23539
- var removes = [];
23540
23789
 
23541
- for (var _item3 of list) {
23542
- computeConstantCondition(_item3, options);
23790
+ shakeConditionalNodes(node, rawContainer, conditionalNodes, rawKey, deleteEmptyArray); // Remove unreachable context/state.
23543
23791
 
23544
- if (_item3.if === false) {
23545
- removes.push(_item3);
23546
- continue;
23547
- }
23792
+ deleteEmptyArray = false;
23548
23793
 
23549
- callback === null || callback === void 0 ? void 0 : callback(_item3);
23794
+ switch (node.type) {
23795
+ case "Route":
23796
+ case "Brick":
23797
+ case "Template":
23798
+ rawContainer = node.raw;
23799
+ rawKey = node.type === "Template" ? "state" : "context";
23800
+ conditionalNodes = node.context;
23801
+ break;
23550
23802
  }
23551
23803
 
23552
- lodash.pull(list, ...removes);
23553
- }
23804
+ shakeConditionalNodes(node, rawContainer, conditionalNodes, rawKey, deleteEmptyArray);
23805
+ });
23554
23806
  }
23555
23807
 
23556
- function removeDeadConditionsInLifeCycle(lifeCycle, options) {
23557
- if (lifeCycle) {
23558
- removeDeadConditionsInArray(lifeCycle.useResolves, options);
23808
+ function shakeConditionalNodes(node, rawContainer, conditionalNodes, rawKey, deleteEmptyArray) {
23809
+ var removedNodes = lodash.remove(conditionalNodes, node => node.raw.if === false);
23559
23810
 
23560
- for (var key of ["onPageLoad", "onPageLeave", "onAnchorLoad", "onAnchorUnload", "onMessageClose", "onBeforePageLoad", "onBeforePageLeave", "onMediaChange"]) {
23561
- removeDeadConditionsInEvent(lifeCycle, key, options);
23562
- }
23563
-
23564
- for (var _key of ["onMessage", "onScrollIntoView"]) {
23565
- for (var withHandlers of [].concat(lifeCycle[_key])) {
23566
- if (withHandlers) {
23567
- removeDeadConditionsInEvent(withHandlers, "handlers", options);
23568
- }
23569
- }
23811
+ if (removedNodes.length > 0) {
23812
+ if (node.type === "UseBrickEntry" && !Array.isArray(rawContainer[rawKey])) {
23813
+ rawContainer[rawKey] = {
23814
+ brick: "div",
23815
+ if: false
23816
+ };
23817
+ } else if (deleteEmptyArray && conditionalNodes.length === 0) {
23818
+ delete rawContainer[rawKey];
23819
+ } else {
23820
+ rawContainer[rawKey] = conditionalNodes.map(node => node.raw);
23570
23821
  }
23571
23822
  }
23572
23823
  }
23824
+ /**
23825
+ * Like `removeDeadConditions` but applied to a custom template.
23826
+ */
23573
23827
 
23828
+
23829
+ function removeDeadConditionsInTpl(tplConstructor, options) {
23830
+ var ast = parseTemplate(tplConstructor);
23831
+ removeDeadConditionsByAst(ast, options);
23832
+ }
23574
23833
  function computeConstantCondition(ifContainer) {
23575
23834
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
23576
23835
 
@@ -23588,8 +23847,8 @@
23588
23847
  } = options;
23589
23848
  var hasDynamicVariables = false;
23590
23849
 
23591
- for (var _item4 of attemptToVisitGlobals) {
23592
- if (_item4 !== "undefined" && (!constantFeatureFlags || _item4 !== "FLAGS")) {
23850
+ for (var item of attemptToVisitGlobals) {
23851
+ if (item !== "undefined" && (!constantFeatureFlags || item !== "FLAGS")) {
23593
23852
  hasDynamicVariables = true;
23594
23853
  break;
23595
23854
  }
@@ -23692,7 +23951,7 @@
23692
23951
  exports.isBrickNode = isBrickNode;
23693
23952
  exports.isCustomTemplateNode = isCustomTemplateNode;
23694
23953
  exports.isEvaluable = isEvaluable;
23695
- exports.isObject = isObject;
23954
+ exports.isObject = isObject$1;
23696
23955
  exports.isRouteNode = isRouteNode;
23697
23956
  exports.isSnippetNode = isSnippetNode;
23698
23957
  exports.lint = lint;
@@ -23702,7 +23961,12 @@
23702
23961
  exports.matchPath = matchPath;
23703
23962
  exports.normalizeBuilderNode = normalizeBuilderNode;
23704
23963
  exports.normalizeMenu = normalizeMenu;
23964
+ exports.parseBrick = parseBrick;
23705
23965
  exports.parseForAnalysis = parseForAnalysis;
23966
+ exports.parseRoutes = parseRoutes;
23967
+ exports.parseStoryboard = parseStoryboard;
23968
+ exports.parseTemplate = parseTemplate;
23969
+ exports.parseTemplates = parseTemplates;
23706
23970
  exports.precook = precook;
23707
23971
  exports.precookFunction = precookFunction;
23708
23972
  exports.preevaluate = preevaluate;
@@ -23725,6 +23989,7 @@
23725
23989
  exports.scanProcessorsInStoryboard = scanProcessorsInStoryboard;
23726
23990
  exports.scanRouteAliasInStoryboard = scanRouteAliasInStoryboard;
23727
23991
  exports.scanStoryboard = scanStoryboard;
23992
+ exports.scanStoryboardAst = scanStoryboardAst;
23728
23993
  exports.scanTemplatesInBrick = scanTemplatesInBrick;
23729
23994
  exports.scanTemplatesInStoryboard = scanTemplatesInStoryboard;
23730
23995
  exports.shouldAllowRecursiveEvaluations = shouldAllowRecursiveEvaluations;
@@ -23738,6 +24003,8 @@
23738
24003
  exports.trackUsedState = trackUsedState;
23739
24004
  exports.transform = transform;
23740
24005
  exports.transformAndInject = transformAndInject;
24006
+ exports.traverse = traverse;
24007
+ exports.traverseStoryboard = traverseStoryboard;
23741
24008
  exports.visitStoryboardExpressions = visitStoryboardExpressions;
23742
24009
  exports.visitStoryboardFunctions = visitStoryboardFunctions;
23743
24010