fixed unique path function (#71)

This commit is contained in:
Arwid Thornström
2021-10-12 15:49:28 +02:00
committed by GitHub
parent 7aff154eb4
commit 3cf38453cd
2 changed files with 32 additions and 21 deletions
+28 -21
View File
@@ -20,7 +20,12 @@ import {
Batch, Batch,
} from '../types/product-types'; } from '../types/product-types';
import { Maybe } from '../types/types'; import { Maybe } from '../types/types';
import { booleanStringField, nullOrNumber, roundOrDefaultTo } from './utils'; import {
booleanStringField,
isInt,
nullOrNumber,
roundOrDefaultTo,
} from './utils';
import { UserInputError } from 'apollo-server'; import { UserInputError } from 'apollo-server';
const MINUTE = 60; const MINUTE = 60;
@@ -279,65 +284,67 @@ export class ProductAPI extends BaseSQLDataSource {
); );
} }
async getUniqueProductSlug( async getUniqueProductPath(
slug: string, path: string,
productId?: number, productId?: number,
): Promise<string> { ): Promise<string> {
// If productId is set then check if slug is already // If productId is set then check if path is already
// set on that product. // set on that product.
if (productId) { if (productId) {
const productPath = await this.knex.raw( const productPath = await this.knex.raw(
`SELECT path FROM "product-products" WHERE productid = ?`, `SELECT path FROM "product-products" WHERE productid = ?`,
[productId], [productId],
); );
if (productPath.rows[0].path === slug) { if (productPath.rows[0].path === path) {
return slug; return path;
} }
} }
// Check for unique-slug // Check for unique-path
// Get paths from product-products // Get paths from product-products
const basePath = slug(path, { remove: /(\d+)(?!.*\d)/ }); // Remove last number adf-1-asdf-123 = adf-1-asdf-
const pathResponse = await this.knex.raw( const pathResponse = await this.knex.raw(
`SELECT path FROM "product-products" WHERE path LIKE ?`, `SELECT path FROM "product-products" WHERE path LIKE ?`,
[slug + '%'], [basePath + '%'],
); );
const paths = pathResponse.rows.map((item) => item.path); const paths = pathResponse.rows.map((item) => item.path);
// Evaluate new pathname // Evaluate new pathname
let newSlug = ''; let newPath = '';
// If the exact match of the slug is not listed // If the exact match of the slug is not listed
// in the paths queried from db. Then use the // in the paths queried from db. Then use the
// tested slug. // tested slug.
if (!paths.includes(slug)) { if (!paths.includes(path)) {
newSlug = slug; newPath = path;
} else { } else {
// Try to find any numbers in the pathname // Try to find any numbers in the pathname
const numbers = paths const numbers = paths
.map((path) => { .map((p) => {
return parseInt(path.replace(slug + '-', '')); const numStr = p.replace(basePath + '-', '');
return isInt(numStr) ? parseInt(numStr) : null;
}) })
.filter(Boolean); // Remove falsy .filter(Boolean); // Remove falsy
if (numbers.length === 0) { if (numbers.length === 0) {
// No numbers found, add 1. // No numbers found, add 1.
newSlug = slug + '-1'; newPath = path + '-1';
} else { } else {
// Get highest number + 1 // Get highest number + 1
const next = Math.max(...numbers) + 1; const next = Math.max(...numbers) + 1;
newSlug = slug + '-' + next; newPath = basePath + '-' + next;
} }
} }
return newSlug; return newPath;
} }
async addProduct(name: string, batch: string): Promise<number> { async addProduct(name: string, batch: string): Promise<number> {
const path = batch ? batch + ' ' + name : name; const path = batch ? batch + ' ' + name : name;
const productSlug = slug(path); const productPath = slug(path);
const safeSlug = await this.getUniqueProductSlug(productSlug, null); const safePath = await this.getUniqueProductPath(productPath, null);
const idres = await this.knex const idres = await this.knex
.table('product-products') .table('product-products')
.insert({ .insert({
path: slug(safeSlug), path: slug(safePath),
browsable: 0, browsable: 0,
visible: 0, visible: 0,
}) })
@@ -354,7 +361,7 @@ export class ProductAPI extends BaseSQLDataSource {
info: ProductInfoInput, info: ProductInfoInput,
): Promise<any[]> { ): Promise<any[]> {
// Check path and insert new unique path if taken // Check path and insert new unique path if taken
const uniquePath = await this.getUniqueProductSlug(info.path, productId); const uniquePath = await this.getUniqueProductPath(info.path, productId);
const promises = []; const promises = [];
promises.push( promises.push(
+4
View File
@@ -4,6 +4,10 @@ function isNumeric(n: InputType) {
return !isNaN(parseFloat(n)); return !isNaN(parseFloat(n));
} }
export function isInt(str: InputType) {
return !isNaN(parseFloat(str)) && Number.isInteger(parseFloat(str));
}
function isBoolean(n: InputType | boolean) { function isBoolean(n: InputType | boolean) {
if (typeof n === 'boolean') { if (typeof n === 'boolean') {
return true; return true;