@svene/juanfi-hotspot
v0.1.1
Published
[](https://www.npmjs.com/package/@svene/juanfi-hotspot) [](https://www.npmjs.com/package/@svene/juanfi-hotspot)
Readme
@svene/juanfi-hotspot
Browser-side helpers for custom JuanFI hotspot pages.
Use this inside hotspot pages when handling voucher login, coin insertion, e-load, selected vendo logic, timers, labels, or local storage.
install
npm install @svene/juanfi-hotspotvoucher login
import { loginWithVoucher } from '@svene/juanfi-hotspot';
const form = document.querySelector<HTMLFormElement>('#sendin');
if (!form) {
throw new Error('Missing login form');
}
loginWithVoucher({
form,
voucher: 'ABC123',
loginOption: 1,
chapId: window.chapId,
chapChallenge: window.chapChallenge,
});MAC-as-voucher fallback:
loginWithVoucher({
form,
voucher: '',
mac: 'AA:BB:CC:DD:EE:FF',
macAsVoucherCode: true,
loginOption: 1,
});member login
import { loginWithMember } from '@svene/juanfi-hotspot';
const sendinForm = document.querySelector<HTMLFormElement>('#sendin');
const loginForm = document.querySelector<HTMLFormElement>('#login');
if (!sendinForm || !loginForm) {
throw new Error('Missing login forms');
}
loginWithMember({
sendinForm,
loginForm,
chapId: window.chapId,
chapChallenge: window.chapChallenge,
});coin flow
createCoinFlow starts top-up, polls coin status, saves voucher state, and calls UI hooks.
import { createCoinFlow } from '@svene/juanfi-hotspot';
import { createJuanFiApi } from '@svene/juanfi-api';
const api = createJuanFiApi({
vendoIp: '10.1.0.41',
});
const flow = createCoinFlow({
api,
mac: 'AA:BB:CC:DD:EE:FF',
ipAddress: '10.0.0.23',
pollMs: 1000,
onStarted(update) {
console.log('voucher', update.voucher);
},
onWaitingForCoin(update) {
console.log('remaining', update.remainTime);
},
onCoinAdded(update) {
console.log('coins', update.totalCoin);
},
onVoucherReady(update) {
console.log('ready', update.voucher);
},
onFailed(error) {
console.log(error.code, error.error);
},
onDone(update) {
console.log('done', update.voucher);
},
});
await flow.start();Stop polling:
flow.stop();Cancel if no coins were inserted:
await flow.cancel();Save voucher:
await flow.save();e-load flow
createLoadFlow manages product loading, mobile number entry, product selection, coin polling, and load completion.
import { createLoadFlow } from '@svene/juanfi-hotspot';
import { createJuanFiApi } from '@svene/juanfi-api';
const api = createJuanFiApi({
vendoIp: '10.1.0.41',
});
const flow = createLoadFlow({
api,
mac: 'AA:BB:CC:DD:EE:FF',
pollMs: 1000,
onStep(state) {
console.log('step', state.step);
},
onProducts(products) {
console.log(products);
},
onCoinAdded(update) {
console.log(update.totalCoin);
},
onVoucherReady(update) {
console.log('leftover voucher', update.voucher);
},
onFailed(error) {
console.log(error.code, error.error);
},
onDone(update) {
console.log('load done', update.voucher);
},
});
await flow.start();
flow.setMobile('09171234567');
await flow.next();
flow.selectGroup('GLOBE');
flow.selectProduct('GLOBE50');
await flow.next();
await flow.next();Read state:
const state = flow.getState();
console.log(state.step);
console.log(state.mobile);
console.log(state.selectedProduct);selected vendo
import { selectVendo } from '@svene/juanfi-hotspot';
const selected = selectVendo({
isMultiVendo: true,
multiVendoOption: 0,
selectedVendoIp: '10.1.0.41',
defaultVendoIp: '10.1.0.41',
multiVendoAddresses: [
{
vendoName: 'Main',
vendoIp: '10.1.0.41',
chargingEnable: true,
eloadEnable: true,
},
],
});
console.log(selected.vendoIp);
console.log(selected.showSelector);multiVendoOption:
0: use selected IP and show selector1: match hotspot address2: match interface name
storage
Storage shape:
type StoragePort = {
readonly saveValue: (key: string, value: string) => void;
readonly readValue: (key: string) => string | null;
readonly removeValue: (key: string) => void;
};Custom storage:
const memoryStorage = new Map<string, string>();
const storage = {
saveValue(key: string, value: string) {
memoryStorage.set(key, value);
},
readValue(key: string) {
return memoryStorage.get(key) ?? null;
},
removeValue(key: string) {
memoryStorage.delete(key);
},
};Use it:
const flow = createCoinFlow({
api,
mac: 'AA:BB:CC:DD:EE:FF',
storage,
});CDN
<script src="https://cdn.jsdelivr.net/npm/@svene/[email protected]/dist/juanfi-hotspot.min.js"></script>Browser global:
JuanFiHotspot.loginWithVoucher({
form: document.querySelector('#sendin'),
voucher: 'ABC123',
loginOption: 1,
});Download:
curl -L -o juanfi-hotspot.js https://cdn.jsdelivr.net/npm/@svene/[email protected]/dist/juanfi-hotspot.min.jsDo not use latest in production. Always pin the version.
scripts
npm run test -w @svene/juanfi-hotspot
npm run build -w @svene/juanfi-hotspot