Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 59 additions & 6 deletions docs/docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,82 @@ sidebar_position: 2

### Breaking Changes

### Capabilities deprecated
The `Salable` class has been replaced with a new `initSalable` function. Using the new initialise function will enable
vendors to use `v2` or `v3` of the API within the same version of the SDK.

**v4.0.0 implementation**
```typescript
const salable = new Salable('your-api-key', 'v2');
```
**v5.0.0 implementation**
```typescript
const salableV2 = initSalable('your-api-key', 'v2'); // v2 still supported
const salableV3 = initSalable('your-api-key', 'v3');
```

### V3 Breaking changes

#### Capabilities deprecated
Capabilities used to be stored on the License at the point of creation with no way of editing them. We found this to be
too rigid, for flexibility we have deprecated capabilities in favour of using the plan's feature values which are
editable in the Salable app.
#### Deprecated capabilities deprecated

##### Deprecated methods that use capabilities
- `plans.capabilities`
- `product.capabilities`
- `products.capabilities`
- `licenses.check`

### Licenses deprecated
#### Licenses deprecated
All license methods have been deprecated in favour of managing them through the subscription instead. This gives a
consistent implementation across all types of subscriptions.
- `licenses.create` moved to `subscriptions.create` - the `owner` value will be applied to the `purchaser` field of the license.
- `license.check` moved to `entitlements.check`
- `licenses.check` moved to `entitlements.check`
- `licenses.getAll` moved to `subscriptions.getSeats`
- `licenses.getOne` support removed
- `licenses.getOne` support removed - fetch the parent subscription instead using `subscriptions.getOne`
- `licenses.getForPurchaser` moved to `subscriptions.getAll` with the owner filter applied.
- `licenses.update` moved to `subscriptions.update`
- To update a seat's grantee use the `subscriptions.manageSeats` method.
- `licenses.updateMany` moved to `subscriptions.manageSeats`
- `licenses.getCount` moved to `subscriptions.getSeatCount`
- `licenses.cancel` moved to `subscriptions.cancel` - this will cancel all the subscription's child licenses.
- `licenses.cancelMany` moved to `subscriptions.cancel` - it is not possible to cancel many subscriptions in the same request.

#### Other deprecated endpoints
- `products.getFeatures` moved to `features.getAll` with the `productUuid` filter applied.
- `products.getPlans` moved to `plans.getAll` with the `productUuid` filter applied.
- `subscriptions.addSeats` moved to `subscriptions.updateSeatCount` with `increment` set.
- `subscriptions.removeSeats` moved to `subscriptions.updateSeatCount` with `decerement` set.

#### Affected responses
- `products.getAll` now uses cursor-based pagination in the response.

### What's new?
#### New methods
- `features.getAll` - Retrieves all features for an organisation. The response uses cursor-based pagination.
- `plans.getAll` - Retrieves all plans for an organisation. The response uses cursor-based pagination.
- `subscriptions.updateSeatCount` - v2 of the API required two different endpoints to add and remove seats on a per-seat subscription. In v3 this has been aligned under one method `subscriptions.updateSeatCount`.
- `entitlements.check` - Check grantee access to specific features (replaces `licenses.check`).

**v4.0.0 SDK with API v2**
```typescript
const salable = new Salable('your-api-key', 'v2');
const check = await salable.licenses.check({
productUuid: 'your-product-uuid',
granteeIds: ['your-grantee-id'],
});
const hasAccess = check?.capabilities.find((c) => c.capability === 'your-boolean-feature');
```

**v5.0.0 SDK with API v3**
```typescript
const salable = initSalable('your-api-key', 'v3');
const check = await salable.entitlements.check({
productUuid: 'your-product-uuid',
granteeIds: ['your-grantee-id'],
});
const hasAccess = check.features.find((f) => f.feature === 'your-boolean-feature');
```

## v4.0.0

### Breaking Changes
Expand Down
6 changes: 3 additions & 3 deletions src/pricing-tables/v2/pricing-table-v2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { testUuids } from '../../../test-utils/scripts/create-salable-test-data'
import { randomUUID } from 'crypto';
import { PricingTableSchema } from '../../schemas/v2/schemas-v2';

const pricingTableUuid = randomUUID();
describe('Pricing Table V2 Tests', () => {
const apiKey = testUuids.devApiKeyV2;
const salable = initSalable(apiKey, 'v2');
const pricingTableUuid = randomUUID();

beforeAll(async() => {
await generateTestData()
await generateTestData(pricingTableUuid)
})

it('getAll: should successfully fetch all pricing tables', async () => {
Expand All @@ -20,7 +20,7 @@ describe('Pricing Table V2 Tests', () => {
});


const generateTestData = async () => {
const generateTestData = async (pricingTableUuid: string) => {

const product = await prismaClient.product.findUnique({
where: { uuid: testUuids.productUuid },
Expand Down
7 changes: 4 additions & 3 deletions src/pricing-tables/v3/pricing-table-v3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { PricingTableSchemaV3 } from '../../schemas/v3/schemas-v3';
import { initSalable } from '../../index';
import { randomUUID } from 'crypto';

const pricingTableUuid = randomUUID();
describe('Pricing Table V3 Tests', () => {
const apiKey = testUuids.devApiKeyV3;
const salable = initSalable(apiKey, 'v3');
const pricingTableUuid = randomUUID();

beforeAll(async() => {
await generateTestData()
await generateTestData(pricingTableUuid)
})

it('getOne: should successfully fetch all pricing tables', async () => {
Expand All @@ -19,7 +20,7 @@ describe('Pricing Table V3 Tests', () => {
});


const generateTestData = async () => {
const generateTestData = async (pricingTableUuid: string) => {

const product = await prismaClient.product.findUnique({
where: { uuid: testUuids.productUuid },
Expand Down
6 changes: 1 addition & 5 deletions src/schemas/v3/schemas-v3.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import {
FeatureEnumOption,
FeatureV3,
Invoice,
LicenseV3,
OrganisationPaymentIntegrationV3,
PaginatedLicenses,
PaginatedSubscription,
PaginatedSubscriptionInvoice,
PlanCurrency,
PlanFeatureV3,
PlanV3,
PricingTableV3,
ProductCurrency,
ProductPricingTableV3,
ProductV3,
Subscription,
} from '../../types';
import { EnumValueSchema, LicenseSchema, SubscriptionSchema } from '../v2/schemas-v2';
import { EnumValueSchema} from '../v2/schemas-v2';

export const ProductSchemaV3: ProductV3 = {
uuid: expect.any(String),
Expand Down