function _arrayLikeToArray(arr, len) {
    if (len == null || len > arr.length) len = arr.length;
    for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
    return arr2;
}
function _arrayWithoutHoles(arr) {
    if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}
function _defineProperties(target, props) {
    for(var i = 0; i < props.length; i++){
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
    }
}
function _createClass(Constructor, protoProps, staticProps) {
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
    if (staticProps) _defineProperties(Constructor, staticProps);
    return Constructor;
}
function _defineProperty(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
function _iterableToArray(iter) {
    if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _nonIterableSpread() {
    throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _objectSpread(target) {
    for(var i = 1; i < arguments.length; i++){
        var source = arguments[i] != null ? arguments[i] : {};
        var ownKeys = Object.keys(source);
        if (typeof Object.getOwnPropertySymbols === "function") {
            ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
                return Object.getOwnPropertyDescriptor(source, sym).enumerable;
            }));
        }
        ownKeys.forEach(function(key) {
            _defineProperty(target, key, source[key]);
        });
    }
    return target;
}
function _toConsumableArray(arr) {
    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _unsupportedIterableToArray(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _arrayLikeToArray(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(n);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
import { isExpression } from "./chunk-CHPQBTTP.js";
// src/validator/SchemaValidator.ts
import Ajv from "ajv";
// src/validator/rules/AllComponentsRules.ts
import { CORE_VERSION, CoreTraitName } from "@subscan/widget-shared";
// src/validator/rules/ComponentRules.ts
import { CORE_VERSION as CORE_VERSION2, CoreComponentName } from "@subscan/widget-shared";
// src/validator/rules/TraitRules.ts
import { GLOBAL_UTIL_METHOD_ID } from "@subscan/widget-runtime";
import { CORE_VERSION as CORE_VERSION3, CoreTraitName as CoreTraitName2, MountEvents } from "@subscan/widget-shared";
import { get } from "lodash";
// src/validator/rules/PropertiesRules.ts
import { cloneDeep, get as get2, has, set } from "lodash";
import { ExpressionKeywords, generateDefaultValueFromSpec, AnyTypePlaceholder } from "@subscan/widget-shared";
// src/validator/SchemaValidator.ts
import { initAjv } from "@subscan/widget-shared";
var ParentValidatorRule = /*#__PURE__*/ function() {
    "use strict";
    function _class() {
        _classCallCheck(this, _class);
        this.kind = "allComponents";
    }
    _createClass(_class, [
        {
            key: "validate",
            value: function validate1(param) {
                var appModel = param.appModel;
                var results = [];
                var allComponents = appModel.allComponents;
                var allComponentsFromSchema = appModel.allComponentsWithOrphan;
                if (allComponents.length === allComponentsFromSchema.length) {
                    return results;
                }
                var orphanComponents = allComponentsFromSchema.filter(function(c) {
                    return !allComponents.find(function(c2) {
                        return c2.id === c.id;
                    });
                });
                orphanComponents.forEach(function(c) {
                    var parent = appModel.getComponentById(c.parentId);
                    if (!parent) {
                        results.push({
                            message: "Cannot find parent component: ".concat(c.parentId, "."),
                            componentId: c.id,
                            traitType: "".concat(CORE_VERSION, "/").concat(CoreTraitName.Slot),
                            property: "/container/id"
                        });
                    }
                    if (parent && !parent.slots.includes(c.parentSlot)) {
                        results.push({
                            message: "Parent component '".concat(parent.id, "' does not have slot: ").concat(c.parentSlot, "."),
                            componentId: c.id,
                            traitType: "".concat(CORE_VERSION, "/").concat(CoreTraitName.Slot),
                            property: "/container/slot"
                        });
                    }
                });
                return results;
            }
        }
    ]);
    return _class;
}();
var AllComponentsRules = [
    new ParentValidatorRule()
];
var ModuleValidatorRule = /*#__PURE__*/ function() {
    "use strict";
    function _class() {
        _classCallCheck(this, _class);
        this.kind = "component";
    }
    _createClass(_class, [
        {
            key: "validate",
            value: function validate1(param) {
                var component = param.component, registry = param.registry;
                if (component.type !== "".concat(CORE_VERSION2, "/").concat(CoreComponentName.ModuleContainer)) {
                    return [];
                }
                var results = [];
                var moduleSpec;
                try {
                    moduleSpec = registry.getModuleByType(component.rawProperties.type);
                } catch (err) {
                    moduleSpec = void 0;
                }
                if (!moduleSpec) {
                    results.push({
                        message: "Module is not registered: ".concat(component.rawProperties.type, "."),
                        componentId: component.id,
                        property: "/type"
                    });
                }
                return results;
            }
        }
    ]);
    return _class;
}();
var ComponentRules = [
    new ModuleValidatorRule()
];
var EventHandlerValidatorRule = /*#__PURE__*/ function() {
    "use strict";
    function _class() {
        _classCallCheck(this, _class);
        this.kind = "trait";
        this.traitMethods = [
            "setValue",
            "resetValue",
            "triggerFetch"
        ];
    }
    _createClass(_class, [
        {
            key: "isErrorAnExpression",
            value: function isErrorAnExpression(error, parameters) {
                var path = "";
                var instancePath = error.instancePath, params = error.params;
                if (instancePath) {
                    path = instancePath.split("/").slice(1).join(".");
                } else {
                    path = params.missingProperty;
                }
                var field = get(parameters, path);
                return isExpression(field);
            }
        },
        {
            key: "validate",
            value: function validate1(param) {
                var appModel = param.appModel, trait = param.trait, component = param.component, ajv = param.ajv, validators = param.validators, traitIndex = param.traitIndex;
                var _this = this;
                var results = [];
                if (trait.type !== "".concat(CORE_VERSION3, "/").concat(CoreTraitName2.Event)) {
                    return results;
                }
                var handlers = trait.rawProperties.handlers;
                handlers.forEach(function(handler, i) {
                    var eventName = handler.type, targetId = handler.componentId, _method = handler.method, methodName = _method.name, parameters = _method.parameters;
                    if (!eventName) {
                        results.push({
                            message: "Event is empty.",
                            componentId: component.id,
                            traitType: trait.type,
                            property: "/handlers/".concat(i, "/type")
                        });
                    }
                    if (eventName && !component.events.includes(eventName) && !MountEvents.includes(eventName)) {
                        results.push({
                            message: "Component does not have event: ".concat(eventName, "."),
                            componentId: component.id,
                            traitType: trait.type,
                            property: "/handlers/".concat(i, "/type")
                        });
                    }
                    if (!targetId) {
                        results.push({
                            message: "Target component Id is empty.",
                            componentId: component.id,
                            traitType: trait.type,
                            property: "/handlers/".concat(i, "/componentId")
                        });
                        return results;
                    }
                    if (!methodName) {
                        results.push({
                            message: "Method is empty.",
                            componentId: component.id,
                            traitType: trait.type,
                            property: "/handlers/".concat(i, "/method/name")
                        });
                        return results;
                    }
                    if (targetId === GLOBAL_UTIL_METHOD_ID) {
                        var validate = validators.utilMethods[methodName];
                        if (!validate) {
                            results.push({
                                message: "$utils does not have method: ".concat(methodName, "."),
                                componentId: component.id,
                                traitType: trait.type,
                                property: "/handlers/".concat(i, "/method/name")
                            });
                        }
                        var valid = validate(parameters);
                        if (!valid) {
                            var _this2 = _this;
                            validate.errors.forEach(function(error) {
                                if (!_this2.isErrorAnExpression(error, parameters)) {
                                    results.push({
                                        message: error.message || "",
                                        componentId: component.id,
                                        property: error.instancePath,
                                        traitType: trait === null || trait === void 0 ? void 0 : trait.type,
                                        traitIndex: traitIndex
                                    });
                                    return results;
                                }
                            });
                        }
                    } else {
                        var targetComponent = appModel.getComponentById(targetId);
                        if (!targetComponent) {
                            results.push({
                                message: "Event target component does not exist: ".concat(targetId, "."),
                                componentId: component.id,
                                traitType: trait.type,
                                property: "/handlers/".concat(i, "/componentId")
                            });
                            return results;
                        }
                        var method = targetComponent.methods.find(function(m) {
                            return m.name === methodName;
                        });
                        if (!method) {
                            results.push({
                                message: "Event target component does not have method: ".concat(methodName, "."),
                                componentId: component.id,
                                traitType: trait.type,
                                property: "/handlers/".concat(i, "/method/name")
                            });
                            return results;
                        }
                        if (method.parameters && !ajv.validate(method.parameters, parameters)) {
                            var _this1 = _this;
                            ajv.errors.forEach(function(error) {
                                if (!_this1.isErrorAnExpression(error, parameters)) {
                                    results.push({
                                        message: error.message || "",
                                        componentId: component.id,
                                        traitType: trait.type,
                                        property: "/handlers/".concat(i, "/method/parameters").concat(error.instancePath)
                                    });
                                }
                            });
                        }
                    }
                });
                return results;
            }
        }
    ]);
    return _class;
}();
var TraitRules = [
    new EventHandlerValidatorRule()
];
var PropertySchemaValidatorRule = /*#__PURE__*/ function() {
    "use strict";
    function _class() {
        _classCallCheck(this, _class);
        this.kind = "properties";
    }
    _createClass(_class, [
        {
            key: "validate",
            value: function validate1(param) {
                var properties = param.properties, component = param.component, trait = param.trait, validators = param.validators, traitIndex = param.traitIndex, componentIdSpecMap = param.componentIdSpecMap;
                var results = [];
                var validate;
                if (trait) {
                    validate = validators.traits[trait.type];
                } else {
                    validate = validators.components[component.type];
                }
                if (!validate) return results;
                var valid = validate(properties.rawValue);
                if (valid) return results;
                validate.errors.forEach(function(error) {
                    var instancePath = error.instancePath, params = error.params;
                    var path = "";
                    if (instancePath) {
                        path = instancePath.split("/").slice(1).join(".");
                    } else {
                        path = params.missingProperty;
                    }
                    var fieldModel = properties.getPropertyByPath(path);
                    if (get2(fieldModel, "isDynamic") !== true) {
                        results.push({
                            message: error.message || "",
                            componentId: component.id,
                            property: error.instancePath,
                            traitType: trait === null || trait === void 0 ? void 0 : trait.type,
                            traitIndex: traitIndex,
                            fix: function() {
                                var defaultValue = generateDefaultValueFromSpec(componentIdSpecMap[component.id].spec.properties);
                                var path2 = instancePath.split("/").slice(1).join(".");
                                var newProperties = cloneDeep(properties.rawValue);
                                set(newProperties, path2, get2(defaultValue, path2));
                                return newProperties;
                            }
                        });
                    }
                });
                return results;
            }
        }
    ]);
    return _class;
}();
var ExpressionValidatorRule = /*#__PURE__*/ function() {
    "use strict";
    function _class() {
        _classCallCheck(this, _class);
        this.kind = "properties";
    }
    _createClass(_class, [
        {
            key: "checkObjHasPath",
            value: function checkObjHasPath(obj, path) {
                var arr = path.split(".");
                var curr = obj;
                var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
                try {
                    for(var _iterator = arr[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
                        var key = _step.value;
                        var value = curr[key];
                        if (value === void 0) {
                            return false;
                        } else if (value === AnyTypePlaceholder) {
                            return true;
                        }
                        curr = value;
                    }
                } catch (err) {
                    _didIteratorError = true;
                    _iteratorError = err;
                } finally{
                    try {
                        if (!_iteratorNormalCompletion && _iterator.return != null) {
                            _iterator.return();
                        }
                    } finally{
                        if (_didIteratorError) {
                            throw _iteratorError;
                        }
                    }
                }
                return true;
            }
        },
        {
            key: "validate",
            value: function validate1(param) {
                var properties = param.properties, component = param.component, trait = param.trait, appModel = param.appModel, dependencyNames = param.dependencyNames;
                var _this = this;
                var results = [];
                properties.traverse(function(fieldModel, key) {
                    var _this5 = _this;
                    Object.keys(fieldModel.refComponentInfos).forEach(function(id) {
                        if (!id) return;
                        var targetComponent = appModel.getComponentById(id);
                        var paths = fieldModel.refComponentInfos[id].refProperties;
                        if (targetComponent) {
                            var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
                            try {
                                for(var _iterator = paths[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
                                    var path = _step.value;
                                    if (!_this5.checkObjHasPath(targetComponent.stateExample, path)) {
                                        results.push({
                                            message: "Component '".concat(id, "' does not have property '").concat(path, "'."),
                                            componentId: component.id,
                                            property: key,
                                            traitType: trait === null || trait === void 0 ? void 0 : trait.type
                                        });
                                        break;
                                    }
                                }
                            } catch (err) {
                                _didIteratorError = true;
                                _iteratorError = err;
                            } finally{
                                try {
                                    if (!_iteratorNormalCompletion && _iterator.return != null) {
                                        _iterator.return();
                                    }
                                } finally{
                                    if (_didIteratorError) {
                                        throw _iteratorError;
                                    }
                                }
                            }
                        } else if (id in window) {
                            var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
                            try {
                                for(var _iterator1 = paths[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
                                    var path1 = _step1.value;
                                    if (!has(window[id], path1)) {
                                        results.push({
                                            message: "Window object '".concat(id, "' does not have property '").concat(path1, "'."),
                                            componentId: component.id,
                                            property: key,
                                            traitType: trait === null || trait === void 0 ? void 0 : trait.type
                                        });
                                        break;
                                    }
                                }
                            } catch (err) {
                                _didIteratorError1 = true;
                                _iteratorError1 = err;
                            } finally{
                                try {
                                    if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
                                        _iterator1.return();
                                    }
                                } finally{
                                    if (_didIteratorError1) {
                                        throw _iteratorError1;
                                    }
                                }
                            }
                        } else if (appModel.moduleIds.includes(id)) {} else if (dependencyNames.includes(id)) {} else if (ExpressionKeywords.includes(id)) {} else {
                            results.push({
                                message: "Cannot find '".concat(id, "' in store or window."),
                                componentId: component.id,
                                property: key,
                                traitType: trait === null || trait === void 0 ? void 0 : trait.type
                            });
                        }
                    });
                });
                return results;
            }
        }
    ]);
    return _class;
}();
var PropertiesRules = [
    new PropertySchemaValidatorRule(),
    new ExpressionValidatorRule()
];
// src/validator/rules/index.ts
var rules = _toConsumableArray(AllComponentsRules).concat(_toConsumableArray(ComponentRules), _toConsumableArray(TraitRules), _toConsumableArray(PropertiesRules));
var SchemaValidator = /*#__PURE__*/ function() {
    "use strict";
    function _class(registry, dependencyNames) {
        _classCallCheck(this, _class);
        this.registry = registry;
        this.dependencyNames = dependencyNames;
        this.result = [];
        this.traitRules = [];
        this.componentRules = [];
        this.allComponentsRules = [];
        this.propertiesRules = [];
        this.componentIdSpecMap = {};
        this.initAjv();
        this.addRules(rules);
    }
    _createClass(_class, [
        {
            key: "addRules",
            value: function addRules(rules2) {
                var _this = this;
                rules2.forEach(function(rule) {
                    switch(rule.kind){
                        case "component":
                            _this.componentRules.push(rule);
                            break;
                        case "allComponents":
                            _this.allComponentsRules.push(rule);
                            break;
                        case "trait":
                            _this.traitRules.push(rule);
                            break;
                        case "properties":
                            _this.propertiesRules.push(rule);
                            break;
                    }
                });
            }
        },
        {
            key: "validate",
            value: function validate1(appModel) {
                var _this7 = this;
                this.genComponentIdSpecMap(appModel);
                this.result = [];
                var components = appModel.toSchema();
                var baseContext = {
                    components: components,
                    validators: this.validatorMap,
                    registry: this.registry,
                    appModel: appModel,
                    componentIdSpecMap: this.componentIdSpecMap,
                    ajv: this.ajv,
                    dependencyNames: this.dependencyNames || []
                };
                this.allComponentsRules.forEach(function(rule) {
                    var r = rule.validate(baseContext);
                    if (r.length > 0) {
                        _this7.result = _this7.result.concat(r);
                    }
                });
                appModel.allComponents.forEach(function(component) {
                    var _this6 = _this7;
                    _this7.componentRules.forEach(function(rule) {
                        var r = rule.validate(_objectSpread({
                            component: component
                        }, baseContext));
                        if (r.length > 0) {
                            _this6.result = _this6.result.concat(r);
                        }
                    });
                    _this7.propertiesRules.forEach(function(rule) {
                        var r = rule.validate(_objectSpread({
                            properties: component.properties,
                            component: component
                        }, baseContext));
                        if (r.length > 0) {
                            _this6.result = _this6.result.concat(r);
                        }
                    });
                    _this7.traitRules.forEach(function(rule) {
                        var _this = _this6;
                        component.traits.forEach(function(trait, i) {
                            var _this8 = _this;
                            var r = rule.validate(_objectSpread({
                                trait: trait,
                                component: component,
                                traitIndex: i
                            }, baseContext));
                            if (r.length > 0) {
                                _this.result = _this.result.concat(r);
                            }
                            _this.propertiesRules.forEach(function(rule2) {
                                var r2 = rule2.validate(_objectSpread({
                                    properties: trait.properties,
                                    trait: trait,
                                    component: component
                                }, baseContext));
                                if (r2.length > 0) {
                                    _this8.result = _this8.result.concat(r2);
                                }
                            });
                        });
                    });
                });
                return this.result;
            }
        },
        {
            key: "genComponentIdSpecMap",
            value: function genComponentIdSpecMap(appModel) {
                var _this = this;
                appModel.traverseTree(function(c) {
                    _this.componentIdSpecMap[c.id] = _this.registry.getComponentByType(c.type);
                });
            }
        },
        {
            key: "fix",
            value: function fix() {
                this.result.forEach(function(r) {
                    var ref;
                    (ref = r.fix) === null || ref === void 0 ? void 0 : ref.call(r);
                });
            }
        },
        {
            key: "initAjv",
            value: function initAjv1() {
                var _this = this;
                this.ajv = initAjv(new Ajv({}));
                this.validatorMap = {
                    components: {},
                    traits: {},
                    utilMethods: {}
                };
                this.registry.getAllComponents().forEach(function(c) {
                    _this.validatorMap.components["".concat(c.version, "/").concat(c.metadata.name)] = _this.ajv.compile(c.spec.properties);
                });
                this.registry.getAllTraits().forEach(function(t) {
                    _this.validatorMap.traits["".concat(t.version, "/").concat(t.metadata.name)] = _this.ajv.compile(t.spec.properties);
                });
                this.registry.getAllUtilMethods().forEach(function(t) {
                    _this.validatorMap.utilMethods["".concat(t.version, "/").concat(t.metadata.name)] = _this.ajv.compile(t.spec.parameters);
                });
            }
        }
    ]);
    return _class;
}();
export { SchemaValidator, rules };
//# sourceMappingURL=validator-IYSECBJG.js.map