"use strict"; const api = require("../api.js"); const uri = require("../util/uri.js"); const events = require("../events.js"); const misc = require("../util/misc.js"); class Tag extends events.EventTarget { constructor() { const TagList = require("./tag_list.js"); super(); this._orig = {}; for (let obj of [this, this._orig]) { obj._suggestions = new TagList(); obj._implications = new TagList(); } this._updateFromResponse({}); } get names() { return this._names; } get category() { return this._category; } get description() { return this._description; } get suggestions() { return this._suggestions; } get implications() { return this._implications; } get postCount() { return this._postCount; } get creationTime() { return this._creationTime; } get lastEditTime() { return this._lastEditTime; } set names(value) { this._names = value; } set category(value) { this._category = value; } set description(value) { this._description = value; } get metric() { return this._metric; } set metric(value) { this._metric = value; } static fromResponse(response) { const ret = new Tag(); ret._updateFromResponse(response); return ret; } static get(name) { return api.get(uri.formatApiLink("tag", name)).then((response) => { return Promise.resolve(Tag.fromResponse(response)); }); } save() { const detail = { version: this._version }; // send only changed fields to avoid user privilege violation if (misc.arraysDiffer(this._names, this._orig._names, true)) { detail.names = this._names; } if (this._category !== this._orig._category) { detail.category = this._category; } if (this._description !== this._orig._description) { detail.description = this._description; } if (misc.arraysDiffer(this._implications, this._orig._implications)) { detail.implications = this._implications.map( (relation) => relation.names[0] ); } if (misc.arraysDiffer(this._suggestions, this._orig._suggestions)) { detail.suggestions = this._suggestions.map( (relation) => relation.names[0] ); } if (this._metric !== this._orig._metric) { detail.metric = { min: this._metric.min, max: this._metric.max }; } let promise = this._origName ? api.put(uri.formatApiLink("tag", this._origName), detail) : api.post(uri.formatApiLink("tags"), detail); return promise.then((response) => { this._updateFromResponse(response); this.dispatchEvent( new CustomEvent("change", { detail: { tag: this, }, }) ); return Promise.resolve(); }); } merge(targetName, addAlias) { return api .get(uri.formatApiLink("tag", targetName)) .then((response) => { return api.post(uri.formatApiLink("tag-merge"), { removeVersion: this._version, remove: this._origName, mergeToVersion: response.version, mergeTo: targetName, }); }) .then((response) => { if (!addAlias) { return Promise.resolve(response); } return api.put(uri.formatApiLink("tag", targetName), { version: response.version, names: response.names.concat(this._names), }); }) .then((response) => { this._updateFromResponse(response); this.dispatchEvent( new CustomEvent("change", { detail: { tag: this, }, }) ); return Promise.resolve(); }); } delete() { return api .delete(uri.formatApiLink("tag", this._origName), { version: this._version, }) .then((response) => { this.dispatchEvent( new CustomEvent("delete", { detail: { tag: this, }, }) ); return Promise.resolve(); }); } deleteMetric() { return api.delete( uri.formatApiLink("metric", this._origName), {version: this.metric.version}) .then((response) => { this.dispatchEvent( new CustomEvent("delete", { detail: { metric: this.metric, }, }) ); return Promise.resolve(); }); } _updateFromResponse(response) { const map = { _version: response.version, _origName: response.names ? response.names[0] : null, _names: response.names || [], _category: response.category, _description: response.description, _creationTime: response.creationTime, _lastEditTime: response.lastEditTime, _postCount: response.usages || 0, _metric: response.metric, }; for (let obj of [this, this._orig]) { obj._suggestions.sync(response.suggestions); obj._implications.sync(response.implications); } Object.assign(this, map); Object.assign(this._orig, map); } } module.exports = Tag;