die heldin script add

This commit is contained in:
2026-02-24 07:04:01 +01:00
parent a1b35fecce
commit 420391f48a
1847 changed files with 597777 additions and 0 deletions

841
node_modules/openmagicline/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,841 @@
import { AxiosInstance } from 'axios';
import debug from 'debug';
type CustomerID = number
type AccessIdentificationID = number
interface SearchOptions {
facility?: unitID
/**
* searchInAddress
* @default false
*/
searchInAddress?: boolean
/**
* searchInBankAccount
* @default false
*/
searchInBankAccount?: boolean
/**
* searchInCardNumber
* @default false
*/
searchInCardNumber?: boolean
/**
* searchInCustomerNumber
* @default true
*/
searchInCustomerNumber?: boolean
/**
* searchInLockerKey
* @default false
*/
searchInLockerKey?: boolean
/**
* searchInName
* @default true
*/
searchInName?: boolean
/**
* searchInPurchasedContingentCode
* @default false
*/
searchInPurchasedContingentCode?: boolean
/**
* showAllFacilities
* @default true
*/
showAllFacilities?: boolean
/**
* showCheckedIn
* @default false
*/
showCheckedIn?: boolean
/**
* showOnlyMembers
* @default false
*/
showOnlyMembers?: boolean
}
type customer_d$1_AccessIdentificationID = AccessIdentificationID;
type customer_d$1_CustomerID = CustomerID;
type customer_d$1_SearchOptions = SearchOptions;
declare namespace customer_d$1 {
export {
customer_d$1_AccessIdentificationID as AccessIdentificationID,
customer_d$1_CustomerID as CustomerID,
customer_d$1_SearchOptions as SearchOptions,
};
}
interface ListOptions {
organizationUnitId?: unitID
offset?: number
/** magiclines webclient sets this to */
maxResults?: number
search?: string
filter?: string
sortedby?: "checkinTime" | "checkinDuration" | "lastname" | "firstname" | "lockerKey"
/** list checkouts instead */
checkouts?: boolean
direction?: "DESCENDING" | "ASCENDING"
}
interface CheckinOptions {
/** not sure what this is for */
customerCardNumber?: null | unknown
/** not sure what this is for */
customerUUID?: string
/** customerID */
fkCustomer: number
/** not sure what this is for */
fkDevice?: null | unknown
/** organizationUnitId */
fkOrganizationUnit?: unitID
lockerKey?: number | string
/** not sure what this is for */
purchasedContingentCode?: null | unknown
/** not sure what this is for */
databaseId?: null | unknown
/** not sure what this is for, was 0 for me */
optlock?: number
/** organizationUnitId */
requiredOrganizationUnitId?: unitID
}
interface CheckoutOptions {
optLockRemote?: number
}
interface LockerKeyOptions {
/** not sure what this is for */
databaseId?: null | unknown
/** not sure what this is for */
optlock?: 0 | number
}
type checkin_d$1_CheckinOptions = CheckinOptions;
type checkin_d$1_CheckoutOptions = CheckoutOptions;
type checkin_d$1_ListOptions = ListOptions;
type checkin_d$1_LockerKeyOptions = LockerKeyOptions;
declare namespace checkin_d$1 {
export {
checkin_d$1_CheckinOptions as CheckinOptions,
checkin_d$1_CheckoutOptions as CheckoutOptions,
checkin_d$1_ListOptions as ListOptions,
checkin_d$1_LockerKeyOptions as LockerKeyOptions,
};
}
interface ProductOptions {
organizationUnitId?: unitID
customerId?: number
}
type sales_d$1_ProductOptions = ProductOptions;
declare namespace sales_d$1 {
export {
sales_d$1_ProductOptions as ProductOptions,
};
}
interface Config {
/**
* the gym's url prefix
*
* when you access your dashboard via https://example.web.magicline.com
* your url prefix will be `example`
*/
gym: string
/**
* login username, making a dedicated account for API access is recommended.
*/
username?: string
/**
* login password, making a dedicated account for API access is recommended.
*/
password?: string
// unitID?: number
}
type index_d$1_Config = Config;
declare namespace index_d$1 {
export {
checkin_d$1 as Checkin,
index_d$1_Config as Config,
customer_d$1 as Customer,
sales_d$1 as Sales,
};
}
interface Benefit {
name: string
available: number | null
total: number | null
hasUsages: boolean
colorHex: string
unit: string
inclusiveContingentId: null
purchasedContingentId: number | null
trialContingentId: null
freeUsage: boolean
benefitId: number
expiryDate: null | string
createdDate: null | string
durationText: null
flat: boolean
}
interface Base {
databaseId: CustomerID
}
interface CheckinCondition {
type: string
messageKey: string
args: string[]
}
interface SearchedCustomer extends Base {
firstname: string
lastname: string
gender: number
dateOfBirth: Date | null
lastCheckIn: Date | null
facilityName: string
customerNumber: string
cardNumber: null
lockerKey: null | string
customerStatus: number
purchasedContingentCode: null
purchasedContingentType: null
imageUrl: null
checkedIn: boolean
street: null | string
houseNumber: null | string
zip: null | string
city: null | string
}
interface AccessIdentification {
databaseId: AccessIdentificationID
optlock: number
fkOrganizationUnit: number
createdDate: Date
type: string
uid: string
stompDestination: string
}
interface Contract {
databaseId: number
optlock: number
rateId: number
rateName: string
publicRateName: string
compunknownId: null
currencyUnit: string
startDate: string
startDateOfUse: null | string
startDateCurrentTerm: null | string
preuseType: number
endDate: string
term: number
extensionType: string
termUnit: number
termExtension: number
termExtensionUnit: number
extensionCancelationPeriod: null
trialPeriod: null
paymentChoice: null
cancelationPeriod: number
cancelationPeriodUnit: number
nextCancelationDate: string
active: boolean
activeAgeBasedAdjustmentDto: null
isCanceled: boolean | null
isReversed: boolean
imported: boolean
hasBonusPeriods: boolean
hasContractIdlePeriods: boolean
contractOutlier: unknown[]
currentPrice: number
currentPriceWithDate: CurrentPriceWithDate
nextPriceWithDate: null
contractCancelation: ContractCancelation | null
paymentDay: number | null
contractPaymentFrequency: ContractPaymentFrequency
moduleContracts: null
flatFeeContracts: FlatFeeContract[] | null
divergentAffiliate: null
contractRestMaturityDto: null
cancelationStrategy: string
subsequentRateName: null
subsequentRateDetailTerm: null
subsequentRateDetailTermUnit: null
subsequentRateDetailPaymentFrequencyTerm: null
subsequentRateDetailPaymentFrequencyTermUnit: null
subsequentRateDetailPaymentFrequencyType: null
subsequentRateDetailPaymentFrequencyPrice: null
subsequentContractId: null
subsequentContractHasSubsequentContract: boolean
subsequentContractName: null
signatureStatus: string
campaignId: null
salesSource: string
notes: null
bonusPeriods: unknown[]
contractIdlePeriods: unknown[]
vouchers: unknown[]
paymentRunGroupSimpleDto: null
}
interface ContractCancelation {
databaseId: number
optlock: number
fkCancelationReason: number
cancelationReasonName: string
cancelationReceiptDate: string
cancelationDate: string
extraordinaryCancelation: boolean
createSystemMessage: boolean
customerMessageId: null
cancelationFee: null
ignoreImportedChargesOnChargeCalendarCalculation: boolean
cancelationByStudio: boolean
}
interface ContractPaymentFrequency {
databaseId: number
optlock: number
type: string
value: number | null
unit: number | null
price: number
money: Money
paidTimePeriodCalculationType: null | string
firstBookingDelay: FirstBookingDelay | null
recurring: null
extensionValue: null
extensionUnit: null
extensionPrice: null
dueDateOffset: null
applyFirstEncashmentOnFirstRegularCharge: boolean
monthDayWithPrices: unknown[]
termWithPrices: unknown[]
monthDays: unknown[]
ageBasedAdjustmentDtos: unknown[]
firstEncashment: string
dynamicAdjustmentRules: unknown[]
}
interface FirstBookingDelay {
term: number
termUnit: number
}
interface Money {
amount: number
currencyCode: string
}
interface CurrentPriceWithDate {
date: string
price: number
}
interface FlatFeeContract {
databaseId: number
optlock: number
currencyUnit: string
startDate: string
startDateOfUse: null
endDate: string
imported: boolean
paymentDay: null
contractCancelation: null
contractPaymentFrequency: ContractPaymentFrequency
contractOutlier: null
contractRestMaturityDto: null
retroactive: boolean
termInformation: null
paymentChoice: null
paymentRunGroupSimpleDto: null
flatFeeRateId: number
flatFeeRateName: string
flatFeeRatePublicName: string
flatFeeRateDetailPaymentFrequencyId: number
reversed: boolean
canceled: boolean
}
interface DetailedBalance {
databaseId: number
optlock: null
consumptionCreditBalance: number
debtClaimBalance: number
debtClaimBalanceWithoutLaterSale: number
laterSaleBalance: number
paymentBalance: number
transferBalance: number
totalWithoutConsumptionCredit: number
}
type customer_d_AccessIdentification = AccessIdentification;
type customer_d_Base = Base;
type customer_d_Benefit = Benefit;
type customer_d_CheckinCondition = CheckinCondition;
type customer_d_Contract = Contract;
type customer_d_ContractCancelation = ContractCancelation;
type customer_d_ContractPaymentFrequency = ContractPaymentFrequency;
type customer_d_CurrentPriceWithDate = CurrentPriceWithDate;
type customer_d_DetailedBalance = DetailedBalance;
type customer_d_FirstBookingDelay = FirstBookingDelay;
type customer_d_FlatFeeContract = FlatFeeContract;
type customer_d_Money = Money;
type customer_d_SearchedCustomer = SearchedCustomer;
declare namespace customer_d {
export {
customer_d_AccessIdentification as AccessIdentification,
customer_d_Base as Base,
customer_d_Benefit as Benefit,
customer_d_CheckinCondition as CheckinCondition,
customer_d_Contract as Contract,
customer_d_ContractCancelation as ContractCancelation,
customer_d_ContractPaymentFrequency as ContractPaymentFrequency,
customer_d_CurrentPriceWithDate as CurrentPriceWithDate,
customer_d_DetailedBalance as DetailedBalance,
customer_d_FirstBookingDelay as FirstBookingDelay,
customer_d_FlatFeeContract as FlatFeeContract,
customer_d_Money as Money,
customer_d_SearchedCustomer as SearchedCustomer,
};
}
interface LockerKeyResponse {
checkinId: number
lockerKey: string
}
interface CheckinResponse {
/** this is the checkinID **not** the customerID, that is `fkCustomer` */
databaseId: number
optlock: number
fkOrganizationUnit: number
/** this is the customerID */
fkCustomer: number
fkEmployee: null
fkDevice: number | null
firstname: string
lastname: string
cardNumber: null
customerNumber: string
employeeNumber: null
dateOfBirth: string
gender: number
imageUrl: null
studioName: null
lockerKey: null | string
checkinTime: string
checkoutTime: null | string
stompDestination: string
}
interface CheckinList {
checkins: Checkin$1[]
summary: { [key: string]: number }
}
interface Checkin$1 {
databaseId: number
optlock: null
customerId: number
customerOrganizationUnitId: number
customerFacilityName: string
lockerKey: null | string
checkinTime: string
previousCheckinTime: null | string
lastCheckoutTime: string
firstname: string
lastname: string
customerNumber: string
gender: number
dateOfBirth: null | string
imageUrl: ImageURL$1 | null
customerCodes: CustomerCode[]
contractNames: string[]
moduleNames: string[]
badges: Badge[]
isAnonymized: boolean
}
interface Badge {
badge: string
label: string
}
interface CustomerCode {
databaseId: number
optlock: number
facilityInfo: null
name: string
description: null | string
colorHex: string
active: boolean
}
interface ImageURL$1 {
url: string
rewrite: boolean
}
type checkin_d_Badge = Badge;
type checkin_d_CheckinList = CheckinList;
type checkin_d_CheckinResponse = CheckinResponse;
type checkin_d_CustomerCode = CustomerCode;
type checkin_d_LockerKeyResponse = LockerKeyResponse;
declare namespace checkin_d {
export {
checkin_d_Badge as Badge,
Checkin$1 as Checkin,
checkin_d_CheckinList as CheckinList,
checkin_d_CheckinResponse as CheckinResponse,
checkin_d_CustomerCode as CustomerCode,
ImageURL$1 as ImageURL,
checkin_d_LockerKeyResponse as LockerKeyResponse,
};
}
interface ProductOverview {
fkOrganizationUnit: null
customer: null
classOfGoodsList: ClassOfGoodsList[]
}
interface ClassOfGoodsList {
databaseId: number
name: string
materialClassOfGoods: boolean
voucher: boolean
productList: ProductList[]
}
interface ProductList {
databaseId: number | null
name: string
regularTaxRate: TaxRate
toGoTaxRate: TaxRate | null
productVariantList: ProductVariantList[]
}
interface ProductVariantList {
databaseId: number
name: string
itemNumber: string
currencyUnit: string
price: number
additionalInfo: null | string
stock: number | null
ean: null | string
}
interface TaxRate {
name: string
percent: number
}
type sales_d_ClassOfGoodsList = ClassOfGoodsList;
type sales_d_ProductList = ProductList;
type sales_d_ProductOverview = ProductOverview;
type sales_d_ProductVariantList = ProductVariantList;
type sales_d_TaxRate = TaxRate;
declare namespace sales_d {
export {
sales_d_ClassOfGoodsList as ClassOfGoodsList,
sales_d_ProductList as ProductList,
sales_d_ProductOverview as ProductOverview,
sales_d_ProductVariantList as ProductVariantList,
sales_d_TaxRate as TaxRate,
};
}
type CallbackFunction<T> = (data: T) => void
type UnsubscribeFunction = () => void
interface CheckinEvent {
type: string
action: string
timestamp: number
tenantName: string
organizationUnitId: number
customerIds: unknown[]
payload: Payload
}
interface Payload {
databaseId: number
optlock: number
fkOrganizationUnit: number
fkCustomer: number
fkEmployee: null
fkDevice: number
firstname: string
lastname: string
cardNumber: null
customerNumber: string
employeeNumber: null
dateOfBirth: string
gender: number
imageUrl: ImageURL | null
studioName: null
lockerKey: null | string
checkinTime: string
checkoutTime: null | string
stompDestination: string
}
interface ImageURL {
url: string
rewrite: boolean
}
type socket_d_CallbackFunction<T> = CallbackFunction<T>;
type socket_d_CheckinEvent = CheckinEvent;
type socket_d_ImageURL = ImageURL;
type socket_d_Payload = Payload;
type socket_d_UnsubscribeFunction = UnsubscribeFunction;
declare namespace socket_d {
export {
socket_d_CallbackFunction as CallbackFunction,
socket_d_CheckinEvent as CheckinEvent,
socket_d_ImageURL as ImageURL,
socket_d_Payload as Payload,
socket_d_UnsubscribeFunction as UnsubscribeFunction,
};
}
type CurrentLocale = string
type SupportedLocales = string[]
interface Success {
success: "true"
}
interface GenericError {
errorMessage: string
errorCode: string
args: unknown[]
typedArgs: unknown[]
}
type ErrorOrSuccess = Partial<Success> & GenericError[]
interface Permitted {
databaseId: null | number
optlock: null | number
name: string
prefix: null | string
type: number
country: null | string
colorHex: string
currencyCode: string
timeZone: string
currency: {
databaseId: null | number
optlock: null | number
unit: string
}
isTenantWithSingleStudio: boolean
permitted: boolean
listChildren: Permitted[]
permissions: string[]
isStudioLoginPermitted: boolean
}
type Notices = unknown[]
interface AccountInfo {
firstname: string
lastname: string
fullName: string
employeeId: number
imageUrl: {
url: string
rewrite: boolean
}
}
interface App {
app: string
status: string
values: {
id?: number
category: string
tier?: string
payment_provider_id?: string
}
}
type index_d_AccountInfo = AccountInfo;
type index_d_App = App;
type index_d_CurrentLocale = CurrentLocale;
type index_d_ErrorOrSuccess = ErrorOrSuccess;
type index_d_GenericError = GenericError;
type index_d_Notices = Notices;
type index_d_Permitted = Permitted;
type index_d_Success = Success;
type index_d_SupportedLocales = SupportedLocales;
declare namespace index_d {
export {
index_d_AccountInfo as AccountInfo,
index_d_App as App,
checkin_d as Checkin,
index_d_CurrentLocale as CurrentLocale,
customer_d as Customer,
index_d_ErrorOrSuccess as ErrorOrSuccess,
index_d_GenericError as GenericError,
index_d_Notices as Notices,
index_d_Permitted as Permitted,
sales_d as Sales,
socket_d as Socket,
index_d_Success as Success,
index_d_SupportedLocales as SupportedLocales,
};
}
/**
* the "organizationUnitId" used to identify different units for the same gym.
* that's what i think what it is at least.
*
* if it's marked as optional it can be omitted for convenience, in which case it
* falls back to the first listed unit, **but it *should* always be provided**.
*
* mine was 2 by default for some reason, you can find yours using `.permitted()`
*/
type unitID = number
declare class Util {
private axios;
private mgl;
constructor(axios: AxiosInstance, mgl: Openmagicline);
getDefaultUnitID(): Promise<unitID>;
/**
* check if the login token works.
*/
testLogin(): Promise<boolean>;
}
declare class Locale {
private axios;
constructor(axios: AxiosInstance);
currentLocale(): Promise<CurrentLocale>;
supportedLocales(): Promise<SupportedLocales>;
}
declare class Organization {
private axios;
private mgl;
constructor(axios: AxiosInstance, mgl: Openmagicline);
permitted(): Promise<Permitted>;
accountInfo(): Promise<AccountInfo>;
apps(unitID?: unitID): Promise<App[]>;
}
declare class Customer {
private axios;
private mgl;
constructor(axios: AxiosInstance, mgl: Openmagicline);
defaultSearchOptions: Required<SearchOptions>;
search(searchString: string, options?: SearchOptions): Promise<SearchedCustomer[]>;
getCards(customerID: CustomerID): Promise<AccessIdentification[]>;
/**
* get contracts of a customer
* @param customerId customer id
* @param isActive get only active contracts (default: `true`)
*/
contract: (customerId: CustomerID, isActive?: boolean) => Promise<Contract[]>;
checkinConditions: (customerId: number, organizationUnitId?: number) => Promise<CheckinCondition[]>;
benefits: (customerId: CustomerID, active?: boolean | "both") => Promise<Benefit[]>;
detailedBalance: (customerId: CustomerID) => Promise<DetailedBalance>;
}
declare class Checkin {
private axios;
private mgl;
constructor(axios: AxiosInstance, mgl: Openmagicline);
defaultListParams: ListOptions;
/**
* list all checked-in customers
* @param options filter, sort, etc.
*/
list(options?: ListOptions): Promise<CheckinList>;
private defaultCheckinParams;
/**
* check-in a customer
*/
checkin(options: CheckinOptions): Promise<CheckinResponse>;
/**
* check-out a customer
* @param checkinId the ID of the checkin, **not** the customer ID
* @param options optional object containing optLockRemote, not sure what it does
*/
checkout(checkinId: number, options?: CheckoutOptions): Promise<CheckinResponse>;
private defaultLockerKeyParams;
lockerKey(checkinId: number, lockerKey: number | string, options?: LockerKeyOptions): Promise<LockerKeyResponse>;
}
declare class Sales {
private axios;
private mgl;
constructor(axios: AxiosInstance, mgl: Openmagicline);
products(options?: ProductOptions): Promise<ProductOverview>;
}
declare class MagicSocket {
private mgl;
private client;
private log;
isActive: false | Promise<unknown>;
private webSocketFactory;
constructor(mgl: Openmagicline, unitID: unitID);
subscriptions: Record<string, UnsubscribeFunction>;
activate(): Promise<unknown>;
unsubscribeAll(): Promise<void>;
deactivate(): Promise<void>;
private deactivateAutomatically;
private subscribeFactory;
onCheckin: (callback: CallbackFunction<CheckinEvent>) => Promise<UnsubscribeFunction>;
}
/** @deprecated todo: move to util */
declare const _log: debug.Debugger;
declare class Openmagicline {
private config;
protected log: debug.Debugger;
protected axios: AxiosInstance;
baseUrl: string;
cookies?: string[];
customer: Customer;
locale: Locale;
organization: Organization;
/** everything related to the checkin process */
checkin: Checkin;
/** miscellaneous helpers and thingies */
util: Util;
/** everything related to retail sales (magicline calls this disposal in some places) */
sales: Sales;
/** reference to this.sales */
disposal: Sales;
/** event handler for magiclines websockets */
socket: (unitID: unitID) => MagicSocket;
constructor(config: Config, axios?: AxiosInstance);
private _login;
/**
* authenticate the Openmagicline instance using username/password from the instance config.
*
* if a token is passed, it will be validated and the request to `/login` will be skipped.
* @param cookies existing cookies, available after login at `.cookies`
* @returns instance for chaining
* @throws when not authenticated
*/
login: (cookies?: string[]) => Promise<Openmagicline>;
}
export { index_d as Magicline, index_d$1 as OMGL, Openmagicline, _log, unitID };

531
node_modules/openmagicline/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,531 @@
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
Openmagicline: () => Openmagicline,
_log: () => _log
});
module.exports = __toCommonJS(src_exports);
var import_axios_auth_refresh = __toESM(require("axios-auth-refresh"));
var import_axios = __toESM(require("axios"));
var import_once = __toESM(require("lodash/once"));
var import_debug = __toESM(require("debug"));
// src/util.ts
var import_form_data = __toESM(require("form-data"));
// src/constants.ts
var DEFAULT_UNIT_ID = 1;
// src/util.ts
var Util = class {
constructor(axios, mgl) {
this.axios = axios;
this.mgl = mgl;
}
async getDefaultUnitID() {
const data = await this.mgl.organization.permitted();
return data.listChildren[0].databaseId ?? DEFAULT_UNIT_ID;
}
/**
* check if the login token works.
*/
async testLogin() {
try {
await this.mgl.locale.currentLocale();
return true;
} catch {
return false;
}
}
};
var headers = (mgl) => {
const u = new URL(mgl.baseUrl);
const returnValue = {
authority: u.hostname,
"sec-ch-ua": `"Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"`,
accept: `application/json, text/javascript, */*; q=0.01`,
"x-requested-with": `XMLHttpRequest`,
"sec-ch-ua-mobile": `?0`,
"user-agent": `Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36`,
origin: u.href,
"sec-fetch-site": `same-origin`,
"sec-fetch-mode": `cors`,
"sec-fetch-dest": `empty`,
referer: u.href,
"accept-language": `en-CA,en-US;q=0.9,en;q=0.8,de-DE;q=0.7,de;q=0.6,en-GB;q=0.5`
};
if (mgl.cookies)
returnValue.cookie = mgl.cookies.join("");
return returnValue;
};
var websocketHeaders = (mgl) => {
const u = new URL(mgl.baseUrl);
const returnValue = {
Pragma: "no-cache",
Origin: u.href,
"Accept-Language": "en-CA,en-US;q=0.9,en;q=0.8,de-DE;q=0.7,de;q=0.6,en-GB;q=0.5",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
"Cache-Control": "no-cache"
};
if (mgl.cookies)
returnValue.cookie = mgl.cookies.join("");
return returnValue;
};
var searchParameters = (data) => {
const parameters = new URLSearchParams();
for (const [key, value] of Object.entries(data))
parameters.set(key, value);
return parameters;
};
// src/locale.ts
var Locale = class {
constructor(axios) {
this.axios = axios;
}
async currentLocale() {
const { data } = await this.axios.get("currentLocale");
return data;
}
async supportedLocales() {
const { data } = await this.axios.get("supportedLocales");
return data;
}
};
// src/organization.ts
var Organization = class {
constructor(axios, mgl) {
this.axios = axios;
this.mgl = mgl;
}
async permitted() {
const { data } = await this.axios("organizationunit/permitted");
return data;
}
async accountInfo() {
const { data } = await this.axios("me/info");
return data;
}
async apps(unitID) {
if (!unitID)
unitID = await this.mgl.util.getDefaultUnitID();
const { data } = await this.axios("app", {
params: { organizationUnitId: unitID }
});
return data;
}
};
// src/customer.ts
var Customer = class {
constructor(axios, mgl) {
this.axios = axios;
this.mgl = mgl;
}
defaultSearchOptions = {
facility: 0,
searchInName: true,
searchInCustomerNumber: true,
searchInAddress: false,
searchInBankAccount: false,
searchInCardNumber: false,
searchInLockerKey: false,
searchInPurchasedContingentCode: false,
showAllFacilities: true,
showCheckedIn: false,
showOnlyMembers: false
};
async search(searchString, options) {
const { data } = await this.axios.post("customersearch", {
...this.defaultSearchOptions,
...options,
searchString
});
return data;
}
async getCards(customerID) {
const { data } = await this.axios(`customer/${customerID}/accessidentification`);
return data;
}
/**
* get contracts of a customer
* @param customerId customer id
* @param isActive get only active contracts (default: `true`)
*/
contract = async (customerId, isActive = true) => {
const { data } = await this.axios.get("contract", {
params: { customerId, isActive }
});
return data;
};
checkinConditions = async (customerId, organizationUnitId) => {
if (typeof organizationUnitId !== "number") {
organizationUnitId = await this.mgl.util.getDefaultUnitID();
}
const { data } = await this.axios.get(`customer/${customerId}/conditions/checkin`, {
params: { organizationUnitId }
});
return data;
};
benefits = async (customerId, active = "both") => {
const returnList = [];
if (active === true || active === "both") {
const { data } = await this.axios.get("benefitaccount", {
params: { customerId, active: true }
});
returnList.push(...data);
}
if (active === false || active === "both") {
const { data } = await this.axios.get("benefitaccount", {
params: { customerId, active: false }
});
returnList.push(...data);
}
return returnList;
};
detailedBalance = async (customerId) => {
const { data } = await this.axios.get(`customer/${customerId}/balance/detailed`);
return data;
};
// todo: implement card methods
//? removed until more card methods are implemented
// removeCard(
// customerID: Openmagicline.Customer.CustomerID,
// AccessIdentificationID: Openmagicline.Customer.AccessIdentificationID
// ): Promise<Magicline.ErrorOrSuccess> {
// return this.got(`customer/${customerID}/accessidentification/${AccessIdentificationID}`, {
// method: "DELETE",
// searchParams: {
// optLockRemote: 0,
// },
// }).json()
// }
};
// src/checkin.ts
var Checkin = class {
constructor(axios, mgl) {
this.axios = axios;
this.mgl = mgl;
}
defaultListParams = {
organizationUnitId: DEFAULT_UNIT_ID,
checkouts: false,
offset: 0,
maxResults: 25,
search: "",
filter: "",
sortedby: "checkinTime",
direction: "DESCENDING"
};
/**
* list all checked-in customers
* @param options filter, sort, etc.
*/
async list(options) {
let organizationUnitId = options?.organizationUnitId;
if (typeof organizationUnitId !== "number") {
organizationUnitId = await this.mgl.util.getDefaultUnitID();
}
const { data } = await this.axios("checkin", {
params: {
...this.defaultListParams,
organizationUnitId,
...options
}
});
return data;
}
defaultCheckinParams = {
customerCardNumber: void 0,
customerUUID: "",
fkCustomer: 0,
fkDevice: void 0,
fkOrganizationUnit: DEFAULT_UNIT_ID,
lockerKey: "",
purchasedContingentCode: void 0,
databaseId: void 0,
optlock: 0,
requiredOrganizationUnitId: DEFAULT_UNIT_ID
};
/**
* check-in a customer
*/
async checkin(options) {
let unitID = options.requiredOrganizationUnitId ?? options.fkOrganizationUnit;
if (typeof unitID !== "number") {
unitID = await this.mgl.util.getDefaultUnitID();
}
const { data } = await this.axios.post("checkin", {
...this.defaultCheckinParams,
fkOrganizationUnit: unitID,
requiredOrganizationUnitId: unitID,
...options
});
return data;
}
/**
* check-out a customer
* @param checkinId the ID of the checkin, **not** the customer ID
* @param options optional object containing optLockRemote, not sure what it does
*/
async checkout(checkinId, options) {
const { data } = await this.axios.delete(`checkin/${checkinId}`, {
params: { ...options }
});
return data;
}
defaultLockerKeyParams = {
databaseId: void 0,
optlock: 0
};
async lockerKey(checkinId, lockerKey, options) {
const { data } = await this.axios.put(`checkin/lockerkey/${checkinId}`, {
...this.defaultLockerKeyParams,
checkinId,
lockerKey,
...options
});
return data;
}
};
// src/sales.ts
var Sales = class {
constructor(axios, mgl) {
this.axios = axios;
this.mgl = mgl;
}
async products(options) {
const organizationUnitId = options?.organizationUnitId ?? await this.mgl.util.getDefaultUnitID();
const { data } = await this.axios("sales/productoverview", {
params: {
organizationUnitId,
...options
}
});
return data;
}
};
// src/socket.ts
var import_stompjs = require("@stomp/stompjs");
var import_ws = __toESM(require("ws"));
var MagicSocket = class {
constructor(mgl, unitID) {
this.mgl = mgl;
this.client = new import_stompjs.Client({
debug: this.log,
heartbeatIncoming: 1e4,
heartbeatOutgoing: 1e4,
webSocketFactory: this.webSocketFactory(mgl.baseUrl, unitID),
onWebSocketError: (
/* istanbul ignore next */
(error) => {
console.log(error.target._req.res);
throw error;
}
),
onStompError: (
/* istanbul ignore next */
(error) => {
throw error;
}
)
});
}
client;
log = _log.extend("socket");
isActive = false;
webSocketFactory = (baseUrl, unitID) => () => {
const socketURL = new URL(baseUrl);
socketURL.protocol = "wss:";
socketURL.pathname = "ws";
socketURL.searchParams.set("organizationUnitId", unitID.toString());
this.log(`connecting to ${socketURL.href}`);
return new import_ws.default(socketURL.href, [], {
headers: websocketHeaders(this.mgl)
});
};
subscriptions = {};
activate() {
if (this.isActive)
return this.isActive;
this.isActive = new Promise((resolve) => {
this.client.onConnect = resolve;
this.client.activate();
});
return this.isActive;
}
unsubscribeAll() {
for (const [key, unsubscribe] of Object.entries(this.subscriptions)) {
unsubscribe();
delete this.subscriptions[key];
}
return this.deactivate();
}
deactivate() {
this.log("deactivating STOMP");
this.isActive = false;
return this.client.deactivate();
}
deactivateAutomatically() {
if (Object.entries(this.subscriptions).length === 0)
this.deactivate();
else
this.log("there are still active subscriptions, keeping stomp active");
}
/* eslint-disable @typescript-eslint/indent */
subscribeFactory = (topic) => async (callback) => {
await this.activate();
this.client.subscribe(topic, ({ body }) => callback(JSON.parse(body)));
this.log(`subscribed to "${topic}"`);
const unsubscribe = () => {
this.client.unsubscribe(topic);
delete this.subscriptions[topic];
this.deactivateAutomatically();
};
this.subscriptions[topic] = unsubscribe;
return this.subscriptions[topic];
};
/* eslint-enable @typescript-eslint/indent */
onCheckin = this.subscribeFactory("/user/topic/checkin");
};
// src/index.ts
var _log = (0, import_debug.default)("openmagicline");
var Openmagicline = class {
// TODO: check version and warn if openmagicline is outdated
constructor(config, axios) {
this.config = config;
this.log = _log.extend(config.gym);
this.baseUrl = `https://${this.config.gym}.web.magicline.com`;
const prefixUrl = `${this.baseUrl}/rest-api`;
const httpAxiosLog = this.log.extend("http");
if (axios)
this.axios = axios;
else {
this.axios = import_axios.default.create({
baseURL: prefixUrl,
headers: headers(this)
});
}
this.axios.interceptors.request.use((config2) => {
if (this.cookies)
config2.headers.cookie = this.cookies;
return config2;
});
this.axios.interceptors.response.use((response) => {
let log = `[${response.config.method}](${response.status}) `;
log += response.config.url;
if (response.status > 200)
log += `
${response.data}`;
httpAxiosLog(log);
return response;
});
(0, import_axios_auth_refresh.default)(this.axios, () => {
console.log("request failed, refreshing token");
return this.login();
});
this.customer = new Customer(this.axios, this);
this.locale = new Locale(this.axios);
this.organization = new Organization(this.axios, this);
this.checkin = new Checkin(this.axios, this);
this.util = new Util(this.axios, this);
this.sales = new Sales(this.axios, this);
this.disposal = this.sales;
this.socket = (unitID) => new MagicSocket(this, unitID);
}
log;
axios;
baseUrl;
cookies;
customer;
locale;
organization;
/** everything related to the checkin process */
checkin;
/** miscellaneous helpers and thingies */
util;
/** everything related to retail sales (magicline calls this disposal in some places) */
sales;
/** reference to this.sales */
disposal;
/** event handler for magiclines websockets */
socket;
_login = async (cookies) => {
if (cookies) {
this.cookies = cookies;
this.login = (0, import_once.default)(this._login);
if (await this.util.testLogin()) {
return this;
} else {
this.cookies = void 0;
throw new Error("invalid token");
}
}
try {
const { username, password } = this.config;
if (!username || !password)
throw new Error("username and password need to be set when cookies aren't provided");
const response = await this.axios.post(
"login",
searchParameters({ username, password, client: "webclient" }),
// @ts-expect-error i am too lazy to fix these types ngl
{ baseURL: this.baseUrl, skipAuthRefresh: true }
);
this.login = (0, import_once.default)(this._login);
this.cookies = response.headers["set-cookie"];
} catch (error_) {
this.cookies = void 0;
const error = error_?.response?.data?.error_description ? new Error(error_.response.data.error_description) : error_;
throw error;
}
return this;
};
/**
* authenticate the Openmagicline instance using username/password from the instance config.
*
* if a token is passed, it will be validated and the request to `/login` will be skipped.
* @param cookies existing cookies, available after login at `.cookies`
* @returns instance for chaining
* @throws when not authenticated
*/
login = (0, import_once.default)(this._login);
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Openmagicline,
_log
});