"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.coerceBadly = exports.Schema = void 0; const grammar_1 = require("./grammar"); /** * The Schema provides information and utilities for an InfluxDB measurement. * @private */ class Schema { constructor(options) { this.options = options; this._tagHash = {}; // FieldNames are sorted for performance: when coerceFields is run the // fields will be added to the output in order. this._fieldNames = Object.keys(options.fields).sort(); options.tags.forEach((tag) => { this._tagHash[tag] = true; }); } /** * CoerceFields converts a map of field values to a strings which * can be injected into the line protocol without further escaping. * The output is given in [key, value] pairs. */ coerceFields(fields) { let consumed = 0; const output = []; this._fieldNames.forEach((field) => { if (!fields.hasOwnProperty(field)) { return; } const value = fields[field]; const typ = typeof value; consumed += 1; if (value === null || value === undefined) { return; } let coerced; switch (this.options.fields[field]) { case grammar_1.FieldType.STRING: coerced = grammar_1.escape.quoted(String(value)); break; case grammar_1.FieldType.INTEGER: if (typ !== "number" && !grammar_1.isNumeric(String(value))) { throw new Error(`Expected numeric value for ${this._ref(field)}, but got '${value}'!`); } coerced = String(Math.floor(value)) + "i"; break; case grammar_1.FieldType.FLOAT: if (typ !== "number" && !grammar_1.isNumeric(String(value))) { throw new Error(`Expected numeric value for ${this._ref(field)}, but got '${value}'!`); } coerced = String(value); break; case grammar_1.FieldType.BOOLEAN: if (typ !== "boolean") { throw new Error(`Expected boolean value for ${this._ref(field)}, but got a ${typ}!`); } coerced = value ? "T" : "F"; break; default: throw new Error(`Unknown field type ${this.options.fields[field]} for ${field} in ` + `${this._ref()}. Please ensure that your configuration is correct.`); } output.push([field, coerced]); }); const keys = Object.keys(fields); if (consumed !== keys.length) { const extraneous = keys.filter((f) => !this._fieldNames.includes(f)); throw new Error("Extraneous fields detected for writing InfluxDB point in " + `${this._ref()}: \`${extraneous.join("`, `")}\`.`); } return output; } /** * Throws an error if the tags include values other than * what was specified in the schema. It returns a list of tag names. */ checkTags(tags) { const names = Object.keys(tags); const extraneous = names.filter((tag) => !this._tagHash[tag]); if (extraneous.length > 0) { throw new Error("Extraneous tags detected for writing InfluxDB point in " + `${this._ref()}: \`${extraneous.join("`, `")}\`.`); } return names; } /** * Returns the 'db'.'measurement'[.'field'] referencing the current schema. */ _ref(field) { let out = this.options.database + "." + this.options.measurement; if (field) { out += "." + field; } return out; } } exports.Schema = Schema; /** * Coerces the field map to a set of writable values, a la coerceFields, * using native guesses based on the field datatypes. * @private */ function coerceBadly(fields) { return Object.keys(fields) .sort() .map((field) => { const value = fields[field]; if (typeof value === "string") { return [field, grammar_1.escape.quoted(value)]; } return [field, String(value)]; }); } exports.coerceBadly = coerceBadly;