@omeron/ota-bre-html-widget (1.0.0)

Published 2026-04-16 17:05:54 +00:00 by omeron-admin

Installation

@omeron:registry=
npm install @omeron/ota-bre-html-widget@1.0.0
"@omeron/ota-bre-html-widget": "1.0.0"

About this package

OTA BRE HTML Widget

🚀 Lightweight JavaScript widget for displaying OTA Business Rules Engine data on any website using a public API key.

No framework required • 5KB minified • Zero dependencies • Works everywhere

Features

Zero Dependencies - Pure vanilla JavaScript
Tiny Size - Only 5KB minified
Universal - Works with any HTML page, CMS, or framework
API Key Auth - Secure public data access
Pre-built Components - Rules table, partners list, domain info
Customizable - Easy to style and extend
XSS Safe - Built-in HTML escaping

Quick Start

1. Include the Script

<!-- CDN (recommended) -->
<script src="https://cdn.omeron.co/ota-bre-widget/1.0.0/ota-bre-widget.min.js"></script>

<!-- Or download and host locally -->
<script src="path/to/ota-bre-widget.min.js"></script>

2. Initialize Widget

<div id="rules-display"></div>

<script>
  // Initialize
  var widget = new OtaBreWidget({
    apiUrl: 'http://localhost:8081/api',
    apiKey: 'YOUR_PUBLIC_API_KEY',
    domainId: 'YOUR_DOMAIN_ID'
  });

  // Load default styles
  widget.loadStyles();

  // Render rules table
  widget.renderRulesTable('rules-display');
</script>

That's it! Your rules are now displayed on the page.

Installation

Option 1: Direct Download

Download ota-bre-widget.min.js from the dist/ folder and include it in your HTML:

<script src="ota-bre-widget.min.js"></script>

Option 2: NPM (for build tools)

npm install @omeron/ota-bre-html-widget

Option 3: CDN

<script src="https://cdn.omeron.co/ota-bre-widget/1.0.0/ota-bre-widget.min.js"></script>

Getting Your API Key

  1. Log in to OTA BRE Admin Panel
  2. Navigate to Settings → API Keys
  3. Click Generate Public API Key
  4. Copy the key and use it in your widget configuration

Note: Public API keys only allow read access to public data. They cannot modify rules or access sensitive information.

API Reference

Constructor

var widget = new OtaBreWidget(config);

Config Options:

Option Type Required Description
apiUrl string Base API URL (e.g., http://localhost:8081/api)
apiKey string Your public API key
domainId string ⚠️ Domain ID (required for domain-scoped endpoints)

Methods

Data Fetching

// Get domain information
widget.getDomainInfo()
  .then(domain => console.log(domain));

// Get rules with pagination
widget.getRules({ page: 0, size: 20 })
  .then(response => console.log(response.content));

// Get partners
widget.getPartners({ page: 0, size: 100 })
  .then(response => console.log(response.content));

// Get location groups
widget.getLocationGroups()
  .then(groups => console.log(groups));

// Get carrier groups
widget.getCarrierGroups()
  .then(groups => console.log(groups));

Booking Ingestion (API Key Auth)

// Upsert a booking event (create or update by PNR)
widget.upsertBooking({
  event_type: 'CREATED',
  pnr_id: 'ABC123',
  source: {
    system: 'IBE',
    channel: 'WEB',
    pos_country: 'US',
    booking_timestamp: '2025-01-15T10:30:00Z'
  },
  travel: {
    origin: 'JFK',
    destination: 'LHR',
    departure_date: '2025-03-15',
    return_date: '2025-03-22',
    carrier_code: 'BA',
    flight_number: 'BA178',
    cabin_class: 'ECONOMY',
    trip_type: 'ROUND_TRIP'
  },
  passengers: {
    adults: 2,
    children: 1,
    infants: 0,
    total: 3
  },
  financials: {
    currency: 'USD',
    base_fare: 1250.00,
    taxes: 185.50,
    total_amount: 1435.50,
    commission_amount: 50.00,
    payment_method: 'CREDIT_CARD'
  }
}).then(response => console.log(response));

// Get booking status
widget.getBookingStatus('ABC123')
  .then(status => console.log(status));

// Convenience methods
widget.createBooking('PNR123', {
  source: { system: 'IBE', channel: 'WEB' },
  travel: { origin: 'JFK', destination: 'LHR' },
  passengers: { adults: 1, total: 1 },
  financials: { currency: 'USD', total_amount: 500.00 }
});

widget.cancelBooking('PNR123', 'Customer request', 75.00);
widget.voidBooking('PNR123', 'Duplicate booking');
widget.refundBooking('PNR123', 450.00, 'Schedule change');
widget.exchangeBooking('PNR123', 'PNR456', 50.00, 125.00, 'Date change');

Event Types:

Event Type Description
CREATED New booking created
MODIFIED Booking details updated
CANCELLED Booking cancelled
VOIDED Booking voided (before ticketing)
REFUNDED Booking refunded
EXCHANGED Booking exchanged for new itinerary

Booking Methods:

Method Description
upsertBooking(request) Upsert booking event (create or update by PNR)
getBookingStatus(pnrId) Get booking status (returns null if not found)
createBooking(pnrId, details) Create a new booking
cancelBooking(pnrId, reason, penaltyAmount) Cancel a booking
voidBooking(pnrId, reason) Void a booking
refundBooking(pnrId, refundAmount, reason) Refund a booking
exchangeBooking(pnrId, newPnrId, exchangeFee, priceDiff, reason) Exchange a booking

UI Rendering

// Render rules table
widget.renderRulesTable('container-id', {
  pageSize: 20  // Optional, default 20
});

// Render partners list
widget.renderPartnersList('container-id', {
  limit: 50  // Optional, default 100
});

// Render domain info card
widget.renderDomainInfo('container-id');

// Load default styles (call once)
widget.loadStyles();

Examples

Example 1: Simple Rules Display

<!DOCTYPE html>
<html>
<head>
  <title>My Rules</title>
</head>
<body>
  <h1>Active Rules</h1>
  <div id="rules"></div>

  <script src="ota-bre-widget.min.js"></script>
  <script>
    var widget = new OtaBreWidget({
      apiUrl: 'http://localhost:8081/api',
      apiKey: 'pk_live_abc123...',
      domainId: 'domain-123'
    });
    widget.loadStyles();
    widget.renderRulesTable('rules');
  </script>
</body>
</html>

Example 2: Custom Data Display

<div id="custom-rules"></div>

<script>
  var widget = new OtaBreWidget({
    apiUrl: 'http://localhost:8081/api',
    apiKey: 'pk_live_abc123...',
    domainId: 'domain-123'
  });

  widget.getRules({ page: 0, size: 5 })
    .then(function(response) {
      var container = document.getElementById('custom-rules');
      var html = '<ul>';
      
      response.content.forEach(function(rule) {
        html += '<li><strong>' + rule.name + '</strong> - ';
        html += 'Sequence: ' + rule.sequenceNumber + ', ';
        html += 'Status: ' + (rule.enabled ? 'Active' : 'Inactive');
        html += '</li>';
      });
      
      html += '</ul>';
      container.innerHTML = html;
    })
    .catch(function(error) {
      console.error('Error:', error);
    });
</script>

Example 3: Multiple Widgets

<div class="row">
  <div class="col">
    <h2>Domain Info</h2>
    <div id="domain-info"></div>
  </div>
  
  <div class="col">
    <h2>Partners</h2>
    <div id="partners"></div>
  </div>
</div>

<div class="row">
  <h2>Active Rules</h2>
  <div id="rules"></div>
</div>

<script src="ota-bre-widget.min.js"></script>
<script>
  var widget = new OtaBreWidget({
    apiUrl: 'http://localhost:8081/api',
    apiKey: 'pk_live_abc123...',
    domainId: 'domain-123'
  });

  widget.loadStyles();
  widget.renderDomainInfo('domain-info');
  widget.renderPartnersList('partners', { limit: 10 });
  widget.renderRulesTable('rules', { pageSize: 15 });
</script>

Styling

Using Default Styles

widget.loadStyles(); // Loads minimal, clean styles

Custom Styling

Override the default classes with your own CSS:

/* Custom table styling */
.ota-bre-table {
  border: 2px solid #333;
}

.ota-bre-table th {
  background: #0066cc !important;
  color: white !important;
}

/* Custom badge colors */
.ota-bre-badge-success {
  background: #28a745 !important;
  color: white !important;
}

/* Custom loading spinner */
.ota-bre-loading {
  font-size: 18px;
  color: #0066cc;
}

Available CSS Classes

  • .ota-bre-table - Rules/data table
  • .ota-bre-badge - Status badge
  • .ota-bre-badge-success - Active status
  • .ota-bre-badge-inactive - Inactive status
  • .ota-bre-loading - Loading state
  • .ota-bre-error - Error messages
  • .ota-bre-domain-card - Domain info card
  • .ota-bre-list - Generic list
  • .ota-bre-pagination - Pagination info

Framework Integration

WordPress

<!-- In your theme's footer.php or custom template -->
<div id="ota-rules"></div>

<script src="<?php echo get_template_directory_uri(); ?>/js/ota-bre-widget.min.js"></script>
<script>
  var widget = new OtaBreWidget({
    apiUrl: '<?php echo get_option('ota_api_url'); ?>',
    apiKey: '<?php echo get_option('ota_api_key'); ?>',
    domainId: '<?php echo get_option('ota_domain_id'); ?>'
  });
  widget.loadStyles();
  widget.renderRulesTable('ota-rules');
</script>

React

import { useEffect } from 'react';

function RulesWidget() {
  useEffect(() => {
    // Load script
    const script = document.createElement('script');
    script.src = '/ota-bre-widget.min.js';
    script.onload = () => {
      const widget = new window.OtaBreWidget({
        apiUrl: 'http://localhost:8081/api',
        apiKey: process.env.REACT_APP_OTA_API_KEY,
        domainId: process.env.REACT_APP_OTA_DOMAIN_ID
      });
      widget.loadStyles();
      widget.renderRulesTable('rules-container');
    };
    document.body.appendChild(script);
  }, []);

  return <div id="rules-container"></div>;
}

Angular

import { Component, OnInit } from '@angular/core';

declare var OtaBreWidget: any;

@Component({
  selector: 'app-rules-widget',
  template: '<div id="rules-container"></div>'
})
export class RulesWidgetComponent implements OnInit {
  ngOnInit() {
    const widget = new OtaBreWidget({
      apiUrl: 'http://localhost:8081/api',
      apiKey: environment.otaApiKey,
      domainId: environment.otaDomainId
    });
    widget.loadStyles();
    widget.renderRulesTable('rules-container');
  }
}

Vue.js

<template>
  <div id="rules-container"></div>
</template>

<script>
export default {
  mounted() {
    const widget = new window.OtaBreWidget({
      apiUrl: 'http://localhost:8081/api',
      apiKey: process.env.VUE_APP_OTA_API_KEY,
      domainId: process.env.VUE_APP_OTA_DOMAIN_ID
    });
    widget.loadStyles();
    widget.renderRulesTable('rules-container');
  }
}
</script>

Error Handling

widget.getRules()
  .then(function(response) {
    // Success
    console.log('Rules loaded:', response);
  })
  .catch(function(error) {
    // Error handling
    console.error('Error:', error.message);
    
    if (error.status === 401) {
      console.error('Invalid API key');
    } else if (error.status === 403) {
      console.error('Access denied');
    } else if (error.status === 404) {
      console.error('Domain not found');
    }
  });

Browser Support

Chrome 60+
Firefox 55+
Safari 11+
Edge 79+
Opera 47+

IE11: Not supported (use polyfills for Promise if needed)

Security

API Key Safety

  • Never expose secret keys in client-side code
  • Only use public API keys (pk_live_... or pk_test_...)
  • Public keys have read-only access to public data
  • Keys can be regenerated if compromised

XSS Protection

All user data is automatically escaped before rendering to prevent XSS attacks.

Performance

  • Initial Load: ~5KB (minified)
  • No Dependencies: Zero external libraries
  • Lazy Loading: Styles loaded only when needed
  • Caching: Responses can be cached via standard HTTP headers

Live Examples

Check the examples/ folder for complete working examples:

  • basic-example.html - Simple integration
  • advanced-dashboard.html - Full dashboard with filters
  • embedded-widget.html - Minimal embed example

Running Examples Locally

# Start a local server
cd sdks/html-plugin
python3 -m http.server 8000

# Or with PHP
php -S localhost:8000

# Then open in browser
open http://localhost:8000/examples/basic-example.html

Troubleshooting

Widget not loading?

  1. Check browser console for errors
  2. Verify API key is correct
  3. Ensure apiUrl is accessible from client
  4. Check CORS settings on backend

No data displayed?

  1. Verify domainId is correct
  2. Check API key has access to domain
  3. Ensure rules/data exist in the domain
  4. Check network tab for API responses

Styling issues?

  1. Ensure widget.loadStyles() is called
  2. Check for CSS conflicts with existing styles
  3. Use !important to override if needed

API Endpoint Requirements

The widget expects these endpoints on your backend:

Public Data (read-only):

  • GET /public/domains/:id - Domain info
  • GET /public/gfs-rules - Rules list
  • GET /public/partners - Partners list
  • GET /public/location-groups - Location groups
  • GET /public/carrier-groups - Carrier groups

Booking Ingestion (read/write):

  • PUT /v1/bookings - Upsert booking event
  • GET /v1/bookings/:pnrId - Get booking status

All requests must include X-API-Key header for authentication.

Changelog

v1.1.0 (2025-01-15)

  • Added Booking Ingestion API support
  • upsertBooking() - Upsert booking events (create/update by PNR)
  • getBookingStatus() - Get booking status by PNR
  • Convenience methods: createBooking(), cancelBooking(), voidBooking(), refundBooking(), exchangeBooking()
  • Added _put() HTTP method support
  • Updated minified build

v1.0.0 (2025-12-24)

  • Initial release
  • Rules table rendering
  • Partners list rendering
  • Domain info card
  • API methods for data fetching
  • Default styling
  • XSS protection
  • Error handling

License

MIT

Support

  • Documentation: This README
  • Examples: See examples/ folder
  • Issues: Contact support@omeron.co
  • Backend: See main OTA BRE documentation

Made with ❤️ by Omeron

Keywords

ota business-rules widget javascript html api-client embeddable
Details
npm
2026-04-16 17:05:54 +00:00
0
Omeron
MIT
latest
13 KiB
Assets (1)
Versions (1) View all
1.0.0 2026-04-16