From 756fc022ed8ae682f9317d102637e6fcbc1a7519 Mon Sep 17 00:00:00 2001 From: "Shay.Gazit" Date: Sat, 13 Mar 2021 18:25:55 +0200 Subject: [PATCH 01/12] #16 --- src/services/storage/drivers/inMemory/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/storage/drivers/inMemory/index.ts b/src/services/storage/drivers/inMemory/index.ts index 3ee34c8..97fa523 100644 --- a/src/services/storage/drivers/inMemory/index.ts +++ b/src/services/storage/drivers/inMemory/index.ts @@ -43,8 +43,8 @@ export class InMemoryStorage implements StorageDriver { let deletedCount = 0 this.storage.data.urls.forEach((storedUrl) => { - const updatedAt = new Date(storedUrl.updatedAt).getTime() - if (updatedAt <= deleteBefore) { + const createdAt = new Date(storedUrl.createdAt).getTime() + if (createdAt <= deleteBefore) { this.storage.data.urls.delete(storedUrl.id) deletedCount++ } From 3720c2eec923323e230036e23b90c553ba56dc6d Mon Sep 17 00:00:00 2001 From: "Shay.Gazit" Date: Sat, 13 Mar 2021 21:01:59 +0200 Subject: [PATCH 02/12] CR fixes --- .env.development | 2 ++ src/config/index.ts | 1 + src/config/normalize.ts | 1 + src/config/types.ts | 2 ++ src/services/storage/drivers/inMemory/index.ts | 17 +++++++++++++++-- 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.env.development b/.env.development index 223b30d..27eff72 100644 --- a/.env.development +++ b/.env.development @@ -4,6 +4,8 @@ BASE_REDIRECT_URL=http://localhost:3000/u/ LOG_LEVEL=debug npm_package_type=module +URL_EXPIRE_FROM=create #update + ########## Storage ########## ## InMemory/Relational STORAGE_DRIVER=InMemory diff --git a/src/config/index.ts b/src/config/index.ts index 5f38eb8..87f5673 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -16,6 +16,7 @@ const rawConfig: RawConfig = { url: { matchPattern: process.env.URL_MATCH_PATTERN || '**', lifetime: process.env.URL_LIFETIME || '7 days', + urlExpireFrom: process.env.URL_EXPIRE_FROM || 'creationTime', }, storage: { driverName: process.env.STORAGE_DRIVER || '', diff --git a/src/config/normalize.ts b/src/config/normalize.ts index 7408ad7..1fa1b94 100644 --- a/src/config/normalize.ts +++ b/src/config/normalize.ts @@ -35,6 +35,7 @@ export function normalizeConfig({ baseRedirectUrl, url: { lifetimeMs: ms(url.lifetime), + urlExpireFrom : url.urlExpireFrom, matchPattern: url.matchPattern, cleanupIntervalMs, }, diff --git a/src/config/types.ts b/src/config/types.ts index f008012..c276c62 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -10,6 +10,7 @@ export interface RawConfig { url: { matchPattern: string lifetime: string + urlExpireFrom: string } storage: { driverName: string @@ -39,6 +40,7 @@ export interface Config { url: { matchPattern: string lifetimeMs: number + urlExpireFrom: string cleanupIntervalMs: number } baseRedirectUrl: string diff --git a/src/services/storage/drivers/inMemory/index.ts b/src/services/storage/drivers/inMemory/index.ts index 97fa523..25ad782 100644 --- a/src/services/storage/drivers/inMemory/index.ts +++ b/src/services/storage/drivers/inMemory/index.ts @@ -1,8 +1,17 @@ import cryptoRandomString from 'crypto-random-string' import { NotFoundError } from '../../../../errors/notFound.js' +import { InvalidConfigError } from '../../../../errors/invalidConfig.js' import { InMemoryStorageConfig } from '../../types/config.js' import type { StorageDriver } from '../../types/index.js' import type { StoredUrl, UrlWithInformation, UrlRequestData } from '../../types/url.js' +import { getRawConfig } from '../../../../config/__test__/helpers' +import { logger } from '../../../logger/logger' + +function validateUrlExpireFrom(deleteFrom: string) { + if (deleteFrom !== 'create' && deleteFrom !== 'update') { + throw new InvalidConfigError("URL_EXPIRE_FROM value must be 'create' or 'update'") + } +} export class InMemoryStorage implements StorageDriver { data: { urls: Map; urlInformation: Map } = { @@ -39,12 +48,16 @@ export class InMemoryStorage implements StorageDriver { this.storage.data.urls.delete(id) } public async deleteOverdue(timespanMs: number): Promise { + const deleteFrom = getRawConfig().url.urlExpireFrom + logger.debug('urlExpireFrom is {}', deleteFrom) + validateUrlExpireFrom(deleteFrom) const deleteBefore = new Date().getTime() - timespanMs let deletedCount = 0 this.storage.data.urls.forEach((storedUrl) => { - const createdAt = new Date(storedUrl.createdAt).getTime() - if (createdAt <= deleteBefore) { + let relativeDate = new Date(storedUrl.createdAt).getTime() + if (deleteFrom === 'update') relativeDate = new Date(storedUrl.updatedAt).getTime() + if (relativeDate <= deleteBefore) { this.storage.data.urls.delete(storedUrl.id) deletedCount++ } From e3d2c325b4bb9d162f37c0eb34d8afbf37115af0 Mon Sep 17 00:00:00 2001 From: "Shay.Gazit" Date: Sat, 13 Mar 2021 21:05:49 +0200 Subject: [PATCH 03/12] resolve conflict --- src/services/storage/drivers/inMemory/index.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/services/storage/drivers/inMemory/index.ts b/src/services/storage/drivers/inMemory/index.ts index d7e54bd..51fa19c 100644 --- a/src/services/storage/drivers/inMemory/index.ts +++ b/src/services/storage/drivers/inMemory/index.ts @@ -3,14 +3,15 @@ import { NotFoundError } from '../../../../errors/notFound.js' import { InvalidConfigError } from '../../../../errors/invalidConfig.js' import { InMemoryStorageConfig } from '../../types/config.js' import type { StorageDriver } from '../../types/index.js' -import type { StoredUrl, UrlWithInformation, UrlRequestData } from '../../types/url.js' +import type {StoredUrl, UrlWithInformation, UrlRequestData, UrlInformation} from '../../types/url.js' +import {logger} from "../../../logger/logger"; +import {getRawConfig} from "../../../../config/__test__/helpers"; function validateUrlExpireFrom(deleteFrom: string) { if (deleteFrom !== 'create' && deleteFrom !== 'update') { throw new InvalidConfigError("URL_EXPIRE_FROM value must be 'create' or 'update'") } } -import type { StoredUrl, UrlWithInformation, UrlRequestData, UrlInformation } from '../../types/url.js' export class InMemoryStorage implements StorageDriver { data: { urls: Map; urlInformation: Map } = { From 9369ee5e7ee0d6c3af0af4fc4459514d0e188369 Mon Sep 17 00:00:00 2001 From: shay123g Date: Tue, 16 Mar 2021 13:39:25 +0200 Subject: [PATCH 04/12] Update .env.development Co-authored-by: lesagi --- .env.development | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.env.development b/.env.development index 27eff72..e95ecb9 100644 --- a/.env.development +++ b/.env.development @@ -4,7 +4,8 @@ BASE_REDIRECT_URL=http://localhost:3000/u/ LOG_LEVEL=debug npm_package_type=module -URL_EXPIRE_FROM=create #update +## create/update +URL_EXPIRE_FROM=create ########## Storage ########## ## InMemory/Relational From 6ab10423ef84f731abc66437adece759dba8d008 Mon Sep 17 00:00:00 2001 From: shay123g Date: Tue, 16 Mar 2021 13:40:39 +0200 Subject: [PATCH 05/12] Update src/services/storage/drivers/inMemory/index.ts Co-authored-by: lesagi --- src/services/storage/drivers/inMemory/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/services/storage/drivers/inMemory/index.ts b/src/services/storage/drivers/inMemory/index.ts index 51fa19c..90e6fc2 100644 --- a/src/services/storage/drivers/inMemory/index.ts +++ b/src/services/storage/drivers/inMemory/index.ts @@ -55,8 +55,7 @@ export class InMemoryStorage implements StorageDriver { let deletedCount = 0 this.storage.data.urls.forEach((storedUrl) => { - let relativeDate = new Date(storedUrl.createdAt).getTime() - if (deleteFrom === 'update') relativeDate = new Date(storedUrl.updatedAt).getTime() + const relativeDate = new Date(deleteFrom === 'update' ? storedUrl.updatedAt : storedUrl.createdAt).getTime() if (relativeDate <= deleteBefore) { this.storage.data.urls.delete(storedUrl.id) deletedCount++ From 71e967feff79fc48c67b1367c09fc852b8d00c09 Mon Sep 17 00:00:00 2001 From: "Shay.Gazit" Date: Tue, 16 Mar 2021 16:30:05 +0200 Subject: [PATCH 06/12] fix test & config --- src/config/__test__/helpers.ts | 1 + src/config/index.ts | 2 +- src/config/validate.ts | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/config/__test__/helpers.ts b/src/config/__test__/helpers.ts index 7986e4b..d3dcf43 100644 --- a/src/config/__test__/helpers.ts +++ b/src/config/__test__/helpers.ts @@ -10,6 +10,7 @@ export function getRawConfig(): RawConfig { url: { matchPattern: 'mock-patter', lifetime: '120', + urlExpireFrom: 'create' }, storage: { driverName: 'InMemory', diff --git a/src/config/index.ts b/src/config/index.ts index 87f5673..8b768a9 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -16,7 +16,7 @@ const rawConfig: RawConfig = { url: { matchPattern: process.env.URL_MATCH_PATTERN || '**', lifetime: process.env.URL_LIFETIME || '7 days', - urlExpireFrom: process.env.URL_EXPIRE_FROM || 'creationTime', + urlExpireFrom: process.env.URL_EXPIRE_FROM || 'create', }, storage: { driverName: process.env.STORAGE_DRIVER || '', diff --git a/src/config/validate.ts b/src/config/validate.ts index b77b608..c424e74 100644 --- a/src/config/validate.ts +++ b/src/config/validate.ts @@ -11,6 +11,7 @@ export function validateConfig(rawConfig: RawConfig): boolean { validateStorageDriver(rawConfig.storage) validateAuthDriver(rawConfig.auth) validateUrlLifetime(rawConfig.url.lifetime) + validateUrlExpireFrom(rawConfig.url.urlExpireFrom) validateLogLevel(rawConfig.logLevel) return true @@ -101,6 +102,13 @@ function validateUrlLifetime(urlLifetime: string): void { } } +function validateUrlExpireFrom(urlExpire: string): void { + logger.debug(`Start validateUrlExpireFrom with ${urlExpire}`) + if (!urlExpire || (urlExpire != 'create' && urlExpire != 'update')) { + throw new InvalidConfigError(`URL_EXPIRE_FROM specified is invalid (received ${urlExpire})`) + } +} + function validateLogLevel(logLevel: string) { logger.debug(`Start validateLogLevel with ${logLevel}`) const levelValues = Object.keys(logger.levels.values) From ad412740f44694ac9ee4dd975c6ef9471e8201f0 Mon Sep 17 00:00:00 2001 From: shay123g Date: Mon, 22 Mar 2021 10:04:17 +0200 Subject: [PATCH 07/12] Update src/config/validate.ts Co-authored-by: Snir Shechter --- src/config/validate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/validate.ts b/src/config/validate.ts index c424e74..a3f7215 100644 --- a/src/config/validate.ts +++ b/src/config/validate.ts @@ -104,7 +104,7 @@ function validateUrlLifetime(urlLifetime: string): void { function validateUrlExpireFrom(urlExpire: string): void { logger.debug(`Start validateUrlExpireFrom with ${urlExpire}`) - if (!urlExpire || (urlExpire != 'create' && urlExpire != 'update')) { + if (!urlExpire || (urlExpire !== 'create' && urlExpire !== 'update')) { throw new InvalidConfigError(`URL_EXPIRE_FROM specified is invalid (received ${urlExpire})`) } } From 2278c4ab462830d80b1f2b66e8a664dbc4337895 Mon Sep 17 00:00:00 2001 From: shay123g Date: Mon, 22 Mar 2021 10:04:44 +0200 Subject: [PATCH 08/12] Update src/config/validate.ts Co-authored-by: Snir Shechter --- src/config/validate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/validate.ts b/src/config/validate.ts index a3f7215..e3fad51 100644 --- a/src/config/validate.ts +++ b/src/config/validate.ts @@ -105,7 +105,7 @@ function validateUrlLifetime(urlLifetime: string): void { function validateUrlExpireFrom(urlExpire: string): void { logger.debug(`Start validateUrlExpireFrom with ${urlExpire}`) if (!urlExpire || (urlExpire !== 'create' && urlExpire !== 'update')) { - throw new InvalidConfigError(`URL_EXPIRE_FROM specified is invalid (received ${urlExpire})`) + throw new InvalidConfigError(`URL_EXPIRE_FROM specified is invalid (received ${urlExpire}, expected 'create' or 'update')`) } } From ff7533a01c43bd755fc36bd582a36fb101564d03 Mon Sep 17 00:00:00 2001 From: "Shay.Gazit" Date: Tue, 23 Mar 2021 21:17:40 +0200 Subject: [PATCH 09/12] . --- src/config/normalize.ts | 8 ++--- src/config/types.ts | 2 +- src/index.ts | 6 +--- .../storage/drivers/inMemory/index.ts | 29 +++++++++---------- .../storage/drivers/inMemory/types.ts | 5 ++-- .../storage/drivers/relational/index.ts | 23 ++++++++++++--- .../storage/drivers/relational/types.ts | 4 ++- src/services/storage/index.ts | 4 +++ 8 files changed, 48 insertions(+), 33 deletions(-) diff --git a/src/config/normalize.ts b/src/config/normalize.ts index 1fa1b94..fb5c8b1 100644 --- a/src/config/normalize.ts +++ b/src/config/normalize.ts @@ -26,8 +26,7 @@ export function normalizeConfig({ const minimumCleanupTime = Math.max(idealCleanupInterval, MIN_URL_CLEANUP_INTERVAL_MS) // No more than the maximum const cleanupIntervalMs = Math.min(minimumCleanupTime, MAX_URL_CLEANUP_INTERVAL_MS) - - return { + return { port, logLevel, apiPrefix, @@ -35,13 +34,14 @@ export function normalizeConfig({ baseRedirectUrl, url: { lifetimeMs: ms(url.lifetime), - urlExpireFrom : url.urlExpireFrom, + urlExpireFrom: url.urlExpireFrom, matchPattern: url.matchPattern, cleanupIntervalMs, }, storage: { + appName: appName, driverName: storage.driverName as StorageDriverName, - driverConfig: storage.driverName === StorageDriverName.Relational ? storage.relationalDriverConfig : {}, + driverConfig: storage.driverName === StorageDriverName.InMemory ? url.urlExpireFrom : StorageDriverName.Relational ? storage.relationalDriverConfig : {}, }, auth: { driverName: auth.driverName as AuthDriverName, diff --git a/src/config/types.ts b/src/config/types.ts index c276c62..481e4ec 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -44,6 +44,6 @@ export interface Config { cleanupIntervalMs: number } baseRedirectUrl: string - storage: Omit + storage: StorageConfig, auth: AuthConfig } diff --git a/src/index.ts b/src/index.ts index 921d3ad..163b313 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,11 +32,7 @@ const auth = new Auth(config.auth) fastify.decorate('auth', auth) // Storage -const storage = new Storage({ - appName: config.appName, - driverName: config.storage.driverName, - driverConfig: config.storage.driverConfig, -}) +const storage = new Storage(config.storage) await storage.initialize() fastify.decorate('storage', storage) diff --git a/src/services/storage/drivers/inMemory/index.ts b/src/services/storage/drivers/inMemory/index.ts index 90e6fc2..6272b39 100644 --- a/src/services/storage/drivers/inMemory/index.ts +++ b/src/services/storage/drivers/inMemory/index.ts @@ -3,17 +3,15 @@ import { NotFoundError } from '../../../../errors/notFound.js' import { InvalidConfigError } from '../../../../errors/invalidConfig.js' import { InMemoryStorageConfig } from '../../types/config.js' import type { StorageDriver } from '../../types/index.js' -import type {StoredUrl, UrlWithInformation, UrlRequestData, UrlInformation} from '../../types/url.js' -import {logger} from "../../../logger/logger"; -import {getRawConfig} from "../../../../config/__test__/helpers"; - -function validateUrlExpireFrom(deleteFrom: string) { - if (deleteFrom !== 'create' && deleteFrom !== 'update') { - throw new InvalidConfigError("URL_EXPIRE_FROM value must be 'create' or 'update'") - } -} +import type { StoredUrl, UrlWithInformation, UrlRequestData, UrlInformation } from '../../types/url.js' +import { logger } from '../../../logger/logger' export class InMemoryStorage implements StorageDriver { + private urlExpireFrom + + constructor(private config: InMemoryStorageConfig) { + this.urlExpireFrom = config.driverConfig.urlExpireFrom + } data: { urls: Map; urlInformation: Map } = { urls: new Map(), urlInformation: new Map(), @@ -48,14 +46,14 @@ export class InMemoryStorage implements StorageDriver { this.storage.data.urls.delete(id) } public async deleteOverdue(timespanMs: number): Promise { - const deleteFrom = getRawConfig().url.urlExpireFrom - logger.debug('urlExpireFrom is {}', deleteFrom) - validateUrlExpireFrom(deleteFrom) + logger.debug('urlExpireFrom is {}', this.storage.urlExpireFrom) const deleteBefore = new Date().getTime() - timespanMs let deletedCount = 0 this.storage.data.urls.forEach((storedUrl) => { - const relativeDate = new Date(deleteFrom === 'update' ? storedUrl.updatedAt : storedUrl.createdAt).getTime() + const relativeDate = new Date( + this.storage.urlExpireFrom === 'update' ? storedUrl.updatedAt : storedUrl.createdAt, + ).getTime() if (relativeDate <= deleteBefore) { this.storage.data.urls.delete(storedUrl.id) deletedCount++ @@ -115,8 +113,7 @@ export class InMemoryStorage implements StorageDriver { public async initialize(): Promise { return } - - // eslint-disable-next-line - constructor(public config: InMemoryStorageConfig) { + shutdown(): Promise { + throw new Error('Method not implemented.') } } diff --git a/src/services/storage/drivers/inMemory/types.ts b/src/services/storage/drivers/inMemory/types.ts index 82aa4cd..522e4e3 100644 --- a/src/services/storage/drivers/inMemory/types.ts +++ b/src/services/storage/drivers/inMemory/types.ts @@ -1,2 +1,3 @@ -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface InMemoryStorageDriverConfig {} +export interface InMemoryStorageDriverConfig { +urlExpireFrom : string +} diff --git a/src/services/storage/drivers/relational/index.ts b/src/services/storage/drivers/relational/index.ts index d15fe37..547616a 100644 --- a/src/services/storage/drivers/relational/index.ts +++ b/src/services/storage/drivers/relational/index.ts @@ -9,6 +9,7 @@ import camelcaseKeys from 'camelcase-keys' import { snakeCase } from 'snake-case' import type { StoredUrl, UrlWithInformation, UrlRequestData, UrlInformation } from '../../types/url.js' import { RelationalStorageConfig } from '../../types/config.js' +import { logger } from '../../../logger/logger' const __dirname = dirname(fileURLToPath(import.meta.url)) @@ -39,6 +40,10 @@ export class RelationalStorage implements StorageDriver { process.env.MIGRATIONS_RANDOM_SEED_1 = cryptoRandomString({ length: 6, type: 'numeric' }) process.env.MIGRATIONS_RANDOM_SEED_2 = cryptoRandomString({ length: 4, type: 'numeric' }) } + + shutdown(): Promise { + throw new Error('Method not implemented.') + } public async initialize(): Promise { await this.upMigrations() } @@ -94,10 +99,20 @@ export class RelationalStorage implements StorageDriver { } public async deleteOverdue(timespanMs: number): Promise { - // const deleteBefore = new Date(new Date().getTime() - timespanMs) - // return await this.storage.db.table('urls').where('updatedAt', '<', deleteBefore).delete() - // TODO temporary fix - return 0 + logger.debug('urlExpireFrom is {}', this.storage.config.driverConfig.urlExpireFrom) + const deleteBefore = new Date().getTime() - timespanMs + let deletedCount = 0 + const urls: StoredUrl[] = await this.storage.db.table('urls') + urls.forEach((value) => { + const relativeDate = new Date( + this.storage.config.driverConfig.urlExpireFrom === 'update' ? value.updatedAt : value.createdAt, + ).getTime() + if (relativeDate <= deleteBefore) { + this.delete(value.id) + deletedCount++ + } + }) + return deletedCount } public async edit(id: string, url: string): Promise { diff --git a/src/services/storage/drivers/relational/types.ts b/src/services/storage/drivers/relational/types.ts index cc0622d..a613a8d 100644 --- a/src/services/storage/drivers/relational/types.ts +++ b/src/services/storage/drivers/relational/types.ts @@ -1,4 +1,6 @@ import type Knex from 'knex' // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface RelationalStorageDriverConfig extends Knex.Config {} +export interface RelationalStorageDriverConfig extends Knex.Config { + urlExpireFrom : string +} diff --git a/src/services/storage/index.ts b/src/services/storage/index.ts index 137e1cb..ffbbcf2 100644 --- a/src/services/storage/index.ts +++ b/src/services/storage/index.ts @@ -23,6 +23,10 @@ export class Storage implements StorageDriver { throw new InvalidConfigError(`Invalid url storage driver selected.`) } } + + shutdown(): Promise { + throw new Error('Method not implemented.') + } get config(): StorageConfig { return this._config } From 2cf11769f3925a18c8d2d85a97319721016f0ed7 Mon Sep 17 00:00:00 2001 From: "Shay.Gazit" Date: Tue, 23 Mar 2021 21:19:12 +0200 Subject: [PATCH 10/12] fix imports --- src/services/storage/drivers/inMemory/index.ts | 3 +-- src/services/storage/drivers/relational/index.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/services/storage/drivers/inMemory/index.ts b/src/services/storage/drivers/inMemory/index.ts index 6272b39..698669c 100644 --- a/src/services/storage/drivers/inMemory/index.ts +++ b/src/services/storage/drivers/inMemory/index.ts @@ -1,10 +1,9 @@ import cryptoRandomString from 'crypto-random-string' import { NotFoundError } from '../../../../errors/notFound.js' -import { InvalidConfigError } from '../../../../errors/invalidConfig.js' import { InMemoryStorageConfig } from '../../types/config.js' import type { StorageDriver } from '../../types/index.js' import type { StoredUrl, UrlWithInformation, UrlRequestData, UrlInformation } from '../../types/url.js' -import { logger } from '../../../logger/logger' +import { logger } from '../../../logger/logger.js' export class InMemoryStorage implements StorageDriver { private urlExpireFrom diff --git a/src/services/storage/drivers/relational/index.ts b/src/services/storage/drivers/relational/index.ts index 547616a..0bcf8ba 100644 --- a/src/services/storage/drivers/relational/index.ts +++ b/src/services/storage/drivers/relational/index.ts @@ -9,7 +9,7 @@ import camelcaseKeys from 'camelcase-keys' import { snakeCase } from 'snake-case' import type { StoredUrl, UrlWithInformation, UrlRequestData, UrlInformation } from '../../types/url.js' import { RelationalStorageConfig } from '../../types/config.js' -import { logger } from '../../../logger/logger' +import { logger } from '../../../logger/logger.js' const __dirname = dirname(fileURLToPath(import.meta.url)) From 7c5386605572d68e16e6827bffd74a80d4f3bfd9 Mon Sep 17 00:00:00 2001 From: "Shay.Gazit" Date: Sun, 28 Mar 2021 20:44:58 +0300 Subject: [PATCH 11/12] fix tests --- src/config/__test__/normalize.test.ts | 4 +++- src/config/normalize.ts | 11 ++++++++--- src/config/types.ts | 2 +- src/services/storage/drivers/inMemory/index.ts | 4 ++-- src/services/storage/drivers/inMemory/types.ts | 5 ++--- src/services/storage/drivers/relational/index.ts | 8 +++++--- src/services/storage/drivers/relational/types.ts | 5 +---- src/services/storage/index.ts | 3 --- src/services/storage/types/config.ts | 1 + 9 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/config/__test__/normalize.test.ts b/src/config/__test__/normalize.test.ts index 6eeaabd..1991386 100644 --- a/src/config/__test__/normalize.test.ts +++ b/src/config/__test__/normalize.test.ts @@ -23,10 +23,12 @@ test('Happy flow', () => { lifetimeMs: ms(url.lifetime), matchPattern: url.matchPattern, cleanupIntervalMs: config.url.cleanupIntervalMs, // We're not yet testing this + urlExpireFrom: config.url.urlExpireFrom }, storage: { + appName:appName, driverName: storage.driverName as StorageDriverName, - driverConfig: storage.driverName === StorageDriverName.Relational ? storage.relationalDriverConfig : {}, + driverConfig: storage.driverName === StorageDriverName.InMemory ? url.urlExpireFrom : StorageDriverName.Relational ? storage.relationalDriverConfig : {}, }, auth: { driverName: auth.driverName, diff --git a/src/config/normalize.ts b/src/config/normalize.ts index fb5c8b1..a38eff3 100644 --- a/src/config/normalize.ts +++ b/src/config/normalize.ts @@ -26,7 +26,7 @@ export function normalizeConfig({ const minimumCleanupTime = Math.max(idealCleanupInterval, MIN_URL_CLEANUP_INTERVAL_MS) // No more than the maximum const cleanupIntervalMs = Math.min(minimumCleanupTime, MAX_URL_CLEANUP_INTERVAL_MS) - return { + return { port, logLevel, apiPrefix, @@ -39,13 +39,18 @@ export function normalizeConfig({ cleanupIntervalMs, }, storage: { - appName: appName, driverName: storage.driverName as StorageDriverName, - driverConfig: storage.driverName === StorageDriverName.InMemory ? url.urlExpireFrom : StorageDriverName.Relational ? storage.relationalDriverConfig : {}, + driverConfig: storage.driverName === StorageDriverName.Relational ? storage.relationalDriverConfig : {}, + urlExpireFrom: url.urlExpireFrom, + cleanupIntervalMs: cleanupIntervalMs, + lifetimeMs:ms(url.lifetime), + appName: appName }, + auth: { driverName: auth.driverName as AuthDriverName, driverConfig: auth.bearerTokenDriverConfig, }, } } + diff --git a/src/config/types.ts b/src/config/types.ts index 481e4ec..9928d2d 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -44,6 +44,6 @@ export interface Config { cleanupIntervalMs: number } baseRedirectUrl: string - storage: StorageConfig, + storage: StorageConfig auth: AuthConfig } diff --git a/src/services/storage/drivers/inMemory/index.ts b/src/services/storage/drivers/inMemory/index.ts index b2e48b7..0351de0 100644 --- a/src/services/storage/drivers/inMemory/index.ts +++ b/src/services/storage/drivers/inMemory/index.ts @@ -9,7 +9,7 @@ export class InMemoryStorage implements StorageDriver { private urlExpireFrom constructor(private config: InMemoryStorageConfig) { - this.urlExpireFrom = config.driverConfig.urlExpireFrom + this.urlExpireFrom = config.urlExpireFrom } data: { urls: Map; urlInformation: Map } = { urls: new Map(), @@ -45,7 +45,7 @@ export class InMemoryStorage implements StorageDriver { this.storage.data.urls.delete(id) } public async deleteOverdue(timespanMs: number): Promise { - logger.debug('urlExpireFrom is {}', this.storage.urlExpireFrom) + logger.debug('urlExpireFrom is ' + "'" + this.storage.urlExpireFrom + "'") const deleteBefore = new Date().getTime() - timespanMs let deletedCount = 0 diff --git a/src/services/storage/drivers/inMemory/types.ts b/src/services/storage/drivers/inMemory/types.ts index 522e4e3..82aa4cd 100644 --- a/src/services/storage/drivers/inMemory/types.ts +++ b/src/services/storage/drivers/inMemory/types.ts @@ -1,3 +1,2 @@ -export interface InMemoryStorageDriverConfig { -urlExpireFrom : string -} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface InMemoryStorageDriverConfig {} diff --git a/src/services/storage/drivers/relational/index.ts b/src/services/storage/drivers/relational/index.ts index 10b988a..2e47c4b 100644 --- a/src/services/storage/drivers/relational/index.ts +++ b/src/services/storage/drivers/relational/index.ts @@ -8,15 +8,17 @@ import { fileURLToPath } from 'url' import camelcaseKeys from 'camelcase-keys' import { snakeCase } from 'snake-case' import type { StoredUrl, UrlWithInformation, UrlRequestData, UrlInformation } from '../../types/url.js' -import { RelationalStorageConfig } from '../../types/config.js' +import {InMemoryStorageConfig, RelationalStorageConfig} from '../../types/config.js' import { logger } from '../../../logger/logger.js' const __dirname = dirname(fileURLToPath(import.meta.url)) export class RelationalStorage implements StorageDriver { private db: Knex + private urlExpireFrom constructor(private config: RelationalStorageConfig) { + this.urlExpireFrom = config.urlExpireFrom this.db = Knex({ ...config.driverConfig, migrations: { @@ -98,13 +100,13 @@ export class RelationalStorage implements StorageDriver { } public async deleteOverdue(timespanMs: number): Promise { - logger.debug('urlExpireFrom is {}', this.storage.config.driverConfig.urlExpireFrom) + logger.debug('urlExpireFrom is ' + "'" + this.storage.urlExpireFrom + "'") const deleteBefore = new Date().getTime() - timespanMs let deletedCount = 0 const urls: StoredUrl[] = await this.storage.db.table('urls') urls.forEach((value) => { const relativeDate = new Date( - this.storage.config.driverConfig.urlExpireFrom === 'update' ? value.updatedAt : value.createdAt, + this.storage.urlExpireFrom === 'update' ? value.updatedAt : value.createdAt, ).getTime() if (relativeDate <= deleteBefore) { this.delete(value.id) diff --git a/src/services/storage/drivers/relational/types.ts b/src/services/storage/drivers/relational/types.ts index a613a8d..8421441 100644 --- a/src/services/storage/drivers/relational/types.ts +++ b/src/services/storage/drivers/relational/types.ts @@ -1,6 +1,3 @@ import type Knex from 'knex' -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface RelationalStorageDriverConfig extends Knex.Config { - urlExpireFrom : string -} +export type RelationalStorageDriverConfig = Knex.Config diff --git a/src/services/storage/index.ts b/src/services/storage/index.ts index 398cf05..1ba30bd 100644 --- a/src/services/storage/index.ts +++ b/src/services/storage/index.ts @@ -24,9 +24,6 @@ export class Storage implements StorageDriver { } } - shutdown(): Promise { - throw new Error('Method not implemented.') - } get config(): StorageConfig { return this._config } diff --git a/src/services/storage/types/config.ts b/src/services/storage/types/config.ts index 2efc90e..803f091 100644 --- a/src/services/storage/types/config.ts +++ b/src/services/storage/types/config.ts @@ -10,6 +10,7 @@ export interface BaseConfig { appName: string lifetimeMs: number cleanupIntervalMs: number + urlExpireFrom: string } export interface RelationalStorageConfig extends BaseConfig { From 75c9a8f18dfd258beeb12bb5a1abb5161b108141 Mon Sep 17 00:00:00 2001 From: "Shay.Gazit" Date: Sun, 28 Mar 2021 20:51:34 +0300 Subject: [PATCH 12/12] fix tests --- src/config/__test__/normalize.test.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/config/__test__/normalize.test.ts b/src/config/__test__/normalize.test.ts index 1991386..b647ef3 100644 --- a/src/config/__test__/normalize.test.ts +++ b/src/config/__test__/normalize.test.ts @@ -26,9 +26,12 @@ test('Happy flow', () => { urlExpireFrom: config.url.urlExpireFrom }, storage: { - appName:appName, + appName: appName, driverName: storage.driverName as StorageDriverName, - driverConfig: storage.driverName === StorageDriverName.InMemory ? url.urlExpireFrom : StorageDriverName.Relational ? storage.relationalDriverConfig : {}, + cleanupIntervalMs: config.url.cleanupIntervalMs, + driverConfig: storage.driverName === StorageDriverName.Relational ? storage.relationalDriverConfig : {}, + urlExpireFrom: url.urlExpireFrom, + lifetimeMs: ms(url.lifetime), }, auth: { driverName: auth.driverName,