Skip to content

Commit

Permalink
Merge pull request #14 from becomevocal/vercel-update
Browse files Browse the repository at this point in the history
Add Vercel support
  • Loading branch information
becomevocal authored Aug 22, 2022
2 parents 3ed1bb3 + 5bca3e9 commit 196cf8f
Show file tree
Hide file tree
Showing 32 changed files with 14,833 additions and 1,242 deletions.
26 changes: 3 additions & 23 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,18 @@
# Copy or rename this file to .env to make app installable on BigCommerce
# Follow the instructions in the readme file on how to get the BigCommerce App info needed here

# Environment
ENV_NAME=Local Dev
NODE_ENV=development

# Base Details
NEXT_PUBLIC_APP_URL=https://xxxxx-xxx-xxx-xx-x.ngrok.io
BCRYPT_SALT_ROUND=10

# Prisma Database Config
DATABASE_URL=file:./sqlite.db
DATABASE_URL=postgresql://xxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxx.co:5432/xxxxxxx

# BigCommerce Single Click App Details
# Found at https://devtools.bigcommerce.com/my/apps
NEXT_PUBLIC_APP_ID=12345
NEXT_PUBLIC_BC_APP_ID=12345
BC_APP_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
BC_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
BC_APP_CALLBACK_URL=$NEXT_PUBLIC_APP_URL/api/auth

# BigCommerce Channel Name
SUBSCRIPTION_CHANNEL_NAME=Stripe Subscriptions

# BigCommerce Customer Attribute Field & Metafield Names
SUBSCRIPTION_CUSTOMER_ATTRIBUTE_NAME=stripe_customer_id
SUBSCRIPTION_IDS_ATTRIBUTE_NAME=stripe_subscription_ids
SUBSCRIPTION_METAFIELD_KEY=subscription_config
SUBSCRIPTION_METAFIELD_NAMESPACE=Stripe Billing

# BigCommerce Content Mode
# 'script' or 'widget'
STOREFRONT_CONTENT_MODE=script

# Stripe API & Connect Details
STRIPE_SECRET_KEY=xx_xxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NEXT_PUBLIC_STRIPE_CLIENT_ID=xx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NEXT_PUBLIC_STRIPE_REDIRECT_URL=$NEXT_PUBLIC_APP_URL/stripe/callback
STRIPE_SECRET_KEY=xx_xxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
4 changes: 4 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "next",
"root": true
}
72 changes: 0 additions & 72 deletions .eslintrc.js

This file was deleted.

8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ All notable changes to this project will be documented in this file.
- Remove 'hours' subscription interval option which is not supported by the Stripe API
- Prevent empty descriptions from being sent to Stripe when creating or updating products
- Update sample .env file to use human readable names for customer attribute fields

### 0.9.2

- Audit and clean up dependencies
- Add support for Vercel, including a deploy button in the readme
- Add prebuild step to automate generation of prisma client and perform db migrations
- Reduce number of required env variables by moving non-private ones to constants
- Use customer attribute id from DB instead of hardcoded value in customer portal nav link template
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

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

## Deploy with Vercel

[![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)

## Key areas of codebase

Expand Down
8 changes: 4 additions & 4 deletions backend/controllers/base-bigcommerce-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { BigApi } from "../services/bigcommerce";
import { NextApiRequest } from "@/types/next";
import { NextApiResponse } from "next";
import { setCookieOnBackend } from "@/frontend/utils/cookies";
import { BC_APP_ID } from "@/constants/common";
import {
BC_APP_ID,
BC_APP_CLIENT_ID,
BC_APP_SECRET,
BC_APP_CALLBACK_URL,
Expand Down Expand Up @@ -51,9 +51,9 @@ export abstract class BaseBigCommerceController extends AuthApiController {
* @param api_version string - Version of the BigCommerce API to use (v2 or v3)
*/
public initBigApi(
api_version: string = "v3",
response_type: string = "json",
log_level: string = "info"
api_version = "v3",
response_type = "json",
log_level = "info"
) {
this.BigCommerceClient = new BigCommerce({
logLevel: log_level,
Expand Down
5 changes: 3 additions & 2 deletions backend/services/bigcommerce/scripts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
SUBSCRIPTION_METAFIELD_KEY,
SUBSCRIPTION_METAFIELD_NAMESPACE
} from "@/shared/constants/bigcommerce";
import { APP_URL } from "@/constants/common";
import BigBaseApi from "../big-base-api";

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

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

Expand Down
24 changes: 13 additions & 11 deletions backend/services/bigcommerce/webhooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import BigBaseApi from "../big-base-api";
import { APP_URL } from "@/constants/common";

export default class WebhooksApi extends BigBaseApi {
public baseUri = "/hooks";
Expand All @@ -11,8 +12,8 @@ export default class WebhooksApi extends BigBaseApi {
*/
public async get(hook_id?: number) {
let request_url: string = this.baseUri;
if(hook_id){
request_url += '/'+hook_id;
if (hook_id) {
request_url += "/" + hook_id;
}

return await this.client.get(request_url);
Expand All @@ -26,34 +27,36 @@ export default class WebhooksApi extends BigBaseApi {
public async create(scope: string) {
const body = {
scope: scope,
destination: process.env.NEXT_PUBLIC_APP_URL + this.callbackUri,
destination: APP_URL + this.callbackUri,
is_active: true
}
};

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

/**
* Set is_active value of specific webhook to true
* Set is_active value of specific webhook to true
* @param {number} hook_id - ID of the BigCommerce webhook to enable
* @returns {Promise}
*/
public async enable(hook_id: number) {
public async enable(hook_id: number) {
const body = {
is_active: true
}
};

return await this.client.put(this.baseUri + '/' + hook_id, body);
return await this.client.put(this.baseUri + "/" + hook_id, body);
}

/**
* Creates / updates BigCommerce webhooks necessary for the app to function end-to-end
*/
public async initAppWebhooks() {
const webhooks = await this.get();
const orderCreatedScope: string = 'store/order/created';
const orderCreatedScope = "store/order/created";
const existingWebhookScopes = webhooks.data.map(webhook => webhook.scope);
const existingOrderWebhook = webhooks.data.filter(webhook => webhook.scope === orderCreatedScope)[0];
const existingOrderWebhook = webhooks.data.filter(
webhook => webhook.scope === orderCreatedScope
)[0];

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

}
10 changes: 5 additions & 5 deletions backend/services/bigcommerce/widgets/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default class WidgetTemplateApi extends BigBaseApi {
public baseUri = "/content/widget-templates";

public getTemplate() {
let content = fs.readFileSync(
const content = fs.readFileSync(
`${process.cwd()}/src/templates/subscribe-and-save-widget.hbs`,
"utf8"
);
Expand All @@ -23,8 +23,8 @@ export default class WidgetTemplateApi extends BigBaseApi {
* @returns response
*/
public async create() {
var template_data = this.getTemplate();
var response = await this.client.post(this.baseUri, {
const template_data = this.getTemplate();
const response = await this.client.post(this.baseUri, {
name: "Subscription Widget Template",
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 } } } } } } } } }`,
schema: [
Expand Down Expand Up @@ -80,9 +80,9 @@ export default class WidgetTemplateApi extends BigBaseApi {
* @returns response
*/
public async update(uuid: string) {
var template_data = this.getTemplate();
const template_data = this.getTemplate();

var response = await this.client.put(`${this.baseUri}/${uuid}`, {
const response = await this.client.put(`${this.baseUri}/${uuid}`, {
name: "Subscription Widget",
template: template_data,
create_new_version: false
Expand Down
5 changes: 3 additions & 2 deletions backend/services/bigcommerce/widgets/widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
SUBSCRIPTION_METAFIELD_KEY,
SUBSCRIPTION_METAFIELD_NAMESPACE
} from "@/shared/constants/bigcommerce";
import { APP_URL } from "@/constants/common";
import BigBaseApi from "../big-base-api";

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

const widget_config = {
appUrl: process.env.NEXT_PUBLIC_APP_URL,
appUrl: APP_URL,
apiToken: store.storefrontToken,
subscriptionMetafieldNamespace: SUBSCRIPTION_METAFIELD_NAMESPACE,
subscriptionMetafieldKey: SUBSCRIPTION_METAFIELD_KEY,
Expand Down Expand Up @@ -63,7 +64,7 @@ export default class WidgetApi extends BigBaseApi {
const displaySetting = store.DisplaySetting;

const widget_config = {
appUrl: process.env.NEXT_PUBLIC_APP_URL,
appUrl: APP_URL,
apiToken: store.storefrontToken,
subscriptionMetafieldNamespace: SUBSCRIPTION_METAFIELD_NAMESPACE,
subscriptionMetafieldKey: SUBSCRIPTION_METAFIELD_KEY,
Expand Down
Loading

0 comments on commit 196cf8f

Please sign in to comment.