109 lines
2.9 KiB
TypeScript
109 lines
2.9 KiB
TypeScript
import { SQLDataSource } from 'datasource-sql';
|
|
import { Keyword, KeywordType } from '../types/keyword-types';
|
|
import { TextsAPI } from './texts-api';
|
|
|
|
const MINUTE = 60;
|
|
|
|
export class KeywordAPI extends SQLDataSource {
|
|
textsApi: TextsAPI;
|
|
constructor(config, textsApi) {
|
|
super(config);
|
|
this.textsApi = textsApi;
|
|
}
|
|
|
|
getType(data: any) {
|
|
// raw queries doesn't camelCase...
|
|
const typeObject = data.type_id ?? data.typeId;
|
|
const typeId = typeObject ?? 0;
|
|
|
|
return {
|
|
...data,
|
|
type: KeywordType[typeId],
|
|
};
|
|
}
|
|
|
|
async getProductKeywords(productId: number): Promise<Array<Keyword>> {
|
|
const query = /* sql */ `
|
|
SELECT keywords.*, keyword_type.type_id FROM keywords
|
|
LEFT JOIN keyword_type ON keyword_type.keyword_id = keywords.id
|
|
JOIN product_keyword ON product_keyword.keyword_id = keywords.id
|
|
WHERE product_keyword.product_id = ?
|
|
ORDER BY keywords.value
|
|
`;
|
|
|
|
return this.knex
|
|
.raw(query, productId)
|
|
.then((data) => data.rows.map((row) => this.getType(row)));
|
|
}
|
|
|
|
async getKeywords(): Promise<Array<Keyword>> {
|
|
const query = /* sql */ `
|
|
SELECT keywords.*, keyword_type.type_id FROM keywords
|
|
LEFT JOIN keyword_type ON keyword_type.keyword_id = keywords.id
|
|
ORDER BY keywords.value
|
|
`;
|
|
return this.knex
|
|
.raw(query)
|
|
.then((data) => data.rows.map((row) => this.getType(row)));
|
|
}
|
|
|
|
async getKeywordById(id: number): Promise<Keyword> {
|
|
return this.knex
|
|
.select('*')
|
|
.from('keywords')
|
|
.leftJoin('keyword_type', 'keyword_type.keyword_id', 'keywords.id')
|
|
.where('id', id)
|
|
.first()
|
|
.cache(MINUTE)
|
|
.then((row) => this.getType(row));
|
|
}
|
|
|
|
async searchKeywords(name: string): Promise<Array<Keyword>> {
|
|
return this.knex
|
|
.select('*')
|
|
.from('keywords')
|
|
.leftJoin('keyword_type', 'keyword_type.keyword_id', 'keywords.id')
|
|
.whereRaw(`LOWER(value) LIKE ?`, [`${name}`]);
|
|
}
|
|
|
|
async setProductKeywords(
|
|
productId: number,
|
|
keywordIds: Array<number>,
|
|
): Promise<any> {
|
|
await this.knex('product_keyword').where('product_id', productId).del();
|
|
|
|
const fieldsToInsert = keywordIds.map((keywordId) => ({
|
|
product_id: productId,
|
|
keyword_id: keywordId,
|
|
}));
|
|
|
|
return this.knex('product_keyword').insert(fieldsToInsert);
|
|
}
|
|
|
|
// Mutations
|
|
async addKeyword(name: string, type: KeywordType): Promise<number> {
|
|
const res = await this.knex('keywords')
|
|
.insert({ value: name })
|
|
.returning('id');
|
|
const keywordId = res[0].id;
|
|
|
|
if (type) {
|
|
const typeRes = await this.knex
|
|
.select('*')
|
|
.from('keywordtypes')
|
|
.where('name', type.toString().toLowerCase());
|
|
|
|
if (typeRes.length > 0) {
|
|
const typeId = typeRes[0].id;
|
|
await this.knex('keyword_type').insert({
|
|
keyword_id: keywordId,
|
|
type_id: typeId,
|
|
});
|
|
}
|
|
}
|
|
await this.textsApi.translateKeyword(keywordId, name);
|
|
|
|
return keywordId;
|
|
}
|
|
}
|