Last active
June 23, 2024 22:59
-
-
Save jayo78/512c5068c1b0bec61414e68be32a1335 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { FragileApiProduct, FragileApiProductCollection } from 'types'; | |
import fetch from 'node-fetch'; | |
export class FragileApi { | |
private static instance: FragileApi; | |
private readonly apiUrl: string; | |
private readonly tenantId: string; | |
private readonly authToken?: string; | |
constructor(apiUrl: string, tenantId: string, authToken?: string) { | |
if (!apiUrl || !tenantId) { | |
throw new Error( | |
`Fragile: Cannot instantiate Fragile API without URL or Tenant ID` | |
); | |
} | |
this.apiUrl = apiUrl; | |
this.tenantId = tenantId; | |
this.authToken = authToken; | |
} | |
public static getInstance(): FragileApi { | |
if (FragileApi.instance) { | |
return FragileApi.instance; | |
} | |
const { FRAGILE_API_URL, FRAGILE_TENANT_ID, FRAGILE_AUTH_TOKEN } = | |
process.env; | |
try { | |
const instance = new FragileApi( | |
FRAGILE_API_URL, | |
FRAGILE_TENANT_ID, | |
FRAGILE_AUTH_TOKEN | |
); | |
FragileApi.instance = instance; | |
return instance; | |
} catch (ex) { | |
throw new Error( | |
`Fragile: Missing environment variables FRAGILE_API_URL and/or FRAGILE_TENANT_ID` | |
); | |
} | |
} | |
public async getProducts(): Promise<{ data: FragileApiProduct[] }> { | |
const res = await fetch( | |
`${this.apiUrl}/products?expand=skus,price,upgrades`, | |
{ | |
method: 'GET', | |
headers: { | |
'Content-Type': 'application/json', | |
'x-fragile-tenant': this.tenantId, | |
...(this.authToken | |
? { Authorization: `Bearer ${this.authToken}` } | |
: {}), | |
}, | |
} | |
); | |
if (!res.ok) { | |
throw new Error('Fragile: Unable to fetch products from Fragile API'); | |
} | |
const resp = await res.json(); | |
return resp; | |
} | |
public async getProduct( | |
productId: string | |
): Promise<{ data: FragileApiProduct }> { | |
const res = await fetch( | |
`${this.apiUrl}/products/${productId}?expand=skus,price,upgrades`, | |
{ | |
method: 'GET', | |
headers: { | |
'Content-Type': 'application/json', | |
'x-fragile-tenant': this.tenantId, | |
...(this.authToken | |
? { Authorization: `Bearer ${this.authToken}` } | |
: {}), | |
}, | |
} | |
); | |
if (!res.ok) { | |
throw new Error('Fragile: Unable to fetch products from Fragile API'); | |
} | |
const resp = await res.json(); | |
return resp; | |
} | |
public async getProductCollection( | |
productCollectionId: string | |
): Promise<FragileApiProductCollection> { | |
const res = await fetch( | |
`${this.apiUrl}/product-collections/${productCollectionId}?expand=products`, | |
{ | |
method: 'GET', | |
headers: { | |
'Content-Type': 'application/json', | |
'x-fragile-tenant': this.tenantId, | |
...(this.authToken | |
? { Authorization: `Bearer ${this.authToken}` } | |
: {}), | |
}, | |
} | |
); | |
if (!res.ok) { | |
throw new Error('Fragile: Unable to fetch products from Fragile API'); | |
} | |
const resp = await res.json(); | |
const productCollection: FragileApiProductCollection = resp.data; | |
productCollection.products = ( | |
await Promise.all( | |
productCollection.products.map(p => this.getProduct(p.productId)) | |
) | |
).map(p => p.data); | |
return productCollection; | |
} | |
public getCollectionMonthlyPrice(productCollection: FragileApiProductCollection) { | |
return productCollection.products.reduce( | |
(acc, product) => | |
acc + | |
(product.price?.recurringInterval === 'MONTH' | |
? product.price?.amount ?? 0 | |
: 0), | |
0 | |
), | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* FRAGILE TYPES | |
*/ | |
export type FragileEntityBaseFields = { | |
tenantId: string; | |
id: string; | |
metadata: any; | |
}; | |
export type FragileApiPrice = FragileEntityBaseFields & { | |
isActive: boolean; | |
type: 'RECURRING' | 'ONE_TIME'; | |
recurringInterval: 'MONTH' | 'WEEK' | 'HOUR' | undefined; | |
recurringIntervalCount: number; | |
amount: number; | |
}; | |
export type FragileApiSku = FragileEntityBaseFields & { | |
name: string; | |
displayName: string; | |
type: 'DEVICE' | 'FEE' | 'MERCHANDISE' | 'PART' | 'SERVICE'; | |
}; | |
export type FragileApiUpgradeOption = FragileEntityBaseFields & { | |
name: string; | |
displayName: string; | |
displayOrder: number; | |
skus: FragileApiSku[]; | |
priceId: string | null; | |
price: FragileApiPrice | null; | |
isActive: boolean; | |
}; | |
export type FragileApiUpgrade = FragileEntityBaseFields & { | |
name: string; | |
displayName: string; | |
description: string; | |
displayOrder: number; | |
productId: string; | |
options: FragileApiUpgradeOption[]; | |
}; | |
export type FragileApiProduct = FragileEntityBaseFields & { | |
productId: string; | |
name: string; | |
displayName: string; | |
isTransactional: boolean; | |
requireScreening: boolean; | |
priceId: string; | |
price: FragileApiPrice; | |
skus: FragileApiSku[]; | |
upgrades: FragileApiUpgrade[]; | |
}; | |
export type FragileApiProductCollection = FragileEntityBaseFields & { | |
name: string; | |
displayName: string; | |
products: FragileApiProduct[]; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment