Skip to content

Commit

Permalink
fix: circular
Browse files Browse the repository at this point in the history
  • Loading branch information
arpowers committed Feb 8, 2022
1 parent 3ab5a94 commit 51faefc
Show file tree
Hide file tree
Showing 17 changed files with 256 additions and 218 deletions.
2 changes: 1 addition & 1 deletion @core/api/hook.ts
@@ -1,4 +1,4 @@
import { CallbackDictionary, UserConfigServer } from "."
import { CallbackDictionary, UserConfigServer } from "@factor/types"

export const runHooks = async <T extends keyof CallbackDictionary>(options: {
config: UserConfigServer
Expand Down
2 changes: 0 additions & 2 deletions @core/api/index.ts
@@ -1,7 +1,5 @@
/// <reference path="./shim.d.ts" />

if (typeof window !== "undefined") window.process.env = {}

export * from "@factor/types"
export * from "./_"
export * from "./endpoint"
Expand Down
2 changes: 0 additions & 2 deletions @core/cli/program.ts
@@ -1,6 +1,4 @@
import "@factor/server"
import { emitEvent, logger } from "@factor/api"

import { Command, OptionValues } from "commander"
import dotenv from "dotenv"
import path from "path"
Expand Down
18 changes: 9 additions & 9 deletions @core/engine/package.json
Expand Up @@ -7,6 +7,15 @@
"license": "MIT",
"type": "module",
"dependencies": {
"@types/bcrypt": "^5.0.0",
"@types/compression": "^1.7.0",
"@types/cors": "^2.8.10",
"@types/jsonwebtoken": "^8.5.0",
"@types/mime-types": "^2.1.0",
"@types/multer": "^1.4.5",
"@types/nodemailer": "^6.4.4",
"@types/nodemailer-html-to-text": "^3.1.0",
"@types/pg": "^8.0.0",
"@factor/api": "4.0.14",
"@factor/server": "4.0.14",
"@factor/types": "4.0.14",
Expand All @@ -32,15 +41,6 @@
"serve-static": "^1.14.1"
},
"devDependencies": {
"@types/bcrypt": "^5.0.0",
"@types/compression": "^1.7.0",
"@types/cors": "^2.8.10",
"@types/jsonwebtoken": "^8.5.0",
"@types/mime-types": "^2.1.0",
"@types/multer": "^1.4.5",
"@types/nodemailer": "^6.4.4",
"@types/nodemailer-html-to-text": "^3.1.0",
"@types/pg": "^8.0.0",
"vitest": "^0.2.0"
}
}
2 changes: 1 addition & 1 deletion @core/engine/query.ts
Expand Up @@ -5,7 +5,7 @@ import { logger } from "@factor/api"
import { _stop } from "@factor/api/error"
import { isNode } from "@factor/api/utils"
import { getDb } from "./db"
import { EndpointMeta } from "./endpoint"
import type { EndpointMeta } from "./endpoint"

export abstract class Query {
qu!: Knex // always set on server
Expand Down
8 changes: 7 additions & 1 deletion @core/lint/config.cjs
Expand Up @@ -82,7 +82,13 @@ module.exports = {
"func-style": ["warn", "expression"],
"no-async-promise-executor": "off",
"vue/no-v-html": "off",
"import/no-cycle": "off",
"import/no-cycle": [
"error",
{
maxDepth: 3,
ignoreExternal: true,
},
],
"import/no-unresolved": "off",
"import/named": "off",
"import/extensions": [
Expand Down
2 changes: 1 addition & 1 deletion @core/render/package.json
Expand Up @@ -37,6 +37,7 @@
"postcss": "^8.4.6",
"react": "^17.0.2",
"serve-favicon": "^2.5.0",
"@types/serve-favicon": "^2.5.2",
"serve-static": "^1.14.1",
"sitemap": "^7.0.0",
"string-similarity": "^4.0.4",
Expand All @@ -49,7 +50,6 @@
"devDependencies": {
"@factor/cli": "4.0.14",
"@types/compression": "^1.7.0",
"@types/serve-favicon": "^2.5.2",
"execa": "^6.0.0",
"fs-extra": "^10.0.0",
"handlebars": "^4.7.6",
Expand Down
2 changes: 1 addition & 1 deletion @core/render/serve.ts
Expand Up @@ -6,7 +6,7 @@ import express, { Express } from "express"
import serveFavicon from "serve-favicon"
import serveStatic from "serve-static"
import * as vite from "vite"
import { CliOptions } from "@factor/cli/program"
import type { CliOptions } from "@factor/cli/program"
import { getRequestHtml, htmlGenerators } from "./render"
import { getViteServer } from "./vite"

Expand Down
2 changes: 1 addition & 1 deletion @core/server/index.ts
Expand Up @@ -8,7 +8,7 @@ import { createEndpointServer } from "./create"
import { endpoints } from "./endpoint"
import { setServerConfig } from "./config"
import { UserConfigServer } from "@factor/types"
import { CliOptions } from "@factor/cli/program"
import type { CliOptions } from "@factor/cli/program"

export const setupServerEnv = async (
entryServerConfig: UserConfigServer = {},
Expand Down
2 changes: 1 addition & 1 deletion @plugins/plugin-highlight-code/package.json
Expand Up @@ -41,6 +41,6 @@
"javascript"
],
"devDependencies": {
"less": "^4.0.0"
"less": "^4.1.1"
}
}
7 changes: 6 additions & 1 deletion @plugins/plugin-stripe/endpoints.ts
Expand Up @@ -8,7 +8,12 @@ import {
EndpointManageAction,
EndpointMethodOptions,
} from "@factor/engine/endpoint"
import { paymentsSetting, CustomerData, stripeEnv, getStripeProducts } from "."
import {
paymentsSetting,
CustomerData,
stripeEnv,
getStripeProducts,
} from "./util"
import Stripe from "stripe"

type RefineResult = {
Expand Down
109 changes: 1 addition & 108 deletions @plugins/plugin-stripe/index.ts
@@ -1,110 +1,3 @@
import { FactorPluginConfigApp } from "@factor/types"
import * as StripeJS from "@stripe/stripe-js"
import type Stripe from "stripe"

export * from "./util"
export * from "./endpoints"

export interface StripePlanInfo {
plan: Stripe.Plan
product: Stripe.Product | Record<string, unknown>
}

export interface CustomerData {
customer?: Stripe.Customer | Stripe.DeletedCustomer
subscriptions?: Stripe.ApiList<Stripe.Subscription>
usage?: Stripe.ApiList<Stripe.UsageRecordSummary>
paymentMethods?: Stripe.ApiList<Stripe.PaymentMethod>
invoices?: Stripe.ApiList<Stripe.Invoice>
allProducts?: Stripe.Product[]
idempotencyKey: string
}

export interface SubscriptionDetails {
subscription: Stripe.Subscription
invoice?: Stripe.Invoice
isRetry?: boolean
priceId: string
paymentMethodId: string
customerId: string
}

type StripeHookCallback = (event: Stripe.Event) => Promise<any> | any

export type CreateSubscriptionArgs = Partial<SubscriptionDetails> &
Stripe.SubscriptionCreateParams

export type StripeOptions = {
hooks?: {
beforeCreateSubscription?: (
args: CreateSubscriptionArgs,
) => Promise<CreateSubscriptionArgs> | CreateSubscriptionArgs
onSubscriptionUpdate?: (sub: Stripe.Subscription) => Promise<any> | any
onSubscriptionTrialWillEnd?: StripeHookCallback
onInvoicePayment?: StripeHookCallback
onInvoicePaymentFailed?: StripeHookCallback
onCustomerSubscriptionDeleted?: StripeHookCallback
onCustomerCreated: (args: {
customer: Stripe.Customer
id: string
name?: string
email?: string
}) => Promise<any> | any
}
}

export const stripeEnv = (): "production" | "development" => {
let env = ""

if (process.env.TEST_ENV) {
env = "development"
} else {
env = process.env.STRIPE_ENV || process.env.NODE_ENV || "development"
}

return env as "production" | "development"
}

/**
* Doc engine settings utility
*/
let __settings: Partial<StripeOptions> = {}
export const paymentsSetting = <T extends keyof StripeOptions>(
key: T,
): Partial<StripeOptions>[T] => {
const v: Partial<StripeOptions>[T] = __settings[key]
return v
}

export const createSettings = (options: Partial<StripeOptions>): void => {
const defaultSettings: Partial<StripeOptions> = {}

__settings = { ...defaultSettings, ...options }
}

/**
* Get the stripe client using public key
* @singleton
*/
let __stripeClient: StripeJS.Stripe | undefined = undefined
export const getStripeClient = async (): Promise<StripeJS.Stripe> => {
if (!__stripeClient) {
const publicKey =
stripeEnv() == "production"
? process.env.STRIPE_PUBLIC_KEY
: process.env.STRIPE_PUBLIC_KEY_TEST

if (!publicKey) throw new Error("no stripe public key")

__stripeClient = (await StripeJS.loadStripe(publicKey)) ?? undefined
}

if (!__stripeClient) throw new Error("no stripe client created")

return __stripeClient
}

export default (options: Partial<StripeOptions>): FactorPluginConfigApp => {
createSettings(options)
return { name: "StripeApp" }
}
export * from "./subscription"
56 changes: 54 additions & 2 deletions @plugins/plugin-stripe/subscription.ts
@@ -1,5 +1,7 @@
import { objectId } from "@factor/api"
import type stripeNode from "stripe"
import { getStripeClient, SubscriptionDetails } from "."
import { getStripeClient, SubscriptionDetails } from "./util"
import { paymentEndpointsMap } from "./endpoints"
export const handleCardSetupRequired = async (
args: SubscriptionDetails,
): Promise<SubscriptionDetails | undefined> => {
Expand Down Expand Up @@ -117,7 +119,9 @@ export const handleRequiresPaymentMethod = async (
return args
}
}

type ManageResult = ReturnType<
typeof paymentEndpointsMap.ManageSubscription.request
>
export const checkPaymentMethod = async (
args: SubscriptionDetails,
): Promise<void> => {
Expand All @@ -127,3 +131,51 @@ export const checkPaymentMethod = async (

await handleRequiresPaymentMethod(args)
}

export const requestCreateSubscription = async (args: {
customerId: string
paymentMethodId: string
priceId: string
}): Promise<ManageResult> => {
const { customerId, paymentMethodId, priceId } = args

let result = await paymentEndpointsMap.ManageSubscription.request({
customerId,
paymentMethodId,
priceId,
_action: "create",
idempotencyKey: objectId(),
})

const subscription = result.data

if (
result.status == "success" &&
subscription &&
paymentMethodId &&
priceId &&
customerId
) {
const checkArgs = {
subscription,
customerId,
paymentMethodId,
priceId,
}
/**
* Run through stripe payment checks
* https://github.com/stripe-samples/subscription-use-cases/blob/master/usage-based-subscriptions/client/script.js
*/
await checkPaymentMethod(checkArgs)
/**
* If successful, retrieving subscription again will update its backend status
*/
result = await paymentEndpointsMap.ManageSubscription.request({
customerId,
_action: "retrieve",
subscriptionId: subscription.id,
})
}

return result
}

0 comments on commit 51faefc

Please sign in to comment.