UNPKG

@citation-js/core

Version:

Convert different bibliographic metadata sources

201 lines (200 loc) 6.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TypeParser = exports.FormatParser = exports.DataParser = void 0; var _type = require("./type.js"); function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } class TypeParser { constructor(data) { _defineProperty(this, "validDataTypes", ['String', 'Array', 'SimpleObject', 'ComplexObject', 'Primitive']); this.data = data; } validateDataType() { const dataType = this.data.dataType; if (dataType && !this.validDataTypes.includes(dataType)) { throw new RangeError(`dataType was ${dataType}; expected one of ${this.validDataTypes}`); } } validateParseType() { const predicate = this.data.predicate; if (predicate && !(predicate instanceof RegExp || typeof predicate === 'function')) { throw new TypeError(`predicate was ${typeof predicate}; expected RegExp or function`); } } validateTokenList() { const tokenList = this.data.tokenList; if (tokenList && typeof tokenList !== 'object') { throw new TypeError(`tokenList was ${typeof tokenList}; expected object or RegExp`); } } validatePropertyConstraint() { const propertyConstraint = this.data.propertyConstraint; if (propertyConstraint && typeof propertyConstraint !== 'object') { throw new TypeError(`propertyConstraint was ${typeof propertyConstraint}; expected array or object`); } } validateElementConstraint() { const elementConstraint = this.data.elementConstraint; if (elementConstraint && typeof elementConstraint !== 'string') { throw new TypeError(`elementConstraint was ${typeof elementConstraint}; expected string`); } } validateExtends() { const extend = this.data.extends; if (extend && typeof extend !== 'string') { throw new TypeError(`extends was ${typeof extend}; expected string`); } } validate() { if (this.data === null || typeof this.data !== 'object') { throw new TypeError(`typeParser was ${typeof this.data}; expected object`); } this.validateDataType(); this.validateParseType(); this.validateTokenList(); this.validatePropertyConstraint(); this.validateElementConstraint(); this.validateExtends(); } parseTokenList() { let tokenList = this.data.tokenList; if (!tokenList) { return []; } else if (tokenList instanceof RegExp) { tokenList = { token: tokenList }; } const { token, split = /\s+/, trim = true, every = true } = tokenList; const trimInput = input => trim ? input.trim() : input; const testTokens = every ? 'every' : 'some'; const predicate = input => trimInput(input).split(split)[testTokens](part => token.test(part)); return [predicate]; } parsePropertyConstraint() { const constraints = [].concat(this.data.propertyConstraint || []); return constraints.map(({ props, match, value }) => { props = [].concat(props); switch (match) { case 'any': case 'some': return input => props.some(prop => prop in input && (!value || value(input[prop]))); case 'none': return input => !props.some(prop => prop in input && (!value || value(input[prop]))); case 'every': default: return input => props.every(prop => prop in input && (!value || value(input[prop]))); } }); } parseElementConstraint() { const constraint = this.data.elementConstraint; return !constraint ? [] : [input => input.every(entry => (0, _type.type)(entry) === constraint)]; } parsePredicate() { if (this.data.predicate instanceof RegExp) { return [this.data.predicate.test.bind(this.data.predicate)]; } else if (this.data.predicate) { return [this.data.predicate]; } else { return []; } } getCombinedPredicate() { const predicates = [...this.parsePredicate(), ...this.parseTokenList(), ...this.parsePropertyConstraint(), ...this.parseElementConstraint()]; if (predicates.length === 0) { return () => true; } else if (predicates.length === 1) { return predicates[0]; } else { return input => predicates.every(predicate => predicate(input)); } } getDataType() { if (this.data.dataType) { return this.data.dataType; } else if (this.data.predicate instanceof RegExp) { return 'String'; } else if (this.data.tokenList) { return 'String'; } else if (this.data.elementConstraint) { return 'Array'; } else { return 'Primitive'; } } get dataType() { return this.getDataType(); } get predicate() { return this.getCombinedPredicate(); } get extends() { return this.data.extends; } } exports.TypeParser = TypeParser; class DataParser { constructor(parser, { async } = {}) { this.parser = parser; this.async = async; } validate() { const parser = this.parser; if (typeof parser !== 'function') { throw new TypeError(`parser was ${typeof parser}; expected function`); } } } exports.DataParser = DataParser; class FormatParser { constructor(format, parsers = {}) { this.format = format; if (parsers.parseType) { this.typeParser = new TypeParser(parsers.parseType); } if (parsers.parse) { this.dataParser = new DataParser(parsers.parse, { async: false }); } if (parsers.parseAsync) { this.asyncDataParser = new DataParser(parsers.parseAsync, { async: true }); } } validateFormat() { const format = this.format; if (!_type.typeMatcher.test(format)) { throw new TypeError(`format name was "${format}"; didn't match expected pattern`); } } validate() { this.validateFormat(); if (this.typeParser) { this.typeParser.validate(); } if (this.dataParser) { this.dataParser.validate(); } if (this.asyncDataParser) { this.asyncDataParser.validate(); } } } exports.FormatParser = FormatParser;