From 75a95469b2b6a15dcc3d55b833825ca9fa2d4180 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 2 May 2024 16:19:27 -0300 Subject: [PATCH] feat(plugin-stripe): update plugin stripe for v3 (#6019) --- packages/plugin-stripe/package.json | 25 +++++++++++-------- packages/plugin-stripe/src/admin.ts | 8 +++--- .../plugin-stripe/src/fields/getFields.ts | 17 ++++++------- .../src/hooks/createNewInStripe.ts | 20 +++++++++------ .../src/hooks/deleteFromStripe.ts | 3 ++- .../src/hooks/syncExistingWithStripe.ts | 18 +++++++------ packages/plugin-stripe/src/index.ts | 7 +++--- packages/plugin-stripe/src/mocks/mockFile.js | 9 ------- packages/plugin-stripe/src/routes/rest.ts | 2 ++ packages/plugin-stripe/src/routes/webhooks.ts | 8 +++--- packages/plugin-stripe/src/ui/LinkToDoc.tsx | 14 +++++------ .../src/utilities/stripeProxy.ts | 2 +- .../src/webhooks/handleCreatedOrUpdated.ts | 17 +++++++------ .../src/webhooks/handleDeleted.ts | 3 ++- packages/plugin-stripe/src/webhooks/index.ts | 14 +++++------ pnpm-lock.yaml | 16 ++++++------ scripts/release.ts | 2 +- test/plugin-stripe/collections/Customers.ts | 16 ++++++------ test/plugin-stripe/config.ts | 2 +- 19 files changed, 104 insertions(+), 99 deletions(-) delete mode 100644 packages/plugin-stripe/src/mocks/mockFile.js diff --git a/packages/plugin-stripe/package.json b/packages/plugin-stripe/package.json index 5e22c7bf03..bd5618c532 100644 --- a/packages/plugin-stripe/package.json +++ b/packages/plugin-stripe/package.json @@ -24,8 +24,8 @@ "exports": { ".": { "import": "./src/index.ts", - "require": "./src/index.ts", - "types": "./src/index.ts" + "types": "./src/index.ts", + "default": "./src/index.ts" } }, "main": "./src/index.ts", @@ -36,12 +36,14 @@ "types.d.ts" ], "scripts": { - "build": "echo \"Build temporarily disabled.\" && exit 0", + "build": "pnpm copyfiles && pnpm build:swc && pnpm build:types", "build:swc": "swc ./src -d ./dist --config-file .swcrc", "build:types": "tsc --emitDeclarationOnly --outDir dist", "clean": "rimraf {dist,*.tsbuildinfo}", - "prepublishOnly": "pnpm clean && pnpm turbo run build && pnpm test", - "test": "echo 'No tests available.'" + "copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/", + "lint": "eslint src", + "lint:fix": "eslint --fix --ext .ts,.tsx src", + "prepublishOnly": "pnpm clean && pnpm turbo build" }, "dependencies": { "@payloadcms/ui": "workspace:*", @@ -51,17 +53,19 @@ }, "devDependencies": { "@payloadcms/eslint-config": "workspace:*", + "@payloadcms/next": "workspace:*", + "@payloadcms/translations": "workspace:*", + "@payloadcms/ui": "workspace:*", "@types/express": "^4.17.9", "@types/lodash.get": "^4.4.7", "@types/react": "18.2.74", "@types/uuid": "^9.0.0", - "payload": "workspace:*", - "prettier": "^2.7.1", - "webpack": "^5.78.0" + "payload": "workspace:*" }, "peerDependencies": { - "payload": "workspace:*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@payloadcms/translations": "workspace:*", + "@payloadcms/ui": "workspace:*", + "payload": "workspace:*" }, "publishConfig": { "exports": { @@ -72,6 +76,7 @@ } }, "main": "./dist/index.js", + "registry": "https://registry.npmjs.org/", "types": "./dist/index.d.ts" }, "homepage:": "https://payloadcms.com" diff --git a/packages/plugin-stripe/src/admin.ts b/packages/plugin-stripe/src/admin.ts index cdccab1991..92f0c24bfb 100644 --- a/packages/plugin-stripe/src/admin.ts +++ b/packages/plugin-stripe/src/admin.ts @@ -1,10 +1,10 @@ import type { Config } from 'payload/config' -import type { SanitizedStripeConfig, StripeConfig } from './types' +import type { SanitizedStripeConfig, StripeConfig } from './types.js' -import { getFields } from './fields/getFields' +import { getFields } from './fields/getFields.js' -const stripePlugin = +export const stripePlugin = (incomingStripeConfig: StripeConfig) => (config: Config): Config => { const { collections } = config @@ -42,5 +42,3 @@ const stripePlugin = }), } } - -export default stripePlugin diff --git a/packages/plugin-stripe/src/fields/getFields.ts b/packages/plugin-stripe/src/fields/getFields.ts index 19c4267df3..f680809799 100644 --- a/packages/plugin-stripe/src/fields/getFields.ts +++ b/packages/plugin-stripe/src/fields/getFields.ts @@ -1,8 +1,8 @@ import type { CollectionConfig, Field } from 'payload/types' -import type { SanitizedStripeConfig } from '../types' +import type { SanitizedStripeConfig } from '../types.js' -import { LinkToDoc } from '../ui/LinkToDoc' +import { LinkToDoc } from '../ui/LinkToDoc.js' interface Args { collection: CollectionConfig @@ -39,13 +39,12 @@ export const getFields = ({ collection, stripeConfig, syncConfig }: Args): Field type: 'ui', admin: { components: { - Field: (args) => - LinkToDoc({ - ...args, - isTestKey: stripeConfig.isTestKey, - nameOfIDField: 'stripeID', - stripeResourceType: syncConfig.stripeResourceType, - }), + Field: LinkToDoc, + }, + custom: { + isTestKey: stripeConfig.isTestKey, + nameOfIDField: 'stripeID', + stripeResourceType: syncConfig.stripeResourceType, }, position: 'sidebar', }, diff --git a/packages/plugin-stripe/src/hooks/createNewInStripe.ts b/packages/plugin-stripe/src/hooks/createNewInStripe.ts index 38b62c18f1..1f65d7337b 100644 --- a/packages/plugin-stripe/src/hooks/createNewInStripe.ts +++ b/packages/plugin-stripe/src/hooks/createNewInStripe.ts @@ -3,11 +3,12 @@ import type { CollectionBeforeValidateHook, CollectionConfig } from 'payload/typ import { APIError } from 'payload/errors' import Stripe from 'stripe' -import type { StripeConfig } from '../types' +import type { StripeConfig } from '../types.js' -import { deepen } from '../utilities/deepen' +import { deepen } from '../utilities/deepen.js' const stripeSecretKey = process.env.STRIPE_SECRET_KEY +// api version can only be the latest, stripe recommends ts ignoring it const stripe = new Stripe(stripeSecretKey || '', { apiVersion: '2022-08-01' }) type HookArgsWithCustomCollection = Omit< @@ -52,12 +53,15 @@ export const createNewInStripe: CollectionBeforeValidateHookWithArgs = async (ar if (syncConfig) { // combine all fields of this object and match their respective values within the document - let syncedFields = syncConfig.fields.reduce((acc, field) => { - const { fieldPath, stripeProperty } = field + let syncedFields = syncConfig.fields.reduce( + (acc, field) => { + const { fieldPath, stripeProperty } = field - acc[stripeProperty] = dataRef[fieldPath] - return acc - }, {} as Record) + acc[stripeProperty] = dataRef[fieldPath] + return acc + }, + {} as Record, + ) syncedFields = deepen(syncedFields) @@ -72,6 +76,7 @@ export const createNewInStripe: CollectionBeforeValidateHookWithArgs = async (ar try { // NOTE: Typed as "any" because the "create" method is not standard across all Stripe resources const stripeResource = await stripe?.[syncConfig.stripeResourceType]?.create( + // @ts-expect-error syncedFields, ) @@ -105,6 +110,7 @@ export const createNewInStripe: CollectionBeforeValidateHookWithArgs = async (ar // NOTE: Typed as "any" because the "create" method is not standard across all Stripe resources const stripeResource = await stripe?.[syncConfig.stripeResourceType]?.create( + // @ts-expect-error syncedFields, ) diff --git a/packages/plugin-stripe/src/hooks/deleteFromStripe.ts b/packages/plugin-stripe/src/hooks/deleteFromStripe.ts index 29576d3069..c0b17397e4 100644 --- a/packages/plugin-stripe/src/hooks/deleteFromStripe.ts +++ b/packages/plugin-stripe/src/hooks/deleteFromStripe.ts @@ -3,9 +3,10 @@ import type { CollectionAfterDeleteHook, CollectionConfig } from 'payload/types' import { APIError } from 'payload/errors' import Stripe from 'stripe' -import type { StripeConfig } from '../types' +import type { StripeConfig } from '../types.js' const stripeSecretKey = process.env.STRIPE_SECRET_KEY +// api version can only be the latest, stripe recommends ts ignoring it const stripe = new Stripe(stripeSecretKey || '', { apiVersion: '2022-08-01' }) type HookArgsWithCustomCollection = Omit[0], 'collection'> & { diff --git a/packages/plugin-stripe/src/hooks/syncExistingWithStripe.ts b/packages/plugin-stripe/src/hooks/syncExistingWithStripe.ts index 6c1ec8e5c8..dd1e010c67 100644 --- a/packages/plugin-stripe/src/hooks/syncExistingWithStripe.ts +++ b/packages/plugin-stripe/src/hooks/syncExistingWithStripe.ts @@ -3,11 +3,12 @@ import type { CollectionBeforeChangeHook, CollectionConfig } from 'payload/types import { APIError } from 'payload/errors' import Stripe from 'stripe' -import type { StripeConfig } from '../types' +import type { StripeConfig } from '../types.js' -import { deepen } from '../utilities/deepen' +import { deepen } from '../utilities/deepen.js' const stripeSecretKey = process.env.STRIPE_SECRET_KEY +// api version can only be the latest, stripe recommends ts ignoring it const stripe = new Stripe(stripeSecretKey || '', { apiVersion: '2022-08-01' }) type HookArgsWithCustomCollection = Omit< @@ -39,12 +40,15 @@ export const syncExistingWithStripe: CollectionBeforeChangeHookWithArgs = async if (syncConfig) { if (operation === 'update') { // combine all fields of this object and match their respective values within the document - let syncedFields = syncConfig.fields.reduce((acc, field) => { - const { fieldPath, stripeProperty } = field + let syncedFields = syncConfig.fields.reduce( + (acc, field) => { + const { fieldPath, stripeProperty } = field - acc[stripeProperty] = data[fieldPath] - return acc - }, {} as Record) + acc[stripeProperty] = data[fieldPath] + return acc + }, + {} as Record, + ) syncedFields = deepen(syncedFields) diff --git a/packages/plugin-stripe/src/index.ts b/packages/plugin-stripe/src/index.ts index 8817b61803..301bf74080 100644 --- a/packages/plugin-stripe/src/index.ts +++ b/packages/plugin-stripe/src/index.ts @@ -9,7 +9,10 @@ import { syncExistingWithStripe } from './hooks/syncExistingWithStripe.js' import { stripeREST } from './routes/rest.js' import { stripeWebhooks } from './routes/webhooks.js' -const stripePlugin = +export { LinkToDoc } from './ui/LinkToDoc.js' +export { stripeProxy } from './utilities/stripeProxy.js' + +export const stripePlugin = (incomingStripeConfig: StripeConfig) => (config: Config): Config => { const { collections } = config @@ -112,5 +115,3 @@ const stripePlugin = endpoints, } } - -export default stripePlugin diff --git a/packages/plugin-stripe/src/mocks/mockFile.js b/packages/plugin-stripe/src/mocks/mockFile.js deleted file mode 100644 index 266dba7fc2..0000000000 --- a/packages/plugin-stripe/src/mocks/mockFile.js +++ /dev/null @@ -1,9 +0,0 @@ -export const createNewInStripe = () => null -export const deleteFromStripe = () => null -export const stripeREST = () => null -export const stripeWebhooks = () => null -export const syncExistingWithStripe = () => null - -export default { - raw: () => {}, // mock express fn -} diff --git a/packages/plugin-stripe/src/routes/rest.ts b/packages/plugin-stripe/src/routes/rest.ts index 7503d3dc84..76709154f5 100644 --- a/packages/plugin-stripe/src/routes/rest.ts +++ b/packages/plugin-stripe/src/routes/rest.ts @@ -33,7 +33,9 @@ export const stripeREST = async (args: { } responseJSON = await stripeProxy({ + // @ts-expect-error stripeArgs, + // @ts-expect-error stripeMethod, stripeSecretKey, }) diff --git a/packages/plugin-stripe/src/routes/webhooks.ts b/packages/plugin-stripe/src/routes/webhooks.ts index f706391ae4..7d2b1dc803 100644 --- a/packages/plugin-stripe/src/routes/webhooks.ts +++ b/packages/plugin-stripe/src/routes/webhooks.ts @@ -19,6 +19,7 @@ export const stripeWebhooks = async (args: { if (stripeWebhooksEndpointSecret) { const stripe = new Stripe(stripeSecretKey, { + // api version can only be the latest, stripe recommends ts ignoring it apiVersion: '2022-08-01', appInfo: { name: 'Stripe Payload Plugin', @@ -26,17 +27,14 @@ export const stripeWebhooks = async (args: { }, }) + const body = await req.text() const stripeSignature = req.headers.get('stripe-signature') if (stripeSignature) { let event: Stripe.Event | undefined try { - event = stripe.webhooks.constructEvent( - await req.text(), - stripeSignature, - stripeWebhooksEndpointSecret, - ) + event = stripe.webhooks.constructEvent(body, stripeSignature, stripeWebhooksEndpointSecret) } catch (err: unknown) { const msg: string = err instanceof Error ? err.message : JSON.stringify(err) req.payload.logger.error(`Error constructing Stripe event: ${msg}`) diff --git a/packages/plugin-stripe/src/ui/LinkToDoc.tsx b/packages/plugin-stripe/src/ui/LinkToDoc.tsx index 7ce678144d..04ba99831b 100644 --- a/packages/plugin-stripe/src/ui/LinkToDoc.tsx +++ b/packages/plugin-stripe/src/ui/LinkToDoc.tsx @@ -1,17 +1,15 @@ +'use client' +import type { CustomComponent } from 'payload/config' import type { UIField } from 'payload/types' +import { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider' // import CopyToClipboard from 'payload/dist/admin/components/elements/CopyToClipboard' import { useFormFields } from '@payloadcms/ui/forms/Form' import React from 'react' -export const LinkToDoc: React.FC< - UIField & { - isTestKey: boolean - nameOfIDField: string - stripeResourceType: string - } -> = (props) => { - const { isTestKey, nameOfIDField, stripeResourceType } = props +export const LinkToDoc: CustomComponent = () => { + const { custom } = useFieldProps() + const { isTestKey, nameOfIDField, stripeResourceType } = custom const field = useFormFields(([fields]) => fields[nameOfIDField]) const { value: stripeID } = field || {} diff --git a/packages/plugin-stripe/src/utilities/stripeProxy.ts b/packages/plugin-stripe/src/utilities/stripeProxy.ts index 6b9d6b7eaf..ed4d1c0193 100644 --- a/packages/plugin-stripe/src/utilities/stripeProxy.ts +++ b/packages/plugin-stripe/src/utilities/stripeProxy.ts @@ -1,7 +1,7 @@ import lodashGet from 'lodash.get' import Stripe from 'stripe' -import type { StripeProxy } from '../types' +import type { StripeProxy } from '../types.js' export const stripeProxy: StripeProxy = async ({ stripeArgs, stripeMethod, stripeSecretKey }) => { const stripe = new Stripe(stripeSecretKey, { diff --git a/packages/plugin-stripe/src/webhooks/handleCreatedOrUpdated.ts b/packages/plugin-stripe/src/webhooks/handleCreatedOrUpdated.ts index 1c3e14442d..6f644cdec6 100644 --- a/packages/plugin-stripe/src/webhooks/handleCreatedOrUpdated.ts +++ b/packages/plugin-stripe/src/webhooks/handleCreatedOrUpdated.ts @@ -1,8 +1,8 @@ import { v4 as uuid } from 'uuid' -import type { SanitizedStripeConfig, StripeWebhookHandler } from '../types' +import type { SanitizedStripeConfig, StripeWebhookHandler } from '../types.js' -import { deepen } from '../utilities/deepen' +import { deepen } from '../utilities/deepen.js' type HandleCreatedOrUpdated = ( args: Parameters[0] & { @@ -62,12 +62,15 @@ export const handleCreatedOrUpdated: HandleCreatedOrUpdated = async (args) => { const foundDoc = payloadQuery.docs[0] as any // combine all properties of the Stripe doc and match their respective fields within the document - let syncedData = syncConfig.fields.reduce((acc, field) => { - const { fieldPath, stripeProperty } = field + let syncedData = syncConfig.fields.reduce( + (acc, field) => { + const { fieldPath, stripeProperty } = field - acc[fieldPath] = stripeDoc[stripeProperty] - return acc - }, {} as Record) + acc[fieldPath] = stripeDoc[stripeProperty] + return acc + }, + {} as Record, + ) syncedData = deepen({ ...syncedData, diff --git a/packages/plugin-stripe/src/webhooks/handleDeleted.ts b/packages/plugin-stripe/src/webhooks/handleDeleted.ts index 4242ee320f..5185a87e46 100644 --- a/packages/plugin-stripe/src/webhooks/handleDeleted.ts +++ b/packages/plugin-stripe/src/webhooks/handleDeleted.ts @@ -1,4 +1,4 @@ -import type { SanitizedStripeConfig, StripeWebhookHandler } from '../types' +import type { SanitizedStripeConfig, StripeWebhookHandler } from '../types.js' type HandleDeleted = ( args: Parameters[0] & { @@ -58,6 +58,7 @@ export const handleDeleted: HandleDeleted = async (args) => { if (logs) payload.logger.info(`- Deleting Payload document with ID: '${foundDoc.id}'...`) try { + // eslint-disable-next-line @typescript-eslint/no-floating-promises payload.delete({ id: foundDoc.id, collection: collectionSlug, diff --git a/packages/plugin-stripe/src/webhooks/index.ts b/packages/plugin-stripe/src/webhooks/index.ts index 97c36a56d6..1db3197cb4 100644 --- a/packages/plugin-stripe/src/webhooks/index.ts +++ b/packages/plugin-stripe/src/webhooks/index.ts @@ -1,9 +1,9 @@ -import type { StripeWebhookHandler } from '../types' +import type { StripeWebhookHandler } from '../types.js' -import { handleCreatedOrUpdated } from './handleCreatedOrUpdated' -import { handleDeleted } from './handleDeleted' +import { handleCreatedOrUpdated } from './handleCreatedOrUpdated.js' +import { handleDeleted } from './handleDeleted.js' -export const handleWebhooks: StripeWebhookHandler = async (args) => { +export const handleWebhooks: StripeWebhookHandler = (args) => { const { event, payload, stripeConfig } = args if (stripeConfig?.logs) @@ -21,7 +21,7 @@ export const handleWebhooks: StripeWebhookHandler = async (args) => { if (syncConfig) { switch (method) { case 'created': { - await handleCreatedOrUpdated({ + void handleCreatedOrUpdated({ ...args, resourceType, stripeConfig, @@ -30,7 +30,7 @@ export const handleWebhooks: StripeWebhookHandler = async (args) => { break } case 'updated': { - await handleCreatedOrUpdated({ + void handleCreatedOrUpdated({ ...args, resourceType, stripeConfig, @@ -39,7 +39,7 @@ export const handleWebhooks: StripeWebhookHandler = async (args) => { break } case 'deleted': { - await handleDeleted({ + void handleDeleted({ ...args, resourceType, stripeConfig, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 02a0eb6733..37d8ebd03b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1188,9 +1188,6 @@ importers: lodash.get: specifier: ^4.4.2 version: 4.4.2 - react: - specifier: ^18.0.0 - version: 18.2.0 stripe: specifier: ^10.2.0 version: 10.17.0 @@ -1201,6 +1198,12 @@ importers: '@payloadcms/eslint-config': specifier: workspace:* version: link:../eslint-config-payload + '@payloadcms/next': + specifier: workspace:* + version: link:../next + '@payloadcms/translations': + specifier: workspace:* + version: link:../translations '@types/express': specifier: ^4.17.9 version: 4.17.21 @@ -1216,12 +1219,6 @@ importers: payload: specifier: workspace:* version: link:../payload - prettier: - specifier: ^2.7.1 - version: 2.8.8 - webpack: - specifier: ^5.78.0 - version: 5.91.0(@swc/core@1.4.13)(esbuild@0.19.12)(webpack-cli@5.1.4) packages/richtext-lexical: dependencies: @@ -13875,6 +13872,7 @@ packages: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} hasBin: true + dev: false /prettier@3.2.5: resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} diff --git a/scripts/release.ts b/scripts/release.ts index 75d4908413..4575717483 100755 --- a/scripts/release.ts +++ b/scripts/release.ts @@ -52,7 +52,7 @@ const packageWhitelist = [ 'plugin-redirects', 'plugin-search', 'plugin-seo', - // 'plugin-stripe', + 'plugin-stripe', // 'plugin-sentry', ] diff --git a/test/plugin-stripe/collections/Customers.ts b/test/plugin-stripe/collections/Customers.ts index c8fe704008..b0e19f898b 100644 --- a/test/plugin-stripe/collections/Customers.ts +++ b/test/plugin-stripe/collections/Customers.ts @@ -1,6 +1,7 @@ import type { CollectionConfig } from 'payload/types' -import { LinkToDoc } from '../../../packages/plugin-stripe/src/ui/LinkToDoc.js' +import { LinkToDoc } from '@payloadcms/plugin-stripe' + import { customersSlug } from '../shared.js' export const Customers: CollectionConfig = { @@ -31,13 +32,12 @@ export const Customers: CollectionConfig = { type: 'ui', admin: { components: { - Field: (args) => - LinkToDoc({ - ...args, - isTestKey: process.env.PAYLOAD_PUBLIC_IS_STRIPE_TEST_KEY === 'true', - nameOfIDField: `${args.path}.stripeSubscriptionID`, - stripeResourceType: 'subscriptions', - }), + Field: LinkToDoc, + }, + custom: { + isTestKey: process.env.PAYLOAD_PUBLIC_IS_STRIPE_TEST_KEY === 'true', + nameOfIDField: `stripeSubscriptionID`, + stripeResourceType: 'subscriptions', }, }, label: 'Link', diff --git a/test/plugin-stripe/config.ts b/test/plugin-stripe/config.ts index 3a3437009c..307383d759 100644 --- a/test/plugin-stripe/config.ts +++ b/test/plugin-stripe/config.ts @@ -1,4 +1,4 @@ -import stripePlugin from '@payloadcms/plugin-stripe' +import { stripePlugin } from '@payloadcms/plugin-stripe' import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js' import { devUser } from '../credentials.js'