@matsukky/perspective-client
Version:
Client library for the Perspective API
177 lines (176 loc) • 6.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Types = exports.Perspective = exports.ResponseError = exports.TextTooLongError = exports.TextEmptyError = exports.PerspectiveAPIClientError = exports.MAX_LENGTH = exports.availableAttributes = void 0;
const axios_1 = require("axios");
exports.availableAttributes = {
IDENTITY_ATTACK: ['ar', 'zh', 'cs', 'nl', 'en', 'fr', 'de', 'hi', 'hi-Latn', 'id', 'it', 'ja', 'ko', 'pl', 'pt', 'ru', 'es', 'sv'],
INSULT: ['ar', 'zh', 'cs', 'nl', 'en', 'fr', 'hi', 'hi-Latn', 'id', 'it', 'ja', 'ko', 'pl', 'pt', 'ru', 'sv'],
PROFANITY: ['ar', 'zh', 'cs', 'nl', 'en', 'fr', 'hi', 'hi-Latn', 'id', 'it', 'ja', 'ko', 'pl', 'pt', 'ru', 'sv'],
SEVERE_TOXICITY: ['ar', 'zh', 'cs', 'nl', 'en', 'fr', 'hi', 'hi-Latn', 'id', 'it', 'ja', 'ko', 'pl', 'pt', 'ru', 'sv'],
THREAT: ['ar', 'zh', 'cs', 'nl', 'en', 'fr', 'hi', 'hi-Latn', 'id', 'it', 'ja', 'ko', 'pl', 'pt', 'ru', 'sv'],
TOXICITY: ['ar', 'zh', 'cs', 'nl', 'en', 'fr', 'hi', 'hi-Latn', 'id', 'it', 'ja', 'ko', 'pl', 'pt', 'ru', 'sv'],
FLIRTATION: ['en'],
IDENTITY_ATTACK_EXPERIMENTAL: ['en'],
INSULT_EXPERIMENTAL: ['en'],
PROFANITY_EXPERIMENTAL: ['en'],
SEVERE_TOXICITY_EXPERIMENTAL: ['en'],
SEXUALLY_EXPLICIT: ['en'],
THREAT_EXPERIMENTAL: ['en'],
TOXICITY_EXPERIMENTAL: ['en'],
AFFINITY_EXPERIMENTAL: ['en'],
COMPASSION_EXPERIMENTAL: ['en'],
CURIOSITY_EXPERIMENTAL: ['en'],
NUANCE_EXPERIMENTAL: ['en'],
PERSONAL_STORY_EXPERIMENTAL: ['en'],
REASONING_EXPERIMENTAL: ['en'],
RESPECT_EXPERIMENTAL: ['en'],
ATTACK_ON_AUTHOR: ['en'],
ATTACK_ON_COMMENTER: ['en'],
INCOHERENT: ['en'],
INFLAMMATORY: ['en'],
LIKELY_TO_REJECT: ['en'],
OBSCENE: ['en'],
SPAM: ['en'],
UNSUBSTANTIAL: ['en']
};
const availableLanguages = [
'ar', // Arabic
'zh', // Chinese
'cs', // Czech
'nl', // Dutch
'en', // English
'fr', // French
'de', // German
'hi', // Hindi
'hi-Latn', // Hinglish
'id', // Indonesian
'it', // Italian
'ja', // Japanese
'ko', // Korean
'pl', // Polish
'pt', // Portuguese
'ru', // Russian
'es', // Spanish
'sv' // Swedish
];
const COMMENT_ANALYZER_URL = "https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze";
exports.MAX_LENGTH = 20480;
class PerspectiveAPIClientError extends Error {
constructor(message) {
super(message);
Error.captureStackTrace(this, this.constructor);
this.name = "PerspectiveAPIClientError";
}
}
exports.PerspectiveAPIClientError = PerspectiveAPIClientError;
class TextEmptyError extends PerspectiveAPIClientError {
constructor() {
super("text must not be empty");
this.name = "TextEmptyError";
}
}
exports.TextEmptyError = TextEmptyError;
class TextTooLongError extends PerspectiveAPIClientError {
constructor() {
super(`text must not be greater than ${exports.MAX_LENGTH.toString()} characters in length`);
this.name = "TextTooLongError";
}
}
exports.TextTooLongError = TextTooLongError;
class ResponseError extends PerspectiveAPIClientError {
response;
constructor(message, response) {
super(message);
this.response = response;
this.name = "ResponseError";
}
}
exports.ResponseError = ResponseError;
class Perspective {
static PerspectiveAPIClientError;
static TextEmptyError;
static TextTooLongError;
static ResponseError;
apiKey;
constructor({ apiKey }) {
this.apiKey = apiKey;
if (!this.apiKey) {
throw new Error("Must provide options.apiKey");
}
}
async analyze(text, attriubtes, options) {
const request = {
comment: { text },
requestedAttributes: this.parseAttributes(attriubtes ?? { TOXICITY: {} }),
...options,
};
this.validateComment(text);
if (options?.languages) {
this.validateLanguages(options.languages);
request.languages = options.languages;
}
const response = await axios_1.default
.post(COMMENT_ANALYZER_URL, request, {
params: { key: this.apiKey },
})
.catch((error) => {
if (axios_1.default.isAxiosError(error)) {
const responseError = new ResponseError(error.message, error);
throw responseError;
}
console.error("Unknown error", error);
return Promise.reject(new Error("Unknown error - see logs"));
});
return response.data;
}
validateComment(text) {
if (!text) {
throw new TextEmptyError();
}
if (text.length > exports.MAX_LENGTH) {
throw new TextTooLongError();
}
}
validateLanguages(languages) {
// Make sure requested languages are valid, if provided
languages.forEach((language) => {
if (!availableLanguages.includes(language)) {
throw new PerspectiveAPIClientError(`language ${language} is not supported`);
}
});
}
validateAttributesAndLanguages(attributes, languages) {
attributes.forEach(attribute => {
/* // Check if the attribute exists in availableAttributes
if (!(attribute in availableAttributes)) {
throw new PerspectiveAPIClientError(
`Attribute ${attribute} is not a valid attribute`
);
} */
languages.forEach(language => {
const allowedLanguages = exports.availableAttributes[attribute];
if (!allowedLanguages.includes(language)) {
throw new PerspectiveAPIClientError(`Language ${language} is not supported for attribute ${attribute}`);
}
});
});
}
parseAttributes(attributes) {
if (Array.isArray(attributes)) {
return attributes.reduce((acc, attribute) => {
acc[attribute] = {};
return acc;
}, {});
}
Object.values(attributes).forEach((attribute) => {
if (attribute.scoreThreshold &&
(attribute.scoreThreshold < 0 || attribute.scoreThreshold > 1)) {
throw new PerspectiveAPIClientError("scoreThreshold must be between 0 and 1");
}
});
return attributes;
}
}
exports.Perspective = Perspective;
exports.Types = require("./types");
exports.default = Perspective;