Skip to content

Commit 196cf8f

Browse files
authored
Merge pull request #14 from becomevocal/vercel-update
Add Vercel support
2 parents 3ed1bb3 + 5bca3e9 commit 196cf8f

32 files changed

Lines changed: 14833 additions & 1242 deletions

File tree

.env.sample

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,18 @@
22
# Copy or rename this file to .env to make app installable on BigCommerce
33
# Follow the instructions in the readme file on how to get the BigCommerce App info needed here
44

5-
# Environment
6-
ENV_NAME=Local Dev
7-
NODE_ENV=development
8-
95
# Base Details
106
NEXT_PUBLIC_APP_URL=https://xxxxx-xxx-xxx-xx-x.ngrok.io
11-
BCRYPT_SALT_ROUND=10
127

138
# Prisma Database Config
14-
DATABASE_URL=file:./sqlite.db
9+
DATABASE_URL=postgresql://xxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxx.co:5432/xxxxxxx
1510

1611
# BigCommerce Single Click App Details
1712
# Found at https://devtools.bigcommerce.com/my/apps
18-
NEXT_PUBLIC_APP_ID=12345
13+
NEXT_PUBLIC_BC_APP_ID=12345
1914
BC_APP_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2015
BC_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
21-
BC_APP_CALLBACK_URL=$NEXT_PUBLIC_APP_URL/api/auth
22-
23-
# BigCommerce Channel Name
24-
SUBSCRIPTION_CHANNEL_NAME=Stripe Subscriptions
25-
26-
# BigCommerce Customer Attribute Field & Metafield Names
27-
SUBSCRIPTION_CUSTOMER_ATTRIBUTE_NAME=stripe_customer_id
28-
SUBSCRIPTION_IDS_ATTRIBUTE_NAME=stripe_subscription_ids
29-
SUBSCRIPTION_METAFIELD_KEY=subscription_config
30-
SUBSCRIPTION_METAFIELD_NAMESPACE=Stripe Billing
31-
32-
# BigCommerce Content Mode
33-
# 'script' or 'widget'
34-
STOREFRONT_CONTENT_MODE=script
3516

3617
# Stripe API & Connect Details
37-
STRIPE_SECRET_KEY=xx_xxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3818
NEXT_PUBLIC_STRIPE_CLIENT_ID=xx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
39-
NEXT_PUBLIC_STRIPE_REDIRECT_URL=$NEXT_PUBLIC_APP_URL/stripe/callback
19+
STRIPE_SECRET_KEY=xx_xxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

.eslintrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": "next",
3+
"root": true
4+
}

.eslintrc.js

Lines changed: 0 additions & 72 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,11 @@ All notable changes to this project will be documented in this file.
99
- Remove 'hours' subscription interval option which is not supported by the Stripe API
1010
- Prevent empty descriptions from being sent to Stripe when creating or updating products
1111
- Update sample .env file to use human readable names for customer attribute fields
12+
13+
### 0.9.2
14+
15+
- Audit and clean up dependencies
16+
- Add support for Vercel, including a deploy button in the readme
17+
- Add prebuild step to automate generation of prisma client and perform db migrations
18+
- Reduce number of required env variables by moving non-private ones to constants
19+
- Use customer attribute id from DB instead of hardcoded value in customer portal nav link template

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
Head to the [Subscription Foundation](https://developer.bigcommerce.com/docs/ae2455ab4d3d8-subscription-foundation) article to begin!
1616

17+
## Deploy with Vercel
18+
19+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fbigcommerce%2Fsubscription-foundation&env=NEXT_PUBLIC_APP_URL,DATABASE_URL,NEXT_PUBLIC_BC_APP_ID,BC_APP_CLIENT_ID,BC_APP_SECRET,NEXT_PUBLIC_STRIPE_CLIENT_ID,STRIPE_SECRET_KEY&envDescription=View%20the%20Subscription%20Foudation%20docs%20for%20information%20on%20each%20ENV%20variable.&envLink=https%3A%2F%2Fdeveloper.bigcommerce.com%2Fdocs%2Fae2455ab4d3d8-subscription-foundation&project-name=bigcommerce-subscription-foundation&demo-title=Subscription%20Foundation&demo-description=Helps%20create%20custom%20subscription%20experiences%20for%20BigCommerce.&demo-url=https%3A%2F%2Fgithub.com%2Fbigcommerce%2Fsubscription-foundation%2Fraw%2Fmain%2Fsample-storefront.png&demo-image=https%3A%2F%2Fgithub.com%2Fbigcommerce%2Fsubscription-foundation%2Fraw%2Fmain%2Fsample-storefront.png)
1720

1821
## Key areas of codebase
1922

backend/controllers/base-bigcommerce-controller.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { BigApi } from "../services/bigcommerce";
33
import { NextApiRequest } from "@/types/next";
44
import { NextApiResponse } from "next";
55
import { setCookieOnBackend } from "@/frontend/utils/cookies";
6-
import { BC_APP_ID } from "@/constants/common";
76
import {
7+
BC_APP_ID,
88
BC_APP_CLIENT_ID,
99
BC_APP_SECRET,
1010
BC_APP_CALLBACK_URL,
@@ -51,9 +51,9 @@ export abstract class BaseBigCommerceController extends AuthApiController {
5151
* @param api_version string - Version of the BigCommerce API to use (v2 or v3)
5252
*/
5353
public initBigApi(
54-
api_version: string = "v3",
55-
response_type: string = "json",
56-
log_level: string = "info"
54+
api_version = "v3",
55+
response_type = "json",
56+
log_level = "info"
5757
) {
5858
this.BigCommerceClient = new BigCommerce({
5959
logLevel: log_level,

backend/services/bigcommerce/scripts/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
SUBSCRIPTION_METAFIELD_KEY,
55
SUBSCRIPTION_METAFIELD_NAMESPACE
66
} from "@/shared/constants/bigcommerce";
7+
import { APP_URL } from "@/constants/common";
78
import BigBaseApi from "../big-base-api";
89

910
const SubscriptWidgetScriptName = "Subscription Widget Script";
@@ -24,7 +25,7 @@ export default class ScriptsApi extends BigBaseApi {
2425

2526
const templateData = {
2627
...store.DisplaySetting,
27-
appUrl: process.env.NEXT_PUBLIC_APP_URL,
28+
appUrl: APP_URL,
2829
apiToken: store.storefrontToken,
2930
subscriptionMetafieldNamespace: SUBSCRIPTION_METAFIELD_NAMESPACE,
3031
subscriptionMetafieldKey: SUBSCRIPTION_METAFIELD_KEY
@@ -33,7 +34,7 @@ export default class ScriptsApi extends BigBaseApi {
3334
// Replace Handlebar variables in template, since we want to be able to reuse between Widgets and Scripts
3435
// (Widgets store custom config variables which are replaced as they are rendered, while Scripts support Stencil objects only)
3536
for (const key in templateData) {
36-
let re = new RegExp(`{{${key}}}`, 'g');
37+
const re = new RegExp(`{{${key}}}`, "g");
3738
content = content.replace(re, templateData[key]);
3839
}
3940

backend/services/bigcommerce/webhooks/index.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import BigBaseApi from "../big-base-api";
2+
import { APP_URL } from "@/constants/common";
23

34
export default class WebhooksApi extends BigBaseApi {
45
public baseUri = "/hooks";
@@ -11,8 +12,8 @@ export default class WebhooksApi extends BigBaseApi {
1112
*/
1213
public async get(hook_id?: number) {
1314
let request_url: string = this.baseUri;
14-
if(hook_id){
15-
request_url += '/'+hook_id;
15+
if (hook_id) {
16+
request_url += "/" + hook_id;
1617
}
1718

1819
return await this.client.get(request_url);
@@ -26,34 +27,36 @@ export default class WebhooksApi extends BigBaseApi {
2627
public async create(scope: string) {
2728
const body = {
2829
scope: scope,
29-
destination: process.env.NEXT_PUBLIC_APP_URL + this.callbackUri,
30+
destination: APP_URL + this.callbackUri,
3031
is_active: true
31-
}
32+
};
3233

3334
return await this.client.post(this.baseUri, body);
3435
}
3536

3637
/**
37-
* Set is_active value of specific webhook to true
38+
* Set is_active value of specific webhook to true
3839
* @param {number} hook_id - ID of the BigCommerce webhook to enable
3940
* @returns {Promise}
4041
*/
41-
public async enable(hook_id: number) {
42+
public async enable(hook_id: number) {
4243
const body = {
4344
is_active: true
44-
}
45+
};
4546

46-
return await this.client.put(this.baseUri + '/' + hook_id, body);
47+
return await this.client.put(this.baseUri + "/" + hook_id, body);
4748
}
4849

4950
/**
5051
* Creates / updates BigCommerce webhooks necessary for the app to function end-to-end
5152
*/
5253
public async initAppWebhooks() {
5354
const webhooks = await this.get();
54-
const orderCreatedScope: string = 'store/order/created';
55+
const orderCreatedScope = "store/order/created";
5556
const existingWebhookScopes = webhooks.data.map(webhook => webhook.scope);
56-
const existingOrderWebhook = webhooks.data.filter(webhook => webhook.scope === orderCreatedScope)[0];
57+
const existingOrderWebhook = webhooks.data.filter(
58+
webhook => webhook.scope === orderCreatedScope
59+
)[0];
5760

5861
if (existingWebhookScopes.indexOf(orderCreatedScope) === -1) {
5962
// If the webhook doesn't exist, create it
@@ -65,5 +68,4 @@ export default class WebhooksApi extends BigBaseApi {
6568
}
6669
}
6770
}
68-
6971
}

backend/services/bigcommerce/widgets/template.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default class WidgetTemplateApi extends BigBaseApi {
1010
public baseUri = "/content/widget-templates";
1111

1212
public getTemplate() {
13-
let content = fs.readFileSync(
13+
const content = fs.readFileSync(
1414
`${process.cwd()}/src/templates/subscribe-and-save-widget.hbs`,
1515
"utf8"
1616
);
@@ -23,8 +23,8 @@ export default class WidgetTemplateApi extends BigBaseApi {
2323
* @returns response
2424
*/
2525
public async create() {
26-
var template_data = this.getTemplate();
27-
var response = await this.client.post(this.baseUri, {
26+
const template_data = this.getTemplate();
27+
const response = await this.client.post(this.baseUri, {
2828
name: "Subscription Widget Template",
2929
storefront_api_query: `query Product($productId: Int) { site { product(entityId: $productId) { variants { edges { node { metafields( namespace: "${SUBSCRIPTION_METAFIELD_NAMESPACE}", keys: ["${SUBSCRIPTION_METAFIELD_KEY}"] ) { edges { node { key value } } } } } } } } }`,
3030
schema: [
@@ -80,9 +80,9 @@ export default class WidgetTemplateApi extends BigBaseApi {
8080
* @returns response
8181
*/
8282
public async update(uuid: string) {
83-
var template_data = this.getTemplate();
83+
const template_data = this.getTemplate();
8484

85-
var response = await this.client.put(`${this.baseUri}/${uuid}`, {
85+
const response = await this.client.put(`${this.baseUri}/${uuid}`, {
8686
name: "Subscription Widget",
8787
template: template_data,
8888
create_new_version: false

backend/services/bigcommerce/widgets/widget.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
SUBSCRIPTION_METAFIELD_KEY,
44
SUBSCRIPTION_METAFIELD_NAMESPACE
55
} from "@/shared/constants/bigcommerce";
6+
import { APP_URL } from "@/constants/common";
67
import BigBaseApi from "../big-base-api";
78

89
export default class WidgetApi extends BigBaseApi {
@@ -24,7 +25,7 @@ export default class WidgetApi extends BigBaseApi {
2425
const displaySetting = store.DisplaySetting;
2526

2627
const widget_config = {
27-
appUrl: process.env.NEXT_PUBLIC_APP_URL,
28+
appUrl: APP_URL,
2829
apiToken: store.storefrontToken,
2930
subscriptionMetafieldNamespace: SUBSCRIPTION_METAFIELD_NAMESPACE,
3031
subscriptionMetafieldKey: SUBSCRIPTION_METAFIELD_KEY,
@@ -63,7 +64,7 @@ export default class WidgetApi extends BigBaseApi {
6364
const displaySetting = store.DisplaySetting;
6465

6566
const widget_config = {
66-
appUrl: process.env.NEXT_PUBLIC_APP_URL,
67+
appUrl: APP_URL,
6768
apiToken: store.storefrontToken,
6869
subscriptionMetafieldNamespace: SUBSCRIPTION_METAFIELD_NAMESPACE,
6970
subscriptionMetafieldKey: SUBSCRIPTION_METAFIELD_KEY,

0 commit comments

Comments
 (0)