@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.
Files changed (70) hide show
  1. package/.prettierignore +12 -0
  2. package/.swcrc +24 -0
  3. package/LICENSE.md +22 -0
  4. package/README.md +3 -0
  5. package/eslint.config.js +18 -0
  6. package/package.json +4 -0
  7. package/src/addresses/addressesCollection.ts +76 -0
  8. package/src/addresses/defaultAddressFields.ts +83 -0
  9. package/src/addresses/defaultCountries.ts +50 -0
  10. package/src/carts/beforeChange.ts +51 -0
  11. package/src/carts/cartsCollection.ts +146 -0
  12. package/src/currencies/index.ts +29 -0
  13. package/src/endpoints/confirmOrder.ts +312 -0
  14. package/src/endpoints/initiatePayment.ts +322 -0
  15. package/src/exports/addresses.ts +2 -0
  16. package/src/exports/currencies.ts +1 -0
  17. package/src/exports/fields.ts +5 -0
  18. package/src/exports/orders.ts +1 -0
  19. package/src/exports/payments/stripe.ts +1 -0
  20. package/src/exports/plugin.ts +1 -0
  21. package/src/exports/products.ts +1 -0
  22. package/src/exports/react.ts +8 -0
  23. package/src/exports/transactions.ts +1 -0
  24. package/src/exports/translations.ts +1 -0
  25. package/src/exports/types.ts +7 -0
  26. package/src/exports/ui.ts +3 -0
  27. package/src/exports/variants.ts +5 -0
  28. package/src/fields/amountField.ts +43 -0
  29. package/src/fields/cartItemsField.ts +84 -0
  30. package/src/fields/currencyField.ts +39 -0
  31. package/src/fields/inventoryField.ts +22 -0
  32. package/src/fields/pricesField.ts +65 -0
  33. package/src/fields/statusField.ts +57 -0
  34. package/src/fields/variantsFields.ts +56 -0
  35. package/src/index.ts +275 -0
  36. package/src/orders/ordersCollection.ts +157 -0
  37. package/src/payments/adapters/stripe/confirmOrder.ts +123 -0
  38. package/src/payments/adapters/stripe/endpoints/webhooks.ts +69 -0
  39. package/src/payments/adapters/stripe/index.ts +135 -0
  40. package/src/payments/adapters/stripe/initiatePayment.ts +131 -0
  41. package/src/products/productsCollection.ts +78 -0
  42. package/src/react/provider/index.tsx +893 -0
  43. package/src/react/provider/types.ts +184 -0
  44. package/src/react/provider/utilities.ts +22 -0
  45. package/src/transactions/transactionsCollection.ts +166 -0
  46. package/src/translations/en.ts +64 -0
  47. package/src/translations/index.ts +11 -0
  48. package/src/translations/translation-schema.json +35 -0
  49. package/src/types.ts +403 -0
  50. package/src/ui/PriceInput/FormattedInput.tsx +134 -0
  51. package/src/ui/PriceInput/index.scss +28 -0
  52. package/src/ui/PriceInput/index.tsx +43 -0
  53. package/src/ui/PriceInput/utilities.ts +46 -0
  54. package/src/ui/PriceRowLabel/index.css +13 -0
  55. package/src/ui/PriceRowLabel/index.tsx +56 -0
  56. package/src/ui/VariantOptionsSelector/ErrorBox.tsx +27 -0
  57. package/src/ui/VariantOptionsSelector/OptionsSelect.tsx +78 -0
  58. package/src/ui/VariantOptionsSelector/index.css +37 -0
  59. package/src/ui/VariantOptionsSelector/index.tsx +83 -0
  60. package/src/utilities/defaultProductsValidation.ts +42 -0
  61. package/src/utilities/errorCodes.ts +14 -0
  62. package/src/utilities/getCollectionSlugMap.ts +84 -0
  63. package/src/utilities/sanitizePluginConfig.ts +80 -0
  64. package/src/variants/variantOptionsCollection.ts +59 -0
  65. package/src/variants/variantTypesCollection.ts +55 -0
  66. package/src/variants/variantsCollection/hooks/beforeChange.ts +47 -0
  67. package/src/variants/variantsCollection/hooks/validateOptions.ts +72 -0
  68. package/src/variants/variantsCollection/index.ts +119 -0
  69. package/tsconfig.json +7 -0
  70. 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
+ }