@payloadcms/storage-r2 0.0.1-beta.0
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/.prettierignore +12 -0
- package/.swcrc +24 -0
- package/LICENSE.md +22 -0
- package/README.md +3 -0
- package/eslint.config.js +18 -0
- package/package.json +4 -0
- package/src/addresses/addressesCollection.ts +76 -0
- package/src/addresses/defaultAddressFields.ts +83 -0
- package/src/addresses/defaultCountries.ts +50 -0
- package/src/carts/beforeChange.ts +51 -0
- package/src/carts/cartsCollection.ts +146 -0
- package/src/currencies/index.ts +29 -0
- package/src/endpoints/confirmOrder.ts +312 -0
- package/src/endpoints/initiatePayment.ts +322 -0
- package/src/exports/addresses.ts +2 -0
- package/src/exports/currencies.ts +1 -0
- package/src/exports/fields.ts +5 -0
- package/src/exports/orders.ts +1 -0
- package/src/exports/payments/stripe.ts +1 -0
- package/src/exports/plugin.ts +1 -0
- package/src/exports/products.ts +1 -0
- package/src/exports/react.ts +8 -0
- package/src/exports/transactions.ts +1 -0
- package/src/exports/translations.ts +1 -0
- package/src/exports/types.ts +7 -0
- package/src/exports/ui.ts +3 -0
- package/src/exports/variants.ts +5 -0
- package/src/fields/amountField.ts +43 -0
- package/src/fields/cartItemsField.ts +84 -0
- package/src/fields/currencyField.ts +39 -0
- package/src/fields/inventoryField.ts +22 -0
- package/src/fields/pricesField.ts +65 -0
- package/src/fields/statusField.ts +57 -0
- package/src/fields/variantsFields.ts +56 -0
- package/src/index.ts +275 -0
- package/src/orders/ordersCollection.ts +157 -0
- package/src/payments/adapters/stripe/confirmOrder.ts +123 -0
- package/src/payments/adapters/stripe/endpoints/webhooks.ts +69 -0
- package/src/payments/adapters/stripe/index.ts +135 -0
- package/src/payments/adapters/stripe/initiatePayment.ts +131 -0
- package/src/products/productsCollection.ts +78 -0
- package/src/react/provider/index.tsx +893 -0
- package/src/react/provider/types.ts +184 -0
- package/src/react/provider/utilities.ts +22 -0
- package/src/transactions/transactionsCollection.ts +166 -0
- package/src/translations/en.ts +64 -0
- package/src/translations/index.ts +11 -0
- package/src/translations/translation-schema.json +35 -0
- package/src/types.ts +403 -0
- package/src/ui/PriceInput/FormattedInput.tsx +134 -0
- package/src/ui/PriceInput/index.scss +28 -0
- package/src/ui/PriceInput/index.tsx +43 -0
- package/src/ui/PriceInput/utilities.ts +46 -0
- package/src/ui/PriceRowLabel/index.css +13 -0
- package/src/ui/PriceRowLabel/index.tsx +56 -0
- package/src/ui/VariantOptionsSelector/ErrorBox.tsx +27 -0
- package/src/ui/VariantOptionsSelector/OptionsSelect.tsx +78 -0
- package/src/ui/VariantOptionsSelector/index.css +37 -0
- package/src/ui/VariantOptionsSelector/index.tsx +83 -0
- package/src/utilities/defaultProductsValidation.ts +42 -0
- package/src/utilities/errorCodes.ts +14 -0
- package/src/utilities/getCollectionSlugMap.ts +84 -0
- package/src/utilities/sanitizePluginConfig.ts +80 -0
- package/src/variants/variantOptionsCollection.ts +59 -0
- package/src/variants/variantTypesCollection.ts +55 -0
- package/src/variants/variantsCollection/hooks/beforeChange.ts +47 -0
- package/src/variants/variantsCollection/hooks/validateOptions.ts +72 -0
- package/src/variants/variantsCollection/index.ts +119 -0
- package/tsconfig.json +7 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { NumberField } from 'payload'
|
|
2
|
+
|
|
3
|
+
import type { CurrenciesConfig, Currency } from '../types.js'
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
currenciesConfig: CurrenciesConfig
|
|
7
|
+
/**
|
|
8
|
+
* Use this specific currency for the field.
|
|
9
|
+
*/
|
|
10
|
+
currency?: Currency
|
|
11
|
+
overrides?: Partial<NumberField>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const amountField: (props: Props) => NumberField = ({
|
|
15
|
+
currenciesConfig,
|
|
16
|
+
currency,
|
|
17
|
+
overrides,
|
|
18
|
+
}) => {
|
|
19
|
+
// @ts-expect-error - issue with payload types
|
|
20
|
+
const field: NumberField = {
|
|
21
|
+
name: 'amount',
|
|
22
|
+
type: 'number',
|
|
23
|
+
label: ({ t }) =>
|
|
24
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
25
|
+
t('plugin-ecommerce:amount'),
|
|
26
|
+
...overrides,
|
|
27
|
+
admin: {
|
|
28
|
+
components: {
|
|
29
|
+
Field: {
|
|
30
|
+
clientProps: {
|
|
31
|
+
currenciesConfig,
|
|
32
|
+
currency,
|
|
33
|
+
},
|
|
34
|
+
path: '@payloadcms/plugin-ecommerce/ui#PriceInput',
|
|
35
|
+
},
|
|
36
|
+
...overrides?.admin?.components,
|
|
37
|
+
},
|
|
38
|
+
...overrides?.admin,
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return field
|
|
43
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { ArrayField, Field } from 'payload'
|
|
2
|
+
|
|
3
|
+
import type { CurrenciesConfig } from '../types.js'
|
|
4
|
+
|
|
5
|
+
import { amountField } from './amountField.js'
|
|
6
|
+
import { currencyField } from './currencyField.js'
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
/**
|
|
10
|
+
* Include this in order to enable support for currencies per item in the cart.
|
|
11
|
+
*/
|
|
12
|
+
currenciesConfig?: CurrenciesConfig
|
|
13
|
+
enableVariants?: boolean
|
|
14
|
+
/**
|
|
15
|
+
* Enables individual prices for each item in the cart.
|
|
16
|
+
* Defaults to false.
|
|
17
|
+
*/
|
|
18
|
+
individualPrices?: boolean
|
|
19
|
+
overrides?: Partial<ArrayField>
|
|
20
|
+
/**
|
|
21
|
+
* Slug of the products collection, defaults to 'products'.
|
|
22
|
+
*/
|
|
23
|
+
productsSlug?: string
|
|
24
|
+
/**
|
|
25
|
+
* Slug of the variants collection, defaults to 'variants'.
|
|
26
|
+
*/
|
|
27
|
+
variantsSlug?: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const cartItemsField: (props?: Props) => ArrayField = (props) => {
|
|
31
|
+
const {
|
|
32
|
+
currenciesConfig,
|
|
33
|
+
enableVariants = false,
|
|
34
|
+
individualPrices,
|
|
35
|
+
overrides,
|
|
36
|
+
productsSlug = 'products',
|
|
37
|
+
variantsSlug = 'variants',
|
|
38
|
+
} = props || {}
|
|
39
|
+
|
|
40
|
+
const field: ArrayField = {
|
|
41
|
+
name: 'items',
|
|
42
|
+
type: 'array',
|
|
43
|
+
fields: [
|
|
44
|
+
{
|
|
45
|
+
name: 'product',
|
|
46
|
+
type: 'relationship',
|
|
47
|
+
label: ({ t }) =>
|
|
48
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
49
|
+
t('plugin-ecommerce:product'),
|
|
50
|
+
relationTo: productsSlug,
|
|
51
|
+
},
|
|
52
|
+
...(enableVariants
|
|
53
|
+
? [
|
|
54
|
+
{
|
|
55
|
+
name: 'variant',
|
|
56
|
+
type: 'relationship',
|
|
57
|
+
label: ({ t }) =>
|
|
58
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
59
|
+
t('plugin-ecommerce:variant'),
|
|
60
|
+
relationTo: variantsSlug,
|
|
61
|
+
} as Field,
|
|
62
|
+
]
|
|
63
|
+
: []),
|
|
64
|
+
{
|
|
65
|
+
name: 'quantity',
|
|
66
|
+
type: 'number',
|
|
67
|
+
defaultValue: 1,
|
|
68
|
+
label: ({ t }) =>
|
|
69
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
70
|
+
t('plugin-ecommerce:quantity'),
|
|
71
|
+
min: 1,
|
|
72
|
+
required: true,
|
|
73
|
+
},
|
|
74
|
+
...(currenciesConfig && individualPrices ? [amountField({ currenciesConfig })] : []),
|
|
75
|
+
...(currenciesConfig ? [currencyField({ currenciesConfig })] : []),
|
|
76
|
+
],
|
|
77
|
+
label: ({ t }) =>
|
|
78
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
79
|
+
t('plugin-ecommerce:cart'),
|
|
80
|
+
...overrides,
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return field
|
|
84
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { SelectField } from 'payload'
|
|
2
|
+
|
|
3
|
+
import type { CurrenciesConfig } from '../types.js'
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
currenciesConfig: CurrenciesConfig
|
|
7
|
+
overrides?: Partial<SelectField>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const currencyField: (props: Props) => SelectField = ({ currenciesConfig, overrides }) => {
|
|
11
|
+
const options = currenciesConfig.supportedCurrencies.map((currency) => {
|
|
12
|
+
const label = currency.label ? `${currency.label} (${currency.code})` : currency.code
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
label,
|
|
16
|
+
value: currency.code,
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const defaultValue =
|
|
21
|
+
(currenciesConfig.defaultCurrency ?? currenciesConfig.supportedCurrencies.length === 1)
|
|
22
|
+
? currenciesConfig.supportedCurrencies[0]?.code
|
|
23
|
+
: undefined
|
|
24
|
+
|
|
25
|
+
// @ts-expect-error - issue with payload types
|
|
26
|
+
const field: SelectField = {
|
|
27
|
+
name: 'currency',
|
|
28
|
+
type: 'select',
|
|
29
|
+
label: ({ t }) =>
|
|
30
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
31
|
+
t('plugin-ecommerce:currency'),
|
|
32
|
+
...(defaultValue && { defaultValue }),
|
|
33
|
+
options,
|
|
34
|
+
...overrides,
|
|
35
|
+
admin: { readOnly: currenciesConfig.supportedCurrencies.length === 1, ...overrides?.admin },
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return field
|
|
39
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { NumberField } from 'payload'
|
|
2
|
+
|
|
3
|
+
type Props = {
|
|
4
|
+
overrides?: Partial<NumberField>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const inventoryField: (props?: Props) => NumberField = (props) => {
|
|
8
|
+
const { overrides } = props || {}
|
|
9
|
+
|
|
10
|
+
// @ts-expect-error - issue with payload types
|
|
11
|
+
const field: NumberField = {
|
|
12
|
+
name: 'inventory',
|
|
13
|
+
type: 'number',
|
|
14
|
+
defaultValue: 0,
|
|
15
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
16
|
+
label: ({ t }) => t('plugin-ecommerce:inventory'),
|
|
17
|
+
min: 0,
|
|
18
|
+
...(overrides || {}),
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return field
|
|
22
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { GroupField } from 'payload'
|
|
2
|
+
|
|
3
|
+
import type { CurrenciesConfig } from '../types.js'
|
|
4
|
+
|
|
5
|
+
import { amountField } from './amountField.js'
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
/**
|
|
9
|
+
* Use this to specify a path for the condition.
|
|
10
|
+
*/
|
|
11
|
+
conditionalPath?: string
|
|
12
|
+
currenciesConfig: CurrenciesConfig
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const pricesField: (props: Props) => GroupField[] = ({
|
|
16
|
+
conditionalPath,
|
|
17
|
+
currenciesConfig,
|
|
18
|
+
}) => {
|
|
19
|
+
const currencies = currenciesConfig.supportedCurrencies
|
|
20
|
+
|
|
21
|
+
const fields: GroupField[] = currencies.map((currency) => {
|
|
22
|
+
const name = `priceIn${currency.code}`
|
|
23
|
+
const label = `Price (${currency.code})`
|
|
24
|
+
|
|
25
|
+
const path = conditionalPath ? `${conditionalPath}.${name}Enabled` : `${name}Enabled`
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
type: 'group',
|
|
29
|
+
fields: [
|
|
30
|
+
{
|
|
31
|
+
type: 'row',
|
|
32
|
+
fields: [
|
|
33
|
+
{
|
|
34
|
+
name: `${name}Enabled`,
|
|
35
|
+
type: 'checkbox',
|
|
36
|
+
admin: {
|
|
37
|
+
style: {
|
|
38
|
+
alignSelf: 'baseline',
|
|
39
|
+
flex: '0 0 auto',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
label: ({ t }) =>
|
|
43
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
44
|
+
t('plugin-ecommerce:enableCurrencyPrice', { currency: currency.code }),
|
|
45
|
+
},
|
|
46
|
+
amountField({
|
|
47
|
+
currenciesConfig,
|
|
48
|
+
currency,
|
|
49
|
+
overrides: {
|
|
50
|
+
name,
|
|
51
|
+
admin: {
|
|
52
|
+
condition: (_, siblingData) => Boolean(siblingData?.[path]),
|
|
53
|
+
},
|
|
54
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
55
|
+
label: ({ t }) => t('plugin-ecommerce:priceIn', { currency: currency.code }),
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
return fields
|
|
65
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { SelectField } from 'payload'
|
|
2
|
+
|
|
3
|
+
export const statusOptions: SelectField['options'] = [
|
|
4
|
+
{
|
|
5
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
6
|
+
label: ({ t }) => t('plugin-ecommerce:pending'),
|
|
7
|
+
value: 'pending',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
11
|
+
label: ({ t }) => t('plugin-ecommerce:succeeded'),
|
|
12
|
+
value: 'succeeded',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
16
|
+
label: ({ t }) => t('plugin-ecommerce:failed'),
|
|
17
|
+
value: 'failed',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
21
|
+
label: ({ t }) => t('plugin-ecommerce:cancelled'),
|
|
22
|
+
value: 'cancelled',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
26
|
+
label: ({ t }) => t('plugin-ecommerce:expired'),
|
|
27
|
+
value: 'expired',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
31
|
+
label: ({ t }) => t('plugin-ecommerce:refunded'),
|
|
32
|
+
value: 'refunded',
|
|
33
|
+
},
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
type Props = {
|
|
37
|
+
overrides?: Partial<SelectField>
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const statusField: (props?: Props) => SelectField = (props) => {
|
|
41
|
+
const { overrides } = props || {}
|
|
42
|
+
|
|
43
|
+
// @ts-expect-error - issue with payload types
|
|
44
|
+
const field: SelectField = {
|
|
45
|
+
name: 'status',
|
|
46
|
+
type: 'select',
|
|
47
|
+
defaultValue: 'pending',
|
|
48
|
+
label: ({ t }) =>
|
|
49
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
50
|
+
t('plugin-ecommerce:status'),
|
|
51
|
+
options: statusOptions,
|
|
52
|
+
required: true,
|
|
53
|
+
...overrides,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return field
|
|
57
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Field } from 'payload'
|
|
2
|
+
|
|
3
|
+
type Props = {
|
|
4
|
+
/**
|
|
5
|
+
* Slug of the variants collection, defaults to 'variants'.
|
|
6
|
+
*/
|
|
7
|
+
variantsSlug?: string
|
|
8
|
+
/**
|
|
9
|
+
* Slug of the variant types collection, defaults to 'variantTypes'.
|
|
10
|
+
*/
|
|
11
|
+
variantTypesSlug?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const variantsFields: (props: Props) => Field[] = ({
|
|
15
|
+
variantsSlug = 'variants',
|
|
16
|
+
variantTypesSlug = 'variantTypes',
|
|
17
|
+
}) => {
|
|
18
|
+
const fields: Field[] = [
|
|
19
|
+
{
|
|
20
|
+
name: 'enableVariants',
|
|
21
|
+
type: 'checkbox',
|
|
22
|
+
label: ({ t }) =>
|
|
23
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
24
|
+
t('plugin-ecommerce:enableVariants'),
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'variantTypes',
|
|
28
|
+
type: 'relationship',
|
|
29
|
+
admin: {
|
|
30
|
+
condition: ({ enableVariants }) => Boolean(enableVariants),
|
|
31
|
+
},
|
|
32
|
+
hasMany: true,
|
|
33
|
+
label: ({ t }) =>
|
|
34
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
35
|
+
t('plugin-ecommerce:variantTypes'),
|
|
36
|
+
relationTo: variantTypesSlug,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'variants',
|
|
40
|
+
type: 'join',
|
|
41
|
+
admin: {
|
|
42
|
+
condition: ({ enableVariants }) => Boolean(enableVariants),
|
|
43
|
+
defaultColumns: ['title', 'options', 'inventory', 'prices'],
|
|
44
|
+
disableListColumn: true,
|
|
45
|
+
},
|
|
46
|
+
collection: variantsSlug,
|
|
47
|
+
label: ({ t }) =>
|
|
48
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
49
|
+
t('plugin-ecommerce:availableVariants'),
|
|
50
|
+
maxDepth: 2,
|
|
51
|
+
on: 'product',
|
|
52
|
+
},
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
return fields
|
|
56
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import type { Config, Endpoint } from 'payload'
|
|
2
|
+
|
|
3
|
+
import { deepMergeSimple } from 'payload/shared'
|
|
4
|
+
|
|
5
|
+
import type { EcommercePluginConfig, SanitizedEcommercePluginConfig } from './types.js'
|
|
6
|
+
|
|
7
|
+
import { addressesCollection } from './addresses/addressesCollection.js'
|
|
8
|
+
import { cartsCollection } from './carts/cartsCollection.js'
|
|
9
|
+
import { confirmOrderHandler } from './endpoints/confirmOrder.js'
|
|
10
|
+
import { initiatePaymentHandler } from './endpoints/initiatePayment.js'
|
|
11
|
+
import { ordersCollection } from './orders/ordersCollection.js'
|
|
12
|
+
import { productsCollection } from './products/productsCollection.js'
|
|
13
|
+
import { transactionsCollection } from './transactions/transactionsCollection.js'
|
|
14
|
+
import { translations } from './translations/index.js'
|
|
15
|
+
import { getCollectionSlugMap } from './utilities/getCollectionSlugMap.js'
|
|
16
|
+
import { sanitizePluginConfig } from './utilities/sanitizePluginConfig.js'
|
|
17
|
+
import { variantOptionsCollection } from './variants/variantOptionsCollection.js'
|
|
18
|
+
import { variantsCollection } from './variants/variantsCollection/index.js'
|
|
19
|
+
import { variantTypesCollection } from './variants/variantTypesCollection.js'
|
|
20
|
+
|
|
21
|
+
export const ecommercePlugin =
|
|
22
|
+
(pluginConfig?: EcommercePluginConfig) =>
|
|
23
|
+
(incomingConfig: Config): Config => {
|
|
24
|
+
if (!pluginConfig) {
|
|
25
|
+
return incomingConfig
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const sanitizedPluginConfig = sanitizePluginConfig({ pluginConfig })
|
|
29
|
+
/**
|
|
30
|
+
* Used to keep track of the slugs of collections in case they are overridden by the user.
|
|
31
|
+
*/
|
|
32
|
+
const collectionSlugMap = getCollectionSlugMap({ sanitizedPluginConfig })
|
|
33
|
+
|
|
34
|
+
// Ensure collections exists
|
|
35
|
+
if (!incomingConfig.collections) {
|
|
36
|
+
incomingConfig.collections = []
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Controls whether variants are enabled in the plugin. This is toggled to true under products config
|
|
40
|
+
let enableVariants = false
|
|
41
|
+
|
|
42
|
+
const currenciesConfig: Required<SanitizedEcommercePluginConfig['currencies']> =
|
|
43
|
+
sanitizedPluginConfig.currencies
|
|
44
|
+
|
|
45
|
+
let addressFields
|
|
46
|
+
|
|
47
|
+
if (sanitizedPluginConfig.addresses) {
|
|
48
|
+
const collectionOverrides =
|
|
49
|
+
typeof sanitizedPluginConfig.addresses === 'object'
|
|
50
|
+
? sanitizedPluginConfig.addresses.collectionOverride
|
|
51
|
+
: undefined
|
|
52
|
+
|
|
53
|
+
addressFields = sanitizedPluginConfig.addresses.addressFields
|
|
54
|
+
|
|
55
|
+
const supportedCountries = sanitizedPluginConfig.addresses.supportedCountries
|
|
56
|
+
|
|
57
|
+
const addresses = addressesCollection({
|
|
58
|
+
addressFields,
|
|
59
|
+
customersSlug: collectionSlugMap.customers,
|
|
60
|
+
overrides: collectionOverrides,
|
|
61
|
+
supportedCountries,
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
incomingConfig.collections.push(addresses)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (sanitizedPluginConfig.products) {
|
|
68
|
+
const productsConfig =
|
|
69
|
+
typeof sanitizedPluginConfig.products === 'boolean'
|
|
70
|
+
? {
|
|
71
|
+
variants: true,
|
|
72
|
+
}
|
|
73
|
+
: sanitizedPluginConfig.products
|
|
74
|
+
|
|
75
|
+
enableVariants = Boolean(productsConfig.variants)
|
|
76
|
+
|
|
77
|
+
if (productsConfig.variants) {
|
|
78
|
+
const overrides =
|
|
79
|
+
typeof productsConfig.variants === 'boolean' ? undefined : productsConfig.variants
|
|
80
|
+
|
|
81
|
+
const variants = variantsCollection({
|
|
82
|
+
currenciesConfig,
|
|
83
|
+
inventory: sanitizedPluginConfig.inventory,
|
|
84
|
+
overrides: overrides?.variantsCollection,
|
|
85
|
+
productsSlug: collectionSlugMap.products,
|
|
86
|
+
variantOptionsSlug: collectionSlugMap.variantOptions,
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const variantTypes = variantTypesCollection({
|
|
90
|
+
overrides: overrides?.variantTypesCollection,
|
|
91
|
+
variantOptionsSlug: collectionSlugMap.variantOptions,
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const variantOptions = variantOptionsCollection({
|
|
95
|
+
overrides: overrides?.variantOptionsCollection,
|
|
96
|
+
variantTypesSlug: collectionSlugMap.variantTypes,
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
incomingConfig.collections.push(variants, variantTypes, variantOptions)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const products = productsCollection({
|
|
103
|
+
currenciesConfig,
|
|
104
|
+
enableVariants,
|
|
105
|
+
inventory: sanitizedPluginConfig.inventory,
|
|
106
|
+
variantsSlug: collectionSlugMap.variants,
|
|
107
|
+
variantTypesSlug: collectionSlugMap.variantTypes,
|
|
108
|
+
...('productsCollection' in productsConfig && productsConfig.productsCollection
|
|
109
|
+
? { overrides: productsConfig.productsCollection }
|
|
110
|
+
: {}),
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
incomingConfig.collections.push(products)
|
|
114
|
+
|
|
115
|
+
if (sanitizedPluginConfig.carts) {
|
|
116
|
+
const carts = cartsCollection({
|
|
117
|
+
currenciesConfig,
|
|
118
|
+
customersSlug: collectionSlugMap.customers,
|
|
119
|
+
enableVariants: Boolean(productsConfig.variants),
|
|
120
|
+
overrides:
|
|
121
|
+
sanitizedPluginConfig.carts === true
|
|
122
|
+
? undefined
|
|
123
|
+
: sanitizedPluginConfig.carts.cartsCollection,
|
|
124
|
+
productsSlug: collectionSlugMap.products,
|
|
125
|
+
variantsSlug: collectionSlugMap.variants,
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
incomingConfig.collections.push(carts)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (sanitizedPluginConfig.orders) {
|
|
133
|
+
const orders = ordersCollection({
|
|
134
|
+
addressFields,
|
|
135
|
+
currenciesConfig,
|
|
136
|
+
customersSlug: collectionSlugMap.customers,
|
|
137
|
+
enableVariants,
|
|
138
|
+
overrides:
|
|
139
|
+
sanitizedPluginConfig.orders === true
|
|
140
|
+
? undefined
|
|
141
|
+
: sanitizedPluginConfig.orders.ordersCollection,
|
|
142
|
+
productsSlug: collectionSlugMap.products,
|
|
143
|
+
variantsSlug: collectionSlugMap.variants,
|
|
144
|
+
})
|
|
145
|
+
incomingConfig.collections.push(orders)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const paymentMethods = sanitizedPluginConfig.payments.paymentMethods
|
|
149
|
+
|
|
150
|
+
if (sanitizedPluginConfig.payments) {
|
|
151
|
+
if (paymentMethods.length) {
|
|
152
|
+
if (!Array.isArray(incomingConfig.endpoints)) {
|
|
153
|
+
incomingConfig.endpoints = []
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const productsValidation =
|
|
157
|
+
(typeof sanitizedPluginConfig.products === 'object' &&
|
|
158
|
+
sanitizedPluginConfig.products.validation) ||
|
|
159
|
+
undefined
|
|
160
|
+
|
|
161
|
+
paymentMethods.forEach((paymentMethod) => {
|
|
162
|
+
const methodPath = `/payments/${paymentMethod.name}`
|
|
163
|
+
const endpoints: Endpoint[] = []
|
|
164
|
+
|
|
165
|
+
const initiatePayment: Endpoint = {
|
|
166
|
+
handler: initiatePaymentHandler({
|
|
167
|
+
currenciesConfig,
|
|
168
|
+
inventory: sanitizedPluginConfig.inventory,
|
|
169
|
+
paymentMethod,
|
|
170
|
+
productsSlug: collectionSlugMap.products,
|
|
171
|
+
productsValidation,
|
|
172
|
+
transactionsSlug: collectionSlugMap.transactions,
|
|
173
|
+
variantsSlug: collectionSlugMap.variants,
|
|
174
|
+
}),
|
|
175
|
+
method: 'post',
|
|
176
|
+
path: `${methodPath}/initiate`,
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const confirmOrder: Endpoint = {
|
|
180
|
+
handler: confirmOrderHandler({
|
|
181
|
+
cartsSlug: collectionSlugMap.carts,
|
|
182
|
+
currenciesConfig,
|
|
183
|
+
ordersSlug: collectionSlugMap.orders,
|
|
184
|
+
paymentMethod,
|
|
185
|
+
productsValidation,
|
|
186
|
+
transactionsSlug: collectionSlugMap.transactions,
|
|
187
|
+
}),
|
|
188
|
+
method: 'post',
|
|
189
|
+
path: `${methodPath}/confirm-order`,
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
endpoints.push(initiatePayment, confirmOrder)
|
|
193
|
+
|
|
194
|
+
// Attach any additional endpoints defined in the payment method
|
|
195
|
+
if (paymentMethod.endpoints && paymentMethod.endpoints.length > 0) {
|
|
196
|
+
const methodEndpoints = paymentMethod.endpoints.map((endpoint) => {
|
|
197
|
+
const path = endpoint.path.startsWith('/') ? endpoint.path : `/${endpoint.path}`
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
...endpoint,
|
|
201
|
+
path: `${methodPath}${path}`,
|
|
202
|
+
}
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
endpoints.push(...methodEndpoints)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
incomingConfig.endpoints!.push(...endpoints)
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (sanitizedPluginConfig.transactions) {
|
|
214
|
+
const transactions = transactionsCollection({
|
|
215
|
+
addressFields,
|
|
216
|
+
cartsSlug: collectionSlugMap.carts,
|
|
217
|
+
currenciesConfig,
|
|
218
|
+
customersSlug: collectionSlugMap.customers,
|
|
219
|
+
enableVariants,
|
|
220
|
+
ordersSlug: collectionSlugMap.orders,
|
|
221
|
+
paymentMethods,
|
|
222
|
+
productsSlug: collectionSlugMap.products,
|
|
223
|
+
variantsSlug: collectionSlugMap.variants,
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
incomingConfig.collections.push(transactions)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (!incomingConfig.i18n) {
|
|
230
|
+
incomingConfig.i18n = {}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (!incomingConfig.i18n?.translations) {
|
|
234
|
+
incomingConfig.i18n.translations = {}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
incomingConfig.i18n.translations = deepMergeSimple(
|
|
238
|
+
translations,
|
|
239
|
+
incomingConfig.i18n?.translations,
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
// incomingConfig.typescript = {
|
|
243
|
+
// ...incomingConfig.typescript,
|
|
244
|
+
// schema: [
|
|
245
|
+
// ({ jsonSchema }) => {
|
|
246
|
+
// if (jsonSchema.definitions) {
|
|
247
|
+
// const supportedCurrencies = pluginConfig.currencies?.supportedCurrencies || []
|
|
248
|
+
// const defaultCurrency = pluginConfig.currencies?.defaultCurrency || 'USD'
|
|
249
|
+
|
|
250
|
+
// // Generate JSON Schema4 for supported currencies
|
|
251
|
+
|
|
252
|
+
// const currenciesSchema = {
|
|
253
|
+
// type: 'array',
|
|
254
|
+
// description: 'A list of supported currency codes.',
|
|
255
|
+
// items: {
|
|
256
|
+
// type: 'string',
|
|
257
|
+
// enum: (supportedCurrencies || []).map((currency) => currency.code),
|
|
258
|
+
// },
|
|
259
|
+
// title: 'Supported Currencies',
|
|
260
|
+
// }
|
|
261
|
+
|
|
262
|
+
// console.log({ defs: jsonSchema.definitions })
|
|
263
|
+
|
|
264
|
+
// jsonSchema.definitions.SupportedCurrencies = currenciesSchema
|
|
265
|
+
// }
|
|
266
|
+
|
|
267
|
+
// return jsonSchema
|
|
268
|
+
// },
|
|
269
|
+
// ],
|
|
270
|
+
// }
|
|
271
|
+
|
|
272
|
+
return {
|
|
273
|
+
...incomingConfig,
|
|
274
|
+
}
|
|
275
|
+
}
|