{"size": 1467, "ext": "js", "max_stars_repo_path": "lib/rules/doctype-first/index.js", "max_stars_repo_name": "alex-lit/linthtml", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "lib/rules/doctype-first/index.js", "max_issues_repo_name": "alex-lit/linthtml", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "lib/rules/doctype-first/index.js", "max_forks_repo_name": "alex-lit/linthtml", "max_forks_repo_forks_event_min_datetime": "2021-05-01T11:46:11.000Z", "max_forks_repo_forks_event_max_datetime": "2021-05-01T11:46:11.000Z"}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": 1, "avg_line_length": 21.8955223881, "max_line_length": 114, "alphanum_fraction": 0.6066802999}
const RULE_NAME = "doctype-first";

function validateConfig(option) {
  if (typeof option === "string" && option !== "smart") {
    throw new Error(`Configuration for rule "${this.name}" is invalid: Only "smart" is accepted as string value`);
  }

  if (typeof option !== "boolean" && typeof option !== "string") {
    throw new Error(`Configuration for rule "${this.name}" is invalid: Expected boolean got ${typeof option}`);
  }

  return option;
}

function end() {
  this.passedFirst = false;
}

function isWhitespace(element) {
  return element.type === "text" && /^[ \t\n\f\r]*$/.test(element.data);
}

/**
 * @param {import('../../parser/index').Node} node
 * @param {*} opts
 * @param {*} param2
 */
function lint(node, opts, { report }) {
  const option = opts[this.name];

  // CHECK if parent if first child instead
  // USE util function to check node type
  if (this.passedFirst || node.type === "comment" || isWhitespace(node)) {
    return;
  }
  this.passedFirst = true;

  if (
    node.type === "directive" &&
    node.name.toUpperCase() === "!DOCTYPE"
  ) {
    return;
  }

  // If the option is 'smart', fail only if a head tag is present.
  if (
    option === "smart" &&
    !(node.type === "tag" && node.name.toLowerCase() === "head")
  ) {
    return;
  }

  report({
    code: "E007",
    position: node.open ? node.open.loc : node.loc
  });
}

module.exports = {
  name: RULE_NAME,
  validateConfig,
  lint,
  end,

  passedFirst: false
};
