UNPKG

robot-directives

Version:

Parse robot directives within HTML meta and/or HTTP headers.

180 lines (123 loc) 3.12 kB
"use strict"; const constants = require("./constants"); const group = require("./group"); const _is = require("./is"); const parseBotAgent = require("./parseBotAgent"); const parseDirectives = require("./parseDirectives"); const splitDirectives = require("./splitDirectives"); const deepFreeze = require("deep-freeze-node"); const defaultOptions = { allIsReadonly: true, currentTime: function(){ return Date.now() }, restrictive: true, userAgent: "" }; function is(instance, directive, options, inverted, any) { let bot = instance.bot; if (options == null) { options = instance.options; } else { // TODO :: use evaluate-value options = Object.assign({}, instance.options, options); if (options.userAgent !== instance.options.userAgent) { bot = parseBotAgent(options.userAgent); } } if (instance.needsRefresh) { instance.needsRefresh = false; refresh(instance.directives_flat, instance.directives, options); } if (instance.directives_flat[bot] == null) { bot = "robots"; } return _is(instance.directives_flat[bot], directive, options, inverted, any); } /* Possibly update multiple values as a result of a single value change. */ function refresh(target, source, options) { Object.keys(source).forEach( function(key) { // `target.robots` is a reference, so it needn't be cloned if (key !== "robots") { // If agent group not yet defined if (target[key] == null) { target[key] = group.blank(); } // Set base as [a copy of] global Object.assign(target[key], target.robots); // Apply overrides group.merge(target[key], source[key], options); } }); } class RobotDirectives { constructor(options) { this.directives = { robots: group.initial() }; this.directives_flat = { robots: this.directives.robots }; this.options = Object.assign({}, defaultOptions, options); this.bot = parseBotAgent(this.options.userAgent); this.needsRefresh = false; } header(value) { value = splitDirectives(value); const bot = parseBotAgent(value.prefix); let prefix; if (bot === "robots") { prefix = value.prefix; } if (parseDirectives(bot, prefix, value.values, this)) { this.needsRefresh = true; } return this; } is(directive, options) { return is(this, directive, options, false, false); } isNot(directive, options) { return is(this, directive, options, true, false); } meta(name, content) { content = splitDirectives(content); // Compensate for any data from unfavorable HTML name = name.trim().toLowerCase(); if (parseDirectives(name, content.prefix, content.values, this)) { this.needsRefresh = true; } return this; } oneIs(directive, options) { return is(this, directive, options, false, true); } oneIsNot(directive, options) { return is(this, directive, options, true, true); } static isBot(botAgent) { return parseBotAgent(botAgent) !== "robots"; } } Object.assign(RobotDirectives, constants); module.exports = deepFreeze(RobotDirectives);