mirror of
https://github.com/toptal/haste-server.git
synced 2024-12-01 13:23:51 +01:00
fix code, readme and lint
This commit is contained in:
parent
42c60c64c2
commit
350abbdf3b
33
.eslintrc.js
33
.eslintrc.js
@ -1,6 +1,6 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
env: {
|
env: {
|
||||||
node: true,
|
node: true
|
||||||
},
|
},
|
||||||
extends: [
|
extends: [
|
||||||
'eslint:recommended',
|
'eslint:recommended',
|
||||||
@ -10,47 +10,44 @@ module.exports = {
|
|||||||
'plugin:import/errors',
|
'plugin:import/errors',
|
||||||
'plugin:import/warnings',
|
'plugin:import/warnings',
|
||||||
'plugin:import/typescript',
|
'plugin:import/typescript',
|
||||||
'prettier',
|
'prettier'
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
'import',
|
|
||||||
'@typescript-eslint'
|
|
||||||
],
|
],
|
||||||
|
plugins: ['import', '@typescript-eslint'],
|
||||||
settings: {
|
settings: {
|
||||||
'import/parsers': {
|
'import/parsers': {
|
||||||
'@typescript-eslint/parser': ['.ts'],
|
'@typescript-eslint/parser': ['.ts']
|
||||||
},
|
},
|
||||||
'import/resolver': {
|
'import/resolver': {
|
||||||
node: {
|
node: {
|
||||||
extensions: ['.js', '.ts'],
|
extensions: ['.js', '.ts'],
|
||||||
moduleDirectory: ['node_modules', 'src/'],
|
moduleDirectory: ['node_modules', 'src/']
|
||||||
},
|
},
|
||||||
typescript: {
|
typescript: {
|
||||||
alwaysTryTypes: true,
|
alwaysTryTypes: true,
|
||||||
project: '.',
|
project: '.'
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
env: {
|
env: {
|
||||||
jest: true,
|
jest: true
|
||||||
},
|
},
|
||||||
files: ['**/__tests__/**/*.[jt]s', '**/?(*.)+(spec|test).[jt]s'],
|
files: ['**/__tests__/**/*.[jt]s', '**/?(*.)+(spec|test).[jt]s'],
|
||||||
extends: ['plugin:jest/recommended'],
|
extends: ['plugin:jest/recommended'],
|
||||||
rules: {
|
rules: {
|
||||||
'import/no-extraneous-dependencies': [
|
'import/no-extraneous-dependencies': [
|
||||||
'off',
|
'off',
|
||||||
{ devDependencies: ['**/?(*.)+(spec|test).[jt]s'] },
|
{ devDependencies: ['**/?(*.)+(spec|test).[jt]s'] }
|
||||||
],
|
],
|
||||||
camelcase: ['off'],
|
camelcase: ['off']
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
ignorePatterns: ['**/*.js', 'node_modules', 'dist'],
|
ignorePatterns: ['**/*.js', 'node_modules', 'dist'],
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
root: true,
|
root: true,
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
project: ['./tsconfig.json'],
|
project: ['./tsconfig.json']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
14
.github/workflows/close-inactive.yaml
vendored
14
.github/workflows/close-inactive.yaml
vendored
@ -2,7 +2,7 @@ name: Close inactive issues and PRs
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "30 1 * * *"
|
- cron: '30 1 * * *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
close-stale:
|
close-stale:
|
||||||
@ -15,16 +15,16 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
days-before-stale: 30
|
days-before-stale: 30
|
||||||
days-before-close: 14
|
days-before-close: 14
|
||||||
stale-issue-label: "stale"
|
stale-issue-label: 'stale'
|
||||||
stale-pr-label: "stale"
|
stale-pr-label: 'stale'
|
||||||
|
|
||||||
exempt-issue-labels: backlog,triage,nostale
|
exempt-issue-labels: backlog,triage,nostale
|
||||||
exempt-pr-labels: backlog,triage,nostale
|
exempt-pr-labels: backlog,triage,nostale
|
||||||
|
|
||||||
stale-pr-message: "This PR is stale because it has been open for 30 days with no activity."
|
stale-pr-message: 'This PR is stale because it has been open for 30 days with no activity.'
|
||||||
close-pr-message: "This PR was closed because it has been inactive for 14 days since being marked as stale."
|
close-pr-message: 'This PR was closed because it has been inactive for 14 days since being marked as stale.'
|
||||||
|
|
||||||
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
|
stale-issue-message: 'This issue is stale because it has been open for 30 days with no activity.'
|
||||||
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
|
close-issue-message: 'This issue was closed because it has been inactive for 14 days since being marked as stale.'
|
||||||
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
2
.prettierignore
Normal file
2
.prettierignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
static
|
||||||
|
/node_modules
|
101
README.md
101
README.md
@ -1,15 +1,15 @@
|
|||||||
# Haste
|
# Haste
|
||||||
|
|
||||||
Haste is an open-source pastebin software written in node.js, which is easily
|
Haste is an open-source pastebin software written in node.js, which is easily
|
||||||
installable in any network. It can be backed by either redis or filesystem,
|
installable in any network. It can be backed by either redis or filesystem,
|
||||||
and has a very easy adapter interface for other stores. A publicly available
|
and has a very easy adapter interface for other stores. A publicly available
|
||||||
version can be found at [hastebin.com](http://hastebin.com)
|
version can be found at [hastebin.com](http://hastebin.com)
|
||||||
|
|
||||||
Major design objectives:
|
Major design objectives:
|
||||||
|
|
||||||
* Be really pretty
|
- Be really pretty
|
||||||
* Be really simple
|
- Be really simple
|
||||||
* Be easy to set up and use
|
- Be easy to set up and use
|
||||||
|
|
||||||
Haste works really well with a little utility called
|
Haste works really well with a little utility called
|
||||||
[haste-client](https://github.com/seejohnrun/haste-client), allowing you
|
[haste-client](https://github.com/seejohnrun/haste-client), allowing you
|
||||||
@ -18,58 +18,58 @@ to do things like:
|
|||||||
`cat something | haste`
|
`cat something | haste`
|
||||||
|
|
||||||
which will output a URL to share containing the contents of `cat something`'s
|
which will output a URL to share containing the contents of `cat something`'s
|
||||||
STDOUT. Check the README there for more details and usages.
|
STDOUT. Check the README there for more details and usages.
|
||||||
|
|
||||||
## Tested Browsers
|
## Tested Browsers
|
||||||
|
|
||||||
* Firefox 8
|
- Firefox 8
|
||||||
* Chrome 17
|
- Chrome 17
|
||||||
* Safari 5.3
|
- Safari 5.3
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
1. Download the package, and expand it
|
1. Download the package, and expand it
|
||||||
3. `yarn add`
|
2. `yarn`
|
||||||
|
|
||||||
## Running the project
|
## Running the project
|
||||||
|
|
||||||
> Explore the settings inside of config.js, but the defaults should be good
|
> Explore the settings inside of project-config.js, but the defaults should be good
|
||||||
|
|
||||||
### Development
|
### Development
|
||||||
|
|
||||||
1. `yarn add`
|
1. `yarn`
|
||||||
2. `yarn dev` (you may specify an optional `<config-path>` as well)
|
2. `yarn dev` (you may specify an optional `<config-path>` as well)
|
||||||
|
|
||||||
### Production
|
### Production
|
||||||
|
|
||||||
1. `yarn add`
|
1. `yarn`
|
||||||
2. `yarn build` to build the package
|
2. `yarn build` to build the package
|
||||||
3. `yarn start` to start the server
|
3. `yarn start` to start the server
|
||||||
|
|
||||||
### Production with Docker
|
### Production with Docker
|
||||||
|
|
||||||
1. `docker compose up`
|
1. `docker-compose up`
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
|
|
||||||
* `host` - the host the server runs on (default localhost)
|
- `host` - the host the server runs on (default localhost)
|
||||||
* `port` - the port the server runs on (default 7777)
|
- `port` - the port the server runs on (default 7777)
|
||||||
* `keyLength` - the length of the keys to user (default 10)
|
- `keyLength` - the length of the keys to user (default 10)
|
||||||
* `maxLength` - maximum length of a paste (default 400000)
|
- `maxLength` - maximum length of a paste (default 400000)
|
||||||
* `staticMaxAge` - max age for static assets (86400)
|
- `staticMaxAge` - max age for static assets (86400)
|
||||||
* `recompressStaticAssets` - whether or not to compile static js assets (true)
|
- `recompressStaticAssets` - whether or not to compile static js assets (true)
|
||||||
* `documents` - static documents to serve (ex: http://hastebin.com/about.com)
|
- `documents` - static documents to serve (ex: http://hastebin.com/about.com)
|
||||||
in addition to static assets. These will never expire.
|
in addition to static assets. These will never expire.
|
||||||
* `storage` - storage options (see below)
|
- `storage` - storage options (see below)
|
||||||
* `logging` - logging preferences
|
- `logging` - logging preferences
|
||||||
* `keyGenerator` - key generator options (see below)
|
- `keyGenerator` - key generator options (see below)
|
||||||
* `rateLimits` - settings for rate limiting (see below)
|
- `rateLimits` - settings for rate limiting (see below)
|
||||||
|
|
||||||
## Rate Limiting
|
## Rate Limiting
|
||||||
|
|
||||||
When present, the `rateLimits` option enables built-in rate limiting courtesy
|
When present, the `rateLimits` option enables built-in rate limiting courtesy
|
||||||
of `connect-ratelimit`. Any of the options supported by that library can be
|
of `connect-ratelimit`. Any of the options supported by that library can be
|
||||||
used and set in `config.js`.
|
used and set in `project-config.js`.
|
||||||
|
|
||||||
See the README for [connect-ratelimit](https://github.com/dharmafly/connect-ratelimit)
|
See the README for [connect-ratelimit](https://github.com/dharmafly/connect-ratelimit)
|
||||||
for more information!
|
for more information!
|
||||||
@ -80,7 +80,7 @@ for more information!
|
|||||||
|
|
||||||
Attempts to generate phonetic keys, similar to `pwgen`
|
Attempts to generate phonetic keys, similar to `pwgen`
|
||||||
|
|
||||||
``` json
|
```json
|
||||||
{
|
{
|
||||||
"type": "phonetic"
|
"type": "phonetic"
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ Attempts to generate phonetic keys, similar to `pwgen`
|
|||||||
|
|
||||||
Generates a random key
|
Generates a random key
|
||||||
|
|
||||||
``` json
|
```json
|
||||||
{
|
{
|
||||||
"type": "random",
|
"type": "random",
|
||||||
"keyspace": "abcdef"
|
"keyspace": "abcdef"
|
||||||
@ -104,10 +104,10 @@ for the key.
|
|||||||
|
|
||||||
### File
|
### File
|
||||||
|
|
||||||
To use file storage (the default) change the storage section in `config.js` to
|
To use file storage (the default) change the storage section in `project-config.js` to
|
||||||
something like:
|
something like:
|
||||||
|
|
||||||
``` json
|
```json
|
||||||
{
|
{
|
||||||
"path": "./data",
|
"path": "./data",
|
||||||
"type": "file"
|
"type": "file"
|
||||||
@ -127,7 +127,7 @@ To use redis storage you must install the `redis` package in npm, and have
|
|||||||
|
|
||||||
Once you've done that, your config section should look like:
|
Once you've done that, your config section should look like:
|
||||||
|
|
||||||
``` json
|
```json
|
||||||
{
|
{
|
||||||
"type": "redis",
|
"type": "redis",
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
@ -152,7 +152,7 @@ To use postgres storage you must install the `pg` package in npm
|
|||||||
|
|
||||||
Once you've done that, your config section should look like:
|
Once you've done that, your config section should look like:
|
||||||
|
|
||||||
``` json
|
```json
|
||||||
{
|
{
|
||||||
"type": "postgres",
|
"type": "postgres",
|
||||||
"connectionUrl": "postgres://user:password@host:5432/database"
|
"connectionUrl": "postgres://user:password@host:5432/database"
|
||||||
@ -179,7 +179,7 @@ To use mongodb storage you must install the 'mongodb' package in npm
|
|||||||
|
|
||||||
Once you've done that, your config section should look like:
|
Once you've done that, your config section should look like:
|
||||||
|
|
||||||
``` json
|
```json
|
||||||
{
|
{
|
||||||
"type": "mongo",
|
"type": "mongo",
|
||||||
"connectionUrl": "mongodb://localhost:27017/database"
|
"connectionUrl": "mongodb://localhost:27017/database"
|
||||||
@ -201,7 +201,7 @@ To use memcache storage you must install the `memcached` package via npm
|
|||||||
|
|
||||||
Once you've done that, your config section should look like:
|
Once you've done that, your config section should look like:
|
||||||
|
|
||||||
``` json
|
```json
|
||||||
{
|
{
|
||||||
"type": "memcached",
|
"type": "memcached",
|
||||||
"host": "127.0.0.1",
|
"host": "127.0.0.1",
|
||||||
@ -223,7 +223,7 @@ To use the RethinkDB storage system, you must install the `rethinkdbdash` packag
|
|||||||
|
|
||||||
Once you've done that, your config section should look like this:
|
Once you've done that, your config section should look like this:
|
||||||
|
|
||||||
``` json
|
```json
|
||||||
{
|
{
|
||||||
"type": "rethinkdb",
|
"type": "rethinkdb",
|
||||||
"host": "127.0.0.1",
|
"host": "127.0.0.1",
|
||||||
@ -245,7 +245,7 @@ To use the Google Datastore storage system, you must install the `@google-cloud/
|
|||||||
|
|
||||||
Once you've done that, your config section should look like this:
|
Once you've done that, your config section should look like this:
|
||||||
|
|
||||||
``` json
|
```json
|
||||||
{
|
{
|
||||||
"type": "google-datastore"
|
"type": "google-datastore"
|
||||||
}
|
}
|
||||||
@ -277,17 +277,14 @@ your bucket:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"Version": "2012-10-17",
|
"Version": "2012-10-17",
|
||||||
"Statement": [
|
"Statement": [
|
||||||
{
|
{
|
||||||
"Action": [
|
"Action": ["s3:GetObject", "s3:PutObject"],
|
||||||
"s3:GetObject",
|
"Effect": "Allow",
|
||||||
"s3:PutObject"
|
"Resource": "arn:aws:s3:::your-bucket-name-goes-here/*"
|
||||||
],
|
}
|
||||||
"Effect": "Allow",
|
]
|
||||||
"Resource": "arn:aws:s3:::your-bucket-name-goes-here/*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -401,6 +398,6 @@ SOFTWARE
|
|||||||
|
|
||||||
### Other components:
|
### Other components:
|
||||||
|
|
||||||
* jQuery: MIT/GPL license
|
- jQuery: MIT/GPL license
|
||||||
* highlight.js: Copyright © 2006, Ivan Sagalaev
|
- highlight.js: Copyright © 2006, Ivan Sagalaev
|
||||||
* highlightjs-coffeescript: WTFPL - Copyright © 2011, Dmytrii Nagirniak
|
- highlightjs-coffeescript: WTFPL - Copyright © 2011, Dmytrii Nagirniak
|
||||||
|
23
about.md
23
about.md
@ -8,7 +8,7 @@ Haste is the prettiest, easiest to use pastebin ever made.
|
|||||||
|
|
||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
Type what you want me to see, click "Save", and then copy the URL. Send that
|
Type what you want me to see, click "Save", and then copy the URL. Send that
|
||||||
URL to someone and they'll see what you see.
|
URL to someone and they'll see what you see.
|
||||||
|
|
||||||
To make a new entry, click "New" (or type 'control + n')
|
To make a new entry, click "New" (or type 'control + n')
|
||||||
@ -16,7 +16,7 @@ To make a new entry, click "New" (or type 'control + n')
|
|||||||
## From the Console
|
## From the Console
|
||||||
|
|
||||||
Most of the time I want to show you some text, it's coming from my current
|
Most of the time I want to show you some text, it's coming from my current
|
||||||
console session. We should make it really easy to take code from the console
|
console session. We should make it really easy to take code from the console
|
||||||
and send it to people.
|
and send it to people.
|
||||||
|
|
||||||
`cat something | haste` # https://hastebin.com/1238193
|
`cat something | haste` # https://hastebin.com/1238193
|
||||||
@ -24,27 +24,28 @@ and send it to people.
|
|||||||
You can even take this a step further, and cut out the last step of copying the
|
You can even take this a step further, and cut out the last step of copying the
|
||||||
URL with:
|
URL with:
|
||||||
|
|
||||||
* osx: `cat something | haste | pbcopy`
|
- osx: `cat something | haste | pbcopy`
|
||||||
* linux: `cat something | haste | xsel`
|
- linux: `cat something | haste | xsel`
|
||||||
* windows: check out [WinHaste](https://github.com/ajryan/WinHaste)
|
- windows: check out [WinHaste](https://github.com/ajryan/WinHaste)
|
||||||
|
|
||||||
After running that, the STDOUT output of `cat something` will show up at a URL
|
After running that, the STDOUT output of `cat something` will show up at a URL
|
||||||
which has been conveniently copied to your clipboard.
|
which has been conveniently copied to your clipboard.
|
||||||
|
|
||||||
That's all there is to that, and you can install it with `gem install haste`
|
That's all there is to that, and you can install it with `gem install haste`
|
||||||
right now.
|
right now.
|
||||||
* osx: you will need to have an up to date version of Xcode
|
|
||||||
* linux: you will need to have rubygems and ruby-devel installed
|
- osx: you will need to have an up to date version of Xcode
|
||||||
|
- linux: you will need to have rubygems and ruby-devel installed
|
||||||
|
|
||||||
## Duration
|
## Duration
|
||||||
|
|
||||||
Pastes will stay for 30 days from their last view. They may be removed earlier
|
Pastes will stay for 30 days from their last view. They may be removed earlier
|
||||||
and without notice.
|
and without notice.
|
||||||
|
|
||||||
## Privacy
|
## Privacy
|
||||||
|
|
||||||
While the contents of hastebin.com are not directly crawled by any search robot
|
While the contents of hastebin.com are not directly crawled by any search robot
|
||||||
that obeys "robots.txt", there should be no great expectation of privacy. Post
|
that obeys "robots.txt", there should be no great expectation of privacy. Post
|
||||||
things at your own risk. Not responsible for any loss of data or removed
|
things at your own risk. Not responsible for any loss of data or removed
|
||||||
pastes.
|
pastes.
|
||||||
|
|
||||||
@ -52,8 +53,8 @@ pastes.
|
|||||||
|
|
||||||
Haste can easily be installed behind your network, and it's all open source!
|
Haste can easily be installed behind your network, and it's all open source!
|
||||||
|
|
||||||
* [haste-client](https://github.com/seejohnrun/haste-client)
|
- [haste-client](https://github.com/seejohnrun/haste-client)
|
||||||
* [haste-server](https://github.com/seejohnrun/haste-server)
|
- [haste-server](https://github.com/seejohnrun/haste-server)
|
||||||
|
|
||||||
## Author
|
## Author
|
||||||
|
|
||||||
|
@ -5,10 +5,8 @@ module.exports = {
|
|||||||
rootDir: '../',
|
rootDir: '../',
|
||||||
testRegex: '\\.test\\.ts$',
|
testRegex: '\\.test\\.ts$',
|
||||||
reporters: ['default'],
|
reporters: ['default'],
|
||||||
roots: [
|
roots: ['test'],
|
||||||
"test"
|
|
||||||
],
|
|
||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
"src/(.*)": "<rootDir>/src/$1"
|
'src/(.*)': '<rootDir>/src/$1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ const {
|
|||||||
RATE_LIMITS_BLACKLIST_TOTAL_REQUESTS,
|
RATE_LIMITS_BLACKLIST_TOTAL_REQUESTS,
|
||||||
RATE_LIMITS_BLACKLIST_EVERY_MILLISECONDS,
|
RATE_LIMITS_BLACKLIST_EVERY_MILLISECONDS,
|
||||||
RATE_LIMITS_BLACKLIST,
|
RATE_LIMITS_BLACKLIST,
|
||||||
DOCUMENTS,
|
DOCUMENTS
|
||||||
} = process.env;
|
} = process.env
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
host: HOST,
|
host: HOST,
|
||||||
@ -47,29 +47,29 @@ const config = {
|
|||||||
{
|
{
|
||||||
level: LOGGING_LEVEL,
|
level: LOGGING_LEVEL,
|
||||||
type: LOGGING_TYPE,
|
type: LOGGING_TYPE,
|
||||||
colorize: LOGGING_COLORIZE,
|
colorize: LOGGING_COLORIZE
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
keyGenerator: {
|
keyGenerator: {
|
||||||
type: KEYGENERATOR_TYPE,
|
type: KEYGENERATOR_TYPE,
|
||||||
keyspace: KEY_GENERATOR_KEYSPACE,
|
keyspace: KEY_GENERATOR_KEYSPACE
|
||||||
},
|
},
|
||||||
|
|
||||||
rateLimits: {
|
rateLimits: {
|
||||||
whitelist: RATE_LIMITS_WHITELIST ? RATE_LIMITS_WHITELIST.split(",") : [],
|
whitelist: RATE_LIMITS_WHITELIST ? RATE_LIMITS_WHITELIST.split(',') : [],
|
||||||
blacklist: RATE_LIMITS_BLACKLIST ? RATE_LIMITS_BLACKLIST.split(",") : [],
|
blacklist: RATE_LIMITS_BLACKLIST ? RATE_LIMITS_BLACKLIST.split(',') : [],
|
||||||
categories: {
|
categories: {
|
||||||
normal: {
|
normal: {
|
||||||
totalRequests: RATE_LIMITS_NORMAL_TOTAL_REQUESTS,
|
totalRequests: RATE_LIMITS_NORMAL_TOTAL_REQUESTS,
|
||||||
every: RATE_LIMITS_NORMAL_EVERY_MILLISECONDS,
|
every: RATE_LIMITS_NORMAL_EVERY_MILLISECONDS
|
||||||
},
|
},
|
||||||
whitelist:
|
whitelist:
|
||||||
RATE_LIMITS_WHITELIST_EVERY_MILLISECONDS ||
|
RATE_LIMITS_WHITELIST_EVERY_MILLISECONDS ||
|
||||||
RATE_LIMITS_WHITELIST_TOTAL_REQUESTS
|
RATE_LIMITS_WHITELIST_TOTAL_REQUESTS
|
||||||
? {
|
? {
|
||||||
totalRequests: RATE_LIMITS_WHITELIST_TOTAL_REQUESTS,
|
totalRequests: RATE_LIMITS_WHITELIST_TOTAL_REQUESTS,
|
||||||
every: RATE_LIMITS_WHITELIST_EVERY_MILLISECONDS,
|
every: RATE_LIMITS_WHITELIST_EVERY_MILLISECONDS
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
blacklist:
|
blacklist:
|
||||||
@ -77,10 +77,10 @@ const config = {
|
|||||||
RATE_LIMITS_BLACKLIST_TOTAL_REQUESTS
|
RATE_LIMITS_BLACKLIST_TOTAL_REQUESTS
|
||||||
? {
|
? {
|
||||||
totalRequests: RATE_LIMITS_WHITELIST_TOTAL_REQUESTS,
|
totalRequests: RATE_LIMITS_WHITELIST_TOTAL_REQUESTS,
|
||||||
every: RATE_LIMITS_BLACKLIST_EVERY_MILLISECONDS,
|
every: RATE_LIMITS_BLACKLIST_EVERY_MILLISECONDS
|
||||||
}
|
}
|
||||||
: null,
|
: null
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
storage: {
|
storage: {
|
||||||
@ -94,15 +94,15 @@ const config = {
|
|||||||
db: STORAGE_DB,
|
db: STORAGE_DB,
|
||||||
user: STORAGE_USERNAME,
|
user: STORAGE_USERNAME,
|
||||||
password: STORAGE_PASSWORD,
|
password: STORAGE_PASSWORD,
|
||||||
path: STORAGE_FILEPATH,
|
path: STORAGE_FILEPATH
|
||||||
},
|
},
|
||||||
|
|
||||||
documents: DOCUMENTS
|
documents: DOCUMENTS
|
||||||
? DOCUMENTS.split(",").reduce((acc, item) => {
|
? DOCUMENTS.split(',').reduce((acc, item) => {
|
||||||
const keyAndValueArray = item.replace(/\s/g, "").split("=");
|
const keyAndValueArray = item.replace(/\s/g, '').split('=')
|
||||||
return { ...acc, [keyAndValueArray[0]]: keyAndValueArray[1] };
|
return { ...acc, [keyAndValueArray[0]]: keyAndValueArray[1] }
|
||||||
}, {})
|
}, {})
|
||||||
: null,
|
: null
|
||||||
};
|
}
|
||||||
|
|
||||||
console.log(JSON.stringify(config));
|
console.log(JSON.stringify(config))
|
||||||
|
@ -95,6 +95,6 @@
|
|||||||
"dev": "nodemon",
|
"dev": "nodemon",
|
||||||
"lint": "eslint src --fix",
|
"lint": "eslint src --fix",
|
||||||
"types:check": "tsc --noEmit --pretty",
|
"types:check": "tsc --noEmit --pretty",
|
||||||
"pretty": "prettier --write src"
|
"pretty": "prettier --write ."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ class DocumentHandler {
|
|||||||
|
|
||||||
maxLength?: number
|
maxLength?: number
|
||||||
|
|
||||||
public store: Store
|
store: Store
|
||||||
|
|
||||||
keyGenerator: KeyGenerator
|
keyGenerator: KeyGenerator
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ class DocumentHandler {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
public handlePost(request: Request, response: Response) {
|
handlePost(request: Request, response: Response) {
|
||||||
// const this = this
|
// const this = this
|
||||||
let buffer = ''
|
let buffer = ''
|
||||||
let cancelled = false
|
let cancelled = false
|
||||||
@ -121,7 +121,7 @@ class DocumentHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public handleRawGet(request: Request, response: Response) {
|
handleRawGet(request: Request, response: Response) {
|
||||||
const key = request.params.id.split('.')[0]
|
const key = request.params.id.split('.')[0]
|
||||||
const skipExpire = !!this.config.documents[key]
|
const skipExpire = !!this.config.documents[key]
|
||||||
|
|
||||||
|
@ -23,29 +23,29 @@ export type BaseStoreConfig = {
|
|||||||
|
|
||||||
export interface MongoStoreConfig extends BaseStoreConfig {
|
export interface MongoStoreConfig extends BaseStoreConfig {
|
||||||
connectionUrl: string
|
connectionUrl: string
|
||||||
type: StoreNames.mongo
|
type: StoreNames.Mongo
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MemcachedStoreConfig extends BaseStoreConfig {
|
export interface MemcachedStoreConfig extends BaseStoreConfig {
|
||||||
host: string
|
host: string
|
||||||
port: number
|
port: number
|
||||||
type: StoreNames.memcached
|
type: StoreNames.Memcached
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileStoreConfig extends BaseStoreConfig {
|
export interface FileStoreConfig extends BaseStoreConfig {
|
||||||
path: string
|
path: string
|
||||||
type: StoreNames.file
|
type: StoreNames.File
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AmazonStoreConfig extends BaseStoreConfig {
|
export interface AmazonStoreConfig extends BaseStoreConfig {
|
||||||
bucket: string
|
bucket: string
|
||||||
region: string
|
region: string
|
||||||
type: StoreNames.amazons3
|
type: StoreNames.AmazonS3
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PostgresStoreConfig extends BaseStoreConfig {
|
export interface PostgresStoreConfig extends BaseStoreConfig {
|
||||||
connectionUrl: string
|
connectionUrl: string
|
||||||
type: StoreNames.postgres
|
type: StoreNames.Postgres
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RethinkDbStoreConfig extends BaseStoreConfig {
|
export interface RethinkDbStoreConfig extends BaseStoreConfig {
|
||||||
@ -54,7 +54,7 @@ export interface RethinkDbStoreConfig extends BaseStoreConfig {
|
|||||||
db: string
|
db: string
|
||||||
user: string
|
user: string
|
||||||
password: string
|
password: string
|
||||||
type: StoreNames.rethinkdb
|
type: StoreNames.RethinkDb
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RedisStoreConfig extends BaseStoreConfig {
|
export interface RedisStoreConfig extends BaseStoreConfig {
|
||||||
@ -65,11 +65,11 @@ export interface RedisStoreConfig extends BaseStoreConfig {
|
|||||||
password?: string
|
password?: string
|
||||||
host?: string
|
host?: string
|
||||||
port?: string
|
port?: string
|
||||||
type: StoreNames.redis
|
type: StoreNames.Redis
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GoogleStoreConfig extends BaseStoreConfig {
|
export interface GoogleStoreConfig extends BaseStoreConfig {
|
||||||
type: StoreNames.googledatastore
|
type: StoreNames.GoogleDataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
export type StoreConfig =
|
export type StoreConfig =
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
// eslint-disable-next-line import/prefer-default-export
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
export enum StoreNames {
|
export enum StoreNames {
|
||||||
amazons3 = 'amazon-s3',
|
AmazonS3 = 'amazon-s3',
|
||||||
file = 'file',
|
File = 'file',
|
||||||
googledatastore = 'google-datastore',
|
GoogleDataStore = 'google-datastore',
|
||||||
memcached = 'memcached',
|
Memcached = 'memcached',
|
||||||
mongo = 'mongo',
|
Mongo = 'mongo',
|
||||||
postgres = 'postgres',
|
Postgres = 'postgres',
|
||||||
redis = 'redis',
|
Redis = 'redis',
|
||||||
rethinkdb = 'rethinkdb'
|
RethinkDb = 'rethinkdb'
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,35 @@
|
|||||||
import { createMock } from 'ts-auto-mock';
|
import { createMock } from 'ts-auto-mock'
|
||||||
import DocumentHandler from 'src/lib/document-handler/index'
|
import DocumentHandler from 'src/lib/document-handler/index'
|
||||||
import Generator from 'src/lib/key-generators/random'
|
import Generator from 'src/lib/key-generators/random'
|
||||||
import constants from 'src/constants'
|
import constants from 'src/constants'
|
||||||
import { Config } from 'src/types/config'
|
import { Config } from 'src/types/config'
|
||||||
import { Store } from 'src/lib/document-stores';
|
import { Store } from 'src/lib/document-stores'
|
||||||
|
|
||||||
const store : Store = createMock<Store>();
|
const store: Store = createMock<Store>()
|
||||||
const config : Config = createMock<Config>();
|
const config: Config = createMock<Config>()
|
||||||
|
|
||||||
describe('document-handler', () => {
|
describe('document-handler', () => {
|
||||||
describe('with random key', () => {
|
describe('with random key', () => {
|
||||||
it('should choose a key of the proper length', () => {
|
it('should choose a key of the proper length', () => {
|
||||||
const gen = new Generator({ type: 'random' })
|
const gen = new Generator({ type: 'random' })
|
||||||
const dh = new DocumentHandler({ keyLength: 6, keyGenerator: gen, store, config})
|
const dh = new DocumentHandler({
|
||||||
expect(dh.acceptableKey()?.length).toEqual(6);
|
keyLength: 6,
|
||||||
|
keyGenerator: gen,
|
||||||
|
store,
|
||||||
|
config
|
||||||
|
})
|
||||||
|
expect(dh.acceptableKey()?.length).toEqual(6)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should choose a default key length', () => {
|
it('should choose a default key length', () => {
|
||||||
const gen = new Generator({ type: 'random' })
|
const gen = new Generator({ type: 'random' })
|
||||||
const dh = new DocumentHandler({ keyGenerator: gen, maxLength: 1, store, config })
|
const dh = new DocumentHandler({
|
||||||
expect(dh.keyLength).toEqual(constants.DEFAULT_KEY_LENGTH);
|
keyGenerator: gen,
|
||||||
|
maxLength: 1,
|
||||||
|
store,
|
||||||
|
config
|
||||||
|
})
|
||||||
|
expect(dh.keyLength).toEqual(constants.DEFAULT_KEY_LENGTH)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -14,7 +14,7 @@ describe('Redis document store', () => {
|
|||||||
it('should be able to set a key and have an expiration set', async () => {
|
it('should be able to set a key and have an expiration set', async () => {
|
||||||
store = new RedisDocumentStore({
|
store = new RedisDocumentStore({
|
||||||
expire: 10,
|
expire: 10,
|
||||||
type: StoreNames.redis
|
type: StoreNames.Redis
|
||||||
})
|
})
|
||||||
return store.set('hello1', 'world', async () => {
|
return store.set('hello1', 'world', async () => {
|
||||||
const res = await store.client?.ttl('hello1')
|
const res = await store.client?.ttl('hello1')
|
||||||
@ -25,7 +25,7 @@ describe('Redis document store', () => {
|
|||||||
it('should not set an expiration when told not to', async () => {
|
it('should not set an expiration when told not to', async () => {
|
||||||
store = new RedisDocumentStore({
|
store = new RedisDocumentStore({
|
||||||
expire: 10,
|
expire: 10,
|
||||||
type: StoreNames.redis
|
type: StoreNames.Redis
|
||||||
})
|
})
|
||||||
|
|
||||||
store.set(
|
store.set(
|
||||||
@ -41,7 +41,7 @@ describe('Redis document store', () => {
|
|||||||
|
|
||||||
it('should not set an expiration when expiration is off', async () => {
|
it('should not set an expiration when expiration is off', async () => {
|
||||||
store = new RedisDocumentStore({
|
store = new RedisDocumentStore({
|
||||||
type: StoreNames.redis
|
type: StoreNames.Redis
|
||||||
})
|
})
|
||||||
|
|
||||||
store.set('hello3', 'world', async () => {
|
store.set('hello3', 'world', async () => {
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
/* eslint-disable jest/no-conditional-expect */
|
/* eslint-disable jest/no-conditional-expect */
|
||||||
import Generator from 'src/lib/key-generators/phonetic'
|
import Generator from 'src/lib/key-generators/phonetic'
|
||||||
|
|
||||||
const vowels = 'aeiou';
|
const vowels = 'aeiou'
|
||||||
const consonants = 'bcdfghjklmnpqrstvwxyz';
|
const consonants = 'bcdfghjklmnpqrstvwxyz'
|
||||||
|
|
||||||
describe('PhoneticKeyGenerator', () => {
|
describe('PhoneticKeyGenerator', () => {
|
||||||
describe('generation', () => {
|
describe('generation', () => {
|
||||||
it('should return a key of the proper length', () => {
|
it('should return a key of the proper length', () => {
|
||||||
const gen = new Generator({ type: 'phonetic'});
|
const gen = new Generator({ type: 'phonetic' })
|
||||||
expect(gen.createKey(6).length).toEqual(6);
|
expect(gen.createKey(6).length).toEqual(6)
|
||||||
});
|
})
|
||||||
|
|
||||||
it('should alternate consonants and vowels', () => {
|
it('should alternate consonants and vowels', () => {
|
||||||
const gen = new Generator({ type: 'phonetic'});
|
const gen = new Generator({ type: 'phonetic' })
|
||||||
const key = gen.createKey(3);
|
const key = gen.createKey(3)
|
||||||
// if it starts with a consonant, we expect cvc
|
// if it starts with a consonant, we expect cvc
|
||||||
// if it starts with a vowel, we expect vcv
|
// if it starts with a vowel, we expect vcv
|
||||||
if(consonants.includes(key[0])) {
|
if (consonants.includes(key[0])) {
|
||||||
expect(consonants.includes(key[0])).toBeTruthy()
|
expect(consonants.includes(key[0])).toBeTruthy()
|
||||||
expect(consonants.includes(key[2])).toBeTruthy()
|
expect(consonants.includes(key[2])).toBeTruthy()
|
||||||
expect(vowels.includes(key[1])).toBeTruthy()
|
expect(vowels.includes(key[1])).toBeTruthy()
|
||||||
@ -25,6 +25,6 @@ describe('PhoneticKeyGenerator', () => {
|
|||||||
expect(vowels.includes(key[2])).toBeTruthy()
|
expect(vowels.includes(key[2])).toBeTruthy()
|
||||||
expect(consonants.includes(key[1])).toBeTruthy()
|
expect(consonants.includes(key[1])).toBeTruthy()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user