Skip to content

Commit

Permalink
Customer Portal Sessions (#74)
Browse files Browse the repository at this point in the history
* feat: add customer portal session resource

* chore: remove unused mock

Co-authored-by: davidgrayston-paddle <[email protected]>

* test: add url assertion

---------

Co-authored-by: davidgrayston-paddle <[email protected]>
  • Loading branch information
danbillson and davidgrayston-paddle authored Nov 21, 2024
1 parent af27a2f commit a3a192d
Show file tree
Hide file tree
Showing 21 changed files with 273 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ When we make [non-breaking changes](https://developer.paddle.com/api-reference/a

This means when upgrading minor versions of the SDK, you may notice type errors. You can safely ignore these or fix by adding additional type guards.

## 2.1.0 - 2024-11-21

### Added

- Added `customerPortalSessions` resources

## 2.0.0 - 2024-11-20

> **Breaking changes:** This version includes major improvements that introduce breaking changes. These are called out below.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@paddle/paddle-node-sdk",
"version": "2.0.0",
"version": "2.1.0",
"description": "A Node.js SDK that you can use to integrate Paddle Billing with applications written in server-side JavaScript.",
"main": "dist/cjs/index.cjs.node.js",
"module": "dist/esm/index.esm.node.js",
Expand Down
36 changes: 36 additions & 0 deletions src/__tests__/mocks/resources/customer-portal-sessions.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

import { ICustomerPortalSessionResponse } from '../../../types/index.js';
import { Response, ResponsePaginated } from '../../../internal/index.js';

export const CustomerPortalSessionMock: ICustomerPortalSessionResponse = {
id: 'cpls_01h4ge9r64c22exjsx0fy8b48b',
customer_id: 'ctm_123',
urls: {
general: {
overview:
'https://customer-portal.paddle.com/cpl_01j7zbyqs3vah3aafp4jf62qaw?action=overview&token=pga_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJjdG1fMDFncm5uNHp0YTVhMW1mMDJqanplN3kyeXMiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE3Mjc2NzkyMzh9._oO12IejzdKmyKTwb7BLjmiILkx4_cSyGjXraOBUI_g',
},
subscriptions: [
{
id: 'sub_123',
cancel_subscription:
'https://customer-portal.paddle.com/cpl_01j7zbyqs3vah3aafp4jf62qaw?action=cancel_subscription&subscription_id=sub_01h04vsc0qhwtsbsxh3422wjs4&token=pga_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJjdG1fMDFncm5uNHp0YTVhMW1mMDJqanplN3kyeXMiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE3Mjc2NzkyMzh9._oO12IejzdKmyKTwb7BLjmiILkx4_cSyGjXraOBUI_g',
update_subscription_payment_method:
'https://customer-portal.paddle.com/cpl_01j7zbyqs3vah3aafp4jf62qaw?action=update_subscription_payment_method&subscription_id=sub_01h04vsc0qhwtsbsxh3422wjs4&token=pga_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJjdG1fMDFncm5uNHp0YTVhMW1mMDJqanplN3kyeXMiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE3Mjc2NzkyMzh9._oO12IejzdKmyKTwb7BLjmiILkx4_cSyGjXraOBUI_g',
},
],
},
created_at: '2024-10-25T06:53:58Z',
};

export const CustomerPortalSessionMockResponse: Response<ICustomerPortalSessionResponse> = {
data: CustomerPortalSessionMock,
meta: {
request_id: '',
},
};
32 changes: 32 additions & 0 deletions src/__tests__/resources/customer-portal-sessions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

import { CustomerPortalSessionsResource } from '../../resources/index.js';
import { getPaddleTestClient } from '../helpers/test-client.js';
import {
CustomerPortalSessionMockResponse,
CustomerPortalSessionMock,
} from '../mocks/resources/customer-portal-sessions.mock.js';

describe('CustomerPortalSessionsResource', () => {
test('should create a new customer portal session', async () => {
const customerId = CustomerPortalSessionMock.customer_id;
const subscriptionIds = ['sub_123'];
const paddleInstance = getPaddleTestClient();
paddleInstance.post = jest.fn().mockResolvedValue(CustomerPortalSessionMockResponse);

const customerPortalSessionsResource = new CustomerPortalSessionsResource(paddleInstance);
const createdCustomerPortalSession = await customerPortalSessionsResource.create(customerId, subscriptionIds);

expect(paddleInstance.post).toBeCalledWith(`/customers/${customerId}/portal-sessions`, {
subscriptionIds,
});
expect(createdCustomerPortalSession).toBeDefined();
expect(createdCustomerPortalSession.id).toBeDefined();
expect(createdCustomerPortalSession.customerId).toBe(customerId);
expect(createdCustomerPortalSession.urls.subscriptions[0].id).toBe(subscriptionIds[0]);
});
});
22 changes: 22 additions & 0 deletions src/entities/customer-portal-session/customer-portal-session.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

import { type ICustomerPortalSessionResponse } from '../../types/index.js';
import { Urls } from './urls.js';

export class CustomerPortalSession {
public readonly id: string;
public readonly customerId: string | null;
public readonly urls: Urls;
public readonly createdAt: string;

constructor(customerPortalSessionResponse: ICustomerPortalSessionResponse) {
this.id = customerPortalSessionResponse.id;
this.customerId = customerPortalSessionResponse.customer_id;
this.urls = new Urls(customerPortalSessionResponse.urls);
this.createdAt = customerPortalSessionResponse.created_at;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

import { type ICustomerPortalSubscriptionUrl } from '../../types/index.js';

export class CustomerPortalSubscriptionUrl {
public readonly id: string;
public readonly cancelSubscription: string;
public readonly updateSubscriptionPaymentMethod: string;

constructor(customerPortalSubscriptionUrlResponse: ICustomerPortalSubscriptionUrl) {
this.id = customerPortalSubscriptionUrlResponse.id;
this.cancelSubscription = customerPortalSubscriptionUrlResponse.cancel_subscription;
this.updateSubscriptionPaymentMethod = customerPortalSubscriptionUrlResponse.update_subscription_payment_method;
}
}
15 changes: 15 additions & 0 deletions src/entities/customer-portal-session/general.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

import { type IGeneralResponse } from '../../types/index.js';

export class General {
public readonly overview: string;

constructor(generalResponse: IGeneralResponse) {
this.overview = generalResponse.overview;
}
}
8 changes: 8 additions & 0 deletions src/entities/customer-portal-session/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

export * from './customer-portal-subscription-url.js';
export * from './customer-portal-session.js';
21 changes: 21 additions & 0 deletions src/entities/customer-portal-session/urls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

import { type IUrlsResponse } from '../../types/index.js';
import { General } from './general.js';
import { CustomerPortalSubscriptionUrl } from './customer-portal-subscription-url.js';

export class Urls {
public readonly general: General;
public readonly subscriptions: CustomerPortalSubscriptionUrl[];

constructor(urlsResponse: IUrlsResponse) {
this.general = new General(urlsResponse.general);
this.subscriptions = urlsResponse.subscriptions?.map(
(subscription) => new CustomerPortalSubscriptionUrl(subscription) ?? [],
);
}
}
1 change: 1 addition & 0 deletions src/entities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from './price/index.js';
export * from './transaction/index.js';
export * from './adjustment/index.js';
export * from './customer/index.js';
export * from './customer-portal-session/index.js';
export * from './business/index.js';
export * from './subscription/index.js';
export * from './address/index.js';
Expand Down
3 changes: 3 additions & 0 deletions src/paddle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
AdjustmentsResource,
BusinessesResource,
CustomersResource,
CustomerPortalSessionsResource,
DiscountsResource,
EventTypesResource,
NotificationSettingsResource,
Expand Down Expand Up @@ -36,6 +37,7 @@ export class Paddle {
public transactions: TransactionsResource;
public adjustments: AdjustmentsResource;
public customers: CustomersResource;
public customerPortalSessions: CustomerPortalSessionsResource;
public addresses: AddressesResource;
public businesses: BusinessesResource;
public discounts: DiscountsResource;
Expand Down Expand Up @@ -64,6 +66,7 @@ export class Paddle {
this.transactions = new TransactionsResource(this.client);
this.adjustments = new AdjustmentsResource(this.client);
this.customers = new CustomersResource(this.client);
this.customerPortalSessions = new CustomerPortalSessionsResource(this.client);
this.addresses = new AddressesResource(this.client);
this.businesses = new BusinessesResource(this.client);
this.discounts = new DiscountsResource(this.client);
Expand Down
34 changes: 34 additions & 0 deletions src/resources/customer-portal-sessions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

import { CustomerPortalSession } from '../../entities/index.js';
import { type ICustomerPortalSessionResponse } from '../../types/index.js';
import { type ErrorResponse, type Response } from '../../internal';
import { BaseResource, PathParameters } from '../../internal/base';
import { type CreateCustomerPortalSessionRequestBody } from './operations/index.js';

const CustomerPortalSessionPaths = {
create: '/customers/{customer_id}/portal-sessions',
} as const;

export class CustomerPortalSessionsResource extends BaseResource {
public async create(customerId: string, subscriptionIds: string[]): Promise<CustomerPortalSession> {
const urlWithPathParams = new PathParameters(CustomerPortalSessionPaths.create, {
customer_id: customerId,
}).deriveUrl();

const response = await this.client.post<
CreateCustomerPortalSessionRequestBody,
Response<ICustomerPortalSessionResponse> | ErrorResponse
>(urlWithPathParams, {
subscriptionIds,
});

const data = this.handleResponse<ICustomerPortalSessionResponse>(response);

return new CustomerPortalSession(data);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

export interface CreateCustomerPortalSessionRequestBody {
subscriptionIds: string[];
}
7 changes: 7 additions & 0 deletions src/resources/customer-portal-sessions/operations/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

export * from './create-customer-portal-session-request-object.js';
1 change: 1 addition & 0 deletions src/resources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export * from './addresses/index.js';
export * from './adjustments/index.js';
export * from './businesses/index.js';
export * from './customers/index.js';
export * from './customer-portal-sessions/index.js';
export * from './discounts/index.js';
export * from './prices/index.js';
export * from './products/index.js';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

import { type IUrlsResponse } from './urls.js';

export interface ICustomerPortalSessionResponse {
id: string;
customer_id: string;
urls: IUrlsResponse;
created_at: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

export interface ICustomerPortalSubscriptionUrl {
id: string;
cancel_subscription: string;
update_subscription_payment_method: string;
}
9 changes: 9 additions & 0 deletions src/types/customer-portal-session/general.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

export interface IGeneralResponse {
overview: string;
}
10 changes: 10 additions & 0 deletions src/types/customer-portal-session/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

export * from './general.js';
export * from './customer-portal-subscription-url.js';
export * from './urls.js';
export * from './customer-portal-session-response.js';
13 changes: 13 additions & 0 deletions src/types/customer-portal-session/urls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* ! Autogenerated code !
* Do not make changes to this file.
* Changes may be overwritten as part of auto-generation.
*/

import { type IGeneralResponse } from './general.js';
import { type ICustomerPortalSubscriptionUrl } from './customer-portal-subscription-url.js';

export interface IUrlsResponse {
general: IGeneralResponse;
subscriptions: ICustomerPortalSubscriptionUrl[];
}
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from './price/index.js';
export * from './transaction/index.js';
export * from './adjustment/index.js';
export * from './customer/index.js';
export * from './customer-portal-session/index.js';
export * from './business/index.js';
export * from './subscription/index.js';
export * from './address/index.js';
Expand Down

0 comments on commit a3a192d

Please sign in to comment.