Skip to content

Commit

Permalink
009 - New product collections methods (#242)
Browse files Browse the repository at this point in the history
* changes to validateVoucher

* simple validations tests

* changelog

* Update tidy-comics-hear.md

* node 16.20

* node 16

* requested changes

* Update tidy-comics-hear.md

* Update generateRandomString.ts

* requested changes

* Update package.json

* Update package.json

* Update tidy-comics-hear.md

* Revert "node 16.20"

This reverts commit f869c79.

* minor changes

* Delete createCampaignWithOnePromotionTierAndRandomName.ts

* requested changes

* docs

* Revert "docs"

This reverts commit 4d1aa28.

* remove validations

* changeset

* Update tidy-comics-hear.md

* Update tidy-comics-hear.md

* Update README.md

* Update tidy-comics-hear.md

* Create CHANGESET-TAMPLATE.md

* Update tidy-comics-hear.md

* Update CHANGESET-TAMPLATE.md

* Update CHANGESET-TAMPLATE.md

* Update CHANGESET-TAMPLATE.md

* in progress

* done

* done

* Update ProductCollections.ts

* Update CHANGESET-TAMPLATE.md

* Update tidy-comics-hear.md

* Update CHANGESET-TAMPLATE.md

* Update CHANGESET-TAMPLATE.md

* Update CHANGESET-TAMPLATE.md

* Update tidy-comics-new.md

* dotenv in packages/sdk package.json

* requested changes

* Update tidy-comics-new.md

* few new tests, in progress

* Update ProductCollections.ts

* Update tidy-comics-hear.md

* Update package.json

* Delete tidy-comics-hear.md

* resolving conflicts

* :(

* Revert ":("

This reverts commit 1d4e35b.

* Update ProductCollections.ts

* domain and 0-level types

* use domain and 0-level types

* fix test

* change ProductCollectionResponseData to ProductCollectionSaved

* move utility types to separate file, update changeset

* update changeset

* fix export of utility types

* fix missing object property for ProductIdentity and SkuIdentity

* update readme

* change any to unknown

* restore missing definitions from readme

* add type assertion to tests

* get rid of types that are used only in one place

* update changeset

* add missing filters keys, do not use required for domain types

---------

Co-authored-by: p-zielinski <[email protected]>
  • Loading branch information
weronika-kurczyna and p-zielinski committed Oct 12, 2023
1 parent 5ce1e1e commit e135b17
Show file tree
Hide file tree
Showing 7 changed files with 454 additions and 0 deletions.
35 changes: 35 additions & 0 deletions .changeset/tidy-comics-new.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
'@voucherify/sdk': minor
---

Added missing methods covering Product Collections API.
- Added support for new endpoints:
- `GET POST /product-collections`,
- `GET DELETE /product-collections/{productCollectionId}`,
- `GET /product-collections/${productCollectionId}/products` [(examples of usage available in readme.md)](..%2F..%2Fpackages%2Fsdk%2FREADME.md)
- New exported types/interfaces in `ProductCollections.ts`:
- Domain types:
- ProductIdentity
- SkuIdentity
- ProductBase
- SkuBase
- ProductSaved
- SkuSaved
- ProductOrSkuIdentity
- ProductCollectionIdentity
- ProductCollectionSaved
- ProductCollectionBase
- StaticProductCollectionBase
- DynamicProductCollectionBase
- Filter
- Junction
- AllowedFiltersKeys
- FiltersCondition
- 0-level types:
- ProductCollectionsCreateRequestBody
- ProductCollectionsCreateResponseBody
- ProductCollectionsListRequestQuery
- ProductCollectionsListResponseBody
- ProductCollectionsGetResponseBody
- ProductCollectionsListProductsRequestQuery
- ProductCollectionsListProductsResponseBody
42 changes: 42 additions & 0 deletions packages/sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ client.campaigns.disable(campaignId)
client.campaigns.qualifications.examine(body)
client.campaigns.qualifications.examine(body, params)
```

---

### Distributions
Expand Down Expand Up @@ -897,6 +898,47 @@ client.products.importSkusCSV(filePath)
client.products.importCSV(filePath)
```

### Product Collections

Methods are provided within `client.productCollections.*` namespace.

- [List Product Collections](#list-product-collections)
- [Create Product Collections](#create-product-collection)
- [Get Product Collection](#get-product-collection)
- [Delete Product Collection](#delete-product-collection)
- [List Products in Collection](#list-products-in-collection)

#### [List Product Collections](https://docs.voucherify.io/reference/list-product-collections)

```javascript
client.productCollections.list()
```

#### [Create Product Collection](https://docs.voucherify.io/reference/create-product-collection)

```javascript
client.productCollections.create(productCollection)
```

#### [Get Product Collection](https://docs.voucherify.io/reference/get-product-collection)

```javascript
client.productCollections.get(productCollectionId)
```

#### [Delete Product Collection](https://docs.voucherify.io/reference/delete-product-collection)

```javascript
client.productCollections.delete(productCollectionId)
```


#### [List Products in Collection](https://docs.voucherify.io/reference/list-products-in-collection)

```javascript
client.productCollections.listProducts(productCollectionId)
```

---

### Rewards
Expand Down
44 changes: 44 additions & 0 deletions packages/sdk/src/ProductCollections.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as T from './types/ProductCollections'

import type { RequestController } from './RequestController'
import { encode } from './helpers'

export class ProductCollections {
constructor(private client: RequestController) {}
/**
* @see https://docs.voucherify.io/reference/create-product-collection
*/
public create(productCollection: T.ProductCollectionsCreateRequestBody) {
return this.client.post<T.ProductCollectionsCreateResponseBody>(`/product-collections`, productCollection)
}
/**
* @see https://docs.voucherify.io/reference/list-product-collections
*/
public list(params?: T.ProductCollectionsListRequestQuery) {
return this.client.get<T.ProductCollectionsListResponseBody>(`/product-collections`, params)
}

/**
* @see https://docs.voucherify.io/reference/delete-product-collection
*/
public delete(productCollectionId: string) {
return this.client.delete<{}>(`/product-collections/${encode(productCollectionId)}`)
}

/**
* @see https://docs.voucherify.io/reference/get-product-collection
*/
public get(productCollectionId: string) {
return this.client.get<T.ProductCollectionsGetResponseBody>(`/product-collections/${encode(productCollectionId)}`)
}

/**
* @see https://docs.voucherify.io/reference/list-products-in-collection
*/
public listProducts(productCollectionId: string, params?: T.ProductCollectionsListProductsRequestQuery) {
return this.client.get<T.ProductCollectionsListProductsResponseBody>(
`/product-collections/${encode(productCollectionId)}/products`,
params,
)
}
}
3 changes: 3 additions & 0 deletions packages/sdk/src/VoucherifyServerSide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { assert, isString, isObject, isOptionalString, environment } from './hel
import { ApiLimitsHandler } from './ApiLimitsHandler'
import { MetadataSchemas } from './MetadataSchemas'
import { Categories } from './Categories'
import { ProductCollections } from './ProductCollections'

export interface VoucherifyServerSideOptions {
/**
Expand Down Expand Up @@ -192,6 +193,7 @@ export function VoucherifyServerSide(options: VoucherifyServerSideOptions) {
const consents = new Consents(client)
const orders = new Orders(client)
const products = new Products(client)
const productCollections = new ProductCollections(client)
const rewards = new Rewards(client)
const loyalties = new Loyalties(client)
const segments = new Segments(client)
Expand All @@ -211,6 +213,7 @@ export function VoucherifyServerSide(options: VoucherifyServerSideOptions) {
consents,
orders,
products,
productCollections,
rewards,
loyalties,
segments,
Expand Down
164 changes: 164 additions & 0 deletions packages/sdk/src/types/ProductCollections.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { WithRequiredProperty } from './UtilityTypes'

// Domain types
// Product
export interface ProductIdentity {
id?: string
object?: 'product'
}

export interface SkuIdentity {
id?: string
product_id?: string
object?: 'sku'
}

export interface ProductBase {
name?: string | null
price?: number | null
attributes?: string[]
metadata?: Record<string, unknown>
}

export interface SkuBase {
sku?: string | null
price?: number | null
attributes?: Record<string, unknown>
metadata?: Record<string, unknown>
product?: Required<ProductIdentity> & Required<ProductBase> & { source_id: string | null; object: 'product' }
image_url?: string | null
}

export interface ProductSaved {
created_at?: string
updated_at?: string | null
image_url?: string | null
object?: 'product'
}

export interface SkuSaved {
created_at?: string
updated_at?: string | null
image_url?: string | null
object?: 'sku'
}

export type ProductOrSkuIdentity = Required<SkuIdentity> | Required<ProductIdentity>

// Product Collection
export interface ProductCollectionIdentity {
id?: string
}

export interface ProductCollectionSaved {
created_at?: string
object?: 'products_collection'
}

export type ProductCollectionBase = StaticProductCollectionBase | DynamicProductCollectionBase
export interface StaticProductCollectionBase {
name?: string
type?: 'STATIC'
products?: ProductOrSkuIdentity[]
}

export interface DynamicProductCollectionBase {
name?: string
type?: 'AUTO_UPDATE'
filter?: Filter
}

export type ProductCollection = ProductCollectionBase & ProductCollectionIdentity & ProductCollectionSaved

export type Filter = {
junction: Junction
} & Partial<Record<AllowedFiltersKeys, { conditions: Partial<Record<FiltersCondition, unknown>> }>>

export declare type Junction = 'and' | 'AND' | 'or' | 'OR'

export type AllowedFiltersKeys =
| 'id'
| 'name'
| 'attributes'
| 'source_id'
| 'price'
| 'image_url'
| 'product_id'
| 'skus'
| 'created_at'
| 'updated_at'
| 'object'
| `metadata.${string}`

export declare type FiltersCondition =
| '$in'
| '$not_in'
| '$is'
| '$is_days_ago'
| '$is_days_in_future'
| '$is_not'
| '$has_value'
| '$is_unknown'
| '$contains'
| '$not_contain'
| '$starts_with'
| '$ends_with'
| '$more_than'
| '$less_than'
| '$more_than_ago'
| '$less_than_ago'
| '$more_than_future'
| '$less_than_future'
| '$more_than_equal'
| '$less_than_equal'
| '$after'
| '$before'
| '$count'
| '$count_less'
| '$count_more'

// 0-level types

// create

export type ProductCollectionsCreateRequestBody =
| WithRequiredProperty<StaticProductCollectionBase, 'name' | 'type'>
| Required<DynamicProductCollectionBase>

export type ProductCollectionsCreateResponseBody = Required<ProductCollectionBase> &
Required<ProductCollectionIdentity> &
Required<ProductCollectionSaved>

// list
export interface ProductCollectionsListRequestQuery {
limit?: number
page?: number
order?: 'created_at' | '-created_at'
}

export interface ProductCollectionsListResponseBody {
object: 'list'
data_ref: 'data'
data: Required<ProductCollection>[]
total: number
}

// get

export type ProductCollectionsGetResponseBody = Required<ProductCollection>

// list products
export interface ProductCollectionsListProductsRequestQuery {
limit?: number
page?: number
}

export interface ProductCollectionsListProductsResponseBody {
object: 'list'
data_ref: 'data'
data: (
| (Required<SkuIdentity> & Required<SkuSaved> & Required<SkuBase> & { source_id: string | null })
| (Required<ProductIdentity> & Required<ProductSaved> & Required<ProductBase> & { source_id: string | null })
)[]
total: number
}
4 changes: 4 additions & 0 deletions packages/sdk/src/types/UtilityTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type WithRequiredProperty<Type, Key extends keyof Type> = Type &
{
[Property in Key]-?: Type[Property]
}
Loading

0 comments on commit e135b17

Please sign in to comment.