The application located in /packages/server is the api for inkVisitor project. It uses express + express router as a base.
Server supports different enviroments - supported by .env-<ENV_FILE>
files, which are governed by ENV_FILE
environmental variable.
See example.env file for description of variables.
You would normally use default development
environment - run in nodemon context for livereload using default start
command for consistency across packages.
pnpm install
pnpm start
- create a new
.env.test
file in theenv
folder that pnpm test
will usejest
framework to test everything, orpnpm run test <regexp>
to test only selected functions (regexp should matchdescribe
orit
statements)- if you are using Visual Studio Code, we recommend installing
Jest Runner
extension
The build
process transpiles typescript files to javascript.
pnpm build
ENV_FILE=<env> pnpm start:dist
to run the built application with loaded.env.<ENV_FILE>
file.
Make sure to have appropriate .env.<ENV_FILE>
file accessible (e.g., running ENV_FILE=production pnpm start:dist
will need env.production
). You can use the example.env
file as a template for creating your own env
file, just check and modify the values here if needed:
NODE_ENV
= environment - production/development (security vs logging)DOMAIN
= identify the instance - points to the domain where the ui should be accessible (used in emails)STATIC_PATH
= http relative path to client files served by the server, use '/' for files hosted in root pathPORT
= port which should be used for this appSECRET
= for signing jwt tokenSENDGRID_API_KEY
= for sendgrid (mails) api integrationMAILER_SENDER
= default address of the mail senderPYTHON_API_HOST
= custom analytics api, optional
Please refer to exported postman collection file to explore the api and available endpoints.
Api uses JWT tokens to authenticate the user. With this the session is controlled by token which makes the development faster, makes api easier for testing but exposes several problems, mainly token expiration question and/or session invalidation. As mentioned avove, the jwt should be replaced by cookie session in the future. Token based authorization, hovewer, should still be available.
Utility script for generating new jwt tokens:
pnpm run jwt
Server has one handler for unknown routes (wildcard - when the route does not exist) and one generic handler for other errors.
They share common IResponseGeneric
(@shared/types/response-generic.ts) interface which is populated by CustomError
instance (@shared/types/errors.ts).
Example of erroneous IResponseGeneric
msg:
{
result: false,
error: "ActionDoesNotExits",
message: "action with id 2 does not exist"
}
The output above is generated from thrown error like:
throw new ActionDoesNotExits(`action with id ${actionId} does not exist)
What happens in the error handler (middleware) is that the error is transformed to IResponseGeneric
by taking values
error <= thrownError.constructor.name
message <= thrownError.message
CustomError
respects the generic Error class logic for constructor parameter (message) and using the custom error's name as name
property
and new static property code
, which will be used as http status code in the api response.
const err = new ActionDoesNotExits(`action with id ${actionId} does not exist)
err.name === "ActionDoesNotExits"
err.statusCode() === 400 | 404 | 500 etc
Its possible, that the server would encounter an unexpected error, ie. corrupt db handler.
The generic error handler then takes the error instance and will use prepared InternalServerError
substitution.
While this error could be completely random, the api will return the same generic message. In the handler, however, the logger will print the original error.