Skip to content

Commit

Permalink
parse URLs before passing them into the network client
Browse files Browse the repository at this point in the history
  • Loading branch information
janpaepke committed Feb 11, 2025
1 parent b695cf3 commit 3c92669
Show file tree
Hide file tree
Showing 13 changed files with 181 additions and 66 deletions.
8 changes: 6 additions & 2 deletions src/data/Helper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { inspect, type InspectOptionsStylized } from 'util';
import breakUrl from '../communication/breakUrl';
import type TransformingNetworkClient from '../communication/TransformingNetworkClient';
import buildFromEntries from '../plumbing/buildFromEntries';
import capitalize from '../plumbing/capitalize';
Expand Down Expand Up @@ -26,13 +27,16 @@ function convertToString(subject: Model<string>, tag: string, depth: number, opt
}

export default class Helper<R extends Model<string, Maybe<string>>, U> {
constructor(protected readonly networkClient: TransformingNetworkClient, protected readonly links: Links) {}
constructor(
protected readonly networkClient: TransformingNetworkClient,
protected readonly links: Links,
) {}

public refresh(): Promise<U>;
public refresh(callback: Callback<U>): void;
public refresh() {
if (renege(this, this.refresh, ...arguments)) return;
return this.networkClient.get<R, U>(this.links.self.href);
return this.networkClient.get<R, U>(...breakUrl(this.links.self.href));
}

public get [Symbol.toStringTag]() {
Expand Down
9 changes: 7 additions & 2 deletions src/data/chargebacks/ChargebackHelper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type TransformingNetworkClient from '../../communication/TransformingNetworkClient';
import breakUrl from '../../communication/breakUrl';
import renege from '../../plumbing/renege';
import resolveIf from '../../plumbing/resolveIf';
import type Callback from '../../types/Callback';
Expand All @@ -9,7 +10,11 @@ import type Chargeback from './Chargeback';
import { type ChargebackData } from './Chargeback';

export default class ChargebackHelper extends Helper<ChargebackData, Chargeback> {
constructor(networkClient: TransformingNetworkClient, protected readonly links: ChargebackData['_links'], protected readonly embedded: ChargebackData['_embedded']) {
constructor(
networkClient: TransformingNetworkClient,
protected readonly links: ChargebackData['_links'],
protected readonly embedded: ChargebackData['_embedded'],
) {
super(networkClient, links);
}

Expand All @@ -22,6 +27,6 @@ export default class ChargebackHelper extends Helper<ChargebackData, Chargeback>
public getPayment(callback: Callback<Array<Payment>>): void;
public getPayment() {
if (renege(this, this.getPayment, ...arguments)) return;
return resolveIf(this.embedded?.payment) ?? this.networkClient.get<PaymentData, Payment>(this.links.payment.href);
return resolveIf(this.embedded?.payment) ?? this.networkClient.get<PaymentData, Payment>(...breakUrl(this.links.payment.href));
}
}
28 changes: 24 additions & 4 deletions src/data/customers/CustomerHelper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { runIf } from 'ruply';
import type TransformingNetworkClient from '../../communication/TransformingNetworkClient';
import breakUrl from '../../communication/breakUrl';
import type HelpfulIterator from '../../plumbing/iteration/HelpfulIterator';
import emptyHelpfulIterator from '../../plumbing/iteration/emptyHelpfulIterator';
import { type ThrottlingParameter } from '../../types/parameters';
Expand All @@ -14,7 +15,10 @@ import type Mandate from './mandates/Mandate';
import { type MandateData } from './mandates/data';

export default class CustomerHelper extends Helper<CustomerData, Customer> {
constructor(networkClient: TransformingNetworkClient, protected readonly links: CustomerData['_links']) {
constructor(
networkClient: TransformingNetworkClient,
protected readonly links: CustomerData['_links'],
) {
super(networkClient, links);
}

Expand All @@ -24,7 +28,13 @@ export default class CustomerHelper extends Helper<CustomerData, Customer> {
* @since 3.6.0
*/
public getMandates(parameters?: ThrottlingParameter): HelpfulIterator<Mandate> {
return runIf(this.links.mandates, ({ href }) => this.networkClient.iterate<MandateData, Mandate>(href, 'mandates', undefined, parameters?.valuesPerMinute)) ?? emptyHelpfulIterator;
return (
runIf(
this.links.mandates,
({ href }) => breakUrl(href),
([pathname, query]) => this.networkClient.iterate<MandateData, Mandate>(pathname, 'mandates', query, parameters?.valuesPerMinute),
) ?? emptyHelpfulIterator
);
}

/**
Expand All @@ -34,7 +44,11 @@ export default class CustomerHelper extends Helper<CustomerData, Customer> {
*/
public getSubscriptions(parameters?: ThrottlingParameter): HelpfulIterator<Subscription> {
return (
runIf(this.links.subscriptions, ({ href }) => this.networkClient.iterate<SubscriptionData, Subscription>(href, 'subscriptions', undefined, parameters?.valuesPerMinute)) ?? emptyHelpfulIterator
runIf(
this.links.subscriptions,
({ href }) => breakUrl(href),
([pathname, query]) => this.networkClient.iterate<SubscriptionData, Subscription>(pathname, 'subscriptions', query, parameters?.valuesPerMinute),
) ?? emptyHelpfulIterator
);
}

Expand All @@ -44,6 +58,12 @@ export default class CustomerHelper extends Helper<CustomerData, Customer> {
* @since 3.6.0
*/
public getPayments(parameters?: ThrottlingParameter): HelpfulIterator<Payment> {
return runIf(this.links.payments, ({ href }) => this.networkClient.iterate<PaymentData, Payment>(href, 'payments', undefined, parameters?.valuesPerMinute)) ?? emptyHelpfulIterator;
return (
runIf(
this.links.payments,
({ href }) => breakUrl(href),
([pathname, query]) => this.networkClient.iterate<PaymentData, Payment>(pathname, 'payments', query, parameters?.valuesPerMinute),
) ?? emptyHelpfulIterator
);
}
}
10 changes: 7 additions & 3 deletions src/data/customers/mandates/MandateHelper.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import breakUrl from '../../../communication/breakUrl';
import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient';
import renege from '../../../plumbing/renege';
import type Callback from '../../../types/Callback';
import Helper from '../../Helper';
import type Customer from '../Customer';
import { type CustomerData } from '../Customer';
import { MandateStatus, type MandateData } from './data';
import { type MandateData } from './data';
import type Mandate from './Mandate';

export default class MandateHelper extends Helper<MandateData, Mandate> {
constructor(networkClient: TransformingNetworkClient, protected readonly links: MandateData['_links']) {
constructor(
networkClient: TransformingNetworkClient,
protected readonly links: MandateData['_links'],
) {
super(networkClient, links);
}

Expand All @@ -21,6 +25,6 @@ export default class MandateHelper extends Helper<MandateData, Mandate> {
public getCustomer(callback: Callback<Customer>): void;
public getCustomer() {
if (renege(this, this.getCustomer, ...arguments)) return;
return this.networkClient.get<CustomerData, Customer>(this.links.customer.href);
return this.networkClient.get<CustomerData, Customer>(...breakUrl(this.links.customer.href));
}
}
10 changes: 7 additions & 3 deletions src/data/onboarding/OnboardingHelper.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import breakUrl from '../../communication/breakUrl';
import type TransformingNetworkClient from '../../communication/TransformingNetworkClient';
import renege from '../../plumbing/renege';
import type Callback from '../../types/Callback';
import Helper from '../Helper';
import type Organization from '../organizations/Organizations';
import { type OrganizationData } from '../organizations/Organizations';
import { OnboardingStatus, type OnboardingData } from './data';
import { type OnboardingData } from './data';
import type Onboarding from './Onboarding';

export default class OnboardingHelper extends Helper<OnboardingData, Onboarding> {
constructor(networkClient: TransformingNetworkClient, protected readonly links: OnboardingData['_links']) {
constructor(
networkClient: TransformingNetworkClient,
protected readonly links: OnboardingData['_links'],
) {
super(networkClient, links);
}

Expand All @@ -21,6 +25,6 @@ export default class OnboardingHelper extends Helper<OnboardingData, Onboarding>
public getOrganization(callback: Callback<Organization>): void;
public getOrganization() {
if (renege(this, this.getOrganization, ...arguments)) return;
return this.networkClient.get<OrganizationData, Organization>(this.links.organization.href);
return this.networkClient.get<OrganizationData, Organization>(...breakUrl(this.links.organization.href));
}
}
11 changes: 6 additions & 5 deletions src/data/orders/OrderHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import type Shipment from './shipments/Shipment';
import { type ShipmentData } from './shipments/Shipment';

export default class OrderHelper extends Helper<OrderData, Order> {
constructor(networkClient: TransformingNetworkClient, protected readonly links: OrderData['_links'], protected readonly embedded: Order['_embedded']) {
constructor(
networkClient: TransformingNetworkClient,
protected readonly links: OrderData['_links'],
protected readonly embedded: Order['_embedded'],
) {
super(networkClient, links);
}

Expand Down Expand Up @@ -93,10 +97,7 @@ export default class OrderHelper extends Helper<OrderData, Order> {
* Recurring, authorized, paid and finalized orders do not have a checkout URL.
*/
public getCheckoutUrl(): Nullable<string> {
if (this.links.checkout == undefined) {
return null;
}
return this.links.checkout.href;
return this.links.checkout?.href ?? null;
}

/**
Expand Down
8 changes: 6 additions & 2 deletions src/data/orders/shipments/ShipmentHelper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import breakUrl from '../../../communication/breakUrl';
import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient';
import renege from '../../../plumbing/renege';
import type Callback from '../../../types/Callback';
Expand All @@ -8,7 +9,10 @@ import { type OrderData } from '../data';
import type Order from '../Order';

export default class ShipmentHelper extends Helper<ShipmentData, Shipment> {
constructor(networkClient: TransformingNetworkClient, protected readonly links: ShipmentData['_links']) {
constructor(
networkClient: TransformingNetworkClient,
protected readonly links: ShipmentData['_links'],
) {
super(networkClient, links);
}

Expand All @@ -21,6 +25,6 @@ export default class ShipmentHelper extends Helper<ShipmentData, Shipment> {
public getOrder(callback: Callback<Order>): void;
public getOrder() {
if (renege(this, this.getOrder, ...arguments)) return;
return this.networkClient.get<OrderData, Order>(this.links.order.href);
return this.networkClient.get<OrderData, Order>(...breakUrl(this.links.order.href));
}
}
48 changes: 31 additions & 17 deletions src/data/payments/PaymentHelper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { runIf } from 'ruply';
import type TransformingNetworkClient from '../../communication/TransformingNetworkClient';
import breakUrl from '../../communication/breakUrl';
import HelpfulIterator from '../../plumbing/iteration/HelpfulIterator';
import emptyHelpfulIterator from '../../plumbing/iteration/emptyHelpfulIterator';
import makeAsync from '../../plumbing/iteration/makeAsync';
Expand All @@ -22,7 +23,11 @@ import { type CaptureData } from './captures/data';
import { type BankTransferLinks, type PaymentData } from './data';

export default class PaymentHelper extends Helper<PaymentData, Payment> {
constructor(networkClient: TransformingNetworkClient, protected readonly links: PaymentData['_links'], protected readonly embedded: Payment['_embedded']) {
constructor(
networkClient: TransformingNetworkClient,
protected readonly links: PaymentData['_links'],
protected readonly embedded: Payment['_embedded'],
) {
super(networkClient, links);
}

Expand Down Expand Up @@ -87,10 +92,7 @@ export default class PaymentHelper extends Helper<PaymentData, Payment> {
* @see https://docs.mollie.com/reference/v2/payments-api/get-payment?path=_links/changePaymentState#response-parameters-for-recurring-payments
*/
public getChangePaymentStateUrl(): Nullable<string> {
if (this.links.changePaymentState == undefined) {
return null;
}
return this.links.changePaymentState.href;
return this.links.changePaymentState?.href ?? null;
}

/**
Expand All @@ -100,10 +102,7 @@ export default class PaymentHelper extends Helper<PaymentData, Payment> {
*/
public getPayOnlineUrl(): Nullable<string> {
const links = this.links as Partial<BankTransferLinks>;
if (links.payOnline == undefined) {
return null;
}
return links.payOnline.href;
return links.payOnline?.href ?? null;
}

/**
Expand All @@ -113,10 +112,7 @@ export default class PaymentHelper extends Helper<PaymentData, Payment> {
*/
public getStatusUrl(): Nullable<string> {
const links = this.links as Partial<BankTransferLinks>;
if (links.status == undefined) {
return null;
}
return links.status.href;
return links.status?.href ?? null;
}

/**
Expand All @@ -127,7 +123,11 @@ export default class PaymentHelper extends Helper<PaymentData, Payment> {
public getRefunds(parameters?: ThrottlingParameter): HelpfulIterator<Refund> {
return (
runIf(this.embedded?.refunds, refunds => new HelpfulIterator(makeAsync(refunds[Symbol.iterator]()))) ??
runIf(this.links.refunds, ({ href }) => this.networkClient.iterate<RefundData, Refund>(href, 'refunds', undefined, parameters?.valuesPerMinute)) ??
runIf(
this.links.refunds,
({ href }) => breakUrl(href),
([pathname, query]) => this.networkClient.iterate<RefundData, Refund>(pathname, 'refunds', query, parameters?.valuesPerMinute),
) ??
emptyHelpfulIterator
);
}
Expand All @@ -140,7 +140,11 @@ export default class PaymentHelper extends Helper<PaymentData, Payment> {
public getChargebacks(parameters?: ThrottlingParameter): HelpfulIterator<Chargeback> {
return (
runIf(this.embedded?.chargebacks, chargebacks => new HelpfulIterator(makeAsync(chargebacks[Symbol.iterator]()))) ??
runIf(this.links.chargebacks, ({ href }) => this.networkClient.iterate<ChargebackData, Chargeback>(href, 'chargebacks', undefined, parameters?.valuesPerMinute)) ??
runIf(
this.links.chargebacks,
({ href }) => breakUrl(href),
([pathname, query]) => this.networkClient.iterate<ChargebackData, Chargeback>(pathname, 'chargebacks', query, parameters?.valuesPerMinute),
) ??
emptyHelpfulIterator
);
}
Expand All @@ -153,7 +157,11 @@ export default class PaymentHelper extends Helper<PaymentData, Payment> {
public getCaptures(parameters?: ThrottlingParameter): HelpfulIterator<Capture> {
return (
runIf(this.embedded?.captures, captures => new HelpfulIterator(makeAsync(captures[Symbol.iterator]()))) ??
runIf(this.links.captures, ({ href }) => this.networkClient.iterate<CaptureData, Capture>(href, 'captures', undefined, parameters?.valuesPerMinute)) ??
runIf(
this.links.captures,
({ href }) => breakUrl(href),
([pathname, query]) => this.networkClient.iterate<CaptureData, Capture>(pathname, 'captures', query, parameters?.valuesPerMinute),
) ??
emptyHelpfulIterator
);
}
Expand All @@ -167,6 +175,12 @@ export default class PaymentHelper extends Helper<PaymentData, Payment> {
public getOrder(callback: Callback<Maybe<Order>>): void;
public getOrder() {
if (renege(this, this.getOrder, ...arguments)) return;
return runIf(this.links.order, ({ href }) => this.networkClient.get<OrderData, Order>(href)) ?? undefinedPromise;
return (
runIf(
this.links.order,
({ href }) => breakUrl(href),
([pathname, query]) => this.networkClient.get<OrderData, Order>(pathname, query),
) ?? undefinedPromise
);
}
}
27 changes: 22 additions & 5 deletions src/data/payments/captures/CaptureHelper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { runIf } from 'ruply';
import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient';
import breakUrl from '../../../communication/breakUrl';
import renege from '../../../plumbing/renege';
import resolveIf from '../../../plumbing/resolveIf';
import undefinedPromise from '../../../plumbing/undefinedPromise';
Expand All @@ -8,14 +9,18 @@ import type Maybe from '../../../types/Maybe';
import Helper from '../../Helper';
import type Shipment from '../../orders/shipments/Shipment';
import { type ShipmentData } from '../../orders/shipments/Shipment';
import type { Settlement, SettlementData } from '../../settlements/data';
import type Payment from '../Payment';
import { type PaymentData } from '../data';
import type Capture from './Capture';
import { type CaptureData } from './data';
import type { Settlement, SettlementData } from '../../settlements/data';

export default class CaptureHelper extends Helper<CaptureData, Capture> {
constructor(networkClient: TransformingNetworkClient, protected readonly links: CaptureData['_links'], protected readonly embedded: Capture['_embedded']) {
constructor(
networkClient: TransformingNetworkClient,
protected readonly links: CaptureData['_links'],
protected readonly embedded: Capture['_embedded'],
) {
super(networkClient, links);
}

Expand All @@ -28,7 +33,7 @@ export default class CaptureHelper extends Helper<CaptureData, Capture> {
public getPayment(callback: Callback<Array<Payment>>): void;
public getPayment() {
if (renege(this, this.getPayment, ...arguments)) return;
return resolveIf(this.embedded?.payment) ?? this.networkClient.get<PaymentData, Payment>(this.links.payment.href);
return resolveIf(this.embedded?.payment) ?? this.networkClient.get<PaymentData, Payment>(...breakUrl(this.links.payment.href));
}

/**
Expand All @@ -40,7 +45,13 @@ export default class CaptureHelper extends Helper<CaptureData, Capture> {
public getShipment(callback: Callback<Maybe<Shipment>>): void;
public getShipment() {
if (renege(this, this.getShipment, ...arguments)) return;
return runIf(this.links.shipment, ({ href }) => this.networkClient.get<ShipmentData, Shipment>(href)) ?? undefinedPromise;
return (
runIf(
this.links.shipment,
({ href }) => breakUrl(href),
([pathname, query]) => this.networkClient.get<ShipmentData, Shipment>(pathname, query),
) ?? undefinedPromise
);
}

/**
Expand All @@ -52,6 +63,12 @@ export default class CaptureHelper extends Helper<CaptureData, Capture> {
public getSettlement(callback: Callback<Maybe<Settlement>>): void;
public getSettlement() {
if (renege(this, this.getSettlement, ...arguments)) return;
return runIf(this.links.settlement, ({ href }) => this.networkClient.get<SettlementData, Settlement>(href)) ?? undefinedPromise;
return (
runIf(
this.links.settlement,
({ href }) => breakUrl(href),
([pathname, query]) => this.networkClient.get<SettlementData, Settlement>(pathname, query),
) ?? undefinedPromise
);
}
}
Loading

0 comments on commit 3c92669

Please sign in to comment.