JSPM

@bhanudeep/tenant-manager

1.0.5
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 6
  • Score
    100M100P100Q33054F
  • License ISC

Framework-agnostic tenant configuration manager with Angular, React, and Vue integrations

Package Exports

  • @bhanudeep/tenant-manager
  • @bhanudeep/tenant-manager/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@bhanudeep/tenant-manager) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Tenant Manager

A framework-agnostic tenant configuration manager with integrations for Angular, React, and Vue.

Features

  • 🚀 Framework-agnostic core with framework-specific integrations
  • 🎨 Manage tenant-specific assets, styles, and configurations
  • 🌐 Support for sub-tenants
  • 📱 Dynamic UI theming based on tenant
  • 🛠️ Easy customization and extension

Installation

npm install @bhanudeep/tenant-manager

Usage

Core Usage (Framework Agnostic)

import { TenantConfigService } from '@bhanudeep/tenant-manager';

// Create instance
const tenantService = new TenantConfigService();

// Initialize tenant
tenantService.initializeTenant('Privilege_Dufry', 'alipay', 'https://api.example.com')
  .then(config => {
    console.log('Tenant initialized:', config);
  });

// Get asset path
const logoPath = tenantService.getAssetPath('partnerLogo');

Angular Integration

// app.module.ts
import { TenantConfigModule, TENANT_CONFIG_OPTIONS } from '@bhanudeep/tenant-manager/frameworks/angular';

@NgModule({
  imports: [
    // Use the forRoot method for configuring TenantConfigService
    TenantConfigModule.forRoot({
      // Optional: pass your configuration
      assetMapping: {
        // Your custom asset mapping
      }
    })
  ]
})
export class AppModule { }

// app-initializer.service.ts
import { Injectable } from '@angular/core';
import { TenantConfigService } from '@bhanudeep/tenant-manager/frameworks/angular';
import { SettingsProviderService } from './settings-provider.service';

@Injectable({
  providedIn: 'root'
})
export class AppInitializerService {
  constructor(
    private settingsProviderService: SettingsProviderService,
    private tenantConfigService: TenantConfigService
  ) {}

  async initializeApp(): Promise<any> {
    await this.settingsProviderService.loadConfig();
    
    // Get tenant code from session storage
    let redemptionPartnerCode = sessionStorage.getItem('RedemptionPartnerCode') || '';
    let subTenantId = sessionStorage.getItem('tenant') || undefined;
    
    // Get k8sUrl from settings provider
    const k8sUrl = this.settingsProviderService.configuration?.k8surl;
    
    // Initialize tenant (using Promise version)
    return await this.tenantConfigService.initializeTenant(
      redemptionPartnerCode, 
      subTenantId, 
      k8sUrl
    );
    
    // Or using Observable version (with proper $ suffix naming convention)
    // return await this.tenantConfigService.initializeTenant$(
    //   redemptionPartnerCode, 
    //   subTenantId, 
    //   k8sUrl
    // ).toPromise();
  }
}

// In components, access the Angular-specific observables
import { Component } from '@angular/core';
import { TenantConfigService } from '@bhanudeep/tenant-manager/frameworks/angular';

@Component({
  selector: 'app-tenant-display',
  template: `
    <div>Current tenant: {{ currentTenant | async }}</div>
    <div *ngIf="currentSubTenant | async">
      Current sub-tenant: {{ currentSubTenant | async }}
    </div>
    <img [src]="logoPath">
  `
})
export class TenantDisplayComponent {
  // Use the Angular-specific observables for template binding
  currentTenant = this.tenantService.angularCurrentTenant$;
  currentSubTenant = this.tenantService.angularCurrentSubTenant$;
  logoPath: string;

  constructor(private tenantService: TenantConfigService) {
    this.logoPath = this.tenantService.getAssetPath('partnerLogo');
  }
}

React Integration

import { TenantProvider, useTenant } from '@bhanudeep/tenant-manager/frameworks/react';

// Wrap your app with the provider
function App() {
  return (
    <TenantProvider 
      initialTenant="Privilege_Dufry" 
      initialSubTenant="alipay"
      k8sUrl="https://api.example.com"
    >
      <YourApp />
    </TenantProvider>
  );
}

// Use the tenant hook in components
function TenantAwareLogo() {
  const { getAssetPath } = useTenant();
  
  return <img src={getAssetPath('partnerLogo')} alt="Partner logo" />;
}

Vue Integration

<script setup>
import { useTenant } from '@bhanudeep/tenant-manager/frameworks/vue';

const { 
  currentTenant, 
  currentSubTenant, 
  getAssetPath, 
  initializeTenant 
} = useTenant(
  undefined,  // options
  'Privilege_Dufry',  // initialTenant
  'alipay',  // initialSubTenant
  'https://api.example.com'  // k8sUrl
);
</script>

<template>
  <div>
    <h1>Current Tenant: {{ currentTenant }}</h1>
    <img :src="getAssetPath('partnerLogo')" alt="Partner logo" />
  </div>
</template>

Customizing Asset Mappings

You can add or update tenant asset mappings:

const tenantService = new TenantConfigService();

// Add a new tenant
tenantService.addTenant('NewTenant', {
  welcomeImg: 'assets/tenants/NewTenant/images/welcome.png',
  partnerLogo: 'assets/tenants/NewTenant/images/logo.png',
  mode: 'NewTenant-mode',
  // ...other asset paths
});

// Add a sub-tenant
tenantService.addSubTenant('NewTenant', 'special', {
  welcomeImg: 'assets/tenants/NewTenant/special/images/welcome.png',
  partnerLogo: 'assets/tenants/NewTenant/special/images/logo.png',
  mode: 'NewTenant-special-mode',
  // ...other asset paths
});

API Reference

TenantConfigService

The core service for managing tenant configurations.

Methods

Method Description
initializeTenant(redemptionPartnerCode, subTenantId?, k8sUrl?) Initialize a tenant configuration
fetchTenantConfigFromAPI(redemptionPartnerCode, k8sUrl?, subTenantId?) Fetch tenant configuration from API
getConfig(key) Get a configuration value
getAssetPath(assetKey, tenant?, subTenant?) Get an asset path
addTenant(tenantId, mapping) Add a new tenant
addSubTenant(tenantId, subTenantId, mapping) Add a sub-tenant to an existing tenant
isValidTenant(tenantId) Check if a tenant is valid
isValidSubTenant(tenantId, subTenantId) Check if a sub-tenant is valid
getCurrentTenant() Get the current tenant ID
getCurrentSubTenant() Get the current sub-tenant ID

License

ISC