Skip to content

Commit f7083be

Browse files
authoredSep 8, 2022
Swell integration (#24)
* installed swell package * added types * added store classes * added products api route * adds more properties to products * added example env * types fixes * final changes
1 parent d8274e3 commit f7083be

11 files changed

+231
-0
lines changed
 

‎.env.example

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
DEFAULT_STORE="swell"
2+
3+
SWELL_STORE_ID=""
4+
SWELL_SECRET_KEY=""

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ yarn-error.log*
3636

3737
# typescript
3838
*.tsbuildinfo
39+
/.env

‎package-lock.json

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"react": "17.0.2",
1717
"react-dom": "17.0.2",
1818
"react-icons": "^4.4.0",
19+
"swell-node": "^4.0.10",
1920
"swiper": "^8.3.2"
2021
},
2122
"devDependencies": {

‎src/lib/Store.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import Swell from './Swell';
2+
3+
/*****************************************************************************
4+
* Wrapper class for given store client
5+
****************************************************************************/
6+
class Store {
7+
private storeClass;
8+
9+
constructor() {
10+
const defaultStore = process.env.DEFAULT_STORE as string;
11+
12+
if (defaultStore === 'swell') {
13+
this.storeClass = new Swell();
14+
} else {
15+
throw new Error('Store not found');
16+
}
17+
}
18+
19+
async getProducts(): Promise<Product[]> {
20+
return await this.storeClass.getProducts();
21+
}
22+
}
23+
24+
export default new Store();

‎src/lib/Swell.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { createClient } from 'swell-node';
2+
3+
/*****************************************************************************
4+
* Initialize Swell client
5+
****************************************************************************/
6+
const SWELL_STORE_ID = process.env.SWELL_STORE_ID as string;
7+
const SWELL_SECRET_KEY = process.env.SWELL_SECRET_KEY as string;
8+
const swell = createClient(SWELL_STORE_ID, SWELL_SECRET_KEY);
9+
10+
export default class Swell {
11+
/*****************************************************************************
12+
* Get products from Swell and transform into a list of Product objects
13+
****************************************************************************/
14+
async getProducts(): Promise<Product[]> {
15+
const { results }: { results: SwellProduct[] } = await swell.get('/products', {
16+
active: true
17+
});
18+
19+
return results.map((product) => ({
20+
id: product.id,
21+
name: product.name,
22+
active: product.active,
23+
description: product.description,
24+
slug: product.slug,
25+
tags: product.tags,
26+
price: product.price,
27+
sale: product.sale,
28+
sku: product.sku
29+
}));
30+
}
31+
}

‎src/pages/api/products.tsx

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type { NextApiRequest, NextApiResponse } from 'next';
2+
3+
import Store from '~/lib/Store';
4+
5+
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
6+
const products = await Store.getProducts();
7+
res.status(200).json(products);
8+
};
9+
10+
export default handler;

‎src/types/Environment.d.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
declare global {
2+
namespace NodeJS {
3+
interface ProcessEnv {
4+
SWELL_STORE_ID?: string;
5+
SWELL_SECRET_KEY?: string;
6+
}
7+
}
8+
}
9+
10+
// If this file has no import/export statements (i.e. is a script)
11+
// convert it into a module by adding an empty export statement.
12+
export {};

‎src/types/Generic/Products.d.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
interface Product {
2+
id: string;
3+
name: string;
4+
active: boolean;
5+
description: string;
6+
slug: string;
7+
tags: string[];
8+
price: number;
9+
images?: ProductImage[];
10+
sale?: boolean;
11+
sku?: string;
12+
}
13+
14+
interface ProductImage {
15+
url: string;
16+
alt?: string;
17+
}

‎src/types/Swell/Product.d.ts

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
interface SwellProduct {
2+
name: string;
3+
active: boolean;
4+
cross_sells: [];
5+
currency: string;
6+
date_created: string;
7+
date_updated: string;
8+
description: string;
9+
meta_title?: string;
10+
meta_description?: string;
11+
options: SwellProductOption[];
12+
slug: string;
13+
stock_tracking: boolean;
14+
tags: string[];
15+
type: string;
16+
up_sells: [];
17+
delivery: string;
18+
tax_class: string;
19+
price: number;
20+
stock_status: string;
21+
images: SwellProductImage[];
22+
stock_level: number;
23+
popularity: number;
24+
prices: [];
25+
sale: boolean;
26+
sale_price?: string;
27+
sku?: string;
28+
id: string;
29+
}
30+
31+
interface SwellProductImage {
32+
caption?: string;
33+
file: SwellProductFile;
34+
id: string;
35+
}
36+
37+
interface SwellProductFile {
38+
width: number;
39+
height: number;
40+
id: string;
41+
length: number;
42+
date_uploaded: string;
43+
content_type: string;
44+
md5: string;
45+
url: string;
46+
}
47+
48+
interface SwellProductOption {
49+
name: string;
50+
variant: boolean;
51+
active: boolean;
52+
values: {
53+
name: string;
54+
id: string;
55+
}[];
56+
required: boolean;
57+
id: string;
58+
}

‎src/types/Swell/swell-node.d.ts

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*****************************************************************************
2+
* Source: https://github.com/swellstores/swell-node/issues/11
3+
****************************************************************************/
4+
5+
declare module 'swell-node' {
6+
import EventEmitter from 'node:events';
7+
8+
type Callback<D, T> = (error: unknown, data?: D, response?: T) => void | Promise<void>;
9+
10+
interface SwellNodeClientParams {
11+
clientId?: string;
12+
clientKey?: string;
13+
host?: string;
14+
port?: string;
15+
verifyCert?: boolean;
16+
version?: string;
17+
session?: unknown;
18+
route?: unknown;
19+
timeout?: number;
20+
routeClientId?: string;
21+
cache?: boolean;
22+
debug?: boolean;
23+
}
24+
25+
interface SwellNodeClient extends EventEmitter {
26+
params: unknown;
27+
server: unknown;
28+
cache: unknown;
29+
authed: boolean;
30+
31+
// eslint-disable-next-line @typescript-eslint/no-misused-new
32+
new (
33+
clientId: string,
34+
clientKey: string,
35+
options?: SwellNodeClientParams,
36+
callback?: (arg: this) => void | Promise<void>
37+
): SwellNodeClient;
38+
create(
39+
clientId: string,
40+
clientKey: string,
41+
options?: SwellNodeClientParams,
42+
callback?: (arg: this) => void | Promise<void>
43+
): SwellNodeClient;
44+
init(clientId: string, clientKey: string, options?: SwellNodeClientParams): SwellNodeClient;
45+
connect(callback: (arg: this) => void | Promise<void>): void;
46+
request<T = unknown>(method: string, url: string, data?: unknown): Promise<T>;
47+
get<T = unknown>(url: string, data?: unknown): Promise<T>;
48+
post<T = unknown>(url: string, data?: unknown): Promise<T>;
49+
put<T = unknown>(url: string, data?: unknown): Promise<T>;
50+
delete<T = unknown>(url: string, data?: unknown): Promise<T>;
51+
}
52+
53+
export function createClient(
54+
clientId: string,
55+
clientKey: string,
56+
options?: SwellNodeClientParams,
57+
callback?: (arg: this) => void
58+
): SwellNodeClient;
59+
}

0 commit comments

Comments
 (0)
Please sign in to comment.