@@ -92,18 +92,36 @@ type PlainObject = {
9292 [ key : string ] : unknown ;
9393} ;
9494
95+ /**
96+ * Configuration for {@linkcode createRemoteClient}.
97+ */
9598export type RemoteClientOptions = {
99+ /**
100+ * Base URI for HTTP requests to Decide API (optional).
101+ *
102+ * Defaults to the environment variable `ARCJET_BASE_URL` (if that value
103+ * is known and allowed) and the standard production API otherwise.
104+ */
96105 baseUrl ?: string ;
106+
107+ /**
108+ * Timeout in milliseconds for the Decide API (optional).
109+ *
110+ * Defaults to `500` in production and `1000` in development.
111+ */
97112 timeout ?: number ;
98113} ;
99114
115+ /**
116+ * Create a remote client.
117+ *
118+ * @param options
119+ * Configuration (optional).
120+ * @returns
121+ * Client.
122+ */
100123export function createRemoteClient ( options ?: RemoteClientOptions ) {
101- // The base URL for the Arcjet API. Will default to the standard production
102- // API unless environment variable `ARCJET_BASE_URL` is set.
103124 const url = options ?. baseUrl ?? baseUrl ( process . env ) ;
104-
105- // The timeout for the Arcjet API in milliseconds. This is set to a low value
106- // in production so calls fail open.
107125 const timeout = options ?. timeout ?? ( isDevelopment ( process . env ) ? 1000 : 500 ) ;
108126
109127 // Transport is the HTTP client that the client uses to make requests.
@@ -126,21 +144,83 @@ type EventHandlerLike = (
126144 listener : ( ...args : any [ ] ) => void ,
127145) => void ;
128146
129- // Interface of fields that the Arcjet Nest.js SDK expects on Request objects
147+ /**
148+ * Nest request.
149+ */
130150export interface ArcjetNestRequest {
151+ /**
152+ * Headers.
153+ */
131154 headers ?: Record < string , string | string [ ] | undefined > ;
155+ /**
156+ * HTTP method of the request.
157+ */
132158 method ?: string ;
159+ /**
160+ * URL.
161+ */
133162 url ?: string ;
163+ /**
164+ * Request body.
165+ */
134166 body ?: unknown ;
135- // Will only exist for Fastify
167+ /**
168+ * Request ID.
169+ *
170+ * This field is available on Fastify requests:
171+ * <https://fastify.dev/docs/latest/Reference/Request/#request>.
172+ */
136173 id ?: string ;
174+ /**
175+ * IP address of the client.
176+ */
137177 ip ?: string ;
178+ /**
179+ * Protocol of the request.
180+ */
138181 protocol ?: string ;
182+ /**
183+ * Host of the request.
184+ */
139185 host ?: string ;
140- // Will only exist for Express
186+ /**
187+ * `net.Socket` object associated with the connection.
188+ *
189+ * This field is available on Express requests,
190+ * as those inherit from Node `http.IncomingMessage`.
191+ *
192+ * See <https://nodejs.org/api/http.html#messagesocket>.
193+ */
141194 socket ?: Partial < { remoteAddress : string ; encrypted : boolean } > ;
195+ /**
196+ * Add event handlers.
197+ *
198+ * This field is available on Express requests,
199+ * as those inherit from Node `http.IncomingMessage`,
200+ * in turn from `stream.Readable` and `EventEmitter`.
201+ *
202+ * See <https://nodejs.org/api/events.html#emitteroneventname-listener>.
203+ */
142204 on ?: EventHandlerLike ;
205+ /**
206+ * Remove event handlers.
207+ *
208+ * This field is available on Express requests,
209+ * as those inherit from Node `http.IncomingMessage`,
210+ * in turn from `stream.Readable` and `EventEmitter`.
211+ *
212+ * See <https://nodejs.org/api/events.html#emitterremovelistenereventname-listener>.
213+ */
143214 removeListener ?: EventHandlerLike ;
215+ /**
216+ * Whether the readable stream is readable.
217+ *
218+ * This field is available on Express requests,
219+ * as those inherit from Node `http.IncomingMessage`,
220+ * in turn from `stream.Readable`.
221+ *
222+ * See <https://nodejs.org/api/stream.html#readablereadable>.
223+ */
144224 readable ?: boolean ;
145225}
146226
@@ -158,34 +238,50 @@ function cookiesToString(cookies: string | string[] | undefined): string {
158238}
159239
160240/**
161- * The options used to configure an {@link ArcjetNest} client.
241+ * Configuration for the Nest integration of Arcjet.
242+ *
243+ * @template Rules
244+ * List of rules.
245+ * @template Characteristics
246+ * Characteristics to track a user by.
162247 */
163248export type ArcjetOptions <
164249 Rules extends [ ...Array < Primitive | Product > ] ,
165250 Characteristics extends readonly string [ ] ,
166251> = Simplify <
167252 CoreOptions < Rules , Characteristics > & {
168253 /**
169- * One or more IP Address of trusted proxies in front of the application.
170- * These addresses will be excluded when Arcjet detects a public IP address .
254+ * IP addresses and CIDR ranges of trusted load balancers and proxies
255+ * (optional, example: `["100.100.100.100", "100.100.100.0/24"]`) .
171256 */
172257 proxies ?: Array < string > ;
173258 }
174259> ;
175260
176261/**
177- * The ArcjetNest client provides a public `protect()` method to
178- * make a decision about how a NestJS request should be handled.
262+ * Instance of the Nest integration of Arcjet.
263+ *
264+ * Primarily has a `protect()` method to make a decision about how a Nest request
265+ * should be handled.
266+ *
267+ * @template Props
268+ * Configuration.
179269 */
180270export interface ArcjetNest < Props extends PlainObject = { } > {
181271 /**
182- * Runs a request through the configured protections. The request is
183- * analyzed and then a decision made on whether to allow, deny, or challenge
184- * the request.
272+ * Make a decision about how to handle a request.
273+ *
274+ * This will analyze the request locally where possible and otherwise call
275+ * the Arcjet decision API.
185276 *
186- * @param req - An `IncomingMessage` provided to the request handler.
187- * @param props - Additonal properties required for running rules against a request.
188- * @returns An {@link ArcjetDecision} indicating Arcjet's decision about the request.
277+ * @param request
278+ * Details about the {@linkcode ArcjetNestRequest} that Arcjet needs to make a
279+ * decision.
280+ * @param props
281+ * Additional properties required for running rules against a request.
282+ * @returns
283+ * Promise that resolves to an {@linkcode ArcjetDecision} indicating
284+ * Arcjet’s decision about the request.
189285 */
190286 protect (
191287 request : ArcjetNestRequest ,
@@ -195,11 +291,17 @@ export interface ArcjetNest<Props extends PlainObject = {}> {
195291 ) : Promise < ArcjetDecision > ;
196292
197293 /**
198- * Augments the client with another rule. Useful for varying rules based on
199- * criteria in your handler—e.g. different rate limit for logged in users.
294+ * Augment the client with another rule.
200295 *
201- * @param rule The rule to add to this execution.
202- * @returns An augmented {@link ArcjetNest} client.
296+ * Useful for varying rules based on criteria in your handler such as
297+ * different rate limit for logged in users.
298+ *
299+ * @template Rule
300+ * Type of rule.
301+ * @param rule
302+ * Rule to add to Arcjet.
303+ * @returns
304+ * Arcjet instance augmented with the given rule.
203305 */
204306 withRule < Rule extends Primitive | Product > (
205307 rule : Rule ,
@@ -405,7 +507,13 @@ function arcjet<
405507 return withClient ( aj ) ;
406508}
407509
510+ /**
511+ * Symbol for Arcjet.
512+ *
513+ * Used as a label of providers that should be available in other modules.
514+ */
408515export const ARCJET = Symbol ( "ARCJET" ) ;
516+
409517const ARCJET_OPTIONS = Symbol ( "ARCJET_OPTIONS" ) ;
410518const ARCJET_WITH_RULES = Symbol ( "ARCJET_WITH_RULES" ) ;
411519
@@ -446,9 +554,22 @@ function requestFromContext(context: ExecutionContext) {
446554 }
447555}
448556
557+ /**
558+ * Nest guard for the Arcjet Nest integration.
559+ *
560+ * See: <https://docs.nestjs.com/guards>.
561+ */
449562let ArcjetGuard = class ArcjetGuard implements CanActivate {
450563 aj : ArcjetNest < WithoutCustomProps > ;
451564
565+ /**
566+ * Create a Nest guard for the Arcjet.
567+ *
568+ * @param aj
569+ * Arcjet Nest integration.
570+ * @returns
571+ * Arcjet Nest guard.
572+ */
452573 constructor ( aj : ArcjetNest < WithoutCustomProps > ) {
453574 this . aj = aj ;
454575 }
@@ -484,12 +605,34 @@ let ArcjetGuard = class ArcjetGuard implements CanActivate {
484605ArcjetGuard = decorate ( [ param ( 0 , Inject ( ARCJET ) ) ] , ArcjetGuard ) ;
485606export { ArcjetGuard } ;
486607
608+ /**
609+ * Create Nest modules for the Arcjet Nest integration.
610+ *
611+ * See: <https://docs.nestjs.com/modules>.
612+ */
487613export class ArcjetModule {
614+ /**
615+ * Create a Nest module for the Arcjet Nest integration.
616+ *
617+ * You can pass your API key and any default rules that you want to apply to
618+ * every route.
619+ * This is usually in the `app.module.ts` file.
620+ *
621+ * @param options
622+ * Configuration (required).
623+ * @returns
624+ * Dynamic Nest module.
625+ */
488626 static forRoot <
489627 const Rules extends ( Primitive | Product ) [ ] ,
490628 const Characteristics extends readonly string [ ] ,
491629 > (
492630 options : ArcjetOptions < Rules , Characteristics > & {
631+ /**
632+ * Whether to make the module global-scoped (`boolean`, default: `false`).
633+ *
634+ * Global-scoped modules will be visible in all modules.
635+ */
493636 isGlobal ?: boolean | undefined ;
494637 } ,
495638 ) : DynamicModule {
@@ -514,13 +657,34 @@ export class ArcjetModule {
514657 exports : [ ARCJET ] ,
515658 } ;
516659 }
660+
661+ /**
662+ * Create a Nest module for the Arcjet Nest integration,
663+ * asynchronously.
664+ *
665+ * You can pass your API key and any default rules that you want to apply to
666+ * every route.
667+ * This is usually in the `app.module.ts` file.
668+ *
669+ * @param options
670+ * Configuration (required).
671+ * @returns
672+ * Dynamic Nest module.
673+ */
517674 static forRootAsync <
518675 const Rules extends ( Primitive | Product ) [ ] ,
519676 const Characteristics extends readonly string [ ] ,
520677 > (
521678 options : ConfigurableModuleAsyncOptions <
522679 ArcjetOptions < Rules , Characteristics >
523- > & { isGlobal ?: boolean | undefined } ,
680+ > & {
681+ /**
682+ * Whether to make the module global-scoped (`boolean`, default: `false`).
683+ *
684+ * Global-scoped modules will be visible in all modules.
685+ */
686+ isGlobal ?: boolean | undefined ;
687+ } ,
524688 ) : DynamicModule {
525689 const ArcjetProvider = {
526690 provide : ARCJET ,
@@ -582,6 +746,21 @@ export class ArcjetModule {
582746 }
583747}
584748
749+ /**
750+ * Decorator that binds Arcjet rules to the scope of the controller or method,
751+ * depending on its context.
752+ *
753+ * When `@WithArcjetRules` is used at the controller level,
754+ * the rules will be applied to every handler (method) in the controller.
755+ *
756+ * When `@WithArcjetRules` is used at the individual handler level,
757+ * the rules will apply only to that specific method.
758+ *
759+ * @param rules
760+ * List of rules.
761+ * @returns
762+ * Decorator.
763+ */
585764export function WithArcjetRules ( rules : Array < Primitive | Product > ) {
586765 return SetMetadata ( ARCJET_WITH_RULES , rules ) ;
587766}
0 commit comments