'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const __chunk_1 = require('./chunk-2755df65.js');
require('./chunk-f5b13333.js');
const __chunk_3 = require('./chunk-451ee4a2.js');

class EntityForm {
    constructor(hostRef) {
        __chunk_1.registerInstance(this, hostRef);
        this.translateService = __chunk_3.TranslateService.instance;
    }
    async setData(data) {
        this.data = data;
    }
    async setDefinitions(data) {
        this.definitions = data;
    }
    translate(str) {
        return this.translateService.get(str);
    }
    renderFormField(key) {
        let field = {
            "label": key,
            "tag": "input",
            "type": "text",
            "placeholder": "",
            "hidden": false,
            "disabled": false
        };
        let fieldData;
        let styles = {};
        if (this.definitions && this.definitions[key]) {
            Object.keys(this.definitions[key]).forEach((k, i) => {
                field[k] = this.definitions[key][k];
            });
        }
        field.label = this.translate(field.label);
        fieldData = this.parseField(key, field);
        // deprecate
        if (field.hidden || field.type === 'hidden')
            styles.display = "none";
        // input: text & password
        if (field.tag === 'input' && (field.type === 'text' ||
            field.type === 'password' ||
            field.type === 'date' ||
            field.type === 'datetime' ||
            field.type === 'datetime-local')) {
            return (__chunk_1.h("ema-form-field", { "key-id": key, value: this.data[key], "config-json": JSON.stringify(field), "data-json": JSON.stringify(fieldData), styles: styles }));
        }
        // input: checkbox
        if (field.tag === 'input' && field.type === 'checkbox') {
            // checkbox boolean
            if (typeof this.data[key] === 'boolean' || typeof this.data[key] === 'number') {
                return (__chunk_1.h("div", { class: "form-group row", style: styles }, __chunk_1.h("label", { class: "col-md-4 col-form-label", htmlFor: key }, __chunk_3.StringUtil.uppercaseFirst(this.translate(field.label))), __chunk_1.h("div", { class: "col-md-8" }, __chunk_1.h("div", { class: "form-check form-check-inline" }, __chunk_1.h("label", { class: "form-check-label" }, __chunk_1.h("input", { class: "form-check-input", name: key, type: field.type, disabled: field.disabled, checked: this.data[key], hidden: field.hidden, value: this.data[key] })))), __chunk_1.h("div", { class: "col-md-8 offset-md-4 messages" })));
            }
            // todo: checkboxes array
            if (fieldData && fieldData.length) {
                let arrayName = key + '[]';
                return (__chunk_1.h("div", { class: "form-group row", style: styles }, __chunk_1.h("label", { class: "col-md-4 col-form-label", htmlFor: key }, __chunk_3.StringUtil.uppercaseFirst(this.translate(field.label))), __chunk_1.h("div", { class: "col-md-8" }, fieldData.map(function (item) {
                    // this.data[key].map(function (item) {
                    return __chunk_1.h("div", { class: "form-check form-check-inline" }, __chunk_1.h("label", { class: "form-check-label" }, __chunk_1.h("input", { class: "form-check-input", name: arrayName, type: field.type, disabled: field.disabled, hidden: field.hidden, checked: item.selected, value: item.value }), item.text));
                })), __chunk_1.h("div", { class: "col-md-8 offset-md-4 messages" })));
            }
        }
        // input: radio
        if (field.tag === 'input' && field.type === 'radio') {
            if (fieldData && fieldData.length) {
                return (__chunk_1.h("div", { class: "form-group row", style: styles }, __chunk_1.h("label", { class: "col-md-4 col-form-label", htmlFor: key }, __chunk_3.StringUtil.uppercaseFirst(this.translate(field.label))), __chunk_1.h("div", { class: "col-md-8" }, fieldData.map(function (item) {
                    return __chunk_1.h("div", { class: "form-check" }, __chunk_1.h("label", { class: "form-check-label" }, __chunk_1.h("input", { class: "form-check-input", name: key, type: field.type, disabled: field.disabled, hidden: field.hidden, checked: item.selected, value: item.value }), item.text));
                })), __chunk_1.h("div", { class: "col-md-8 offset-md-4 messages" })));
            }
        }
        // textarea
        if (field.tag === 'textarea') {
            return (__chunk_1.h("div", { class: "form-group row", style: styles }, __chunk_1.h("label", { htmlFor: key, class: "col-md-4 col-form-label" }, __chunk_3.StringUtil.uppercaseFirst(this.translate(field.label))), __chunk_1.h("div", { class: "col-md-8" }, __chunk_1.h("textarea", { class: "form-control", name: key, placeholder: field.placeholder, disabled: field.disabled, hidden: field.hidden, value: this.data[key], cols: 40, rows: 5 })), __chunk_1.h("div", { class: "col-md-8 offset-md-4 messages" })));
        }
        // select
        if (field.tag === 'select' && fieldData) {
            return (__chunk_1.h("div", { class: "form-group row", style: styles }, __chunk_1.h("label", { htmlFor: key, class: "col-md-4 col-form-label" }, __chunk_3.StringUtil.uppercaseFirst(this.translate(field.label))), __chunk_1.h("div", { class: "col-md-8" }, __chunk_1.h("select", { name: key, class: "form-control" }, fieldData.map(function (item) {
                return __chunk_1.h("option", { value: item.value, selected: item.selected }, item.text);
            }))), __chunk_1.h("div", { class: "col-md-8 offset-md-4 messages" })));
        }
    }
    parseField(key, field) {
        let fieldData;
        let fieldRelationship;
        if (this.entity.relationships) {
            Object.keys(this.entity.relationships).forEach((k, i) => {
                if (k.match('field_' + key)) {
                    fieldRelationship = this.entity.relationships[k];
                }
            });
        }
        if (fieldRelationship && fieldRelationship.data) {
            fieldData = fieldRelationship.data;
        }
        // input: select
        if (field.tag === 'select') {
            fieldData = this.parseFieldDataArray(key, fieldData);
        }
        // input: checkbox
        if (field.tag === 'input' && field.type === 'checkbox') {
            fieldData = this.parseFieldDataArray(key, fieldData);
        }
        // input: radio
        if (field.tag === 'input' && field.type === 'radio') {
            fieldData = this.parseFieldDataArray(key, fieldData);
        }
        // console.log(key, fieldData);
        return fieldData;
    }
    parseFieldDataArray(key, fieldData) {
        if (!fieldData && Array.isArray(this.data[key])) {
            fieldData = this.data[key];
        }
        else {
            if (fieldData) {
                fieldData.map((item) => {
                    if (this.data[key] == item.value) {
                        item.selected = true;
                    }
                });
            }
        }
        return fieldData;
    }
    render() {
        let entity = {};
        if (this.definitionsJson) {
            this.definitions = JSON.parse(this.definitionsJson);
        }
        if (this.dataJson) {
            this.data = JSON.parse(this.dataJson);
        }
        if (this.data) {
            entity = this.entity = this.data;
        }
        if (entity.attributes) {
            this.data = entity.attributes;
        }
        else {
            this.data = entity;
        }
        if (entity.type) {
            this.type = entity.type;
        }
        this.dataCopy = JSON.parse(JSON.stringify(entity));
        return (__chunk_1.h("div", null, Object.keys(this.data).map((key) => {
            return this.renderFormField(key);
        })));
    }
}

class FormField {
    constructor(hostRef) {
        __chunk_1.registerInstance(this, hostRef);
        this.data = {};
        this.config = {
            "label": "",
            "tag": "input",
            "type": "text",
            "placeholder": "",
            "hidden": false,
            "disabled": false
        };
        this.keyId = '';
        this.tag = 'input';
        this.type = 'text';
        this.translateService = __chunk_3.TranslateService.instance;
        this.changed = __chunk_1.createEvent(this, "changed", 7);
    }
    componentDidLoad() {
        this.postRender();
    }
    componentDidUpdate() {
        this.postRender();
    }
    postRender() {
        if (this.config.hidden || this.config.type === 'hidden')
            this.el.style.display = "none";
        this.changed.emit({ value: this.currentValue, el: this.el });
    }
    async setData(data) {
        this.data = data;
    }
    async getValue() {
        return this.currentValue;
    }
    translate(str) {
        return this.translateService.get(str);
    }
    render() {
        let field;
        if (this.dataJson) {
            this.data = Object.assign({}, this.data, JSON.parse(this.dataJson));
        }
        if (this.configJson) {
            this.config = Object.assign({}, this.config, JSON.parse(this.configJson));
            field = this.config;
        }
        if (this.value) {
            this.currentValue = __chunk_3.Util.tryParseJSON(this.value) || this.value;
        }
        return (__chunk_1.h("div", null, field.tag === 'input' && (field.type === 'text' ||
            field.type === 'password' ||
            field.type === 'date' ||
            field.type === 'datetime' ||
            field.type === 'datetime-local') &&
            __chunk_1.h("div", { class: "form-group row", style: this.styles }, __chunk_1.h("label", { class: "col-md-4 col-form-label", htmlFor: this.keyId }, __chunk_3.StringUtil.uppercaseFirst(this.translate(field.label))), __chunk_1.h("div", { class: "col-md-8" }, __chunk_1.h("input", { class: "form-control", name: this.keyId, placeholder: field.placeholder, disabled: field.disabled, hidden: field.hidden, type: field.type, value: this.currentValue })), __chunk_1.h("div", { class: "col-md-8 offset-md-4 messages" }))));
    }
    get el() { return __chunk_1.getElement(this); }
}

/*
 *
 * Copryright 2018, Craig Condon
 * Licensed under MIT
 *
 * Filter JavaScript objects with mongodb queries
 */

/**
 */

function isFunction(value) {
  return typeof value === 'function';
}

/**
 */

function isArray(value) {
  return Object.prototype.toString.call(value) === '[object Array]';
}

/**
 */

function comparable(value) {
  if (value instanceof Date) {
    return value.getTime();
  } else if (isArray(value)) {
    return value.map(comparable);
  } else if (value && typeof value.toJSON === 'function') {
    return value.toJSON();
  } else {
    return value;
  }
}

function get(obj, key) {
  return isFunction(obj.get) ? obj.get(key) : obj[key];
}

/**
 */

function or(validator) {
  return function(a, b) {
    if (!isArray(b) || !b.length) {
      return validator(a, b);
    }
    for (var i = 0, n = b.length; i < n; i++) {
      if (validator(a, get(b,i))) return true;
    }
    return false;
  }
}

/**
 */

function and(validator) {
  return function(a, b) {
    if (!isArray(b) || !b.length) {
      return validator(a, b);
    }
    for (var i = 0, n = b.length; i < n; i++) {
      if (!validator(a, get(b, i))) return false;
    }
    return true;
  };
}

function validate(validator, b, k, o) {
  return validator.v(validator.a, b, k, o);
}

var OPERATORS = {

  /**
   */

  $eq: or(function(a, b) {
    return a(b);
  }),

  /**
   */

  $ne: and(function(a, b) {
    return !a(b);
  }),

  /**
   */

  $gt: or(function(a, b) {
    return compare(comparable(b), a) > 0;
  }),

  /**
   */

  $gte: or(function(a, b) {
    return compare(comparable(b), a) >= 0;
  }),

  /**
   */

  $lt: or(function(a, b) {
    return compare(comparable(b), a) < 0;
  }),

  /**
   */

  $lte: or(function(a, b) {
    return compare(comparable(b), a) <= 0;
  }),

  /**
   */

  $mod: or(function(a, b) {
    return b % a[0] == a[1];
  }),

  /**
   */

  $in: function(a, b) {

    if (b instanceof Array) {
      for (var i = b.length; i--;) {
        if (~a.indexOf(comparable(get(b, i)))) {
          return true;
        }
      }
    } else {
      var comparableB = comparable(b);
      if (comparableB === b && typeof b === 'object') {
        for (var i = a.length; i--;) {
          if (String(a[i]) === String(b) && String(b) !== '[object Object]') {
            return true;
          }
        }
      }

      /*
        Handles documents that are undefined, whilst also
        having a 'null' element in the parameters to $in.
      */
      if (typeof comparableB == 'undefined') {
        for (var i = a.length; i--;) {
          if (a[i] == null) {
            return true;
          }
        }
      }

      /*
        Handles the case of {'field': {$in: [/regexp1/, /regexp2/, ...]}}
      */
      for (var i = a.length; i--;) {
        var validator = createRootValidator(get(a, i), undefined);
        var result = validate(validator, b, i, a);
        if ((result) && (String(result) !== '[object Object]') && (String(b) !== '[object Object]')) {
          return true;
        }
      }

      return !!~a.indexOf(comparableB);
    }

    return false;
  },

  /**
   */

  $nin: function(a, b, k, o) {
    return !OPERATORS.$in(a, b, k, o);
  },

  /**
   */

  $not: function(a, b, k, o) {
    return !validate(a, b, k, o);
  },

  /**
   */

  $type: function(a, b) {
    return b != void 0 ? b instanceof a || b.constructor == a : false;
    },

  /**
   */

  $all: function(a, b, k, o) {
    return OPERATORS.$and(a, b, k, o);
  },

  /**
   */

  $size: function(a, b) {
    return b ? a === b.length : false;
  },

  /**
   */

  $or: function(a, b, k, o) {
    for (var i = 0, n = a.length; i < n; i++) if (validate(get(a, i), b, k, o)) return true;
    return false;
  },

  /**
   */

  $nor: function(a, b, k, o) {
    return !OPERATORS.$or(a, b, k, o);
  },

  /**
   */

  $and: function(a, b, k, o) {
    for (var i = 0, n = a.length; i < n; i++) {
      if (!validate(get(a, i), b, k, o)) {
        return false;
      }
    }
    return true;
  },

  /**
   */

  $regex: or(function(a, b) {
    return typeof b === 'string' && a.test(b);
  }),

  /**
   */

  $where: function(a, b, k, o) {
    return a.call(b, b, k, o);
  },

  /**
   */

  $elemMatch: function(a, b, k, o) {
    if (isArray(b)) {
      return !!~search(b, a);
    }
    return validate(a, b, k, o);
  },

  /**
   */

  $exists: function(a, b, k, o) {
    return o.hasOwnProperty(k) === a;
  }
};

/**
 */

var prepare = {

  /**
   */

  $eq: function(a) {

    if (a instanceof RegExp) {
      return function(b) {
        return typeof b === 'string' && a.test(b);
      };
    } else if (a instanceof Function) {
      return a;
    } else if (isArray(a) && !a.length) {
      // Special case of a == []
      return function(b) {
        return (isArray(b) && !b.length);
      };
    } else if (a === null){
      return function(b){
        //will match both null and undefined
        return b == null;
      }
    }

    return function(b) {
      return compare(comparable(b), comparable(a)) === 0;
    };
  },

  /**
   */

  $ne: function(a) {
    return prepare.$eq(a);
  },

  /**
   */

  $and: function(a) {
    return a.map(parse);
  },

  /**
   */

  $all: function(a) {
    return prepare.$and(a);
  },

  /**
   */

  $or: function(a) {
    return a.map(parse);
  },

  /**
   */

  $nor: function(a) {
    return a.map(parse);
  },

  /**
   */

  $not: function(a) {
    return parse(a);
  },

  /**
   */

  $regex: function(a, query) {
    return new RegExp(a, query.$options);
  },

  /**
   */

  $where: function(a) {
    return typeof a === 'string' ? new Function('obj', 'return ' + a) : a;
  },

  /**
   */

  $elemMatch: function(a) {
    return parse(a);
  },

  /**
   */

  $exists: function(a) {
    return !!a;
  }
};

/**
 */

function search(array, validator) {

  for (var i = 0; i < array.length; i++) {
    var result = get(array, i);
    if (validate(validator, get(array, i))) {
      return i;
    }
  }

  return -1;
}

/**
 */

function createValidator(a, validate) {
  return { a: a, v: validate };
}

/**
 */

function nestedValidator(a, b) {
  var values  = [];
  findValues(b, a.k, 0, b, values);

  if (values.length === 1) {
    var first = values[0];
    return validate(a.nv, first[0], first[1], first[2]);
  }

  // If the query contains $ne, need to test all elements ANDed together
  var inclusive = a && a.q && typeof a.q.$ne !== 'undefined';
  var allValid = inclusive;
  for (var i = 0; i < values.length; i++) {
    var result = values[i];
    var isValid = validate(a.nv, result[0], result[1], result[2]);
    if (inclusive) {
      allValid &= isValid;
    } else {
      allValid |= isValid;
    }
  }
  return allValid;
}

/**
 */

function findValues(current, keypath, index, object, values) {

  if (index === keypath.length || current == void 0) {

    values.push([current, keypath[index - 1], object]);
    return;
  }

  var k = get(keypath, index);

  // ensure that if current is an array, that the current key
  // is NOT an array index. This sort of thing needs to work:
  // sift({'foo.0':42}, [{foo: [42]}]);
  if (isArray(current) && isNaN(Number(k))) {
    for (var i = 0, n = current.length; i < n; i++) {
      findValues(get(current, i), keypath, index, current, values);
    }
  } else {
    findValues(get(current, k), keypath, index + 1, current, values);
  }
}

/**
 */

function createNestedValidator(keypath, a, q) {
  return { a: { k: keypath, nv: a, q: q }, v: nestedValidator };
}

/**
 * flatten the query
 */

function isVanillaObject(value) {
  return value && value.constructor === Object;
}

function parse(query) {
  query = comparable(query);

  if (!query || !isVanillaObject(query)) { // cross browser support
    query = { $eq: query };
  }

  var validators = [];

  for (var key in query) {
    var a = query[key];

    if (key === '$options') {
      continue;
    }

    if (OPERATORS[key]) {
      if (prepare[key]) a = prepare[key](a, query);
      validators.push(createValidator(comparable(a), OPERATORS[key]));
    } else {

      if (key.charCodeAt(0) === 36) {
        throw new Error('Unknown operation ' + key);
      }
      validators.push(createNestedValidator(key.split('.'), parse(a), a));
    }
  }

  return validators.length === 1 ? validators[0] : createValidator(validators, OPERATORS.$and);
}

/**
 */

function createRootValidator(query, getter) {
  var validator = parse(query);
  if (getter) {
    validator = {
      a: validator,
      v: function(a, b, k, o) {
        return validate(a, getter(b), k, o);
      }
    };
  }
  return validator;
}

/**
 */

function sift(query, array, getter) {

  if (isFunction(array)) {
    getter = array;
    array  = void 0;
  }

  var validator = createRootValidator(query, getter);

  function filter(b, k, o) {
    return validate(validator, b, k, o);
  }

  if (array) {
    return array.filter(filter);
  }

  return filter;
}

/**
 */

function compare(a, b) {
  if(a===b) return 0;
  if(typeof a === typeof b) {
    if (a > b) {
      return 1;
    }
    if (a < b) {
      return -1;
    }
  }
}

function ForbiddenError(message, options = {}) {
  Error.call(this);
  this.constructor = ForbiddenError;
  this.subject = options.subject;
  this.subjectName = options.subjectName;
  this.action = options.action;
  this.field = options.field;
  this.message = message || `Cannot execute "${this.action}" on "${this.subjectName}"`;

  if (typeof Error.captureStackTrace === 'function') {
    this.name = this.constructor.name;
    Error.captureStackTrace(this, this.constructor);
  } else {
    this.stack = new Error(this.message).stack;
  }
}

ForbiddenError.prototype = Object.create(Error.prototype);

function wrapArray(value) {
  return Array.isArray(value) ? value : [value];
}

function getSubjectName(subject) {
  if (!subject || typeof subject === 'string') {
    return subject;
  }

  const Type = typeof subject === 'object' ? subject.constructor : subject;

  return Type.modelName || Type.name;
}

class Rule {
  constructor(params) {
    this.actions = params.actions || params.action;
    this.subject = params.subject;
    this.fields = !params.fields || params.fields.length === 0 ? undefined : wrapArray(params.fields);
    this.inverted = !!params.inverted;
    this.conditions = params.conditions;
    this._matches = this.conditions ? sift(this.conditions) : undefined;
    this.reason = params.reason;
  }

  matches(object) {
    if (!this._matches) {
      return true;
    }

    if (typeof object === 'string') {
      return !this.inverted;
    }

    return this._matches(object);
  }

  isRelevantFor(object, field) {
    if (!this.fields) {
      return true;
    }

    if (!field) {
      return !this.inverted;
    }

    return this.fields.indexOf(field) !== -1;
  }
}

function clone(object) {
  return JSON.parse(JSON.stringify(object));
}

const DEFAULT_ALIASES = {
  manage: ['create', 'read', 'update', 'delete']
};
const PRIVATE_FIELD = typeof Symbol !== 'undefined' ? Symbol('private') : `__${Date.now()}`;

class Ability {
  static addAlias(alias, actions) {
    if (alias === actions || Array.isArray(actions) && actions.indexOf(alias) !== -1) {
      throw new Error(`Attempt to alias action to itself: ${alias} -> ${actions.toString()}`);
    }

    DEFAULT_ALIASES[alias] = actions;
    return this;
  }

  constructor(rules, { RuleType = Rule, subjectName = getSubjectName } = {}) {
    this[PRIVATE_FIELD] = {
      RuleType,
      subjectName,
      originalRules: rules || [],
      rules: {},
      events: {},
      aliases: clone(DEFAULT_ALIASES)
    };
    this.update(rules);
  }

  update(rules) {
    if (Array.isArray(rules)) {
      const payload = { rules, ability: this };

      this.emit('update', payload);
      this[PRIVATE_FIELD].originalRules = Object.freeze(rules.slice(0));
      this[PRIVATE_FIELD].rules = this.buildIndexFor(this.rules);
      this.emit('updated', payload);
    }

    return this;
  }

  buildIndexFor(rules) {
    const indexedRules = {};
    const { RuleType } = this[PRIVATE_FIELD];

    for (let i = 0; i < rules.length; i++) {
      const rule = new RuleType(rules[i]);
      const actions = this.expandActions(rule.actions);
      const subjects = wrapArray(rule.subject);

      for (let k = 0; k < subjects.length; k++) {
        const subject = subjects[k];
        indexedRules[subject] = indexedRules[subject] || {};

        for (let j = 0; j < actions.length; j++) {
          const action = actions[j];
          indexedRules[subject][action] = indexedRules[subject][action] || [];
          indexedRules[subject][action].unshift(rule);
        }
      }
    }

    return indexedRules;
  }

  expandActions(rawActions) {
    const { aliases } = this[PRIVATE_FIELD];
    let actions = wrapArray(rawActions);
    let i = 0;

    while (i < actions.length) {
      const action = actions[i++];

      if (aliases.hasOwnProperty(action)) {
        actions = actions.concat(aliases[action]);
      }
    }

    return actions;
  }

  get rules() {
    return this[PRIVATE_FIELD].originalRules;
  }

  can(action, subject, field) {
    const rule = this.relevantRuleFor(action, subject, field);

    return !!rule && !rule.inverted;
  }

  relevantRuleFor(action, subject, field) {
    const rules = this.rulesFor(action, subject, field);

    for (let i = 0; i < rules.length; i++) {
      if (rules[i].matches(subject)) {
        return rules[i];
      }
    }

    return null;
  }

  possibleRulesFor(action, subject) {
    const subjectName = this[PRIVATE_FIELD].subjectName(subject);
    const { rules } = this[PRIVATE_FIELD];
    const specificRules = rules.hasOwnProperty(subjectName) ? rules[subjectName][action] : null;
    const generalRules = rules.hasOwnProperty('all') ? rules.all[action] : null;

    return (specificRules || []).concat(generalRules || []);
  }

  rulesFor(action, subject, field) {
    return this.possibleRulesFor(action, subject).filter(rule => rule.isRelevantFor(subject, field));
  }

  cannot(...args) {
    return !this.can(...args);
  }

  throwUnlessCan(...args) {
    const rule = this.relevantRuleFor(...args);

    if (!rule || rule.inverted) {
      const [action, subject, field] = args;
      const subjectName = this[PRIVATE_FIELD].subjectName(subject);

      throw new ForbiddenError(rule ? rule.reason : null, {
        action,
        subjectName,
        subject,
        field
      });
    }
  }

  on(event, handler) {
    const { events } = this[PRIVATE_FIELD];
    let isAttached = true;

    if (!events[event]) {
      events[event] = [];
    }

    events[event].push(handler);

    return () => {
      if (isAttached) {
        const index = events[event].indexOf(handler);
        events[event].splice(index, 1);
        isAttached = false;
      }
    };
  }

  emit(event, payload) {
    const handlers = this[PRIVATE_FIELD].events[event];

    if (handlers) {
      handlers.forEach(handler => handler(payload));
    }
  }
}

class Permission {
    // @Prop() rolesOnly: string;
    // @Prop() rolesExcept: string;
    constructor(hostRef) {
        __chunk_1.registerInstance(this, hostRef);
        this.roles = ['ANONYMOUS'];
        this.rules = [];
        this.can = '["read"]';
        this.subject = 'all';
        this.permissions = __chunk_3.PermissionsService.instance;
        this.rules = this.permissions.rules;
        addEventListener('permissionsRulesChange', (event) => {
            if (!this.isolate) {
                this.render();
            }
        });
    }
    componentDidLoad() {
        this.displayDefault = __chunk_3.Css.getStyle('display', this.el);
        this.parsePermissions();
    }
    componentDidUpdate() {
        this.parsePermissions();
    }
    componentDidUnload() {
        // todo: remove event listener
        // removeAllListeners()
    }
    async setPermissionService(instance) {
        this.permissions = instance;
        this.rules = [...this.permissions.rules];
    }
    async getRules() {
        return this.rules;
    }
    async setRules(rules, replace = true) {
        if (replace === true) {
            this.rules = [...rules];
        }
        else {
            this.rules = [...this.rules, ...rules];
        }
    }
    async update() {
        this.render();
    }
    parsePermissions() {
        if (!this.ability) {
            return;
        }
        this.el.style.display = this.displayDefault;
        this.canArray.forEach((action) => {
            if (!this.ability.can(action, this.subject)) {
                this.el.style.display = 'none';
                //this.el.removeChild(this.el.firstChild);
            }
        });
        // todo:
        // this.cannotArray.forEach((action) => {
        //     if(!this.ability.cannot(action, this.subject)) {
        //         this.el.style.display = 'none';
        //         //this.el.removeChild(this.el.firstChild);
        //     }
        // });
    }
    onPermissionsRulesChange() {
        if (!this.isolate) {
            this.render();
        }
    }
    render() {
        if (this.rulesJson) {
            this.rules = JSON.parse(this.rulesJson);
        }
        if (this.rules.length) {
            this.rules = [...this.permissions.rules];
            this.ability = new Ability(this.rules);
        }
        if (this.can) {
            this.canArray = JSON.parse(this.can);
        }
        if (this.cannot) {
            this.cannotArray = JSON.parse(this.cannot);
        }
        // console.log('render: ', this.rules.length);
        return (__chunk_1.h("span", null, __chunk_1.h("slot", null)));
    }
    get el() { return __chunk_1.getElement(this); }
}

exports.ema_entity_form = EntityForm;
exports.ema_form_field = FormField;
exports.ema_permission = Permission;
