@forklaunch/core 0.17.2 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { UnionToIntersection, TypeSafeFunction, StringWithoutSlash, Prettify, MakePropertyOptionalIfChildrenOptional, SanitizePathSlashes } from '@forklaunch/common';
1
+ import { UnionToIntersection, TypeSafeFunction, StringWithoutSlash, Prettify, SanitizePathSlashes, MakePropertyOptionalIfChildrenOptional } from '@forklaunch/common';
2
2
  import { AnySchemaValidator, UnboxedObjectSchema, IdiomaticSchema, Schema } from '@forklaunch/validator';
3
3
  import { Counter, Gauge, Histogram, UpDownCounter, ObservableCounter, ObservableGauge, ObservableUpDownCounter, Span } from '@opentelemetry/api';
4
4
  import { JWTPayload, JWK } from 'jose';
@@ -247,6 +247,8 @@ type SchemaAuthMethods<SV extends AnySchemaValidator, ParamsSchema extends Param
247
247
  readonly requiredScope?: string;
248
248
  readonly scopeHeirarchy?: string[];
249
249
  readonly surfaceScopes?: ExpressLikeSchemaAuthMapper<SV, ParamsSchema, ReqBody, QuerySchema, ReqHeaders, VersionedApi, SessionObject<SV>, BaseRequest>;
250
+ readonly requiredFeatures?: string[];
251
+ readonly requireActiveSubscription?: boolean;
250
252
  } & ({
251
253
  readonly surfacePermissions?: ExpressLikeSchemaAuthMapper<SV, ParamsSchema, ReqBody, QuerySchema, ReqHeaders, VersionedApi, SessionObject<SV>, BaseRequest>;
252
254
  } | {
@@ -257,6 +259,8 @@ type AuthMethods<SV extends AnySchemaValidator, P extends ParamsDictionary, ReqB
257
259
  readonly requiredScope?: string;
258
260
  readonly scopeHeirarchy?: string[];
259
261
  readonly surfaceScopes?: ExpressLikeAuthMapper<SV, P, ReqBody, ReqQuery, ReqHeaders, VersionedReqs, SessionObject<SV>, BaseRequest>;
262
+ readonly requiredFeatures?: string[];
263
+ readonly requireActiveSubscription?: boolean;
260
264
  } & (({
261
265
  readonly surfacePermissions?: ExpressLikeAuthMapper<SV, P, ReqBody, ReqQuery, ReqHeaders, VersionedReqs, SessionObject<SV>, BaseRequest>;
262
266
  } & PermissionSet) | ({
@@ -416,16 +420,28 @@ type DocsConfiguration = ({
416
420
  type: 'swagger';
417
421
  };
418
422
 
423
+ /**
424
+ * Default subscription data structure.
425
+ * Applications can override this with their own subscription type.
426
+ */
427
+ type DefaultSubscriptionData = {
428
+ subscriptionId: string;
429
+ planId: string;
430
+ planName: string;
431
+ status: string;
432
+ currentPeriodEnd: Date;
433
+ } | null;
419
434
  /**
420
435
  * Options for global authentication in Express-like applications.
421
436
  *
422
437
  * @template SV - The schema validator type.
423
438
  * @template SessionSchema - The session schema type.
439
+ * @template SubscriptionData - The subscription data type (defaults to DefaultSubscriptionData, must extend Record<string, unknown> | null).
424
440
  *
425
441
  * Can be `false` to disable authentication, or an object specifying session schema and
426
- * functions to surface scopes, permissions, and roles from the JWT/session.
442
+ * functions to surface scopes, permissions, roles, subscription, and features from the JWT/session.
427
443
  */
428
- type ExpressLikeGlobalAuthOptions<SV extends AnySchemaValidator, SessionSchema extends Record<string, unknown>> = false | {
444
+ type ExpressLikeGlobalAuthOptions<SV extends AnySchemaValidator, SessionSchema extends Record<string, unknown>, SubscriptionData extends Record<string, unknown> | null = DefaultSubscriptionData> = false | {
429
445
  /**
430
446
  * Optional session schema for the authentication context.
431
447
  */
@@ -446,25 +462,37 @@ type ExpressLikeGlobalAuthOptions<SV extends AnySchemaValidator, SessionSchema e
446
462
  * Function to extract a set of roles from the JWT payload and request.
447
463
  */
448
464
  surfaceRoles?: (payload: JWTPayload & SessionSchema, req?: ForklaunchRequest<SV, Record<string, string>, Record<string, unknown>, Record<string, unknown>, Record<string, unknown>, string, SessionSchema>) => Set<string> | Promise<Set<string>>;
465
+ /**
466
+ * Function to extract subscription data from the JWT payload and request.
467
+ * Returns subscription information (status, plan, etc.) or null if no subscription.
468
+ */
469
+ surfaceSubscription?: (payload: JWTPayload & SessionSchema, req?: ForklaunchRequest<SV, Record<string, string>, Record<string, unknown>, Record<string, unknown>, Record<string, unknown>, string, SessionSchema>) => SubscriptionData | Promise<SubscriptionData>;
470
+ /**
471
+ * Function to extract a set of feature flags from the JWT payload and request.
472
+ * Returns features available to the organization based on their billing plan.
473
+ */
474
+ surfaceFeatures?: (payload: JWTPayload & SessionSchema, req?: ForklaunchRequest<SV, Record<string, string>, Record<string, unknown>, Record<string, unknown>, Record<string, unknown>, string, SessionSchema>) => Set<string> | Promise<Set<string>>;
449
475
  };
450
476
  /**
451
477
  * Schema-aware version of ExpressLikeGlobalAuthOptions.
452
478
  *
453
479
  * @template SV - The schema validator type.
454
480
  * @template SessionSchema - The session object type.
481
+ * @template SubscriptionData - The subscription data type.
455
482
  */
456
- type ExpressLikeSchemaGlobalAuthOptions<SV extends AnySchemaValidator, SessionSchema extends SessionObject<SV>> = ExpressLikeGlobalAuthOptions<SV, MapSessionSchema<SV, SessionSchema>>;
483
+ type ExpressLikeSchemaGlobalAuthOptions<SV extends AnySchemaValidator, SessionSchema extends SessionObject<SV>, SubscriptionData extends Record<string, unknown> | null = DefaultSubscriptionData> = ExpressLikeGlobalAuthOptions<SV, MapSessionSchema<SV, SessionSchema>, SubscriptionData>;
457
484
  /**
458
485
  * Options for configuring an Express-like router.
459
486
  *
460
487
  * @template SV - The schema validator type.
461
488
  * @template SessionSchema - The session object type.
489
+ * @template SubscriptionData - The subscription data type.
462
490
  */
463
- type ExpressLikeRouterOptions<SV extends AnySchemaValidator, SessionSchema extends SessionObject<SV>> = {
491
+ type ExpressLikeRouterOptions<SV extends AnySchemaValidator, SessionSchema extends SessionObject<SV>, SubscriptionData extends Record<string, unknown> | null = DefaultSubscriptionData> = {
464
492
  /**
465
493
  * Authentication options for the router.
466
494
  */
467
- auth?: ExpressLikeSchemaGlobalAuthOptions<SV, SessionSchema>;
495
+ auth?: ExpressLikeSchemaGlobalAuthOptions<SV, SessionSchema, SubscriptionData>;
468
496
  /**
469
497
  * Validation options for request and response.
470
498
  * Can be `false` to disable validation, or an object to configure request/response validation levels.
@@ -493,8 +521,9 @@ type ExpressLikeRouterOptions<SV extends AnySchemaValidator, SessionSchema exten
493
521
  *
494
522
  * @template SV - The schema validator type.
495
523
  * @template SessionSchema - The session object type.
524
+ * @template SubscriptionData - The subscription data type.
496
525
  */
497
- type ExpressLikeApplicationOptions<SV extends AnySchemaValidator, SessionSchema extends SessionObject<SV>> = Omit<ExpressLikeRouterOptions<SV, SessionSchema>, 'openapi' | 'mcp'> & {
526
+ type ExpressLikeApplicationOptions<SV extends AnySchemaValidator, SessionSchema extends SessionObject<SV>, SubscriptionData extends Record<string, unknown> | null = DefaultSubscriptionData> = Omit<ExpressLikeRouterOptions<SV, SessionSchema, SubscriptionData>, 'openapi' | 'mcp'> & {
498
527
  /**
499
528
  * Documentation configuration.
500
529
  */
@@ -1065,4 +1094,4 @@ type ResponseShape<Params, Headers, Query, Body> = {
1065
1094
  */
1066
1095
  type PathMatch<SuppliedPath extends `/${string}`, ActualPath extends `/${string}`> = ActualPath extends SuppliedPath ? SuppliedPath extends ActualPath ? SuppliedPath : never : never;
1067
1096
 
1068
- export { type MapReqBodySchema as $, type AuthMethodsBase as A, type Body as B, type ContractDetails as C, type DecodeResource as D, type ExpressLikeRouterOptions as E, type ForklaunchRequest as F, type ForklaunchBaseRequest as G, type HttpContractDetails as H, type ResolvedForklaunchRequest as I, type ResolvedForklaunchAuthRequest as J, type VersionedResponses as K, type LiveTypeFunction as L, type Method as M, type ResolvedForklaunchResponse as N, OpenTelemetryCollector as O, type PathParamHttpContractDetails as P, type QueryObject as Q, type ResponsesObject as R, type StringOnlyObject as S, type TelemetryOptions as T, type ExpressLikeHandler as U, type VersionSchema as V, type MapParamsSchema as W, type ExtractContentType as X, type ExtractResponseBody as Y, type MapResBodyMapSchema as Z, type ExtractBody as _, type SessionObject as a, type MapReqQuerySchema as a0, type MapReqHeadersSchema as a1, type MapResHeadersSchema as a2, type MapVersionedReqsSchema as a3, type MapVersionedRespsSchema as a4, type MapSessionSchema as a5, type ExpressLikeAuthMapper as a6, type LiveTypeFunctionRequestInit as a7, type ForklaunchResErrors as a8, type ErrorContainer as a9, type MetricType as aA, type ResponseShape as aa, type NumberOnlyObject as ab, type BodyObject as ac, type RawTypedResponseBody as ad, type TypedResponseBody as ae, type ResponseBody as af, type JsonBody as ag, type TextBody as ah, type FileBody as ai, type MultipartForm as aj, type UrlEncodedForm as ak, type ServerSentEventBody as al, type UnknownBody as am, type UnknownResponseBody as an, type TypedRequestBody as ao, type TypedBody as ap, type JwtAuthMethods as aq, type HmacMethods as ar, type MapSchema as as, type ExtractedParamsObject as at, type PathParamMethod as au, type HttpMethod as av, type ResponseCompiledSchema as aw, type DocsConfiguration as ax, type ExpressLikeGlobalAuthOptions as ay, type ExpressLikeSchemaGlobalAuthOptions as az, type ParamsObject as b, type HeadersObject as c, type SchemaAuthMethods as d, type ExpressLikeSchemaHandler as e, type ResolvedSessionObject as f, type PathMatch as g, type LiveSdkFunction as h, type MetricsDefinition as i, type ExpressLikeApplicationOptions as j, type ParamsDictionary as k, type VersionedRequests as l, type AuthMethods as m, type BasicAuthMethods as n, type MiddlewareContractDetails as o, type ExpressLikeSchemaAuthMapper as p, type ForklaunchNextFunction as q, type ForklaunchResponse as r, type ForklaunchResHeaders as s, type ForklaunchStatusResponse as t, type ForklaunchSendableData as u, type LoggerMeta as v, type LogFn as w, httpRequestsTotalCounter as x, httpServerDurationHistogram as y, type RequestContext as z };
1097
+ export { type ForklaunchResErrors as $, type AuthMethodsBase as A, type Body as B, type ContractDetails as C, type DecodeResource as D, type ExpressLikeRouterOptions as E, type ForklaunchRequest as F, type ErrorContainer as G, type HttpContractDetails as H, type ExpressLikeAuthMapper as I, type ExpressLikeGlobalAuthOptions as J, type ExpressLikeHandler as K, type LiveTypeFunction as L, type Method as M, type ExpressLikeSchemaGlobalAuthOptions as N, OpenTelemetryCollector as O, type PathParamHttpContractDetails as P, type QueryObject as Q, type ResponsesObject as R, type StringOnlyObject as S, type TelemetryOptions as T, type ExtractBody as U, type VersionSchema as V, type ExtractContentType as W, type ExtractResponseBody as X, type ExtractedParamsObject as Y, type FileBody as Z, type ForklaunchBaseRequest as _, type SessionObject as a, type HmacMethods as a0, type HttpMethod as a1, type JsonBody as a2, type JwtAuthMethods as a3, type LiveTypeFunctionRequestInit as a4, type MapParamsSchema as a5, type MapReqBodySchema as a6, type MapReqHeadersSchema as a7, type MapReqQuerySchema as a8, type MapResBodyMapSchema as a9, httpRequestsTotalCounter as aA, httpServerDurationHistogram as aB, type MapResHeadersSchema as aa, type MapSchema as ab, type MapSessionSchema as ac, type MapVersionedReqsSchema as ad, type MapVersionedRespsSchema as ae, type MetricType as af, type MultipartForm as ag, type NumberOnlyObject as ah, type PathParamMethod as ai, type RawTypedResponseBody as aj, type RequestContext as ak, type ResolvedForklaunchAuthRequest as al, type ResolvedForklaunchRequest as am, type ResolvedForklaunchResponse as an, type ResponseBody as ao, type ResponseCompiledSchema as ap, type ResponseShape as aq, type ServerSentEventBody as ar, type TextBody as as, type TypedBody as at, type TypedRequestBody as au, type TypedResponseBody as av, type UnknownBody as aw, type UnknownResponseBody as ax, type UrlEncodedForm as ay, type VersionedResponses as az, type ParamsObject as b, type HeadersObject as c, type SchemaAuthMethods as d, type ExpressLikeSchemaHandler as e, type ResolvedSessionObject as f, type PathMatch as g, type LiveSdkFunction as h, type MetricsDefinition as i, type ExpressLikeApplicationOptions as j, type ParamsDictionary as k, type VersionedRequests as l, type AuthMethods as m, type BasicAuthMethods as n, type MiddlewareContractDetails as o, type ExpressLikeSchemaAuthMapper as p, type ForklaunchNextFunction as q, type ForklaunchResponse as r, type ForklaunchResHeaders as s, type ForklaunchStatusResponse as t, type ForklaunchSendableData as u, type LoggerMeta as v, type LogFn as w, type BodyObject as x, type DefaultSubscriptionData as y, type DocsConfiguration as z };
@@ -1,4 +1,4 @@
1
- import { UnionToIntersection, TypeSafeFunction, StringWithoutSlash, Prettify, MakePropertyOptionalIfChildrenOptional, SanitizePathSlashes } from '@forklaunch/common';
1
+ import { UnionToIntersection, TypeSafeFunction, StringWithoutSlash, Prettify, SanitizePathSlashes, MakePropertyOptionalIfChildrenOptional } from '@forklaunch/common';
2
2
  import { AnySchemaValidator, UnboxedObjectSchema, IdiomaticSchema, Schema } from '@forklaunch/validator';
3
3
  import { Counter, Gauge, Histogram, UpDownCounter, ObservableCounter, ObservableGauge, ObservableUpDownCounter, Span } from '@opentelemetry/api';
4
4
  import { JWTPayload, JWK } from 'jose';
@@ -247,6 +247,8 @@ type SchemaAuthMethods<SV extends AnySchemaValidator, ParamsSchema extends Param
247
247
  readonly requiredScope?: string;
248
248
  readonly scopeHeirarchy?: string[];
249
249
  readonly surfaceScopes?: ExpressLikeSchemaAuthMapper<SV, ParamsSchema, ReqBody, QuerySchema, ReqHeaders, VersionedApi, SessionObject<SV>, BaseRequest>;
250
+ readonly requiredFeatures?: string[];
251
+ readonly requireActiveSubscription?: boolean;
250
252
  } & ({
251
253
  readonly surfacePermissions?: ExpressLikeSchemaAuthMapper<SV, ParamsSchema, ReqBody, QuerySchema, ReqHeaders, VersionedApi, SessionObject<SV>, BaseRequest>;
252
254
  } | {
@@ -257,6 +259,8 @@ type AuthMethods<SV extends AnySchemaValidator, P extends ParamsDictionary, ReqB
257
259
  readonly requiredScope?: string;
258
260
  readonly scopeHeirarchy?: string[];
259
261
  readonly surfaceScopes?: ExpressLikeAuthMapper<SV, P, ReqBody, ReqQuery, ReqHeaders, VersionedReqs, SessionObject<SV>, BaseRequest>;
262
+ readonly requiredFeatures?: string[];
263
+ readonly requireActiveSubscription?: boolean;
260
264
  } & (({
261
265
  readonly surfacePermissions?: ExpressLikeAuthMapper<SV, P, ReqBody, ReqQuery, ReqHeaders, VersionedReqs, SessionObject<SV>, BaseRequest>;
262
266
  } & PermissionSet) | ({
@@ -416,16 +420,28 @@ type DocsConfiguration = ({
416
420
  type: 'swagger';
417
421
  };
418
422
 
423
+ /**
424
+ * Default subscription data structure.
425
+ * Applications can override this with their own subscription type.
426
+ */
427
+ type DefaultSubscriptionData = {
428
+ subscriptionId: string;
429
+ planId: string;
430
+ planName: string;
431
+ status: string;
432
+ currentPeriodEnd: Date;
433
+ } | null;
419
434
  /**
420
435
  * Options for global authentication in Express-like applications.
421
436
  *
422
437
  * @template SV - The schema validator type.
423
438
  * @template SessionSchema - The session schema type.
439
+ * @template SubscriptionData - The subscription data type (defaults to DefaultSubscriptionData, must extend Record<string, unknown> | null).
424
440
  *
425
441
  * Can be `false` to disable authentication, or an object specifying session schema and
426
- * functions to surface scopes, permissions, and roles from the JWT/session.
442
+ * functions to surface scopes, permissions, roles, subscription, and features from the JWT/session.
427
443
  */
428
- type ExpressLikeGlobalAuthOptions<SV extends AnySchemaValidator, SessionSchema extends Record<string, unknown>> = false | {
444
+ type ExpressLikeGlobalAuthOptions<SV extends AnySchemaValidator, SessionSchema extends Record<string, unknown>, SubscriptionData extends Record<string, unknown> | null = DefaultSubscriptionData> = false | {
429
445
  /**
430
446
  * Optional session schema for the authentication context.
431
447
  */
@@ -446,25 +462,37 @@ type ExpressLikeGlobalAuthOptions<SV extends AnySchemaValidator, SessionSchema e
446
462
  * Function to extract a set of roles from the JWT payload and request.
447
463
  */
448
464
  surfaceRoles?: (payload: JWTPayload & SessionSchema, req?: ForklaunchRequest<SV, Record<string, string>, Record<string, unknown>, Record<string, unknown>, Record<string, unknown>, string, SessionSchema>) => Set<string> | Promise<Set<string>>;
465
+ /**
466
+ * Function to extract subscription data from the JWT payload and request.
467
+ * Returns subscription information (status, plan, etc.) or null if no subscription.
468
+ */
469
+ surfaceSubscription?: (payload: JWTPayload & SessionSchema, req?: ForklaunchRequest<SV, Record<string, string>, Record<string, unknown>, Record<string, unknown>, Record<string, unknown>, string, SessionSchema>) => SubscriptionData | Promise<SubscriptionData>;
470
+ /**
471
+ * Function to extract a set of feature flags from the JWT payload and request.
472
+ * Returns features available to the organization based on their billing plan.
473
+ */
474
+ surfaceFeatures?: (payload: JWTPayload & SessionSchema, req?: ForklaunchRequest<SV, Record<string, string>, Record<string, unknown>, Record<string, unknown>, Record<string, unknown>, string, SessionSchema>) => Set<string> | Promise<Set<string>>;
449
475
  };
450
476
  /**
451
477
  * Schema-aware version of ExpressLikeGlobalAuthOptions.
452
478
  *
453
479
  * @template SV - The schema validator type.
454
480
  * @template SessionSchema - The session object type.
481
+ * @template SubscriptionData - The subscription data type.
455
482
  */
456
- type ExpressLikeSchemaGlobalAuthOptions<SV extends AnySchemaValidator, SessionSchema extends SessionObject<SV>> = ExpressLikeGlobalAuthOptions<SV, MapSessionSchema<SV, SessionSchema>>;
483
+ type ExpressLikeSchemaGlobalAuthOptions<SV extends AnySchemaValidator, SessionSchema extends SessionObject<SV>, SubscriptionData extends Record<string, unknown> | null = DefaultSubscriptionData> = ExpressLikeGlobalAuthOptions<SV, MapSessionSchema<SV, SessionSchema>, SubscriptionData>;
457
484
  /**
458
485
  * Options for configuring an Express-like router.
459
486
  *
460
487
  * @template SV - The schema validator type.
461
488
  * @template SessionSchema - The session object type.
489
+ * @template SubscriptionData - The subscription data type.
462
490
  */
463
- type ExpressLikeRouterOptions<SV extends AnySchemaValidator, SessionSchema extends SessionObject<SV>> = {
491
+ type ExpressLikeRouterOptions<SV extends AnySchemaValidator, SessionSchema extends SessionObject<SV>, SubscriptionData extends Record<string, unknown> | null = DefaultSubscriptionData> = {
464
492
  /**
465
493
  * Authentication options for the router.
466
494
  */
467
- auth?: ExpressLikeSchemaGlobalAuthOptions<SV, SessionSchema>;
495
+ auth?: ExpressLikeSchemaGlobalAuthOptions<SV, SessionSchema, SubscriptionData>;
468
496
  /**
469
497
  * Validation options for request and response.
470
498
  * Can be `false` to disable validation, or an object to configure request/response validation levels.
@@ -493,8 +521,9 @@ type ExpressLikeRouterOptions<SV extends AnySchemaValidator, SessionSchema exten
493
521
  *
494
522
  * @template SV - The schema validator type.
495
523
  * @template SessionSchema - The session object type.
524
+ * @template SubscriptionData - The subscription data type.
496
525
  */
497
- type ExpressLikeApplicationOptions<SV extends AnySchemaValidator, SessionSchema extends SessionObject<SV>> = Omit<ExpressLikeRouterOptions<SV, SessionSchema>, 'openapi' | 'mcp'> & {
526
+ type ExpressLikeApplicationOptions<SV extends AnySchemaValidator, SessionSchema extends SessionObject<SV>, SubscriptionData extends Record<string, unknown> | null = DefaultSubscriptionData> = Omit<ExpressLikeRouterOptions<SV, SessionSchema, SubscriptionData>, 'openapi' | 'mcp'> & {
498
527
  /**
499
528
  * Documentation configuration.
500
529
  */
@@ -1065,4 +1094,4 @@ type ResponseShape<Params, Headers, Query, Body> = {
1065
1094
  */
1066
1095
  type PathMatch<SuppliedPath extends `/${string}`, ActualPath extends `/${string}`> = ActualPath extends SuppliedPath ? SuppliedPath extends ActualPath ? SuppliedPath : never : never;
1067
1096
 
1068
- export { type MapReqBodySchema as $, type AuthMethodsBase as A, type Body as B, type ContractDetails as C, type DecodeResource as D, type ExpressLikeRouterOptions as E, type ForklaunchRequest as F, type ForklaunchBaseRequest as G, type HttpContractDetails as H, type ResolvedForklaunchRequest as I, type ResolvedForklaunchAuthRequest as J, type VersionedResponses as K, type LiveTypeFunction as L, type Method as M, type ResolvedForklaunchResponse as N, OpenTelemetryCollector as O, type PathParamHttpContractDetails as P, type QueryObject as Q, type ResponsesObject as R, type StringOnlyObject as S, type TelemetryOptions as T, type ExpressLikeHandler as U, type VersionSchema as V, type MapParamsSchema as W, type ExtractContentType as X, type ExtractResponseBody as Y, type MapResBodyMapSchema as Z, type ExtractBody as _, type SessionObject as a, type MapReqQuerySchema as a0, type MapReqHeadersSchema as a1, type MapResHeadersSchema as a2, type MapVersionedReqsSchema as a3, type MapVersionedRespsSchema as a4, type MapSessionSchema as a5, type ExpressLikeAuthMapper as a6, type LiveTypeFunctionRequestInit as a7, type ForklaunchResErrors as a8, type ErrorContainer as a9, type MetricType as aA, type ResponseShape as aa, type NumberOnlyObject as ab, type BodyObject as ac, type RawTypedResponseBody as ad, type TypedResponseBody as ae, type ResponseBody as af, type JsonBody as ag, type TextBody as ah, type FileBody as ai, type MultipartForm as aj, type UrlEncodedForm as ak, type ServerSentEventBody as al, type UnknownBody as am, type UnknownResponseBody as an, type TypedRequestBody as ao, type TypedBody as ap, type JwtAuthMethods as aq, type HmacMethods as ar, type MapSchema as as, type ExtractedParamsObject as at, type PathParamMethod as au, type HttpMethod as av, type ResponseCompiledSchema as aw, type DocsConfiguration as ax, type ExpressLikeGlobalAuthOptions as ay, type ExpressLikeSchemaGlobalAuthOptions as az, type ParamsObject as b, type HeadersObject as c, type SchemaAuthMethods as d, type ExpressLikeSchemaHandler as e, type ResolvedSessionObject as f, type PathMatch as g, type LiveSdkFunction as h, type MetricsDefinition as i, type ExpressLikeApplicationOptions as j, type ParamsDictionary as k, type VersionedRequests as l, type AuthMethods as m, type BasicAuthMethods as n, type MiddlewareContractDetails as o, type ExpressLikeSchemaAuthMapper as p, type ForklaunchNextFunction as q, type ForklaunchResponse as r, type ForklaunchResHeaders as s, type ForklaunchStatusResponse as t, type ForklaunchSendableData as u, type LoggerMeta as v, type LogFn as w, httpRequestsTotalCounter as x, httpServerDurationHistogram as y, type RequestContext as z };
1097
+ export { type ForklaunchResErrors as $, type AuthMethodsBase as A, type Body as B, type ContractDetails as C, type DecodeResource as D, type ExpressLikeRouterOptions as E, type ForklaunchRequest as F, type ErrorContainer as G, type HttpContractDetails as H, type ExpressLikeAuthMapper as I, type ExpressLikeGlobalAuthOptions as J, type ExpressLikeHandler as K, type LiveTypeFunction as L, type Method as M, type ExpressLikeSchemaGlobalAuthOptions as N, OpenTelemetryCollector as O, type PathParamHttpContractDetails as P, type QueryObject as Q, type ResponsesObject as R, type StringOnlyObject as S, type TelemetryOptions as T, type ExtractBody as U, type VersionSchema as V, type ExtractContentType as W, type ExtractResponseBody as X, type ExtractedParamsObject as Y, type FileBody as Z, type ForklaunchBaseRequest as _, type SessionObject as a, type HmacMethods as a0, type HttpMethod as a1, type JsonBody as a2, type JwtAuthMethods as a3, type LiveTypeFunctionRequestInit as a4, type MapParamsSchema as a5, type MapReqBodySchema as a6, type MapReqHeadersSchema as a7, type MapReqQuerySchema as a8, type MapResBodyMapSchema as a9, httpRequestsTotalCounter as aA, httpServerDurationHistogram as aB, type MapResHeadersSchema as aa, type MapSchema as ab, type MapSessionSchema as ac, type MapVersionedReqsSchema as ad, type MapVersionedRespsSchema as ae, type MetricType as af, type MultipartForm as ag, type NumberOnlyObject as ah, type PathParamMethod as ai, type RawTypedResponseBody as aj, type RequestContext as ak, type ResolvedForklaunchAuthRequest as al, type ResolvedForklaunchRequest as am, type ResolvedForklaunchResponse as an, type ResponseBody as ao, type ResponseCompiledSchema as ap, type ResponseShape as aq, type ServerSentEventBody as ar, type TextBody as as, type TypedBody as at, type TypedRequestBody as au, type TypedResponseBody as av, type UnknownBody as aw, type UnknownResponseBody as ax, type UrlEncodedForm as ay, type VersionedResponses as az, type ParamsObject as b, type HeadersObject as c, type SchemaAuthMethods as d, type ExpressLikeSchemaHandler as e, type ResolvedSessionObject as f, type PathMatch as g, type LiveSdkFunction as h, type MetricsDefinition as i, type ExpressLikeApplicationOptions as j, type ParamsDictionary as k, type VersionedRequests as l, type AuthMethods as m, type BasicAuthMethods as n, type MiddlewareContractDetails as o, type ExpressLikeSchemaAuthMapper as p, type ForklaunchNextFunction as q, type ForklaunchResponse as r, type ForklaunchResHeaders as s, type ForklaunchStatusResponse as t, type ForklaunchSendableData as u, type LoggerMeta as v, type LogFn as w, type BodyObject as x, type DefaultSubscriptionData as y, type DocsConfiguration as z };
@@ -3,9 +3,9 @@ export { ParsedQs } from 'qs';
3
3
  import { Prettify, SanitizePathSlashes, PrettyCamelCase, TypeSafeFunction, UnionToIntersection, EmptyObject } from '@forklaunch/common';
4
4
  import { AnySchemaValidator } from '@forklaunch/validator';
5
5
  import { ServerOptions, IncomingMessage, ServerResponse } from 'node:http';
6
- import { M as Method, P as PathParamHttpContractDetails, H as HttpContractDetails, E as ExpressLikeRouterOptions, a as SessionObject, b as ParamsObject, R as ResponsesObject, B as Body, Q as QueryObject, c as HeadersObject, V as VersionSchema, d as SchemaAuthMethods, C as ContractDetails, e as ExpressLikeSchemaHandler, f as ResolvedSessionObject, g as PathMatch, L as LiveTypeFunction, h as LiveSdkFunction, A as AuthMethodsBase, O as OpenTelemetryCollector, i as MetricsDefinition, j as ExpressLikeApplicationOptions, k as ParamsDictionary, l as VersionedRequests, m as AuthMethods, D as DecodeResource, n as BasicAuthMethods, F as ForklaunchRequest, o as MiddlewareContractDetails, p as ExpressLikeSchemaAuthMapper, q as ForklaunchNextFunction, r as ForklaunchResponse, s as ForklaunchResHeaders, t as ForklaunchStatusResponse, u as ForklaunchSendableData, T as TelemetryOptions, v as LoggerMeta, w as LogFn } from '../apiDefinition.types-XZ0lrfFc.mjs';
7
- export { ac as BodyObject, ax as DocsConfiguration, a9 as ErrorContainer, a6 as ExpressLikeAuthMapper, ay as ExpressLikeGlobalAuthOptions, U as ExpressLikeHandler, az as ExpressLikeSchemaGlobalAuthOptions, _ as ExtractBody, X as ExtractContentType, Y as ExtractResponseBody, at as ExtractedParamsObject, ai as FileBody, G as ForklaunchBaseRequest, a8 as ForklaunchResErrors, ar as HmacMethods, av as HttpMethod, ag as JsonBody, aq as JwtAuthMethods, a7 as LiveTypeFunctionRequestInit, W as MapParamsSchema, $ as MapReqBodySchema, a1 as MapReqHeadersSchema, a0 as MapReqQuerySchema, Z as MapResBodyMapSchema, a2 as MapResHeadersSchema, as as MapSchema, a5 as MapSessionSchema, a3 as MapVersionedReqsSchema, a4 as MapVersionedRespsSchema, aA as MetricType, aj as MultipartForm, ab as NumberOnlyObject, au as PathParamMethod, ad as RawTypedResponseBody, z as RequestContext, J as ResolvedForklaunchAuthRequest, I as ResolvedForklaunchRequest, N as ResolvedForklaunchResponse, af as ResponseBody, aw as ResponseCompiledSchema, aa as ResponseShape, al as ServerSentEventBody, S as StringOnlyObject, ah as TextBody, ap as TypedBody, ao as TypedRequestBody, ae as TypedResponseBody, am as UnknownBody, an as UnknownResponseBody, ak as UrlEncodedForm, K as VersionedResponses, x as httpRequestsTotalCounter, y as httpServerDurationHistogram } from '../apiDefinition.types-XZ0lrfFc.mjs';
8
- import { JWK, JWTPayload } from 'jose';
6
+ import { M as Method, P as PathParamHttpContractDetails, H as HttpContractDetails, E as ExpressLikeRouterOptions, a as SessionObject, b as ParamsObject, R as ResponsesObject, B as Body, Q as QueryObject, c as HeadersObject, V as VersionSchema, d as SchemaAuthMethods, e as ExpressLikeSchemaHandler, f as ResolvedSessionObject, C as ContractDetails, g as PathMatch, L as LiveTypeFunction, h as LiveSdkFunction, A as AuthMethodsBase, O as OpenTelemetryCollector, i as MetricsDefinition, j as ExpressLikeApplicationOptions, k as ParamsDictionary, l as VersionedRequests, m as AuthMethods, D as DecodeResource, n as BasicAuthMethods, F as ForklaunchRequest, o as MiddlewareContractDetails, p as ExpressLikeSchemaAuthMapper, q as ForklaunchNextFunction, r as ForklaunchResponse, s as ForklaunchResHeaders, t as ForklaunchStatusResponse, u as ForklaunchSendableData, T as TelemetryOptions, v as LoggerMeta, w as LogFn } from '../apiDefinition.types-DnUkFmfT.mjs';
7
+ export { x as BodyObject, y as DefaultSubscriptionData, z as DocsConfiguration, G as ErrorContainer, I as ExpressLikeAuthMapper, J as ExpressLikeGlobalAuthOptions, K as ExpressLikeHandler, N as ExpressLikeSchemaGlobalAuthOptions, U as ExtractBody, W as ExtractContentType, X as ExtractResponseBody, Y as ExtractedParamsObject, Z as FileBody, _ as ForklaunchBaseRequest, $ as ForklaunchResErrors, a0 as HmacMethods, a1 as HttpMethod, a2 as JsonBody, a3 as JwtAuthMethods, a4 as LiveTypeFunctionRequestInit, a5 as MapParamsSchema, a6 as MapReqBodySchema, a7 as MapReqHeadersSchema, a8 as MapReqQuerySchema, a9 as MapResBodyMapSchema, aa as MapResHeadersSchema, ab as MapSchema, ac as MapSessionSchema, ad as MapVersionedReqsSchema, ae as MapVersionedRespsSchema, af as MetricType, ag as MultipartForm, ah as NumberOnlyObject, ai as PathParamMethod, aj as RawTypedResponseBody, ak as RequestContext, al as ResolvedForklaunchAuthRequest, am as ResolvedForklaunchRequest, an as ResolvedForklaunchResponse, ao as ResponseBody, ap as ResponseCompiledSchema, aq as ResponseShape, ar as ServerSentEventBody, S as StringOnlyObject, as as TextBody, at as TypedBody, au as TypedRequestBody, av as TypedResponseBody, aw as UnknownBody, ax as UnknownResponseBody, ay as UrlEncodedForm, az as VersionedResponses, aA as httpRequestsTotalCounter, aB as httpServerDurationHistogram } from '../apiDefinition.types-DnUkFmfT.mjs';
8
+ import { JWTPayload, JWK } from 'jose';
9
9
  import { ZodSchemaValidator } from '@forklaunch/validator/zod';
10
10
  import { FastMCP } from 'fastmcp';
11
11
  import http from 'http';
@@ -3,9 +3,9 @@ export { ParsedQs } from 'qs';
3
3
  import { Prettify, SanitizePathSlashes, PrettyCamelCase, TypeSafeFunction, UnionToIntersection, EmptyObject } from '@forklaunch/common';
4
4
  import { AnySchemaValidator } from '@forklaunch/validator';
5
5
  import { ServerOptions, IncomingMessage, ServerResponse } from 'node:http';
6
- import { M as Method, P as PathParamHttpContractDetails, H as HttpContractDetails, E as ExpressLikeRouterOptions, a as SessionObject, b as ParamsObject, R as ResponsesObject, B as Body, Q as QueryObject, c as HeadersObject, V as VersionSchema, d as SchemaAuthMethods, C as ContractDetails, e as ExpressLikeSchemaHandler, f as ResolvedSessionObject, g as PathMatch, L as LiveTypeFunction, h as LiveSdkFunction, A as AuthMethodsBase, O as OpenTelemetryCollector, i as MetricsDefinition, j as ExpressLikeApplicationOptions, k as ParamsDictionary, l as VersionedRequests, m as AuthMethods, D as DecodeResource, n as BasicAuthMethods, F as ForklaunchRequest, o as MiddlewareContractDetails, p as ExpressLikeSchemaAuthMapper, q as ForklaunchNextFunction, r as ForklaunchResponse, s as ForklaunchResHeaders, t as ForklaunchStatusResponse, u as ForklaunchSendableData, T as TelemetryOptions, v as LoggerMeta, w as LogFn } from '../apiDefinition.types-XZ0lrfFc.js';
7
- export { ac as BodyObject, ax as DocsConfiguration, a9 as ErrorContainer, a6 as ExpressLikeAuthMapper, ay as ExpressLikeGlobalAuthOptions, U as ExpressLikeHandler, az as ExpressLikeSchemaGlobalAuthOptions, _ as ExtractBody, X as ExtractContentType, Y as ExtractResponseBody, at as ExtractedParamsObject, ai as FileBody, G as ForklaunchBaseRequest, a8 as ForklaunchResErrors, ar as HmacMethods, av as HttpMethod, ag as JsonBody, aq as JwtAuthMethods, a7 as LiveTypeFunctionRequestInit, W as MapParamsSchema, $ as MapReqBodySchema, a1 as MapReqHeadersSchema, a0 as MapReqQuerySchema, Z as MapResBodyMapSchema, a2 as MapResHeadersSchema, as as MapSchema, a5 as MapSessionSchema, a3 as MapVersionedReqsSchema, a4 as MapVersionedRespsSchema, aA as MetricType, aj as MultipartForm, ab as NumberOnlyObject, au as PathParamMethod, ad as RawTypedResponseBody, z as RequestContext, J as ResolvedForklaunchAuthRequest, I as ResolvedForklaunchRequest, N as ResolvedForklaunchResponse, af as ResponseBody, aw as ResponseCompiledSchema, aa as ResponseShape, al as ServerSentEventBody, S as StringOnlyObject, ah as TextBody, ap as TypedBody, ao as TypedRequestBody, ae as TypedResponseBody, am as UnknownBody, an as UnknownResponseBody, ak as UrlEncodedForm, K as VersionedResponses, x as httpRequestsTotalCounter, y as httpServerDurationHistogram } from '../apiDefinition.types-XZ0lrfFc.js';
8
- import { JWK, JWTPayload } from 'jose';
6
+ import { M as Method, P as PathParamHttpContractDetails, H as HttpContractDetails, E as ExpressLikeRouterOptions, a as SessionObject, b as ParamsObject, R as ResponsesObject, B as Body, Q as QueryObject, c as HeadersObject, V as VersionSchema, d as SchemaAuthMethods, e as ExpressLikeSchemaHandler, f as ResolvedSessionObject, C as ContractDetails, g as PathMatch, L as LiveTypeFunction, h as LiveSdkFunction, A as AuthMethodsBase, O as OpenTelemetryCollector, i as MetricsDefinition, j as ExpressLikeApplicationOptions, k as ParamsDictionary, l as VersionedRequests, m as AuthMethods, D as DecodeResource, n as BasicAuthMethods, F as ForklaunchRequest, o as MiddlewareContractDetails, p as ExpressLikeSchemaAuthMapper, q as ForklaunchNextFunction, r as ForklaunchResponse, s as ForklaunchResHeaders, t as ForklaunchStatusResponse, u as ForklaunchSendableData, T as TelemetryOptions, v as LoggerMeta, w as LogFn } from '../apiDefinition.types-DnUkFmfT.js';
7
+ export { x as BodyObject, y as DefaultSubscriptionData, z as DocsConfiguration, G as ErrorContainer, I as ExpressLikeAuthMapper, J as ExpressLikeGlobalAuthOptions, K as ExpressLikeHandler, N as ExpressLikeSchemaGlobalAuthOptions, U as ExtractBody, W as ExtractContentType, X as ExtractResponseBody, Y as ExtractedParamsObject, Z as FileBody, _ as ForklaunchBaseRequest, $ as ForklaunchResErrors, a0 as HmacMethods, a1 as HttpMethod, a2 as JsonBody, a3 as JwtAuthMethods, a4 as LiveTypeFunctionRequestInit, a5 as MapParamsSchema, a6 as MapReqBodySchema, a7 as MapReqHeadersSchema, a8 as MapReqQuerySchema, a9 as MapResBodyMapSchema, aa as MapResHeadersSchema, ab as MapSchema, ac as MapSessionSchema, ad as MapVersionedReqsSchema, ae as MapVersionedRespsSchema, af as MetricType, ag as MultipartForm, ah as NumberOnlyObject, ai as PathParamMethod, aj as RawTypedResponseBody, ak as RequestContext, al as ResolvedForklaunchAuthRequest, am as ResolvedForklaunchRequest, an as ResolvedForklaunchResponse, ao as ResponseBody, ap as ResponseCompiledSchema, aq as ResponseShape, ar as ServerSentEventBody, S as StringOnlyObject, as as TextBody, at as TypedBody, au as TypedRequestBody, av as TypedResponseBody, aw as UnknownBody, ax as UnknownResponseBody, ay as UrlEncodedForm, az as VersionedResponses, aA as httpRequestsTotalCounter, aB as httpServerDurationHistogram } from '../apiDefinition.types-DnUkFmfT.js';
8
+ import { JWTPayload, JWK } from 'jose';
9
9
  import { ZodSchemaValidator } from '@forklaunch/validator/zod';
10
10
  import { FastMCP } from 'fastmcp';
11
11
  import http from 'http';
package/lib/http/index.js CHANGED
@@ -502,6 +502,11 @@ async function discriminateAuthMethod(auth, openTelemetryCollector) {
502
502
  return authMethod;
503
503
  }
504
504
 
505
+ // src/http/guards/hasFeatureChecks.ts
506
+ function hasFeatureChecks(maybeFeatureAuth) {
507
+ return typeof maybeFeatureAuth === "object" && maybeFeatureAuth !== null && "requiredFeatures" in maybeFeatureAuth && Array.isArray(maybeFeatureAuth.requiredFeatures) && maybeFeatureAuth.requiredFeatures.length > 0;
508
+ }
509
+
505
510
  // src/http/guards/hasPermissionChecks.ts
506
511
  function hasPermissionChecks(maybePermissionedAuth) {
507
512
  return typeof maybePermissionedAuth === "object" && maybePermissionedAuth !== null && ("allowedPermissions" in maybePermissionedAuth || "forbiddenPermissions" in maybePermissionedAuth);
@@ -517,6 +522,11 @@ function hasScopeChecks(maybePermissionedAuth) {
517
522
  return typeof maybePermissionedAuth === "object" && maybePermissionedAuth !== null && "requiredScope" in maybePermissionedAuth && maybePermissionedAuth.requiredScope != null;
518
523
  }
519
524
 
525
+ // src/http/guards/hasSubscriptionChecks.ts
526
+ function hasSubscriptionChecks(maybeSubscriptionAuth) {
527
+ return typeof maybeSubscriptionAuth === "object" && maybeSubscriptionAuth !== null && "requireActiveSubscription" in maybeSubscriptionAuth && maybeSubscriptionAuth.requireActiveSubscription === true;
528
+ }
529
+
520
530
  // src/http/telemetry/pinoLogger.ts
521
531
  var import_common5 = require("@forklaunch/common");
522
532
  var import_api2 = require("@opentelemetry/api");
@@ -699,6 +709,14 @@ var invalidAuthorizationTokenRoles = [
699
709
  403,
700
710
  "Invalid Authorization roles."
701
711
  ];
712
+ var invalidAuthorizationTokenFeatures = [
713
+ 403,
714
+ "Required features not available."
715
+ ];
716
+ var invalidAuthorizationSubscription = [
717
+ 403,
718
+ "Active subscription required."
719
+ ];
702
720
  var invalidAuthorizationToken = [
703
721
  403,
704
722
  "Invalid Authorization token."
@@ -906,6 +924,34 @@ async function checkAuthorizationToken(req, authorizationMethod, authorizationTo
906
924
  } else {
907
925
  return invalidAuthorizationMethod;
908
926
  }
927
+ if (hasSubscriptionChecks(collapsedAuthorizationMethod)) {
928
+ if (!collapsedAuthorizationMethod.surfaceSubscription) {
929
+ return [500, "No subscription surfacing function provided."];
930
+ }
931
+ const subscription = await collapsedAuthorizationMethod.surfaceSubscription(
932
+ sessionPayload,
933
+ req
934
+ );
935
+ if (!subscription) {
936
+ return invalidAuthorizationSubscription;
937
+ }
938
+ }
939
+ if (hasFeatureChecks(collapsedAuthorizationMethod)) {
940
+ if (!collapsedAuthorizationMethod.surfaceFeatures) {
941
+ return [500, "No features surfacing function provided."];
942
+ }
943
+ const availableFeatures = await collapsedAuthorizationMethod.surfaceFeatures(
944
+ sessionPayload,
945
+ req
946
+ );
947
+ const requiredFeatures = collapsedAuthorizationMethod.requiredFeatures ?? [];
948
+ const missingFeatures = requiredFeatures.filter(
949
+ (feature) => !availableFeatures.has(feature)
950
+ );
951
+ if (missingFeatures.length > 0) {
952
+ return invalidAuthorizationTokenFeatures;
953
+ }
954
+ }
909
955
  }
910
956
  async function parseRequestAuth(req, res, next) {
911
957
  const auth = req.contractDetails.auth;
@@ -1391,7 +1437,8 @@ function resolveRouteMiddlewares(params) {
1391
1437
  params.requestSchema,
1392
1438
  params.responseSchemas,
1393
1439
  params.openTelemetryCollector,
1394
- () => params.routerOptions
1440
+ // Use dynamic lookup from router instance instead of captured params
1441
+ () => params.router ? params.router.routerOptions : params.routerOptions
1395
1442
  ),
1396
1443
  ...params.postEnrichMiddleware,
1397
1444
  parse,
@@ -1667,7 +1714,8 @@ var ForklaunchExpressLikeRouter = class _ForklaunchExpressLikeRouter {
1667
1714
  routerOptions: this.routerOptions,
1668
1715
  postEnrichMiddleware: this.postEnrichMiddleware,
1669
1716
  includeCreateContext: false,
1670
- handlers
1717
+ handlers,
1718
+ router: this
1671
1719
  });
1672
1720
  registrationMethod.bind(this.internal)(
1673
1721
  path,