micro-kit-atlas v9.11.23
Atlas
Atlas is the core library used by the services inside the globaliD microservice architecture.
Basic use:
process.env.AWS_REGION = 'local' // Required
import { Lib , init, setKeepAliveTimeout } from 'micro-kit-atlas'
const options: Lib.Config = {
name: 'veritas-service',
}
export async function initService (): Promise<any> {
try {
const app = await init(options)
const inst = await app.listen(8080, () => {
console.log('running on port:', 8080)
})
setKeepAliveTimeout(inst)
return inst
} catch (err) {
console.error('initService() error', err)
process.exit()
}
}
initService()To run the example:
cd examples
npm install
npm run basic_useDD trace
Altas initializes dd trace by default. This can be turned off by setting env variable DISABLE_DDTRACE=1.
In order for dd trace to work properly, atlas should be the first import in project's entry file.
TODO?
Describe init(options)?
Features
- Routing.
- Internal.
- TokenProtected (+ ScopeProtected, RoleProtected, GbacProtected)
- Exposed.
- Storage.
- MySql.
- Redis.
- Transport.
- SNS/SQS.
- Utility.
- Custom logger.
- Data dog stats
- Obfuscator
- Lodash extensions
Installation
Install from npm:
npm install micro-kit-atlasConfiguration Options
Atlas accepts the following properties in the options object:
name
string required
Name of the service.
version
string optional
Version of the service.
routing
object optional
Configuration options object for routing. See Routing.Config.
redis
boolean optional
Enables Redis client.
redis_config
object optional
Configuration options object for ioredis client.
database
boolean optional
Enables MySql.
database_config
object optional
Configuration options object for Sequelize client.
obfuscator
boolean optional
Enables obfuscator
stats
boolean optional
transport
boolean optional
Routing configuration
Routing.Config object accepts the following properties:
controllers
Function[] required
List of routing-controllers controller classes.
jwtOptions
ojbect optional
{
secret: string | Buffer | SecretCallback | SecretCallbackLong
issuer: string | string[] | false
algorithms?: string[] // defaults to ['RS256', 'HS256']
audience?: string | string[]
// + other options
}Options are passed to express-jwt.
For services without protected API routes, JWT auth can be disabled. This is done by setting JWT_AUTH_DISABLED env variable to "1" and not passing the jwtOptions to config.
middlewares
Function[] optional
List of routing-controllers middleware classes.
optionsOverwrites
RoutingControllersOptions optional
routing-controllers options to overwrite default atlas configuration.
Environment Variables
- Globals
- AWS_REGION - Required. AWS region must be provided so Atlas can initialize.
- AWS_ACCESS_KEY_ID - Required. AWS region must be provided so Atlas can initialize.
- AWS_SECRET_ACCESS_KEY - Required. AWS region must be provided so Atlas can initialize.
- NAMESPACE - Optional, required for SNS/SQS to be namespaced.
- NODE_ENV - Optional, used for logger to determine if it should insert white space into the output. If
productionno white space will be inserted.
- Routing
- DISABLE_RESPONSE_VALIDATION - Optional. Disables API response validation if set to true or 1.
- Database (MySql)
- DATABASE_CONNECTION_URL - Required. Database connection string.
- DATABASE_LOGGING - Optional. Enables or disables logging. Accepts both true or 1.
- DATABASE_HOST - Optional. Overrides the DATABASE_CONNECTION_URL if provided.
- DATABASE_PORT - Optional. Overrides the DATABASE_CONNECTION_URL if provided.
- DATABASE_USERNAME - Optional. Overrides the DATABASE_CONNECTION_URL if provided.
- DATABASE_PASSWORD - Optional. Overrides the DATABASE_CONNECTION_URL if provided.
- DATABASE_NAME - Optional. Overrides the DATABASE_CONNECTION_URL if provided.
- Redis
- REDIS_HOST - Optional. Overrides the default host
127.0.0.1. - REDIS_PORT - Optional. Overrides the default port
6379.
- REDIS_HOST - Optional. Overrides the default host
- Obfuscator
- OBFUSCATOR_SALT_ID - Required.
- OBFUSCATOR_SALT_PART - Required.
- OBFUSCATOR_ENDPOINT - Required.
- OBFUSCATOR_RETRY_COUNT - Optional. Overrides the default
3. - OBFUSCATOR_RETRY_TIMEOUT_MS - Optional. Overrides the default
1000.
Routing
For apps using Atlas, routing is defined with list of controller classes in atlas.init(options). Controller classes must be decorated with one of the controller decorators Controller, JsonController or RestController. First two are defined in routing-controllers library. RestController is defined in atlas on top of JsonController to ease implementing REST API. Param and response classes should be defined using routing-controllers as described on routing-controllers page. Atlas defined some extra validation decorators described in the Extra validation decorators section.
Basic use
controller.ts
import { JsonController, Exposed } from 'micro-kit-atlas/routing'
@JsonController()
export class FirstController () {
@Exposed.GET('status')
async getStatus(): Promise<string> {
return 'Ok'
}
}app.ts
import { Lib , init } from 'micro-kit-atlas'
import { FirstController } from './controller'
const options: Lib.Config = {
name: 'check_status',
routing: {
controllers: [FirstController]
}
}
export async function initService (): Promise<any> {
const app = await init(options)
const inst = await app.listen(8080, () => {
console.log('running on port:', 8080)
})
return inst
}
initService()
.then(() => {
logger.info('Running server')
})
.catch((err: Error) => {
logger.error(err)
process.exit(1)
})To run the example:
cd examples
npm install
npm run routing:basic_useTo see the example in browser open http://localhost:8080/v1/status
The Router in Atlas has three decorator namespaces Exposed, TokenProtected, RoleProtected, ScopeProtected, GbacProtected, and Internal. All of them have the same set of decorators with different params type. The exposed and token protected decorators requires a version property while the internal doesn't. Generated routes have different format. The exposed and token protected decorators start with configured version (eg. /v1/route) while internal start with /internal/.
Exposed Decorators
GET: (route: string, params?: ExposedRouteParams): MethodDecorator
POST: (route: string, params?: ExposedRouteParams): MethodDecorator
PUT: (route: string, params?: ExposedRouteParams): MethodDecorator
DELETE: (route: string, params?: ExposedRouteParams): MethodDecoratorrouterequired - The last segment of the URI path component.paramsoptional - SeeExposedRouteParams.
Example controller
import { JsonController, Exposed } from 'micro-kit-atlas'
@JsonController()
export class FirstController () {
@Exposed.GET('status', { version: 2 })
async getStatus(): Promise<string> {
return 'ok'
}
}To see the example in browser open http://localhost:8080/v2/status
TokenProtected Decorators
GET: (route: string, params?: TokenProtectedRouteParams): MethodDecorator
POST: (route: string, params?: TokenProtectedRouteParams): MethodDecorator
PUT: (route: string, params?: TokenProtectedRouteParams): MethodDecorator
DELETE: (route: string, params?: TokenProtectedRouteParams): MethodDecoratorrouterequired - The last segment of the URI path component.paramsoptional - SeeTokenProtectedRouteParams.
Protected routes run a middleware which verifies and parses a JWT access token (configuration). Unauthorised request will be met with a 401 Unauthorised response. Use @TokenDataParam() tokenData: TokenData parameter to access parsed claims.
For optional authentication use @TokenDataParam(false) tokenData?: TokenData with Exposed route decorator.
Example controller
import { JsonController, TokenProtected, TokenDataParam, TokenData } from 'micro-kit-atlas'
@JsonController()
export class FirstController () {
@TokenProtected.GET('my-uuid')
async getMyUuid(@TokenDataParam() tokenData: TokenData): Promise<TokenData> {
return tokenData
}
}Example controller with additional claim requirements
import { JsonController, TokenProtected, TokenDataParam, TokenData } from 'micro-kit-atlas'
@JsonController()
export class FirstController () {
@TokenProtected.GET('my-uuid', {
entityType: TokenEntityType.CLIENT,
scopes: ['idenity.read', 'identity.manage'],
roles: ['admin'],
claims: {
extraClaim: true,
andAnother: 'yup',
}
})
async getMyUuid(@TokenDataParam() tokenData: TokenData): Promise<ToknData> {
return tokenData
}
}GbacProtected Decorators
GbacProtected(allowedPermissions?: string | string[])GbacProtected decorator is intended to be used with GBAC permissions. The handler needs to be linked to a group. It takes one optional parameter. The execution of the handler is always allowed when the caller is the owner of the group. If the caller is not the owner of the group the execution will be allowed only when the called has one of the permissions required. A special permissions is defined 'GROUP_MEMBER' as GROUP_MEMBER_ROLE constant.
GET: (route: string, params?: GbacProtectedRouteParams): MethodDecorator
POST: (route: string, params?: GbacProtectedRouteParams): MethodDecorator
PUT: (route: string, params?: GbacProtectedRouteParams): MethodDecorator
DELETE: (route: string, params?: GbacProtectedRouteParams): MethodDecoratorrouterequired - The last segment of the URI path component.paramsoptional - SeeGbacProtectedRouteParams.
Example:
import { JsonController, Internal } from 'micro-kit-atlas'
@JsonController()
export class FirstController {
@GbacProtected('ger-perm').GET('status')
async getStatus(): Promise<string> {
return 'ok'
}
}To see the example in browser open http://localhost:8080/internal/status
Internal Decorators
GET: (route: string, params?: RouteParams): MethodDecorator
POST: (route: string, params?: RouteParams): MethodDecorator
PUT: (route: string, params?: RouteParams): MethodDecorator
DELETE: (route: string, params?: RouteParams): MethodDecoratorrouterequired - The last segment of the URI path component.paramsoptional - SeeRouteParams.
Example:
import { JsonController, Internal } from 'micro-kit-atlas'
@JsonController()
export class FirstController {
@Internal.GET('status')
async getStatus(): Promise<string> {
return 'ok'
}
}To see the example in browser open http://localhost:8080/internal/status
REST Controllers
REST routing can be defined using RestController class decorator and Exposed.Rest, TokenProtected.Rest and Internal.Rest set of method decorators.
RestController decorator
RestController decorator is an extension of JsonController defined in routing-controllers library. It takes two parameters:
Example:
import { RestController, Internal, Body, Params, OrUndefined } from 'micro-kit-atlas'
import { IsString, IsUUID, IsInstance, IsEmail, IsUrl, MinLength } from 'micro-kit-atlas/routing'
class AddUserBody {
@IsString() @MinLength(2) name!: string
@IsString() @IsUrl() @OrUndefined() picture?: string
@IsString() @IsEmail() contact_email!: string
}
class ModifyUserBody {
@IsString() @MinLength(2) @OrUndefined() name?: string
@IsString() @IsUrl() @OrUndefined() picture?: string
@IsString() @IsEmail() @OrUndefined() contact_email?: string
}
class User extends AddUserBody {
@IsUUID('4') uuid!: string
}
class Users {
@IsInstance(User, { each: true })
users!: User[]
}
class UserIdParams {
@IsUUID('4') user_uuid!: string
}
@RestController('user', 'user_id')
export class FirstController {
@Internal.Rest.create({
description: `Create a new user`,
response: User,
responseDescription: `New user was created`,
errors: [UserWithEmailAlreadyExistsError],
})
async createUser(@Body() body: AddUserBody): Promise<User> {
if (userWithEmailExists(body.contact_email)) {
throw new UserWithEmailAlreadyExistsError()
}
return addUserToDb(body)
}
@Internal.Rest.getOne({
description: `Get a user by id`,
response: User,
responseDescription: `Return a single user`,
errors: [UserMissingError],
})
async getUser(@Params() params: UserIdParams): Promise<User> {
if (userMissing(params.user_uuid)) {
throw new UserMissingError()
}
return getUserFromDb(params.user_uuid)
}
@Internal.Rest.getList({
description: `Get all users`,
response: User,
responseDescription: `Return a list of users`,
})
async getUsers(): Promise<Users> {
return getUsersFromDb()
}
@Internal.Rest.update({
description: `Modify a user`,
response: User,
responseDescription: `User was updated`,
errors: [UserMissingError],
})
async updateUser(@Params() params: UserIdParams, @Body() body: ModifyUserBody): Promise<User> {
if (userMissing(params.user_uuid)) {
throw new UserMissingError()
}
return updateUserInDb(params.user_uuid, body)
}
@Internal.Rest.remove({
description: `Remove a user by id`,
responseDescription: `User was deleted`,
})
async removeUser(@Params() params: UserIdParams): Promise<void> {
return removeUserFromDb(params.user_uuid)
}
}To see the example in browser open http://localhost:8080/internal/status
controllerNamespace
String required
Namespace of API defined with this class. All routes will have this namespace as first part of the URI. See REST Route URIs section.
idName
String required
ID name of the resource. See REST Route URIs section.
Route Decorators
create (params: RestParams, routeParams?: T): MethodDecorator
getOne (params: RestParamsWithResponse, routeParams?: T): MethodDecorator
getList (params: RestParamsWithResponse, routeParams?: T): MethodDecorator
update (params: RestParams, routeParams?: T): MethodDecorator
updateAll (params: RestParams, routeParams?: T): MethodDecorator
remove (params: RestParams, routeParams?: T): MethodDecorator
search (params: RestParamsWithResponse, routeParams?: T): MethodDecorator
action (action: string, params: RestParams, routeParams?: T): MethodDecoratorparamsrequired - SeeRestParamsandRestParamsWithResponse.routeParamsoptional - SeeExposedRouteParams,TokenProtectedRouteParamsandRouteParams.
create decorator
Define a POST route with 201 response code. It can respond with a created entity.
getOne decorator
Define a GET route with 200 response code. It should respond with a single entity. Entity ID is provided as path parameter.
getList decorator
Define a GET route with 200 response code. It should respond with a list of entities.
update decorator
Define a PUT route with 200 response code. It can respond with an updated entity. Entity ID is provided as path parameter.
updateAll decorator
Define a PUT route with 200 response code. It can respond with an updated entities. Entity ID is NOT provided as path parameter.
remove decorator
Define a DELETE route with 204 response code. It should respond with empty body. Entity ID is provided as path parameter.
search decorator
Define a POST route with 200 response code. It should respond with a list of entities. Body of the request contains search parameters.
action decorator
Define a POST route with 200 response code. This is used to define action route which modifies the entity.
REST Route URIs
REST Route URIs are generated by combining access level, controller namespace, ID name, route and command. Route and command are optional. The format is:
/<access-level>/<controller-namespace>/<route>/<command>for collection APIs and
/<access-level>/<controller-namespace>/<route>/:<id-name>/<command>for single resource APIs.
Any empty part of the URI will be removed. For example if route and command are not defined the URIs will be:
/<access-level>/<controller-namespace>
/<access-level>/<controller-namespace>/:<id-name>Route Interfaces
RouteParams
tagoptional - Used for swagger generation. Default value isExposed.descriptionoptional - Used for swagger generation.responseoptional - Used for swagger generation. CheckResponseOptions.errorsoptional - List of whitelisted errors for this route. A list should contain classes which inherit from HttpError. In the class constructor prototype should be set explicitly (as explained here)
ExposedRouteParams
versionoptional - Used for route versioning. The lettervis added before the number. Defaut value is1.tagoptional - Used for swagger generation. Default value isExposed.descriptionoptional - Used for swagger generation.responseoptional - Used for swagger generation. CheckResponseOptions.errorsoptional - List of whitelisted errors for this route. A list should contain classes which inherit from HttpError. In the class constructor prototype should be set explicitly (as explained here)
TokenProtectedRouteParams
Can be used to specify additional requirements for various JWT claims:
entityTypeoptional - only allow access using Client Credentials / Identity access tokenscopesoptional - required scopes allowed to access this routerolesoptional - required roles allowed to access this routeclaimsoptional - JWT needs to contain all of these claimsauthorizeTokenDataoptional - callback method for custom JWT inspection- + the ones from ExposedRouteParams
GbacProtectedRouteParams
Can be used to specify additional requirements for various JWT claims:
entityTypeoptional - only allow access using Client Credentials / Identity access token- + the ones from ExposedRouteParams
RestParams
routeoptional - The last segment of the URI entity path part. SeeREST Route URIssection.commandoptional - The last segment of the URI path. SeeREST Route URIssection.descriptionrequired - Description to use for swagger generation.responseDescriptionrequired - Response description to use for swagger generation.errorsoptional - List of whitelisted errors for this route. A list should contain classes which inherit from HttpError. In the class constructor prototype should be set explicitly (as explained here)responseoptional - Responserefto use for swagger generation.
RestParamsWithResponse
routeoptional - The last segment of the URI entity path part. SeeREST Route URIssection.commandoptional - The last segment of the URI path. SeeREST Route URIssection.descriptionrequired - Description to use for swagger generation.responseDescriptionrequired - Response description to use for swagger generation.errorsoptional - List of whitelisted errors for this route. A list should contain classes which inherit from HttpError. In the class constructor prototype should be set explicitly (as explained here)responserequired - Responserefto use for swagger generation.
Extra parameter decorators
MultiBody
routing-controllers package defines a set of decorators to inject various parameters to route handlers. One of them is a Body parameter decorator which injects the request body. Body decorator has a limitation and it can be defined for one type only. Sometimes we expect request body which can be multiple different types based on a property value contained within the body.
We defined a new decorator MultiBody which defines a set of possible types and rules to select them.
MultiBody (targetTypes: ClassConstructor<any>[], options?: BodyOptions): ParameterDecorator
MultiBody (typeOptions: MultiTypeOptions, options?: BodyOptions): ParameterDecoratorTwo different overloads are defined. If we define an array of types MultiTypeOptions will be generated automatically like this
{
discriminator: {
property: 'type',
subTypes: targetTypes.map((t: ClassConstructor<any>) => ({ value: t, name: _.kebabCase(t.name) }))
},
keepDiscriminatorProperty: true,
}Or we can use it with MultiTypeOptions and have more control over how types will be selected. MultiTypeOptions type is used the same way as described in class-transformer package.
Example:
@JsonController()
class BodyTestController {
@Route('post', '/body-test-route', { response: { schemaRef: ResponseClass } })
async routeBodyTestRoute (@Body() body: BodyBase): Promise<ResponseClass> {
...
}
@Route('post', '/multi-body-test-route', { response: { schemaRef: ResponseClass } })
async routeMultiBodyTestRoute (@MultiBody([Body1, Body2, Body3]) body: Body1 | Body2 | Body3): Promise<ResponseClass> {
...
}
@Route('post', '/multi-body-custom-test-route', { response: { schemaRef: ResponseClass } })
async routeMultiBodyCustomTestRoute (@MultiBody({
discriminator: {
property: 'bodyType',
subTypes: [
{ name: 'body-A', value: CustomBody1 },
{ name: 'body-B', value: CustomBody2 },
{ name: 'body-C', value: CustomBody3 }
]
}
}) body: CustomBody1 | CustomBody2 | CustomBody3): Promise<ResponseClass> {
...
}
}Extra validation decorators
OrUndefined
OrUndefined(validationOptions?: ValidationOptions): PropertyDecoratorThis validator is used to disable validation when the value is undefined so the undefined value is accepted. When generating swagger it will remove the property from required list.
OrNull
OrNull(validationOptions?: ValidationOptions): PropertyDecoratorThis validator is used to disable validation when the value is null so the null value is accepted. When generating swagger it will add nullable: true to the property descriptor.
IsNumberOrString
IsNumberOrString(options: IsNumberOptions = {}, validationOptions?: ValidationOptions): PropertyDecoratorThis validator is used to validate the property to be either a number or a string. It is identical to a combination of IsNumber and IsString validators defined in class-validator package.
IsInstanceOf
IsInstanceOf(targetType: ClassConstructor<any>, validationOptions?: ValidationOptions): PropertyDecoratorThis validator is used to validate and convert the property to a scpecific type. It is a combination of three validators IsInstance, ValidateNested and IsDefined.
IsArrayOf
IsArrayOf(targetType: ClassConstructor<any>, validationOptions?: ValidationOptions): PropertyDecoratorThis validator is used to validate and convert the property to an array of items of a scpecific type. It is a combination of three validators IsInstance, ValidateNested and IsDefined.
IsOneInstance
IsOneInstance(targetTypes: ClassConstructor<any>[], validationOptions?: ValidationOptions): PropertyDecoratorThis validator is used to validate the property to be one of scpecified types.
IsOneInstanceOf
IsOneInstanceOf (targetTypes: ClassConstructor<any>[], validationOptions?: ValidationOptions): PropertyDecorator
IsOneInstanceOf (typeOptions: MultiTypeOptions, validationOptions?: ValidationOptions): PropertyDecoratorThis validator is used to validate and convert the property to one of the specified types. It is a combination of three validators IsOneInstance, ValidateNested and IsDefined.
Two different overloads are defined. If we define an array of types MultiTypeOptions will be generated automatically like this
{
discriminator: {
property: 'type',
subTypes: targetTypes.map((t: ClassConstructor<any>) => ({ value: t, name: _.kebabCase(t.name) }))
},
keepDiscriminatorProperty: true,
}For example when using @IsOneInstanceOf([Type1, Type2, Type3]) typeOptions would be
{
discriminator: {
property: 'type',
subTypes: [
{ value: Type1, name: 'type1' },
{ value: Type2, name: 'type2' },
{ value: Type3, name: 'type3' }
]
},
keepDiscriminatorProperty: true
}We can also use it with MultiTypeOptions and have more control over how types will be selected. MultiTypeOptions type is used the same way as described in class-transformer package.
Storage
MySql
TODO
Redis
TODO
Transport
For apps using Atlas, SNS/SQS handling is defined with list of handler classes in atlas.init(options). Each handler class defines one or more event handlers which must be decorated with EventHandler decorator. Event param can be obtained by decorating event handler's params with one of the param decorators QueueMessage or MessageBody. MessageBody decorator uses a type of the param to validate the message after being parsed from JSON. Message type should be defined using class-validator decorators you can import from micro-kit-atlas/rounting.
Basic use
handler.ts
import { EventHandler, MessageBody } from 'micro-kit-atlas/transport'
import { IsString } from 'micro-kit-atlas/routing'
const EVENT_TOPIC: string = 'EVENT_TOPIC'
export class FirstMessageBody {
@IsString() stringParam!: string
}
export class FirstHandler () {
@EventHandler(EVENT_TOPIC)
async eventHandler(@MessageBody() message: FirstMessageBody): Promise<void> {
// event handler code
}
}app.ts
import { Lib , init } from 'micro-kit-atlas'
import { FirstHandler } from './handler'
const options: Lib.Config = {
name: 'check_status',
routing: {
controllers: []
},
transport: {
handlers: [FirstHandler]
},
}
export async function initService (): Promise<any> {
const app = await init(options)
const inst = await app.listen(8080, () => {
console.log('running on port:', 8080)
})
return inst
}
initService()
.then(() => {
logger.info('Running server')
})
.catch((err: Error) => {
logger.error(err)
process.exit(1)
})Decorators
EventHandler decorator
Decorator used to mark a class method as an event handler.
EventHandler: (topic: string, options?: EventHandlerOptions): MethodDecoratortopicrequired - Name of the event topicoptionsoptional - Options used when registering event withsubscribeToEventfunction frommicro-kit-aws-queuepackage.
QueueMessage decorator
Decorator used to mark an event handler's parameter to contain entire queue message object.
QueueMessage (): ParameterDecoratorExample:
export class FirstHandler () {
@EventHandler(EVENT_TOPIC)
async eventHandler(@QueueMessage() message: Transport.QueueMessage): Promise<void> {
// event handler code
}
}MessageId decorator
Decorator used to mark an event handler's parameter to contain queue message id.
MessageId (): ParameterDecoratorExample:
export class FirstHandler () {
@EventHandler(EVENT_TOPIC)
async eventHandler(@MessageId() messageId: string): Promise<void> {
// event handler code
}
}MessageBody decorator
Decorator used to mark an event handler's parameter to contain parsed queue message data.
MessageBody (targetType?: ClassConstructor<any>, options?: MessageBodyOptions): ParameterDecoratortargetTypeoptional - Target type to be used to convert and validate a parsed JSON object. If not provided type of the parameter is used.optionsoptional - SeeMessageBodyOptions.
Example:
export class FirstHandler () {
@EventHandler(EVENT_TOPIC)
async eventHandler(@MessageBody() messageBody: FirstMessageBody): Promise<void> {
// event handler code
}
async eventHandler2(@MessageBody(FirstMessageBody) messageBody: any): Promise<void> {
// event handler code
}
}Transport Interfaces
BaseParamOptions
classTransform?: ClassTransformOptions validate?: boolean | ValidatorOptions
classTransformoptional -ClassTransformOptionsobject used when transforming object to class using class-transformervalidateoptional - If true, class-validator will be used to validate param object. If validation options are given then it means validation will be applied. Default istrue.
MessageBodyOptions
Inherits properties from BaseParamOptions.
Utility
Atlas provides some utility modules.
Obfuscator
Usage
Importing & enabling
To use this in your project you must enable it by passing obfuscataor: true to the Atlas configuration object.
// to import the obfuscator functions
import * as obfuscator from 'micro-kit-atlas/obfuscator'String obfuscating
const obfuscated_item: obfuscator.ObfuscatedItem = await obfuscator.obfuscateSingle('string')
const obfuscated_string: string = obfuscated_item.obfuscatedString array obfuscating
const strings: string[] = ['string1', 'string2', 'string3']
const obfuscated_items: obfuscator.ObfuscatedItem[] = await obfuscator.obfuscateArray(strings)
obfuscated_items.forEach((obfuscated_item: obfuscator.ObfuscatedItem) => {
const obfuscated_string: string = obfuscated_item.obfuscated
})Lodash extensions
(Lodash)https://lodash.com/ is a library we use in many of our projects to ease JS/TS development. We use it in mocha/chai testing with (chai-match-pattern)https://github.com/originate/chai-match-pattern extension. We add some extra matcher functions in Atlas. To enable them in your project you have to initialize the mixin. The best place to do this is in your test setup file.
import * as _ from 'lodash'
import { atlasLodash } from 'micro-kit-atlas';
_.mixin(atlasLodash)Atlas defines these matcher functions:
isNonEmptyString (value: string): boolean
isStringOrNumber (value: string | number): boolean
isStringOrNull (value: string | null): boolean
isNumberOrNull (value: number | null): boolean
isBooleanOrNull (value: boolean | null): boolean
isUuid (value: string): boolean3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago