Changes so that I don't have to change the OAuthApp class if I change the custom claims next time (the types should just work automatically)
All checks were successful
Publish to Private NPM Registry / publish (push) Successful in 33s

This commit is contained in:
Alan Bridgeman 2026-01-29 11:57:17 -06:00
parent 7d2397966f
commit 90168f0858

View file

@ -14,7 +14,7 @@ import type { AppSubscriptionTier } from './types/AppSubscriptionTier.js';
import type { Addon } from './types/addons/Addon.js'; import type { Addon } from './types/addons/Addon.js';
import type { Webhook } from './types/Webhook.js'; import type { Webhook } from './types/Webhook.js';
type OAuthAppOptions = { interface BasicOAuthAppOptions {
// ------------------ // ------------------
// Basic app metadata // Basic app metadata
// ------------------ // ------------------
@ -23,7 +23,7 @@ type OAuthAppOptions = {
baseAppUrl?: URL, baseAppUrl?: URL,
/** The abbreviation of the app */ /** The abbreviation of the app */
appAbbrv?: string, //appAbbrv?: string,
/** The (potentially localized) name of the app */ /** The (potentially localized) name of the app */
appName?: string | { appName?: string | {
@ -82,27 +82,30 @@ type OAuthAppOptions = {
// ------------------------------ // ------------------------------
/** The webhooks supported by the app */ /** The webhooks supported by the app */
webhooks?: Webhook[], //webhooks?: Webhook[],
// ------------------------------------------ // ------------------------------------------
// Purchasable Stuff (Subscriptions + Addons) // Purchasable Stuff (Subscriptions + Addons)
// ------------------------------------------ // ------------------------------------------
/** If a subscription is required */ /** If a subscription is required */
subscriptionRequired?: boolean, //subscriptionRequired?: boolean,
/** The subscription tiers available for the app */ /** The subscription tiers available for the app */
subscriptionTiers?: AppSubscriptionTier[], //subscriptionTiers?: AppSubscriptionTier[],
/** Addons offered by the app */ /** Addons offered by the app */
addons?: Addon[], //addons?: Addon[],
}; };
type OAuthAppOptions<T extends BridgemanAccessibleAppClaims> = T & BasicOAuthAppOptions;
export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims> extends App { export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims> extends App {
private onAuth: OnAuthCallback; private onAuth: OnAuthCallback;
private saveSecret: (secret: string) => void | Promise<void>; private saveSecret: (secret: string) => void | Promise<void>;
private baseAppUrl?: URL; private options: OAuthAppOptions<TCustomClaims>;
/*private baseAppUrl?: URL;
private appAbbrv?: string; private appAbbrv?: string;
private appName?: string | { [language: string]: string }; private appName?: string | { [language: string]: string };
private contacts?: string[]; private contacts?: string[];
@ -118,7 +121,7 @@ export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims> extend
private webhooks?: Webhook[]; private webhooks?: Webhook[];
private subscriptionRequired?: boolean; private subscriptionRequired?: boolean;
private subscriptionTiers?: AppSubscriptionTier[]; private subscriptionTiers?: AppSubscriptionTier[];
private addons?: Addon[]; private addons?: Addon[];*/
private client: Client<TCustomClaims>; private client: Client<TCustomClaims>;
@ -169,13 +172,14 @@ export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims> extend
constructor( constructor(
onAuth: OnAuthCallback, onAuth: OnAuthCallback,
saveSecret: (secret: string) => void | Promise<void>, saveSecret: (secret: string) => void | Promise<void>,
options?: OAuthAppOptions options?: OAuthAppOptions<TCustomClaims>
) { ) {
super(); super();
this.onAuth = onAuth; this.onAuth = onAuth;
this.saveSecret = saveSecret; this.saveSecret = saveSecret;
this.options = options ?? {} as OAuthAppOptions<TCustomClaims>;
if(typeof options !== 'undefined') { /*if(typeof options !== 'undefined') {
this.baseAppUrl = options.baseAppUrl; this.baseAppUrl = options.baseAppUrl;
this.appAbbrv = options.appAbbrv; this.appAbbrv = options.appAbbrv;
this.appName = options.appName; this.appName = options.appName;
@ -193,7 +197,7 @@ export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims> extend
this.subscriptionRequired = options.subscriptionRequired; this.subscriptionRequired = options.subscriptionRequired;
this.subscriptionTiers = options.subscriptionTiers; this.subscriptionTiers = options.subscriptionTiers;
this.addons = options.addons; this.addons = options.addons;
} }*/
} }
/** Returns the OAuthApp's Client instance (which is useful for managing keys, creating resource request, etc...) */ /** Returns the OAuthApp's Client instance (which is useful for managing keys, creating resource request, etc...) */
@ -211,18 +215,18 @@ export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims> extend
*/ */
private async setupOAuthClient(app: App) { private async setupOAuthClient(app: App) {
// If the base URL of the app isn't provided, get it from the environment variable // If the base URL of the app isn't provided, get it from the environment variable
let baseAppUrl = this.baseAppUrl; let baseAppUrl = this.options.baseAppUrl;
if(typeof baseAppUrl === 'undefined') { if(typeof baseAppUrl === 'undefined') {
baseAppUrl = new URL(getValueFromEnvironmentVariable('BASE_APP_URL', { description: 'app\'s base URL', blank_allowed: false })); baseAppUrl = new URL(getValueFromEnvironmentVariable('BASE_APP_URL', { description: 'app\'s base URL', blank_allowed: false }));
} }
// The app abbreviation (used for user properties associated with the app) // The app abbreviation (used for user properties associated with the app)
let appAbbrv = this.appAbbrv; let appAbbrv = this.options.client_abbreviation;
if(typeof appAbbrv === 'undefined') { if(typeof appAbbrv === 'undefined') {
appAbbrv = getValueFromEnvironmentVariable('APP_ABBRV', { description: 'app abbreviation', blank_allowed: false }); appAbbrv = getValueFromEnvironmentVariable('APP_ABBRV', { description: 'app abbreviation', blank_allowed: false });
} }
logMessage(`Attempting to create/register the app:\n\tApp Base URL: ${baseAppUrl}\n\tApp Abbreviation: ${appAbbrv}\n\tApp Name: ${typeof this.appName === 'undefined' ? 'uses APP_NAME environment variable (' + process.env.APP_NAME + ')' : this.appName}\n\tScopes: ${typeof this.scopes === 'undefined' ? 'uses SCOPES environment variable (' + process.env.SCOPES + ')' : this.scopes.join(', ')}`, LogLevel.DEBUG); logMessage(`Attempting to create/register the app:\n\tApp Base URL: ${baseAppUrl}\n\tApp Abbreviation: ${appAbbrv}\n\tApp Name: ${typeof this.options.appName === 'undefined' ? 'uses APP_NAME environment variable (' + process.env.APP_NAME + ')' : this.options.appName}\n\tScopes: ${typeof this.options.scopes === 'undefined' ? 'uses SCOPES environment variable (' + process.env.SCOPES + ')' : this.options.scopes.join(', ')}`, LogLevel.DEBUG);
// Because we need this for registration to work properly. It make sense to put it here // Because we need this for registration to work properly. It make sense to put it here
app.getInitializer() app.getInitializer()
@ -236,23 +240,23 @@ export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims> extend
this.saveSecret, this.saveSecret,
{ {
client_abbreviation: appAbbrv, client_abbreviation: appAbbrv,
subscription_required: this.subscriptionRequired ?? false, subscription_required: this.options.subscriptionRequired ?? false,
subscription_tiers: this.subscriptionTiers, subscription_tiers: this.options.subscriptionTiers,
addons: this.addons, addons: this.options.addons,
webhooks: this.webhooks webhooks: this.options.webhooks
} as TCustomClaims, } as TCustomClaims,
this.appName, this.options.appName,
this.scopes, this.options.scopes,
{ {
contacts: this.contacts, contacts: this.options.contacts,
logo_url: this.logo_url, logo_url: this.options.logo_url,
tos_url: this.tos_url, tos_url: this.options.tos_url,
policy_url: this.policy_url, policy_url: this.options.policy_url,
vault_type: this.vault_type, vault_type: this.options.vault_type,
auth_default_method: this.auth_default_method, auth_default_method: this.options.auth_default_method,
auth_default_use_JWT: this.auth_default_use_JWT, auth_default_use_JWT: this.options.auth_default_use_JWT,
auth_default_response_mode: this.auth_default_response_mode, auth_default_response_mode: this.options.auth_default_response_mode,
client_secret: this.client_secret client_secret: this.options.client_secret
} }
); );