@payloadcms/plugin-stripe 4.0.0-canary.33 → 4.0.0-canary.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin.d.ts.map +1 -1
- package/dist/admin.js +4 -2
- package/dist/admin.js.map +1 -1
- package/dist/exports/types.d.ts +1 -1
- package/dist/exports/types.d.ts.map +1 -1
- package/dist/exports/types.js.map +1 -1
- package/dist/fields/getFields.d.ts.map +1 -1
- package/dist/fields/getFields.js +8 -0
- package/dist/fields/getFields.js.map +1 -1
- package/dist/hooks/createNewInStripe.d.ts.map +1 -1
- package/dist/hooks/createNewInStripe.js +6 -7
- package/dist/hooks/createNewInStripe.js.map +1 -1
- package/dist/hooks/syncExistingWithStripe.d.ts.map +1 -1
- package/dist/hooks/syncExistingWithStripe.js +6 -7
- package/dist/hooks/syncExistingWithStripe.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/index.spec.js +73 -0
- package/dist/index.spec.js.map +1 -0
- package/dist/routes/rest.d.ts +3 -3
- package/dist/routes/rest.d.ts.map +1 -1
- package/dist/routes/rest.js +104 -27
- package/dist/routes/rest.js.map +1 -1
- package/dist/routes/rest.spec.js +275 -0
- package/dist/routes/rest.spec.js.map +1 -0
- package/dist/types.d.ts +10 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/deepen.d.ts +6 -0
- package/dist/utilities/deepen.d.ts.map +1 -1
- package/dist/utilities/deepen.js +33 -3
- package/dist/utilities/deepen.js.map +1 -1
- package/dist/utilities/deepen.spec.js +110 -0
- package/dist/utilities/deepen.spec.js.map +1 -0
- package/dist/utilities/sanitizeStripeRESTConfig.d.ts +5 -0
- package/dist/utilities/sanitizeStripeRESTConfig.d.ts.map +1 -0
- package/dist/utilities/sanitizeStripeRESTConfig.js +25 -0
- package/dist/utilities/sanitizeStripeRESTConfig.js.map +1 -0
- package/dist/utilities/sanitizeStripeRESTConfig.spec.js +116 -0
- package/dist/utilities/sanitizeStripeRESTConfig.spec.js.map +1 -0
- package/dist/webhooks/handleCreatedOrUpdated.d.ts.map +1 -1
- package/dist/webhooks/handleCreatedOrUpdated.js +6 -6
- package/dist/webhooks/handleCreatedOrUpdated.js.map +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { sanitizeStripeRESTConfig } from './sanitizeStripeRESTConfig.js';
|
|
3
|
+
describe('sanitizeStripeRESTConfig', ()=>{
|
|
4
|
+
it('should disable the REST endpoint when configuration is absent', ()=>{
|
|
5
|
+
expect(sanitizeStripeRESTConfig({
|
|
6
|
+
rest: undefined
|
|
7
|
+
})).toBeUndefined();
|
|
8
|
+
});
|
|
9
|
+
it('should treat false from an untyped configuration as disabled', ()=>{
|
|
10
|
+
expect(sanitizeStripeRESTConfig({
|
|
11
|
+
rest: false
|
|
12
|
+
})).toBeUndefined();
|
|
13
|
+
});
|
|
14
|
+
it('should return a new configuration with exact, de-duplicated, frozen methods', ()=>{
|
|
15
|
+
const access = vi.fn(()=>true);
|
|
16
|
+
const rest = {
|
|
17
|
+
access,
|
|
18
|
+
allowedMethods: [
|
|
19
|
+
'subscriptions.list',
|
|
20
|
+
' paymentIntents.retrieve ',
|
|
21
|
+
'subscriptions.list'
|
|
22
|
+
]
|
|
23
|
+
};
|
|
24
|
+
const sanitized = sanitizeStripeRESTConfig({
|
|
25
|
+
rest
|
|
26
|
+
});
|
|
27
|
+
expect(sanitized).not.toBe(rest);
|
|
28
|
+
expect(sanitized).toEqual({
|
|
29
|
+
access,
|
|
30
|
+
allowedMethods: [
|
|
31
|
+
'subscriptions.list',
|
|
32
|
+
' paymentIntents.retrieve '
|
|
33
|
+
]
|
|
34
|
+
});
|
|
35
|
+
expect(Object.isFrozen(sanitized.allowedMethods)).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
it.each([
|
|
38
|
+
[
|
|
39
|
+
'the legacy boolean form',
|
|
40
|
+
true
|
|
41
|
+
],
|
|
42
|
+
[
|
|
43
|
+
'an array',
|
|
44
|
+
[
|
|
45
|
+
{
|
|
46
|
+
allowedMethods: [
|
|
47
|
+
'subscriptions.list'
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
],
|
|
52
|
+
[
|
|
53
|
+
'a missing allowlist',
|
|
54
|
+
{}
|
|
55
|
+
],
|
|
56
|
+
[
|
|
57
|
+
'a non-array allowlist',
|
|
58
|
+
{
|
|
59
|
+
allowedMethods: 'subscriptions.list'
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
[
|
|
63
|
+
'an empty allowlist',
|
|
64
|
+
{
|
|
65
|
+
allowedMethods: []
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
'an empty method',
|
|
70
|
+
{
|
|
71
|
+
allowedMethods: [
|
|
72
|
+
''
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
[
|
|
77
|
+
'a whitespace-only method',
|
|
78
|
+
{
|
|
79
|
+
allowedMethods: [
|
|
80
|
+
' '
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
],
|
|
84
|
+
[
|
|
85
|
+
'a non-string method',
|
|
86
|
+
{
|
|
87
|
+
allowedMethods: [
|
|
88
|
+
123
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
[
|
|
93
|
+
'a wildcard method',
|
|
94
|
+
{
|
|
95
|
+
allowedMethods: [
|
|
96
|
+
'subscriptions.*'
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
[
|
|
101
|
+
'a non-function access value',
|
|
102
|
+
{
|
|
103
|
+
access: true,
|
|
104
|
+
allowedMethods: [
|
|
105
|
+
'subscriptions.list'
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
])('should reject %s', (_description, rest)=>{
|
|
110
|
+
expect(()=>sanitizeStripeRESTConfig({
|
|
111
|
+
rest
|
|
112
|
+
})).toThrow('The Stripe REST endpoint now requires an object with a non-empty allowedMethods array');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
//# sourceMappingURL=sanitizeStripeRESTConfig.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/sanitizeStripeRESTConfig.spec.ts"],"sourcesContent":["import { describe, expect, it, vi } from 'vitest'\n\nimport { sanitizeStripeRESTConfig } from './sanitizeStripeRESTConfig.js'\n\ndescribe('sanitizeStripeRESTConfig', () => {\n it('should disable the REST endpoint when configuration is absent', () => {\n expect(sanitizeStripeRESTConfig({ rest: undefined })).toBeUndefined()\n })\n\n it('should treat false from an untyped configuration as disabled', () => {\n expect(sanitizeStripeRESTConfig({ rest: false })).toBeUndefined()\n })\n\n it('should return a new configuration with exact, de-duplicated, frozen methods', () => {\n const access = vi.fn(() => true)\n const rest = {\n access,\n allowedMethods: ['subscriptions.list', ' paymentIntents.retrieve ', 'subscriptions.list'],\n } as const\n\n const sanitized = sanitizeStripeRESTConfig({ rest })\n\n expect(sanitized).not.toBe(rest)\n expect(sanitized).toEqual({\n access,\n allowedMethods: ['subscriptions.list', ' paymentIntents.retrieve '],\n })\n expect(Object.isFrozen(sanitized.allowedMethods)).toBe(true)\n })\n\n it.each([\n ['the legacy boolean form', true],\n ['an array', [{ allowedMethods: ['subscriptions.list'] }]],\n ['a missing allowlist', {}],\n ['a non-array allowlist', { allowedMethods: 'subscriptions.list' }],\n ['an empty allowlist', { allowedMethods: [] }],\n ['an empty method', { allowedMethods: [''] }],\n ['a whitespace-only method', { allowedMethods: [' '] }],\n ['a non-string method', { allowedMethods: [123] }],\n ['a wildcard method', { allowedMethods: ['subscriptions.*'] }],\n ['a non-function access value', { access: true, allowedMethods: ['subscriptions.list'] }],\n ])('should reject %s', (_description, rest) => {\n expect(() => sanitizeStripeRESTConfig({ rest })).toThrow(\n 'The Stripe REST endpoint now requires an object with a non-empty allowedMethods array',\n )\n })\n})\n"],"names":["describe","expect","it","vi","sanitizeStripeRESTConfig","rest","undefined","toBeUndefined","access","fn","allowedMethods","sanitized","not","toBe","toEqual","Object","isFrozen","each","_description","toThrow"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ,SAAQ;AAEjD,SAASC,wBAAwB,QAAQ,gCAA+B;AAExEJ,SAAS,4BAA4B;IACnCE,GAAG,iEAAiE;QAClED,OAAOG,yBAAyB;YAAEC,MAAMC;QAAU,IAAIC,aAAa;IACrE;IAEAL,GAAG,gEAAgE;QACjED,OAAOG,yBAAyB;YAAEC,MAAM;QAAM,IAAIE,aAAa;IACjE;IAEAL,GAAG,+EAA+E;QAChF,MAAMM,SAASL,GAAGM,EAAE,CAAC,IAAM;QAC3B,MAAMJ,OAAO;YACXG;YACAE,gBAAgB;gBAAC;gBAAsB;gBAA6B;aAAqB;QAC3F;QAEA,MAAMC,YAAYP,yBAAyB;YAAEC;QAAK;QAElDJ,OAAOU,WAAWC,GAAG,CAACC,IAAI,CAACR;QAC3BJ,OAAOU,WAAWG,OAAO,CAAC;YACxBN;YACAE,gBAAgB;gBAAC;gBAAsB;aAA4B;QACrE;QACAT,OAAOc,OAAOC,QAAQ,CAACL,UAAUD,cAAc,GAAGG,IAAI,CAAC;IACzD;IAEAX,GAAGe,IAAI,CAAC;QACN;YAAC;YAA2B;SAAK;QACjC;YAAC;YAAY;gBAAC;oBAAEP,gBAAgB;wBAAC;qBAAqB;gBAAC;aAAE;SAAC;QAC1D;YAAC;YAAuB,CAAC;SAAE;QAC3B;YAAC;YAAyB;gBAAEA,gBAAgB;YAAqB;SAAE;QACnE;YAAC;YAAsB;gBAAEA,gBAAgB,EAAE;YAAC;SAAE;QAC9C;YAAC;YAAmB;gBAAEA,gBAAgB;oBAAC;iBAAG;YAAC;SAAE;QAC7C;YAAC;YAA4B;gBAAEA,gBAAgB;oBAAC;iBAAM;YAAC;SAAE;QACzD;YAAC;YAAuB;gBAAEA,gBAAgB;oBAAC;iBAAI;YAAC;SAAE;QAClD;YAAC;YAAqB;gBAAEA,gBAAgB;oBAAC;iBAAkB;YAAC;SAAE;QAC9D;YAAC;YAA+B;gBAAEF,QAAQ;gBAAME,gBAAgB;oBAAC;iBAAqB;YAAC;SAAE;KAC1F,EAAE,oBAAoB,CAACQ,cAAcb;QACpCJ,OAAO,IAAMG,yBAAyB;gBAAEC;YAAK,IAAIc,OAAO,CACtD;IAEJ;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleCreatedOrUpdated.d.ts","sourceRoot":"","sources":["../../src/webhooks/handleCreatedOrUpdated.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAIpF,KAAK,sBAAsB,GAAG,CAC5B,IAAI,EAAE;IACJ,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,2BAA2B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;CACnD,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,KACpC,OAAO,CAAC,IAAI,CAAC,CAAA;AAElB,eAAO,MAAM,sBAAsB,EAAE,
|
|
1
|
+
{"version":3,"file":"handleCreatedOrUpdated.d.ts","sourceRoot":"","sources":["../../src/webhooks/handleCreatedOrUpdated.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAIpF,KAAK,sBAAsB,GAAG,CAC5B,IAAI,EAAE;IACJ,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,2BAA2B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;CACnD,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,KACpC,OAAO,CAAC,IAAI,CAAC,CAAA;AAElB,eAAO,MAAM,sBAAsB,EAAE,sBAqMpC,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { v4 as uuid } from 'uuid';
|
|
2
|
-
import { deepen } from '../utilities/deepen.js';
|
|
2
|
+
import { deepen, getSyncedFields } from '../utilities/deepen.js';
|
|
3
3
|
export const handleCreatedOrUpdated = async (args)=>{
|
|
4
4
|
const { config: payloadConfig, event, payload, pluginConfig, resourceType, syncConfig } = args;
|
|
5
5
|
const { logs } = pluginConfig || {};
|
|
@@ -37,11 +37,11 @@ export const handleCreatedOrUpdated = async (args)=>{
|
|
|
37
37
|
});
|
|
38
38
|
const foundDoc = payloadQuery.docs[0];
|
|
39
39
|
// combine all properties of the Stripe doc and match their respective fields within the document
|
|
40
|
-
let syncedData =
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
40
|
+
let syncedData = getSyncedFields({
|
|
41
|
+
data: stripeDoc,
|
|
42
|
+
fields: syncConfig.fields,
|
|
43
|
+
source: 'stripe'
|
|
44
|
+
});
|
|
45
45
|
syncedData = deepen({
|
|
46
46
|
...syncedData,
|
|
47
47
|
skipSync: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/webhooks/handleCreatedOrUpdated.ts"],"sourcesContent":["import { v4 as uuid } from 'uuid'\n\nimport type { SanitizedStripePluginConfig, StripeWebhookHandler } from '../types.js'\n\nimport { deepen } from '../utilities/deepen.js'\n\ntype HandleCreatedOrUpdated = (\n args: {\n resourceType: string\n syncConfig: SanitizedStripePluginConfig['sync'][0]\n } & Parameters<StripeWebhookHandler>[0],\n) => Promise<void>\n\nexport const handleCreatedOrUpdated: HandleCreatedOrUpdated = async (args) => {\n const { config: payloadConfig, event, payload, pluginConfig, resourceType, syncConfig } = args\n\n const { logs } = pluginConfig || {}\n\n const stripeDoc: any = event?.data?.object || {}\n\n const { id: stripeID, object: eventObject } = stripeDoc\n\n // NOTE: the Stripe API does not nest fields, everything is an object at the top level\n // if the event object and resource type don't match, this change was not top-level\n const isNestedChange = eventObject !== resourceType\n\n // let stripeID = docID;\n // if (isNestedChange) {\n // const parentResource = stripeDoc[resourceType];\n // stripeID = parentResource;\n // }\n\n if (isNestedChange) {\n if (logs) {\n payload.logger.info(\n `- This change occurred on a nested field of ${resourceType}. Nested fields are not yet supported in auto-sync but can be manually setup.`,\n )\n }\n }\n\n if (!isNestedChange) {\n if (logs) {\n payload.logger.info(\n `- A new document was created or updated in Stripe, now syncing to Payload...`,\n )\n }\n\n const collectionSlug = syncConfig?.collection\n\n const isAuthCollection = Boolean(\n payloadConfig?.collections?.find((collection) => collection.slug === collectionSlug)?.auth,\n )\n\n // First, search for an existing document in Payload\n const payloadQuery = await payload.find({\n collection: collectionSlug,\n limit: 1,\n pagination: false,\n where: {\n stripeID: {\n equals: stripeID,\n },\n },\n })\n\n const foundDoc = payloadQuery.docs[0] as any\n\n // combine all properties of the Stripe doc and match their respective fields within the document\n let syncedData = syncConfig.fields.reduce(\n (acc, field) => {\n const { fieldPath, stripeProperty } = field\n\n acc[fieldPath] = stripeDoc[stripeProperty]\n return acc\n },\n {} as Record<string, any>,\n )\n\n syncedData = deepen({\n ...syncedData,\n skipSync: true,\n stripeID,\n })\n\n if (!foundDoc) {\n if (logs) {\n payload.logger.info(\n `- No existing '${collectionSlug}' document found with Stripe ID: '${stripeID}', creating new...`,\n )\n }\n\n // auth docs must use unique emails\n let authDoc = null\n\n if (isAuthCollection) {\n try {\n if (stripeDoc?.email) {\n const authQuery = await payload.find({\n collection: collectionSlug,\n limit: 1,\n pagination: false,\n where: {\n email: {\n equals: stripeDoc.email,\n },\n },\n })\n\n authDoc = authQuery.docs[0] as any\n\n if (authDoc) {\n if (logs) {\n payload.logger.info(\n `- Account already exists with e-mail: ${stripeDoc.email}, updating now...`,\n )\n }\n\n // account exists by email, so update it instead\n try {\n await payload.update({\n id: authDoc.id,\n collection: collectionSlug,\n data: syncedData,\n })\n\n if (logs) {\n payload.logger.info(\n `✅ Successfully updated '${collectionSlug}' document in Payload with ID: '${authDoc.id}.'`,\n )\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : err\n if (logs) {\n payload.logger.error(\n `- Error updating existing '${collectionSlug}' document: ${msg}`,\n )\n }\n }\n }\n } else {\n if (logs) {\n payload.logger.error(\n `No email was provided from Stripe, cannot create new '${collectionSlug}' document.`,\n )\n }\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : error\n if (logs) {\n payload.logger.error(`Error looking up '${collectionSlug}' document in Payload: ${msg}`)\n }\n }\n }\n\n if (!isAuthCollection || (isAuthCollection && !authDoc)) {\n try {\n if (logs) {\n payload.logger.info(\n `- Creating new '${collectionSlug}' document in Payload with Stripe ID: '${stripeID}'.`,\n )\n }\n\n // generate a strong, unique password for the new user\n const password: string = uuid()\n\n await payload.create({\n collection: collectionSlug,\n data: {\n ...syncedData,\n password,\n passwordConfirm: password,\n },\n disableVerificationEmail: isAuthCollection ? true : undefined,\n })\n\n if (logs) {\n payload.logger.info(\n `✅ Successfully created new '${collectionSlug}' document in Payload with Stripe ID: '${stripeID}'.`,\n )\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : error\n if (logs) {\n payload.logger.error(`Error creating new document in Payload: ${msg}`)\n }\n }\n }\n } else {\n if (logs) {\n payload.logger.info(\n `- Existing '${collectionSlug}' document found in Payload with Stripe ID: '${stripeID}', updating now...`,\n )\n }\n\n try {\n await payload.update({\n id: foundDoc.id,\n collection: collectionSlug,\n data: syncedData,\n })\n\n if (logs) {\n payload.logger.info(\n `✅ Successfully updated '${collectionSlug}' document in Payload from Stripe ID: '${stripeID}'.`,\n )\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : error\n if (logs) {\n payload.logger.error(`Error updating '${collectionSlug}' document in Payload: ${msg}`)\n }\n }\n }\n }\n}\n"],"names":["v4","uuid","deepen","handleCreatedOrUpdated","args","config","payloadConfig","event","payload","pluginConfig","resourceType","syncConfig","logs","stripeDoc","data","object","id","stripeID","eventObject","isNestedChange","logger","info","collectionSlug","collection","isAuthCollection","Boolean","collections","find","slug","auth","payloadQuery","limit","pagination","where","equals","foundDoc","docs","syncedData","fields","reduce","acc","field","fieldPath","stripeProperty","skipSync","authDoc","email","authQuery","update","err","msg","Error","message","error","password","create","passwordConfirm","disableVerificationEmail","undefined"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/webhooks/handleCreatedOrUpdated.ts"],"sourcesContent":["import { v4 as uuid } from 'uuid'\n\nimport type { SanitizedStripePluginConfig, StripeWebhookHandler } from '../types.js'\n\nimport { deepen, getSyncedFields } from '../utilities/deepen.js'\n\ntype HandleCreatedOrUpdated = (\n args: {\n resourceType: string\n syncConfig: SanitizedStripePluginConfig['sync'][0]\n } & Parameters<StripeWebhookHandler>[0],\n) => Promise<void>\n\nexport const handleCreatedOrUpdated: HandleCreatedOrUpdated = async (args) => {\n const { config: payloadConfig, event, payload, pluginConfig, resourceType, syncConfig } = args\n\n const { logs } = pluginConfig || {}\n\n const stripeDoc: any = event?.data?.object || {}\n\n const { id: stripeID, object: eventObject } = stripeDoc\n\n // NOTE: the Stripe API does not nest fields, everything is an object at the top level\n // if the event object and resource type don't match, this change was not top-level\n const isNestedChange = eventObject !== resourceType\n\n // let stripeID = docID;\n // if (isNestedChange) {\n // const parentResource = stripeDoc[resourceType];\n // stripeID = parentResource;\n // }\n\n if (isNestedChange) {\n if (logs) {\n payload.logger.info(\n `- This change occurred on a nested field of ${resourceType}. Nested fields are not yet supported in auto-sync but can be manually setup.`,\n )\n }\n }\n\n if (!isNestedChange) {\n if (logs) {\n payload.logger.info(\n `- A new document was created or updated in Stripe, now syncing to Payload...`,\n )\n }\n\n const collectionSlug = syncConfig?.collection\n\n const isAuthCollection = Boolean(\n payloadConfig?.collections?.find((collection) => collection.slug === collectionSlug)?.auth,\n )\n\n // First, search for an existing document in Payload\n const payloadQuery = await payload.find({\n collection: collectionSlug,\n limit: 1,\n pagination: false,\n where: {\n stripeID: {\n equals: stripeID,\n },\n },\n })\n\n const foundDoc = payloadQuery.docs[0] as any\n\n // combine all properties of the Stripe doc and match their respective fields within the document\n let syncedData = getSyncedFields({\n data: stripeDoc,\n fields: syncConfig.fields,\n source: 'stripe',\n })\n\n syncedData = deepen({\n ...syncedData,\n skipSync: true,\n stripeID,\n })\n\n if (!foundDoc) {\n if (logs) {\n payload.logger.info(\n `- No existing '${collectionSlug}' document found with Stripe ID: '${stripeID}', creating new...`,\n )\n }\n\n // auth docs must use unique emails\n let authDoc = null\n\n if (isAuthCollection) {\n try {\n if (stripeDoc?.email) {\n const authQuery = await payload.find({\n collection: collectionSlug,\n limit: 1,\n pagination: false,\n where: {\n email: {\n equals: stripeDoc.email,\n },\n },\n })\n\n authDoc = authQuery.docs[0] as any\n\n if (authDoc) {\n if (logs) {\n payload.logger.info(\n `- Account already exists with e-mail: ${stripeDoc.email}, updating now...`,\n )\n }\n\n // account exists by email, so update it instead\n try {\n await payload.update({\n id: authDoc.id,\n collection: collectionSlug,\n data: syncedData,\n })\n\n if (logs) {\n payload.logger.info(\n `✅ Successfully updated '${collectionSlug}' document in Payload with ID: '${authDoc.id}.'`,\n )\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : err\n if (logs) {\n payload.logger.error(\n `- Error updating existing '${collectionSlug}' document: ${msg}`,\n )\n }\n }\n }\n } else {\n if (logs) {\n payload.logger.error(\n `No email was provided from Stripe, cannot create new '${collectionSlug}' document.`,\n )\n }\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : error\n if (logs) {\n payload.logger.error(`Error looking up '${collectionSlug}' document in Payload: ${msg}`)\n }\n }\n }\n\n if (!isAuthCollection || (isAuthCollection && !authDoc)) {\n try {\n if (logs) {\n payload.logger.info(\n `- Creating new '${collectionSlug}' document in Payload with Stripe ID: '${stripeID}'.`,\n )\n }\n\n // generate a strong, unique password for the new user\n const password: string = uuid()\n\n await payload.create({\n collection: collectionSlug,\n data: {\n ...syncedData,\n password,\n passwordConfirm: password,\n },\n disableVerificationEmail: isAuthCollection ? true : undefined,\n })\n\n if (logs) {\n payload.logger.info(\n `✅ Successfully created new '${collectionSlug}' document in Payload with Stripe ID: '${stripeID}'.`,\n )\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : error\n if (logs) {\n payload.logger.error(`Error creating new document in Payload: ${msg}`)\n }\n }\n }\n } else {\n if (logs) {\n payload.logger.info(\n `- Existing '${collectionSlug}' document found in Payload with Stripe ID: '${stripeID}', updating now...`,\n )\n }\n\n try {\n await payload.update({\n id: foundDoc.id,\n collection: collectionSlug,\n data: syncedData,\n })\n\n if (logs) {\n payload.logger.info(\n `✅ Successfully updated '${collectionSlug}' document in Payload from Stripe ID: '${stripeID}'.`,\n )\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : error\n if (logs) {\n payload.logger.error(`Error updating '${collectionSlug}' document in Payload: ${msg}`)\n }\n }\n }\n }\n}\n"],"names":["v4","uuid","deepen","getSyncedFields","handleCreatedOrUpdated","args","config","payloadConfig","event","payload","pluginConfig","resourceType","syncConfig","logs","stripeDoc","data","object","id","stripeID","eventObject","isNestedChange","logger","info","collectionSlug","collection","isAuthCollection","Boolean","collections","find","slug","auth","payloadQuery","limit","pagination","where","equals","foundDoc","docs","syncedData","fields","source","skipSync","authDoc","email","authQuery","update","err","msg","Error","message","error","password","create","passwordConfirm","disableVerificationEmail","undefined"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/plugin-stripe",
|
|
3
|
-
"version": "4.0.0-canary.
|
|
3
|
+
"version": "4.0.0-canary.35",
|
|
4
4
|
"description": "Stripe plugin for Payload",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"payload",
|
|
@@ -55,19 +55,19 @@
|
|
|
55
55
|
"lodash.get": "^4.4.2",
|
|
56
56
|
"stripe": "^10.2.0",
|
|
57
57
|
"uuid": "14.0.0",
|
|
58
|
-
"@payloadcms/translations": "4.0.0-canary.
|
|
59
|
-
"@payloadcms/ui": "4.0.0-canary.
|
|
58
|
+
"@payloadcms/translations": "4.0.0-canary.35",
|
|
59
|
+
"@payloadcms/ui": "4.0.0-canary.35"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/lodash.get": "^4.4.7",
|
|
63
63
|
"@types/react": "19.2.14",
|
|
64
64
|
"@types/react-dom": "19.2.3",
|
|
65
65
|
"@payloadcms/eslint-config": "3.28.0",
|
|
66
|
-
"
|
|
67
|
-
"
|
|
66
|
+
"@payloadcms/next": "4.0.0-canary.35",
|
|
67
|
+
"payload": "4.0.0-canary.35"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"payload": "4.0.0-canary.
|
|
70
|
+
"payload": "4.0.0-canary.35"
|
|
71
71
|
},
|
|
72
72
|
"publishConfig": {
|
|
73
73
|
"registry": "https://registry.npmjs.org/"
|