1
0
mirror of https://github.com/seejohnrun/haste-server.git synced 2026-02-10 16:01:32 +00:00

Add tests and fix docker files

This commit is contained in:
Yusuf Yilmaz
2022-05-27 15:04:54 +02:00
parent 9f45927593
commit f527b13535
30 changed files with 2126 additions and 4468 deletions
+1 -1
View File
@@ -125,7 +125,7 @@ class App {
winston.info('loading static document', { name, path: documentPath })
if (data) {
this.documentHandler?.store.set(
this.documentHandler?.store?.set(
name,
data,
cb => {
+5
View File
@@ -0,0 +1,5 @@
const DEFAULT_KEY_LENGTH = 10
export default {
DEFAULT_KEY_LENGTH,
}
-13
View File
@@ -23,24 +23,11 @@ declare module 'rethinkdbdash' {
table(s: string): RethinkFunctions
}
// function rethink<T>(obj: T[]): RethinkArray<T>
function rethink<T>(obj: T): RethinkClient<T>
export = rethink
}
// export {}
// declare module 'connect-ratelimit' {
// export = connectRateLimit
// }
// declare namespace Express {
// export interface Request {
// sturl?: string
// }
// }
declare module 'connect-ratelimit' {
function connectRateLimit(
as: RateLimits,
+11 -12
View File
@@ -5,22 +5,21 @@ import type { Config } from '../../types/config'
import type { Store } from '../../types/store'
import type { KeyGenerator } from '../../types/key-generator'
import type { Document } from '../../types/document'
const defaultKeyLength = 10
import constants from '../../constants'
class DocumentHandler {
keyLength: number
maxLength: number
maxLength?: number
public store: Store
public store?: Store
keyGenerator: KeyGenerator
config: Config
config?: Config
constructor(options: Document) {
this.keyLength = options.keyLength || defaultKeyLength
this.keyLength = options.keyLength || constants.DEFAULT_KEY_LENGTH
this.maxLength = options.maxLength // none by default
this.store = options.store
this.config = options.config
@@ -29,9 +28,9 @@ class DocumentHandler {
public handleGet(request: Request, response: Response) {
const key = request.params.id.split('.')[0]
const skipExpire = !!this.config.documents[key]
const skipExpire = !!this.config?.documents[key]
this.store.get(
this.store?.get(
key,
ret => {
if (ret) {
@@ -75,7 +74,7 @@ class DocumentHandler {
}
// And then save if we should
this.chooseKey(key => {
this.store.set(key, buffer, res => {
this.store?.set(key, buffer, res => {
if (res) {
winston.verbose('added document', { key })
response.writeHead(200, { 'content-type': 'application/json' })
@@ -124,9 +123,9 @@ class DocumentHandler {
public handleRawGet(request: Request, response: Response) {
const key = request.params.id.split('.')[0]
const skipExpire = !!this.config.documents[key]
const skipExpire = !!this.config?.documents[key]
this.store.get(
this.store?.get(
key,
ret => {
if (ret) {
@@ -158,7 +157,7 @@ class DocumentHandler {
if (!key) return
this.store.get(
this.store?.get(
key,
(ret: string | boolean) => {
if (ret) {
+4 -14
View File
@@ -2,21 +2,11 @@ import type { Config } from '../../types/config'
import type { Store } from '../../types/store'
const build = async (config: Config): Promise<Store> => {
const DocumentStore = (
await import(`../document-stores/${config.storage.type}`)
).default
if (process.env.REDISTOGO_URL && config.storage.type === 'redis') {
// const redisClient = require("redis-url").connect(process.env.REDISTOGO_URL);
// Store = require("./lib/document-stores/redis");
// preferredStore = new Store(config.storage, redisClient);
const DocumentStore = (await import(`../document-stores/${config.storage.type}`)).default
return new DocumentStore(config.storage)
}
const DocumentStore = (await import(`../document-stores/${config.storage.type}`)).default
return new DocumentStore(config.storage)
return new DocumentStore(config.storage)
}
export default build
+98
View File
@@ -0,0 +1,98 @@
import * as winston from 'winston'
import { createClient } from 'redis'
import { bool } from 'aws-sdk/clients/redshiftdata'
import { Callback, Store } from '../../types/store'
import { RedisStoreConfig } from '../../types/config'
export type RedisClientType = ReturnType<typeof createClient>
// For storing in redis
// options[type] = redis
// options[url] - the url to connect to redis
// options[host] - The host to connect to (default localhost)
// options[port] - The port to connect to (default 5379)
// options[db] - The db to use (default 0)
// options[expire] - The time to live for each key set (default never)
class RedisDocumentStore implements Store {
type: string
expire?: number | undefined
client?: RedisClientType
constructor(options: RedisStoreConfig) {
this.expire = options.expire
this.type = options.type
this.connect(options)
}
connect = (options: RedisStoreConfig) => {
winston.info('configuring redis')
const url = process.env.REDISTOGO_URL || options.url
const host = options.host || '127.0.0.1'
const port = options.port || 6379
const index = options.db || 0
if (url) {
this.client = createClient({ url })
this.client.connect()
} else {
this.client = createClient({
url: `http://${host}:${port}`,
database: index as number,
username: options.username,
password: options.password,
})
}
this.client.on('error', err => {
winston.error('redis disconnected', err)
})
this.client
.select(index as number)
.then(() => {
winston.info(
`connected to redis on ${url || `${host}:${port}`}/${index}`,
)
})
.catch(err => {
winston.error(`error connecting to redis index ${index}`, {
error: err,
})
process.exit(1)
})
}
getExpire = (skipExpire?: bool) => (!skipExpire ? { EX: this.expire } : {})
get = (key: string, callback: Callback): void => {
this.client
?.get(key)
.then(reply => {
callback(reply || false)
})
.catch(() => {
callback(false)
})
}
set = (
key: string,
data: string,
callback: Callback,
skipExpire?: boolean | undefined,
): void => {
this.client?.set(key, data, this.getExpire(skipExpire))
.then(() => {
callback(true)
})
.catch(() => {
callback(false)
})
}
}
export default RedisDocumentStore
+7 -2
View File
@@ -1,9 +1,14 @@
import * as fs from 'fs'
import * as path from 'path'
import { Config } from '../../types/config'
const getConfig = (): Config => {
const configPath = process.argv.length <= 2 ? 'config.json' : process.argv[2]
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'))
const configPath =
process.argv.length <= 2 ? 'project-config.js' : process.argv[2]
const config = JSON.parse(
fs.readFileSync(path.join('config', configPath), 'utf8'),
)
config.port = (process.env.PORT || config.port || 7777) as number
config.host = process.env.HOST || config.host || 'localhost'
+2 -2
View File
@@ -7,7 +7,7 @@ class DictionaryGenerator implements KeyGenerator {
dictionary: string[]
constructor(options: KeyGeneratorConfig, readyCallback: () => void) {
constructor(options: KeyGeneratorConfig, readyCallback?: () => void) {
// Check options format
if (!options) throw Error('No options passed to generator')
if (!options.path) throw Error('No dictionary path specified in options')
@@ -21,7 +21,7 @@ class DictionaryGenerator implements KeyGenerator {
this.dictionary = data.split(/[\n\r]+/)
if (readyCallback) readyCallback()
readyCallback?.()
})
}
+13
View File
@@ -50,6 +50,16 @@ export interface RethinkDbStoreConfig extends BaseStoreConfig {
password: string
}
export interface RedisStoreConfig extends BaseStoreConfig {
url?: string
host?: string
port?: string
db?: string
user?: string
username?: string | undefined
password?: string
}
export type GoogleStoreConfig = BaseStoreConfig
export type StoreConfig =
@@ -59,6 +69,9 @@ export type StoreConfig =
| AmazonStoreConfig
| FileStoreConfig
| MongoStoreConfig
| RedisStoreConfig
| RethinkDbStoreConfig
| PostgresStoreConfig
export interface KeyGeneratorConfig {
type: string
+4 -4
View File
@@ -3,10 +3,10 @@ import type { KeyGenerator } from './key-generator'
import type { Store } from './store'
export type Document = {
store: Store
config: Config
maxLength: number
keyLength: number
store?: Store
config?: Config
maxLength?: number
keyLength?: number
keyGenerator: KeyGenerator
}
-5
View File
@@ -1,5 +0,0 @@
import DocumentHandler from '../lib/document-handler'
export type RequestParams = {
documentHandler: DocumentHandler
}