@emeritus-engineering/growth-platform-core
v0.1.2
Published
Modular Growth Platform utilities: rate limiting, Keycloak auth, and white-label theme data.
Downloads
507
Keywords
Readme
@emeritus-engineering/growth-platform-core
NestJS package for Growth Platform Core auth, rate limiting, and white-label theme data.
Install
yarn add @emeritus-engineering/growth-platform-corePeer dependencies:
@nestjs/common
@nestjs/core
@nestjs/config
@nestjs/throttler
@nestjs/axios
axios
rxjs
reflect-metadataImports
import {
KeycloakAuthModule,
KeycloakAuthGuard,
RolesGuard,
Roles,
Public,
Role
} from '@emeritus-engineering/growth-platform-core/auth'
import {
RateLimiterModule,
RateLimitGuard,
ApiThrottleMiddleware,
API_THROTTLE_REDIS_CLIENT
} from '@emeritus-engineering/growth-platform-core/rate-limiter'
import {
WHITE,
WhiteLabelColorValue,
getWhiteLabelTheme
} from '@emeritus-engineering/growth-platform-core/white-label'The package root re-exports the same symbols for convenience; subpath imports are preferred for tree-shaking.
Keycloak Auth
Introspection mode (default)
KeycloakAuthModule.forRoot({
validationMode: 'introspection',
keycloakBaseUrl: process.env.KEYCLOAK_BASE_URL,
keycloakRealm: process.env.KEYCLOAK_REALM,
clients: [{ clientId: 'growth-api', clientSecret: process.env.KEYCLOAK_GROWTH_SECRET! }],
authBypassHeaders: [
{ headerName: 'x-internal-api-key', expectedValueConfigKey: 'INTERNAL_API_SECRET' }
]
})JWKS mode
KeycloakAuthModule.forRoot({
validationMode: 'jwks',
keycloakBaseUrl: process.env.KEYCLOAK_BASE_URL,
keycloakRealm: process.env.KEYCLOAK_REALM,
audience: 'growth-api'
// jwksUrl / issuer optional; built from baseUrl + realm when omitted
})Set verifyIssuer: false (or KEYCLOAK_VERIFY_ISSUER=false) to disable the iss claim check while keeping signature, expiry, and audience checks. Default is true.
@nestjs/jose is loaded dynamically; no extra peer dependency required (the package depends on jose directly).
Async config from ConfigService
KeycloakAuthModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
validationMode: config.get('KEYCLOAK_VALIDATION_MODE', 'introspection'),
keycloakBaseUrl: config.getOrThrow('KEYCLOAK_BASE_URL'),
keycloakRealm: config.getOrThrow('KEYCLOAK_REALM'),
isAuthDisabled: config.get<boolean>('IS_KEYCLOAK_AUTH_DISABLED', false)
})
})configKeys lets you map non-default env names; see KeycloakAuthConfigKeys in the public types.
Rate Limiting
Nest ThrottlerModule wrapper
RateLimiterModule.forRoot({
throttlers: [{ name: 'default', ttl: 60_000, limit: 100 }]
})Provides RateLimitGuard (alias for ThrottlerGuard) and RateLimiterService (imperative storage access).
Growth-style API throttle middleware
RateLimiterModule.forApiThrottle({
configKey: 'API_THROTTLE_CONFIG',
redisClientProvider: {
provide: API_THROTTLE_REDIS_CLIENT,
useExisting: RedisService
}
})Apply ApiThrottleMiddleware with Nest's MiddlewareConsumer:
configure(consumer: MiddlewareConsumer) {
consumer.apply(ApiThrottleMiddleware).forRoutes('*')
}Set API_THROTTLE_CONFIG (JSON in env or object via config) with this shape:
{
"enableRateLimit": true,
"global": { "limit": 100, "cooldown": 60 },
"excludeIps": ["127.0.0.1"],
"excludedPaths": ["/health"],
"apiLimits": {
"/growth/api/v1/programs/:id": { "limit": 10, "cooldown": 60 }
},
"dynamicRules": [
{ "headerKey": "x-client-type", "value": "partner", "limit": 20, "cooldown": 60 }
]
}cooldown is in seconds. Limit breaches throw ApiRateLimitExceededError (HTTP 429 with diagnostic metadata).
The Redis client provided to API_THROTTLE_REDIS_CLIENT must implement hget, hset, hdel, hgetall, and multi.
White-label
const emeritusTheme = getWhiteLabelTheme('emeritus')
const white = WHITE
const allThemes = WhiteLabelColorValueBuild
npm install
npm run buildOutputs ESM + CJS bundles under dist/. Decorator metadata (required for Nest DI) is emitted via tsup's swc plugin (@swc/core is a dev dependency).
