@nexo-labs/payload-stripe-inventory 1.6.10 → 1.6.12
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/index-BFzOtUiG.d.mts +72 -0
- package/dist/index-BFzOtUiG.d.mts.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/server/index.d.mts +187 -30
- package/dist/server/index.d.mts.map +1 -1
- package/dist/server/index.mjs +338 -164
- package/dist/server/index.mjs.map +1 -1
- package/package.json +4 -4
- package/dist/index-D-NQPUJO.d.mts +0 -892
- package/dist/index-D-NQPUJO.d.mts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["prices","customers","existingCustomer: Customer | null","customer","products","headers","getHeaders","metadata: Stripe.MetadataParam","flowData: Stripe.BillingPortal.SessionCreateParams.FlowData | undefined","metadata: Stripe.MetadataParam","isAdmin: Access","isAnyone: Access","isAdminOrCurrentUser: Access","isAdminOrPublished: Access","isAdminOrStripeActive: Access","isAdminOrUserFieldMatchingCurrentUser: Access","loggedInOrPublished: Access","customers: CollectionConfig","permissionEvaluationField: Field","prices: CollectionConfig","products: CollectionConfig"],"sources":["../../src/server/utils/payload/upsert.ts","../../src/server/utils/stripe/stripe-builder.ts","../../src/server/actions/price.ts","../../src/server/actions/product.ts","../../src/server/utils/payload/sync-customer-by-email.ts","../../src/server/utils/payload/upsert-customer-inventory-and-sync-with-user.ts","../../src/server/utils/payload/get-userId-by-email.ts","../../src/server/utils/stripe/get-customer.ts","../../src/server/utils/payload/remove-customer-by-stripe-id.ts","../../src/server/utils/payload/find-or-create-customer.ts","../../src/server/actions/subscription.ts","../../src/server/actions/donation.ts","../../src/server/actions/invoice.ts","../../src/server/actions/customer.ts","../../src/server/access/get-current-user-query.ts","../../src/server/actions/unlock-item-for-user-action.ts","../../src/server/actions/update-products-and-prices-action.ts","../../src/server/utils/stripe/create-customer-at-stripe.ts","../../src/server/utils/stripe/get-customer-from-stripe-or-create.ts","../../src/server/api/handle-donation.ts","../../src/server/api/handle-update.ts","../../src/server/api/handle-portal.ts","../../src/server/api/handle-checkout.ts","../../src/server/api/index.ts","../../src/server/access/access-queries.ts","../../src/server/collections/customers.ts","../../src/server/collections/fields/permission-evaluation-field.ts","../../src/server/collections/prices.ts","../../src/server/collections/products.ts","../../src/server/plugin.ts"],"sourcesContent":["\"use server\";\n\nimport { Payload } from \"payload\"\n\ntype Config = {\n collections: {\n [key: string]: any\n }\n}\n\ninterface UpsertOptions<T extends keyof Config['collections']> {\n collection: T\n payload: Payload\n data: Omit<Config['collections'][T], 'createdAt' | 'id' | 'updatedAt' | 'sizes'>\n where: any\n}\n\nexport const payloadUpsert = async <T extends keyof Config['collections']>({\n payload,\n collection,\n data,\n where,\n}: UpsertOptions<T>): Promise<Config['collections'][T] | null> => {\n try {\n const existingDocs = await payload.find({\n collection: collection as any,\n where,\n pagination: false,\n limit: 1,\n })\n\n const existingDocId = existingDocs.docs?.at(0)?.id\n if (existingDocId) {\n const updatedDoc = await payload.update({\n collection: collection as any,\n id: existingDocId,\n data: data as any,\n })\n\n return updatedDoc || null\n }\n\n return await payload.create({\n collection,\n data,\n } as any)\n } catch (error) {\n console.error(`Error in payloadUpsert: ${error}`)\n throw new Error(`Failed to upsert document in collection ${collection} ${error}`)\n }\n}\n","import Stripe from \"stripe\";\nexport const stripeBuilder = (): Stripe => {\n return new Stripe(process.env.STRIPE_SECRET_KEY!, {\n apiVersion: '2024-09-30.acacia'\n })\n}\n","\"use server\";\n\nimport type { Payload } from \"payload\";\nimport type Stripe from \"stripe\";\nimport {\n COLLECTION_SLUG_PRICES,\n COLLECTION_SLUG_PRODUCTS,\n} from \"../../model/index.js\";\nimport { payloadUpsert } from \"../utils/payload/upsert.js\";\nimport { stripeBuilder } from \"../utils/stripe/stripe-builder.js\";\n\nexport const updatePrices = async (payload: Payload) => {\n const stripe = await stripeBuilder();\n const prices = await stripe.prices.list({ limit: 100, active: true });\n const promises = prices.data.map(price => priceUpsert(price, payload));\n const pricesUpserted = await Promise.all(promises);\n\n const pricesByProductId = pricesUpserted\n .mapNotNull(t => t)\n .reduce(\n (acc, { productId, priceId }) => {\n if (!acc[productId]) {\n acc[productId] = [];\n }\n acc[productId].push(priceId);\n return acc;\n },\n {} as Record<string, number[]>\n );\n\n Object.entries(pricesByProductId).map(async ([productId, prices]) => {\n await payload.update({\n collection: COLLECTION_SLUG_PRODUCTS,\n data: {\n prices,\n },\n where: {\n stripeID: { equals: productId },\n },\n });\n });\n};\n\ninterface PriceUpserted {\n productId: string;\n priceId: number;\n}\n\nexport async function priceUpsert(\n price: Stripe.Price,\n payload: Payload\n): Promise<PriceUpserted | null> {\n const stripeProductID =\n typeof price.product === \"string\" ? price.product : price.product.id;\n\n if (price.deleted !== undefined) {\n priceDeleted(price, payload);\n return null;\n }\n if (price.unit_amount == null) return null;\n const priceUpserted = await payloadUpsert({\n payload,\n collection: COLLECTION_SLUG_PRICES,\n data: {\n stripeID: price.id,\n stripeProductId: stripeProductID,\n active: price.active,\n unitAmount: price.unit_amount as number,\n currency: price.currency,\n type: price.type,\n interval: price.recurring?.interval,\n intervalCount: price.recurring?.interval_count,\n },\n where: {\n stripeID: { equals: price.id },\n },\n });\n if (!priceUpserted) return null;\n return { productId: stripeProductID, priceId: priceUpserted.id };\n}\n\nexport const priceDeleted = async (price: Stripe.Price, payload: Payload) => {\n const { id } = price;\n\n try {\n await payload.delete({\n collection: COLLECTION_SLUG_PRICES,\n where: {\n stripeID: { equals: id },\n },\n });\n } catch (error) {\n payload.logger.error(`- Error deleting price: ${error}`);\n throw error;\n }\n};\n","\"use server\";\n\nimport type { Payload } from \"payload\";\nimport type Stripe from \"stripe\";\nimport { COLLECTION_SLUG_PRODUCTS } from \"../../model/index.js\";\nimport { payloadUpsert } from \"../utils/payload/upsert.js\";\nimport { stripeBuilder } from \"../utils/stripe/stripe-builder.js\";\n\nconst logs = false;\n\nexport const updateProducts = async (payload: Payload) => {\n const stripe = await stripeBuilder();\n const products = await stripe.products.list({ limit: 100, active: true });\n products.data.forEach(product => productSync(product, payload));\n};\n\nexport const productSync = async (object: Stripe.Product, payload: Payload) => {\n const { id: stripeProductID, name, description, images } = object;\n if (object.deleted !== undefined) return productDeleted(object, payload);\n try {\n await payloadUpsert({\n payload,\n collection: COLLECTION_SLUG_PRODUCTS,\n data: {\n prices: [],\n stripeID: stripeProductID,\n active: true,\n metadata: object.metadata,\n type: object.type,\n name,\n description,\n images: images?.map(image => ({ url: image })) || [],\n },\n where: {\n stripeID: { equals: stripeProductID },\n },\n });\n } catch (error) {\n console.error(error);\n throw error;\n }\n};\n\nexport const productDeleted = async (\n object: Stripe.Product,\n payload: Payload\n) => {\n const { id: stripeProductID } = object;\n\n try {\n const productQuery = await payload.find({\n collection: COLLECTION_SLUG_PRODUCTS,\n where: {\n stripeID: { equals: stripeProductID },\n },\n });\n\n const payloadProductID = productQuery.docs?.[0]?.id;\n\n if (payloadProductID) {\n await payload.delete({\n collection: COLLECTION_SLUG_PRODUCTS,\n id: payloadProductID,\n });\n\n if (logs)\n payload.logger.info(\n `✅ Successfully deleted product with Stripe ID: ${stripeProductID}`\n );\n }\n } catch (error) {\n payload.logger.error(`- Error deleting product: ${error}`);\n throw error;\n }\n};\n","import { COLLECTION_SLUG_CUSTOMERS } from \"../../../model/index.js\";\nimport { Payload } from \"payload\";\n\nexport async function syncCustomerByEmail({ email, payload }: { email: string, payload: Payload }) {\n const customers = await payload.find({\n collection: COLLECTION_SLUG_CUSTOMERS,\n where: { email: { equals: email } },\n });\n const customerId = customers.docs?.[0]?.id;\n\n await payload.update({\n collection: \"users\",\n data: {\n customer: customerId,\n },\n where: { email: { equals: email } },\n });\n}\n","import { COLLECTION_SLUG_CUSTOMERS, generateCustomerInventory } from \"../../../model/index.js\";\nimport type { CustomerInventory } from \"../../../types/index.js\";\nimport { syncCustomerByEmail } from \"./sync-customer-by-email.js\";\nimport { payloadUpsert } from \"./upsert.js\";\nimport { Payload } from \"payload\";\n\nexport async function upsertCustomerInventoryAndSyncWithUser(\n payload: Payload,\n inventory: CustomerInventory | null | undefined,\n email: string,\n stripeCustomerId?: string | null\n) {\n await payloadUpsert({\n payload,\n collection: COLLECTION_SLUG_CUSTOMERS,\n data: {\n email: email,\n stripeId: stripeCustomerId,\n inventory: inventory ?? generateCustomerInventory(),\n },\n where: { email: { equals: email } },\n });\n await syncCustomerByEmail({ email, payload });\n}\n","import { COLLECTION_SLUG_USER } from \"../../../model/index.js\";\nimport { Payload } from \"payload\";\n\ninterface Props {\n email: string;\n payload: Payload;\n}\n\n/**\n * Gets a user ID by email address using Payload's find method\n * @param email - The email address to search for\n * @returns The user ID if found, null otherwise\n */\nexport async function getUserIdByEmail({email, payload}: Props): Promise<string | null | undefined> {\n const userQuery = await payload.find({\n collection: COLLECTION_SLUG_USER,\n where: {\n email: { equals: email },\n },\n });\n\n const user = userQuery.docs?.[0];\n return user?.id as string | null;\n}\n","import Stripe from \"stripe\";\nimport { stripeBuilder } from \"./stripe-builder.js\";\n\nexport async function getCustomer({\n stripe,\n email,\n}: {\n stripe?: Stripe;\n email: string;\n}): Promise<Stripe.Customer | null> {\n stripe = stripe ?? stripeBuilder();\n const customers = await stripe.customers.search({\n query: `email:'${email}'`,\n });\n return customers.data.length ? customers.data[0] as Stripe.Customer : null;\n \n}\n\nexport async function resolveStripeCustomer({ customer }: {\n customer: string | Stripe.Customer | Stripe.DeletedCustomer | null\n}): Promise<Stripe.Customer | Stripe.DeletedCustomer | null> {\n const stripe = stripeBuilder();\n if (typeof customer === \"string\") {\n return await stripe.customers.retrieve(customer);\n }\n return customer;\n}","import { Payload } from \"payload\";\nimport { COLLECTION_SLUG_CUSTOMERS } from \"../../../model/index.js\";\n\nexport async function removeCustomerByStripeId({\n stripeId,\n payload,\n}: {\n stripeId: string;\n payload: Payload;\n}) {\n await payload.delete({\n collection: COLLECTION_SLUG_CUSTOMERS,\n where: { stripeId: { equals: stripeId } },\n });\n payload.logger.info(`✅ Successfully removed customer with Stripe ID: ${stripeId}`);\n}","import { Payload } from \"payload\";\nimport {\n COLLECTION_SLUG_CUSTOMERS,\n generateCustomerInventory,\n} from \"../../../model/index.js\";\nimport { Customer, CustomerInventory } from \"../../../types/index.js\";\n\ninterface FindOrCreateCustomerProps {\n email: string;\n payload: Payload;\n stripeId?: string;\n}\n\n/**\n * Finds a customer by email address in the customers collection, or creates one if not found\n * @param email - The email address to search for\n * @param payload - Payload instance\n * @param stripeId - Optional Stripe customer ID to set when creating\n * @returns The customer document (found or created)\n */\nexport async function findOrCreateCustomer({\n email,\n payload,\n stripeId,\n}: FindOrCreateCustomerProps): Promise<Customer | null> {\n if (!email) {\n payload.logger.error(\"Email is required to find or create customer\");\n return null;\n }\n\n try {\n const userQuery = await payload.find({\n collection: COLLECTION_SLUG_CUSTOMERS,\n where: {\n email: { equals: email },\n },\n });\n\n let existingCustomer: Customer | null = userQuery.docs?.[0] as unknown as Customer | null;\n if (existingCustomer) {\n existingCustomer.inventory = existingCustomer?.inventory\n ? (existingCustomer.inventory as unknown as CustomerInventory)\n : generateCustomerInventory();\n return existingCustomer;\n }\n\n payload.logger.info(`Creating new customer for email: ${email}`);\n\n const newCustomer = await payload.create({\n collection: COLLECTION_SLUG_CUSTOMERS,\n data: {\n email,\n stripeId: stripeId || \"\",\n inventory: generateCustomerInventory() as unknown as [k: string],\n },\n });\n\n payload.logger.info(`✅ Successfully created customer for email: ${email}`);\n return newCustomer as unknown as Customer;\n } catch (error) {\n payload.logger.error(\n `Error finding or creating customer for email ${email}: ${error}`\n );\n throw error;\n }\n}\n","import { Payload } from \"payload\";\nimport type Stripe from \"stripe\";\nimport { COLLECTION_SLUG_PRODUCTS } from \"../../model/index.js\";\nimport { getPermissionsSlugs } from \"../../model/permissions.js\";\nimport type { CustomerInventory } from \"../../types/index.js\";\nimport { upsertCustomerInventoryAndSyncWithUser } from \"../utils/payload/upsert-customer-inventory-and-sync-with-user.js\";\nimport { getUserIdByEmail } from \"../utils/payload/get-userId-by-email.js\";\nimport { resolveStripeCustomer } from \"../utils/stripe/get-customer.js\";\nimport { removeCustomerByStripeId } from \"../utils/payload/remove-customer-by-stripe-id.js\";\nimport { findOrCreateCustomer } from \"../utils/payload/find-or-create-customer.js\";\n\nexport const subscriptionUpsert = async (\n subscription: Stripe.Subscription,\n payload: Payload,\n onSubscriptionUpdate: (\n type: \"create\" | \"delete\",\n userId: string\n ) => Promise<void>\n) => {\n const { id: stripeID, status, customer: stripeCustomer } = subscription;\n const customer = await resolveStripeCustomer({ customer: stripeCustomer });\n const error = (message: string) =>\n payload.logger.error(\"Subscription Upsert: \", message as any);\n const info = (message: string) =>\n payload.logger.info(\"Subscription Upsert: \", message as any);\n\n if (!customer) {\n error(\"No stripe customer found for subscription\");\n return;\n }\n if (customer.deleted) {\n await removeCustomerByStripeId({ stripeId: customer.id, payload });\n return;\n }\n if (!customer.email) {\n error(\"No email found for stripe customer\");\n return;\n }\n const email = customer.email;\n const stripeId = customer.id;\n\n try {\n const customer = await findOrCreateCustomer({\n email,\n payload,\n stripeId,\n });\n\n const item = subscription.items.data.at(0);\n if (!item || !customer) {\n error(`No item ${item} or customer ${customer} found`);\n return;\n }\n\n const { docs: products } = await payload.find({\n collection: COLLECTION_SLUG_PRODUCTS,\n where: { stripeID: { equals: item.price.product } },\n });\n const product = products.at(0);\n if (!product) return;\n\n const inventory = customer.inventory;\n inventory.subscriptions[stripeID] = {\n ...subscription,\n permissions: getPermissionsSlugs({ permissions: product.roles }),\n };\n info(`INVENTORY OF THE SUBSCRIPTION ${inventory}`);\n await upsertCustomerInventoryAndSyncWithUser(payload, inventory, email, stripeId);\n\n if ([\"active\", \"trialing\"].includes(status)) {\n const userId = await getUserIdByEmail({ email, payload });\n if (!userId) return;\n await onSubscriptionUpdate(\"create\", userId);\n }\n info(\n `✅ Successfully updated subscription with ID: ${stripeID} for user: ${email}`\n );\n } catch (e) {\n error(`- Error managing subscription: ${e}`);\n throw e;\n }\n};\n\nexport const subscriptionDeleted = async (\n subscription: Stripe.Subscription,\n payload: Payload,\n onSubscriptionUpdate: (\n type: \"create\" | \"delete\",\n userId: string\n ) => Promise<void>\n) => {\n const { id, customer: customerId } = subscription;\n const customer = await resolveStripeCustomer({ customer: customerId });\n const stripeId = customer?.id;\n if (!customer) {\n payload.logger.error(\"No stripe customer found for subscription\");\n return;\n } \n if (customer.deleted) {\n await removeCustomerByStripeId({ stripeId: customer.id, payload });\n return;\n }\n if (!customer.email) {\n payload.logger.error(\"No email found for stripe customer\");\n return;\n }\n const email = customer.email;\n try {\n const customer = await findOrCreateCustomer({\n email,\n payload,\n stripeId\n });\n if (!customer) {\n payload.logger.error(\"No customer found for subscription\");\n return;\n }\n\n const inventory = customer.inventory as unknown as CustomerInventory;\n delete inventory.subscriptions[id];\n\n await upsertCustomerInventoryAndSyncWithUser(payload, inventory, email, stripeId);\n const userId = await getUserIdByEmail({ email, payload });\n if (!userId) {\n payload.logger.error(\"No user found for subscription\");\n return;\n }\n await onSubscriptionUpdate(\"delete\", userId);\n\n payload.logger.info(\n `✅ Successfully deleted subscription: ${id} for user: ${email}`\n );\n } catch (error) {\n payload.logger.error(`- Error deleting subscription: ${error}`);\n throw error;\n }\n};\n","import { Payload } from \"payload\";\nimport type Stripe from \"stripe\";\nimport { COLLECTION_SLUG_CUSTOMERS } from \"../../model/index.js\";\nimport { resolveStripeCustomer } from \"../utils/stripe/get-customer.js\";\nimport { findOrCreateCustomer } from \"../utils/payload/find-or-create-customer.js\";\nimport { removeCustomerByStripeId } from \"../utils/payload/remove-customer-by-stripe-id.js\";\n\nexport const paymentSucceeded = async (\n paymentIntent: Stripe.PaymentIntent,\n payload: Payload\n) => {\n const { id, customer: paymentCustomer } = paymentIntent;\n const stripeCustomer = await resolveStripeCustomer({ customer: paymentCustomer });\n if (!stripeCustomer) {\n payload.logger.error(\"No stripe customer found for payment\");\n return\n }\n if (stripeCustomer.deleted) {\n await removeCustomerByStripeId({ stripeId: stripeCustomer.id, payload });\n return;\n }\n if (!stripeCustomer.email) {\n payload.logger.error(\"No email found for stripe customer\");\n return;\n }\n\n try {\n const customer = await findOrCreateCustomer({\n email: stripeCustomer.email,\n payload,\n stripeId: stripeCustomer.id,\n });\n if (!customer) return;\n\n if (!customer) {\n payload.logger.error(`User not found for payment: ${stripeCustomer.email}`);\n return;\n }\n\n let inventory = customer.inventory\n inventory.payments[id] = paymentIntent;\n\n await payload.update({\n collection: COLLECTION_SLUG_CUSTOMERS,\n data: { inventory: inventory as unknown as { [x: string]: {} } },\n where: { email: { equals: stripeCustomer.email } },\n });\n\n payload.logger.info(\n `✅ Successfully recorded ${stripeCustomer.metadata?.type ?? \"subscription\"} with Payment Intent ID: ${id} for user: ${stripeCustomer.email}`\n );\n } catch (error) {\n payload.logger.error(`- Error recording payment: ${error}`);\n throw error;\n }\n};\n","import { Payload } from \"payload\";\nimport type Stripe from \"stripe\";\nimport { COLLECTION_SLUG_CUSTOMERS } from \"../../model/index.js\";\nimport { findOrCreateCustomer } from \"../utils/payload/find-or-create-customer.js\";\nimport { resolveStripeCustomer } from \"../utils/stripe/get-customer.js\";\nimport { removeCustomerByStripeId } from \"../utils/payload/remove-customer-by-stripe-id.js\";\n\nexport const invoiceSucceeded = async (\n invoiceIntent: Stripe.Invoice,\n payload: Payload\n) => {\n const { id, customer: paymentCustomer } = invoiceIntent;\n const stripeCustomer = await resolveStripeCustomer({ customer: paymentCustomer });\n if (!stripeCustomer) {\n payload.logger.error(\"No stripe customer found for payment\");\n return\n }\n if (stripeCustomer.deleted) {\n await removeCustomerByStripeId({ stripeId: stripeCustomer.id, payload });\n return;\n }\n if (!stripeCustomer.email) {\n payload.logger.error(\"No email found for stripe customer\");\n return;\n }\n\n try {\n const customer = await findOrCreateCustomer({\n email: stripeCustomer.email,\n payload,\n stripeId: stripeCustomer.id,\n });\n if (!customer) return;\n\n let inventory = customer.inventory\n inventory.invoices[id] = invoiceIntent;\n\n await payload.update({\n collection: COLLECTION_SLUG_CUSTOMERS,\n data: { inventory: inventory as unknown as { [x: string]: {} } },\n where: { email: { equals: stripeCustomer.email } },\n });\n\n payload.logger.info(\n `✅ Successfully recorded ${stripeCustomer.metadata?.type ?? \"subscription\"} with Payment Intent ID: ${id} for user: ${stripeCustomer.email}`\n );\n } catch (error) {\n payload.logger.error(`- Error recording payment: ${error}`);\n throw error;\n }\n};\n","import { Payload } from \"payload\";\nimport Stripe from \"stripe\";\nimport { COLLECTION_SLUG_CUSTOMERS } from \"../../index.js\";\n\nexport const customerDeleted = async (\n customer: Stripe.Customer,\n payload: Payload,\n ) => {\n const { id, email } = customer;\n try { \n await payload.delete({\n collection: COLLECTION_SLUG_CUSTOMERS,\n where: { email: { equals: email } },\n });\n payload.logger.info(\n `✅ Successfully deleted customer with Stripe ID: ${id}`\n );\n } catch (error) {\n payload.logger.error(`- Error deleting subscription: ${error}`);\n throw error;\n }\n };\n ","'use server'\n\nimport { headers as getHeaders } from 'next/headers.js'\nimport { BasePayload } from 'payload'\nimport { BaseUser } from '../../index.js'\n\nexport async function getCurrentUserQuery(payload: BasePayload): Promise<BaseUser | null> {\n const headers = await getHeaders()\n return (await payload.auth({ headers })).user as BaseUser | null\n}\n","import { Payload } from \"payload\";\nimport {\n checkIfUserCanUnlockQuery,\n COLLECTION_SLUG_USER,\n countWeeklyUnlocksQuery,\n MAX_UNLOCKS_PER_WEEK,\n} from \"../../model/index.js\";\nimport { generateUserInventory } from \"../../model/builders.js\";\nimport { getPermissionsSlugs } from \"../../model/permissions.js\";\nimport type { UnlockItem, UserInventory } from \"../../types/index.js\";\nimport { getCurrentUserQuery } from \"../access/get-current-user-query.js\";\n\nexport type Result<T, E = string> = {\n data: T;\n error?: never;\n} | {\n data?: never;\n error: E;\n}\n\n\nconst addUniqueUnlock = (\n unlocks: UnlockItem[],\n collection: string,\n contentId: number\n): UnlockItem[] => {\n const isDuplicate = unlocks.some(\n unlock => unlock.collection === collection && unlock.id === contentId\n );\n\n if (isDuplicate) {\n return unlocks;\n }\n return [\n ...unlocks,\n {\n collection,\n id: contentId,\n dateUnlocked: new Date(),\n },\n ];\n};\n\nexport const unlockItemForUser = async (\n getPayload: () => Promise<Payload>,\n collection: string,\n contentId: number\n): Promise<Result<boolean>> => {\n const payload = await getPayload();\n const user = await getCurrentUserQuery(payload);\n if (!user || !user.id) {\n return { error: \"Usuario no válido\" };\n }\n const item = await payload.findByID({\n collection: collection as any,\n id: contentId.toString(),\n });\n\n if (!item) {\n return { error: \"Elemento no encontrado\" };\n }\n const permissions = getPermissionsSlugs({ permissions: item.permissions });\n\n if (!checkIfUserCanUnlockQuery(user, permissions)) {\n return { error: \"No tienes permisos para desbloquear este elemento\" };\n }\n\n const weeklyUnlocks = countWeeklyUnlocksQuery(user);\n if (weeklyUnlocks >= MAX_UNLOCKS_PER_WEEK) {\n return {\n error: `Has alcanzado el límite de ${MAX_UNLOCKS_PER_WEEK} desbloqueos para esta semana`,\n };\n }\n\n const inventory =\n (user.inventory as UserInventory) ?? generateUserInventory();\n\n const updatedUnlocks = addUniqueUnlock(\n inventory.unlocks,\n collection,\n contentId\n );\n\n if (updatedUnlocks.length === inventory.unlocks.length) {\n return { data: true };\n }\n\n try {\n await payload.update({\n collection: COLLECTION_SLUG_USER,\n id: user.id.toString(),\n data: {\n inventory: {\n ...inventory,\n unlocks: updatedUnlocks,\n },\n },\n });\n\n return { data: true };\n } catch (error) {\n console.error(\"Error al actualizar el inventario del usuario:\", error);\n return { error: \"Error al actualizar el inventario del usuario\" };\n }\n};\n","\"use server\";\n\nimport { updatePrices } from \"./price.js\";\nimport { updateProducts } from \"./product.js\";\nimport { Payload } from \"payload\";\n\nexport async function updateProductsAndPrices(payload: Payload) {\n await updateProducts(payload);\n await updatePrices(payload);\n}\n","import Stripe from \"stripe\";\nimport { stripeBuilder } from \"./stripe-builder.js\";\n\nexport async function createCustomerAtStripe({\n stripe,\n email,\n name,\n}: {\n stripe?: Stripe;\n email: string;\n name?: string;\n}) {\n stripe = stripe ?? stripeBuilder();\n return await stripe.customers.create({\n email: email,\n name: name || undefined,\n });\n}\n","import { createCustomerAtStripe } from \"./create-customer-at-stripe.js\";\nimport { getCustomer } from \"./get-customer.js\";\nimport { stripeBuilder } from \"./stripe-builder.js\";\n\nexport async function getCustomerFromStripeOrCreate(\n email: string,\n name?: string\n): Promise<string> {\n const stripe = stripeBuilder();\n let customer = await getCustomer({ stripe, email });\n if (!customer) {\n customer = await createCustomerAtStripe({ stripe, email, name });\n }\n return customer.id;\n}\n","import { NextResponse } from \"next/server.js\";\nimport Stripe from \"stripe\";\nimport { upsertCustomerInventoryAndSyncWithUser } from \"../utils/payload/upsert-customer-inventory-and-sync-with-user.js\";\nimport { getCustomerFromStripeOrCreate } from \"../utils/stripe/get-customer-from-stripe-or-create.js\";\nimport { stripeBuilder } from \"../utils/stripe/stripe-builder.js\";\nimport { getCurrentUserQuery } from \"../access/get-current-user-query.js\";\nimport { Payload } from \"payload\";\n\nexport async function handleDonation(\n request: Request,\n getPayload: () => Promise<Payload>,\n getRoutes: () => { nextJS: { subscriptionPageHref: string } }\n) {\n const payload = await getPayload();\n const payloadUser = await getCurrentUserQuery(payload);\n if (!payloadUser || !payloadUser.email)\n throw new Error(\"You must be logged in to make a donation\");\n\n const url = new URL(request.url);\n const amountParam = url.searchParams.get(\"amount\");\n\n if (!amountParam) throw new Error(\"Amount is required\");\n\n const amount = parseInt(amountParam);\n if (amount < 100) throw new Error(\"Minimum donation amount is €1\");\n\n const stripe = stripeBuilder();\n const customerId = await getCustomerFromStripeOrCreate(\n payloadUser.email,\n payloadUser.name\n );\n await upsertCustomerInventoryAndSyncWithUser(\n payload,\n payloadUser.customer?.inventory,\n payloadUser.email,\n customerId\n );\n const metadata: Stripe.MetadataParam = {\n type: \"donation\",\n };\n const session = await stripe.checkout.sessions.create({\n customer: customerId,\n payment_method_types: [\"card\"],\n line_items: [\n {\n price_data: {\n currency: \"eur\",\n product_data: {\n name: \"Donación - Portal Escohotado\",\n description:\n \"Apoyo al mantenimiento del legado digital de Antonio Escohotado\",\n },\n unit_amount: amount,\n },\n quantity: 1,\n },\n ],\n mode: \"payment\",\n success_url: `${process.env.DOMAIN}${getRoutes().nextJS.subscriptionPageHref}?success=donation`,\n cancel_url: `${process.env.DOMAIN}${getRoutes().nextJS.subscriptionPageHref}?error=donation_cancelled`,\n metadata,\n payment_intent_data: { metadata },\n invoice_creation: { enabled: true, invoice_data: { metadata } },\n });\n\n return NextResponse.json({ url: session.url });\n}\n","import { NextResponse } from \"next/server.js\";\nimport type { Customer, CustomerInventory } from \"../../types/index.js\";\nimport { upsertCustomerInventoryAndSyncWithUser } from \"../utils/payload/upsert-customer-inventory-and-sync-with-user.js\";\nimport { stripeBuilder } from \"../utils/stripe/stripe-builder.js\";\nimport { getCurrentUserQuery } from \"../access/get-current-user-query.js\";\nimport { Payload } from \"payload\";\n\nexport async function handleUpdate(\n request: Request,\n getPayload: () => Promise<Payload>,\n getRoutes: () => { nextJS: { subscriptionPageHref: string } }\n) {\n const payload = await getPayload();\n const payloadUser = await getCurrentUserQuery(payload);\n if (!payloadUser) {\n throw new Error(\"You must be logged in to access this page\");\n }\n const { searchParams } = new URL(request.url);\n const subscriptionId = searchParams.get(\"subscriptionId\");\n const cancelAtPeriodEnd = searchParams.get(\"cancelAtPeriodEnd\") === \"true\";\n if (!subscriptionId) throw Error(\"SubscriptionId could not be found.\");\n\n await stripeBuilder().subscriptions.update(subscriptionId, {\n cancel_at_period_end: cancelAtPeriodEnd,\n });\n const customer = payloadUser.customer as Customer;\n console.error(\"UPDATE: customer\", customer);\n const inventory = customer.inventory as CustomerInventory | null;\n if (inventory && inventory.subscriptions && inventory.subscriptions[subscriptionId]) {\n inventory.subscriptions[subscriptionId].cancel_at_period_end =\n cancelAtPeriodEnd;\n }\n\n await upsertCustomerInventoryAndSyncWithUser(\n payload,\n inventory,\n customer.email\n );\n\n const routes = getRoutes();\n return NextResponse.redirect(\n `${process.env.DOMAIN}${routes.nextJS.subscriptionPageHref}?refresh=${Date.now()}`,\n 303\n );\n}\n","import { NextResponse } from \"next/server.js\";\nimport Stripe from \"stripe\";\nimport { upsertCustomerInventoryAndSyncWithUser } from \"../utils/payload/upsert-customer-inventory-and-sync-with-user.js\";\nimport { getCustomerFromStripeOrCreate } from \"../utils/stripe/get-customer-from-stripe-or-create.js\";\nimport { stripeBuilder } from \"../utils/stripe/stripe-builder.js\";\nimport { getCurrentUserQuery } from \"../access/get-current-user-query.js\";\nimport { Payload } from \"payload\";\n\nexport async function handlePortal(\n request: Request,\n getPayload: () => Promise<Payload>,\n getRoutes: () => { nextJS: { subscriptionPageHref: string } }\n) {\n const payload = await getPayload();\n const payloadUser = await getCurrentUserQuery(payload);\n if (!payloadUser || !payloadUser.email)\n throw new Error(\"You must be logged in to access this page\");\n const url = new URL(request.url);\n const cancelSubscriptionId = url.searchParams.get(\"cancelSubscriptionId\");\n const updateSubscriptionId = url.searchParams.get(\"updateSubscriptionId\");\n\n let flowData: Stripe.BillingPortal.SessionCreateParams.FlowData | undefined;\n if (cancelSubscriptionId)\n flowData = {\n type: \"subscription_cancel\",\n subscription_cancel: { subscription: cancelSubscriptionId },\n };\n else if (updateSubscriptionId)\n flowData = {\n type: \"subscription_update\",\n subscription_update: { subscription: updateSubscriptionId },\n };\n\n const stripe = stripeBuilder();\n const routes = getRoutes();\n const customerId = await getCustomerFromStripeOrCreate(\n payloadUser.email,\n payloadUser.name\n );\n await upsertCustomerInventoryAndSyncWithUser(\n payload,\n payloadUser.customer?.inventory,\n payloadUser.email,\n customerId\n );\n\n const session = await stripe.billingPortal.sessions.create({\n flow_data: flowData,\n customer: customerId,\n return_url: `${process.env.DOMAIN}${routes.nextJS.subscriptionPageHref}`,\n });\n\n return NextResponse.redirect(session.url, 303);\n}\n","import { NextResponse } from \"next/server.js\";\nimport Stripe from \"stripe\";\nimport { upsertCustomerInventoryAndSyncWithUser } from \"../utils/payload/upsert-customer-inventory-and-sync-with-user.js\";\nimport { getCustomerFromStripeOrCreate } from \"../utils/stripe/get-customer-from-stripe-or-create.js\";\nimport { stripeBuilder } from \"../utils/stripe/stripe-builder.js\";\nimport { getCurrentUserQuery } from \"../access/get-current-user-query.js\";\nimport { Payload } from \"payload\";\n\nexport async function handleCheckout(\n request: Request,\n getPayload: () => Promise<Payload>,\n getRoutes: () => { nextJS: { subscriptionPageHref: string } }\n) {\n const payload = await getPayload();\n const payloadUser = await getCurrentUserQuery(payload);\n\n const url = new URL(request.url);\n const priceId = url.searchParams.get(\"priceId\");\n if (!priceId || !payloadUser || !payloadUser.email)\n throw new Error(\"Invalid request\");\n\n const stripe = stripeBuilder();\n const routes = getRoutes();\n const customerId = await getCustomerFromStripeOrCreate(\n payloadUser.email,\n payloadUser.name\n );\n await upsertCustomerInventoryAndSyncWithUser(\n payload,\n payloadUser.customer?.inventory,\n payloadUser.email,\n customerId\n );\n\n const metadata: Stripe.MetadataParam = {\n type: \"subscription\",\n };\n\n const checkoutResult = await stripe.checkout.sessions.create({\n success_url: `${process.env.DOMAIN}${routes.nextJS.subscriptionPageHref}?success=${Date.now()}`,\n cancel_url: `${process.env.DOMAIN}${routes.nextJS.subscriptionPageHref}?error=${Date.now()}`,\n mode: \"subscription\",\n customer: customerId,\n client_reference_id: String(payloadUser.id),\n line_items: [{ price: priceId, quantity: 1 }],\n metadata,\n tax_id_collection: { enabled: true },\n customer_update: {\n name: \"auto\",\n address: \"auto\",\n shipping: \"auto\",\n },\n subscription_data: { metadata },\n });\n if (checkoutResult.url) return NextResponse.redirect(checkoutResult.url, 303);\n else return NextResponse.json(\"Create checkout url failed\", { status: 406 });\n}\n","import { NextResponse } from \"next/server.js\";\nimport { handleDonation } from \"./handle-donation.js\";\nimport { handleUpdate } from \"./handle-update.js\";\nimport { handlePortal } from \"./handle-portal.js\";\nimport { handleCheckout } from \"./handle-checkout.js\";\nimport type { StripeHandlers } from \"../../types/index.js\";\nimport { Payload } from \"payload\";\nexport * from \"../utils/stripe/get-customer-from-stripe-or-create.js\";\n\nexport function createStripeInventoryHandlers(\n getPayload: () => Promise<Payload>,\n getRoutes: () => { nextJS: { subscriptionPageHref: string } }\n): StripeHandlers {\n return {\n checkout: {\n GET: (request: Request) =>\n handleCheckout(request, getPayload, getRoutes),\n },\n portal: {\n GET: (request: Request) =>\n handlePortal(request, getPayload, getRoutes),\n },\n update: {\n GET: (request: Request) =>\n handleUpdate(request, getPayload, getRoutes),\n },\n donation: {\n GET: (request: Request) =>\n handleDonation(request, getPayload, getRoutes),\n },\n };\n}\n\nexport function createRouteHandlers(\n getPayload: () => Promise<Payload>,\n getRoutes: () => { nextJS: { subscriptionPageHref: string } }\n) {\n return {\n GET: async (\n request: Request,\n { params }: { params: Promise<{ stripe: string[] }> }\n ) => {\n const path = (await params).stripe[0];\n const handlers = createStripeInventoryHandlers(getPayload, getRoutes);\n\n if (\n path === \"checkout\" ||\n path === \"portal\" ||\n path === \"update\" ||\n path === \"donation\"\n ) {\n return handlers[path].GET(request);\n }\n\n return NextResponse.json({ error: \"Route not found\" }, { status: 404 });\n },\n };\n}\n","import { Access } from \"payload\";\nimport { permissionSlugs } from \"../../model/constants.js\";\n\nexport const isAdmin: Access = ({ req }) => {\n return req?.user?.roles?.includes(permissionSlugs.webAdmin) || false;\n};\n\nexport const isAnyone: Access = () => true;\n\nexport const isAdminOrCurrentUser: Access = ({ req }) => {\n if (req?.user?.roles?.includes(permissionSlugs.webAdmin)) return true;\n return { id: { equals: req.user?.id } };\n};\n\nexport const isAdminOrPublished: Access = ({ req: { user } }) => {\n if (user && user?.roles?.includes(permissionSlugs.webAdmin)) {\n return true;\n }\n\n return {\n _status: {\n equals: \"published\",\n },\n };\n};\n\nexport const isAdminOrStripeActive: Access = ({ req: { user } }) => {\n if (user && user?.roles?.includes(permissionSlugs.webAdmin)) {\n return true;\n }\n\n return {\n active: {\n equals: true,\n },\n };\n};\n\nexport const isAdminOrUserFieldMatchingCurrentUser: Access = ({\n req: { user },\n}) => {\n if (user) {\n if (user?.roles?.includes(permissionSlugs.webAdmin)) return true;\n return {\n user: {\n equals: user?.id,\n },\n };\n }\n return false;\n};\n\nexport const loggedInOrPublished: Access = ({ req: { user } }) => {\n if (user) {\n return true;\n }\n\n return {\n _status: {\n equals: \"published\",\n },\n };\n};\n","import { CollectionConfig } from \"payload\";\nimport { isAdmin } from \"../access/index.js\";\nimport { COLLECTION_SLUG_CUSTOMERS } from \"../../model/index.js\";\n\nexport const customers: CollectionConfig = {\n slug: COLLECTION_SLUG_CUSTOMERS,\n admin: {\n useAsTitle: \"email\",\n group: \"Stripe\",\n defaultColumns: [\"email\", \"stripeId\", \"createdAt\"],\n },\n access: {\n read: () => true,\n create: () => false,\n update: () => false,\n delete: isAdmin,\n },\n fields: [\n {\n name: \"email\",\n type: \"email\",\n required: true,\n unique: true,\n admin: {\n position: \"sidebar\",\n },\n },\n {\n name: \"stripeId\",\n type: \"text\",\n required: true,\n unique: true,\n admin: {\n position: \"sidebar\",\n readOnly: true,\n },\n },\n {\n name: \"inventory\",\n type: \"json\",\n label: \"Inventario\",\n admin: {\n description: \"Datos de inventario de Stripe almacenados como JSON\",\n readOnly: true,\n },\n },\n ],\n};\n","import { COLLECTION_SLUG_TAXONOMY } from \"@nexo-labs/payload-taxonomies\";\nimport { Field } from \"payload\";\n\nexport const permissionEvaluationField: Field = {\n type: 'row',\n fields: [\n {\n type: 'select',\n name: 'type_of_permissions',\n options: [\n { label: 'Todos', value: 'all' },\n { label: 'Permisos por roles', value: 'roles' },\n { label: 'Solo para usuarios sin roles', value: 'only_no_roles' },\n { label: 'Solo invitados', value: 'only_guess' },\n ],\n defaultValue: 'all',\n label: 'Tipo de permisos',\n },\n {\n type: 'relationship',\n name: 'permissions',\n relationTo: [COLLECTION_SLUG_TAXONOMY],\n hasMany: false,\n admin: {\n condition: (_, siblingData) => siblingData.type_of_permissions === 'roles',\n }\n }\n ]\n}","import { CollectionConfig } from \"payload\";\nimport {\n COLLECTION_SLUG_PRICES,\n COLLECTION_SLUG_PRODUCTS,\n PricingPlanInterval,\n PricingType,\n formatOptions,\n} from \"../../model/index.js\";\nimport { isAdmin, isAdminOrStripeActive } from \"../access/index.js\";\n\nexport const prices: CollectionConfig = {\n slug: COLLECTION_SLUG_PRICES,\n admin: {\n useAsTitle: \"unitAmount\",\n group: \"Stripe\",\n },\n access: {\n read: isAdminOrStripeActive,\n create: () => false,\n update: () => false,\n delete: isAdmin,\n },\n fields: [\n {\n name: \"stripeID\",\n label: \"Stripe ID\",\n type: \"text\",\n required: true,\n admin: { position: \"sidebar\", readOnly: true },\n },\n {\n name: \"stripeProductId\",\n type: \"text\",\n required: true,\n admin: { position: \"sidebar\", readOnly: true },\n },\n {\n name: \"product\",\n type: \"join\",\n collection: COLLECTION_SLUG_PRODUCTS,\n on: \"prices\",\n hasMany: false,\n },\n {\n name: \"active\",\n type: \"checkbox\",\n required: true,\n admin: { position: \"sidebar\" },\n },\n { name: \"description\", type: \"textarea\" },\n {\n type: \"row\",\n fields: [\n { name: \"unitAmount\", type: \"number\", required: true },\n { name: \"currency\", type: \"text\", required: true },\n {\n name: \"type\",\n type: \"select\",\n options: formatOptions(PricingType),\n required: true,\n },\n ],\n },\n {\n type: \"row\",\n fields: [\n {\n name: \"interval\",\n type: \"select\",\n options: formatOptions(PricingPlanInterval),\n },\n { name: \"intervalCount\", type: \"number\" },\n { name: \"trialPeriodDays\", type: \"number\" },\n ],\n },\n { name: \"metadata\", type: \"json\", label: \"Metadata\" },\n ],\n};\n","import { buildTaxonomyRelationship } from \"@nexo-labs/payload-taxonomies\";\nimport { CollectionConfig } from \"payload\";\nimport { COLLECTION_SLUG_PRICES, COLLECTION_SLUG_PRODUCTS } from \"../../model/index.js\";\nimport { isAdminOrStripeActive } from \"../access/index.js\";\n\nexport const products: CollectionConfig = {\n slug: COLLECTION_SLUG_PRODUCTS,\n admin: {\n useAsTitle: \"name\",\n group: \"Stripe\",\n },\n access: {\n read: isAdminOrStripeActive,\n create: () => false,\n },\n fields: [\n {\n name: \"stripeID\",\n label: \"Stripe ID\",\n type: \"text\",\n required: true,\n admin: { position: \"sidebar\", readOnly: true },\n },\n {\n name: \"type\",\n type: \"select\",\n options: [\n { value: \"good\", label: \"Bienes\" },\n { value: \"service\", label: \"Service\" },\n ],\n },\n {\n name: \"active\",\n type: \"checkbox\",\n required: true,\n admin: { position: \"sidebar\" },\n },\n {\n name: \"show\",\n type: \"checkbox\",\n defaultValue: false,\n admin: { position: \"sidebar\" },\n },\n { name: \"name\", type: \"text\", required: true },\n { name: \"description\", type: \"textarea\" },\n { name: \"images\", type: \"array\", fields: [{ type: \"text\", name: \"url\" }] },\n {\n name: \"prices\",\n type: \"relationship\",\n relationTo: COLLECTION_SLUG_PRICES,\n hasMany: true,\n required: false,\n },\n { name: \"metadata\", type: \"json\", label: \"Metadata\" },\n {\n type: \"array\",\n name: \"features\",\n fields: [{ type: \"text\", name: \"title\" }],\n },\n buildTaxonomyRelationship({\n name: \"roles\",\n label: \"Roles\",\n defaultValue: [],\n filterOptions: () => {\n return {\n \"payload.types\": { in: [\"role\"] },\n };\n },\n required: false,\n }),\n ],\n};\n","import { stripePlugin } from \"@payloadcms/plugin-stripe\";\nimport {\n priceDeleted,\n subscriptionUpsert,\n subscriptionDeleted,\n productDeleted,\n paymentSucceeded,\n invoiceSucceeded,\n customerDeleted,\n} from \"./actions/index.js\";\nimport { Plugin } from \"payload\";\n\nexport const plugin = (\n onSubscriptionUpdate: (\n type: \"create\" | \"delete\",\n userId: string\n ) => Promise<void>\n): Plugin => {\n return stripePlugin({\n isTestKey: process.env.STRIPE_SECRET_KEY?.includes(\"sk_test\"),\n stripeSecretKey: process.env.STRIPE_SECRET_KEY || \"\",\n stripeWebhooksEndpointSecret: process.env.STRIPE_WEBHOOK_SECRET,\n webhooks: {\n \"price.deleted\": async ({ event, payload }) =>\n await priceDeleted(event.data.object, payload),\n \"customer.subscription.created\": async ({ event, payload }) =>\n await subscriptionUpsert(\n event.data.object,\n payload,\n onSubscriptionUpdate\n ),\n \"customer.subscription.paused\": async ({ event, payload }) =>\n await subscriptionUpsert(\n event.data.object,\n payload,\n onSubscriptionUpdate\n ),\n \"customer.subscription.updated\": async ({ event, payload }) =>\n await subscriptionUpsert(\n event.data.object,\n payload,\n onSubscriptionUpdate\n ),\n \"customer.subscription.deleted\": async ({ event, payload }) =>\n await subscriptionDeleted(\n event.data.object,\n payload,\n onSubscriptionUpdate\n ),\n \"customer.deleted\": async ({ event, payload }) =>\n await customerDeleted(event.data.object, payload),\n \"product.deleted\": async ({ event, payload }) =>\n await productDeleted(event.data.object, payload),\n \"payment_intent.succeeded\": async ({ event, payload }) => {\n await paymentSucceeded(event.data.object, payload)\n },\n \"invoice.paid\": async ({ event, payload }) => {\n await invoiceSucceeded(event.data.object, payload)\n }\n },\n });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["prices","customers","existingCustomer: Customer | null","customer","products","user: BaseUser | null","metadata: Stripe.MetadataParam","metadata: Stripe.MetadataParam","flowData: Stripe.BillingPortal.SessionCreateParams.FlowData | undefined","endpointConfig: StripeEndpointConfig","configWithEndpoints: Config","isAdmin: Access","isAnyone: Access","isAdminOrCurrentUser: Access","isAdminOrPublished: Access","isAdminOrStripeActive: Access","isAdminOrUserFieldMatchingCurrentUser: Access","loggedInOrPublished: Access","customers: CollectionConfig","permissionEvaluationField: Field","prices: CollectionConfig","products: CollectionConfig"],"sources":["../../src/server/utils/payload/upsert.ts","../../src/server/utils/stripe/stripe-builder.ts","../../src/server/actions/price.ts","../../src/server/actions/product.ts","../../src/server/utils/payload/sync-customer-by-email.ts","../../src/server/utils/payload/upsert-customer-inventory-and-sync-with-user.ts","../../src/server/utils/payload/get-userId-by-email.ts","../../src/server/utils/stripe/get-customer.ts","../../src/server/utils/payload/remove-customer-by-stripe-id.ts","../../src/server/utils/payload/find-or-create-customer.ts","../../src/server/actions/subscription.ts","../../src/server/actions/donation.ts","../../src/server/actions/invoice.ts","../../src/server/actions/customer.ts","../../src/server/actions/unlock-item-for-user-action.ts","../../src/server/actions/update-products-and-prices-action.ts","../../src/server/utils/stripe/create-customer-at-stripe.ts","../../src/server/utils/stripe/get-customer-from-stripe-or-create.ts","../../src/server/endpoints/validators/request-validator.ts","../../src/server/endpoints/handlers/checkout-handler.ts","../../src/server/endpoints/handlers/donation-handler.ts","../../src/server/endpoints/handlers/portal-handler.ts","../../src/server/endpoints/handlers/update-handler.ts","../../src/server/endpoints/index.ts","../../src/server/plugin/create-stripe-inventory-plugin.ts","../../src/server/access/access-queries.ts","../../src/server/access/get-user-from-request.ts","../../src/server/collections/customers.ts","../../src/server/collections/fields/permission-evaluation-field.ts","../../src/server/collections/prices.ts","../../src/server/collections/products.ts"],"sourcesContent":["\"use server\";\n\nimport { Payload } from \"payload\"\n\ntype Config = {\n collections: {\n [key: string]: any\n }\n}\n\ninterface UpsertOptions<T extends keyof Config['collections']> {\n collection: T\n payload: Payload\n data: Omit<Config['collections'][T], 'createdAt' | 'id' | 'updatedAt' | 'sizes'>\n where: any\n}\n\nexport const payloadUpsert = async <T extends keyof Config['collections']>({\n payload,\n collection,\n data,\n where,\n}: UpsertOptions<T>): Promise<Config['collections'][T] | null> => {\n try {\n const existingDocs = await payload.find({\n collection: collection as any,\n where,\n pagination: false,\n limit: 1,\n })\n\n const existingDocId = existingDocs.docs?.at(0)?.id\n if (existingDocId) {\n const updatedDoc = await payload.update({\n collection: collection as any,\n id: existingDocId,\n data: data as any,\n })\n\n return updatedDoc || null\n }\n\n return await payload.create({\n collection,\n data,\n } as any)\n } catch (error) {\n console.error(`Error in payloadUpsert: ${error}`)\n throw new Error(`Failed to upsert document in collection ${collection} ${error}`)\n }\n}\n","import Stripe from \"stripe\";\nexport const stripeBuilder = (): Stripe => {\n return new Stripe(process.env.STRIPE_SECRET_KEY!, {\n apiVersion: '2024-09-30.acacia'\n })\n}\n","\"use server\";\n\nimport type { Payload } from \"payload\";\nimport type Stripe from \"stripe\";\nimport {\n COLLECTION_SLUG_PRICES,\n COLLECTION_SLUG_PRODUCTS,\n} from \"../../model/index.js\";\nimport { payloadUpsert } from \"../utils/payload/upsert.js\";\nimport { stripeBuilder } from \"../utils/stripe/stripe-builder.js\";\n\nexport const updatePrices = async (payload: Payload) => {\n const stripe = await stripeBuilder();\n const prices = await stripe.prices.list({ limit: 100, active: true });\n const promises = prices.data.map(price => priceUpsert(price, payload));\n const pricesUpserted = await Promise.all(promises);\n\n const pricesByProductId = pricesUpserted\n .filter((p): p is PriceUpserted => p !== null)\n .reduce(\n (acc, { productId, priceId }) => {\n if (!acc[productId]) {\n acc[productId] = [];\n }\n acc[productId].push(priceId);\n return acc;\n },\n {} as Record<string, number[]>\n );\n\n Object.entries(pricesByProductId).map(async ([productId, prices]) => {\n await payload.update({\n collection: COLLECTION_SLUG_PRODUCTS,\n data: {\n prices,\n },\n where: {\n stripeID: { equals: productId },\n },\n });\n });\n};\n\ninterface PriceUpserted {\n productId: string;\n priceId: number;\n}\n\nexport async function priceUpsert(\n price: Stripe.Price,\n payload: Payload\n): Promise<PriceUpserted | null> {\n const stripeProductID =\n typeof price.product === \"string\" ? price.product : price.product.id;\n\n if (price.deleted !== undefined) {\n priceDeleted(price, payload);\n return null;\n }\n if (price.unit_amount == null) return null;\n const priceUpserted = await payloadUpsert({\n payload,\n collection: COLLECTION_SLUG_PRICES,\n data: {\n stripeID: price.id,\n stripeProductId: stripeProductID,\n active: price.active,\n unitAmount: price.unit_amount as number,\n currency: price.currency,\n type: price.type,\n interval: price.recurring?.interval,\n intervalCount: price.recurring?.interval_count,\n },\n where: {\n stripeID: { equals: price.id },\n },\n });\n if (!priceUpserted) return null;\n return { productId: stripeProductID, priceId: priceUpserted.id };\n}\n\nexport const priceDeleted = async (price: Stripe.Price, payload: Payload) => {\n const { id } = price;\n\n try {\n await payload.delete({\n collection: COLLECTION_SLUG_PRICES,\n where: {\n stripeID: { equals: id },\n },\n });\n } catch (error) {\n payload.logger.error(`- Error deleting price: ${error}`);\n throw error;\n }\n};\n","\"use server\";\n\nimport type { Payload } from \"payload\";\nimport type Stripe from \"stripe\";\nimport { COLLECTION_SLUG_PRODUCTS } from \"../../model/index.js\";\nimport { payloadUpsert } from \"../utils/payload/upsert.js\";\nimport { stripeBuilder } from \"../utils/stripe/stripe-builder.js\";\n\nconst logs = false;\n\nexport const updateProducts = async (payload: Payload) => {\n const stripe = await stripeBuilder();\n const products = await stripe.products.list({ limit: 100, active: true });\n products.data.forEach(product => productSync(product, payload));\n};\n\nexport const productSync = async (object: Stripe.Product, payload: Payload) => {\n const { id: stripeProductID, name, description, images } = object;\n if (object.deleted !== undefined) return productDeleted(object, payload);\n try {\n await payloadUpsert({\n payload,\n collection: COLLECTION_SLUG_PRODUCTS,\n data: {\n prices: [],\n stripeID: stripeProductID,\n active: true,\n metadata: object.metadata,\n type: object.type,\n name,\n description,\n images: images?.map(image => ({ url: image })) || [],\n },\n where: {\n stripeID: { equals: stripeProductID },\n },\n });\n } catch (error) {\n console.error(error);\n throw error;\n }\n};\n\nexport const productDeleted = async (\n object: Stripe.Product,\n payload: Payload\n) => {\n const { id: stripeProductID } = object;\n\n try {\n const productQuery = await payload.find({\n collection: COLLECTION_SLUG_PRODUCTS,\n where: {\n stripeID: { equals: stripeProductID },\n },\n });\n\n const payloadProductID = productQuery.docs?.[0]?.id;\n\n if (payloadProductID) {\n await payload.delete({\n collection: COLLECTION_SLUG_PRODUCTS,\n id: payloadProductID,\n });\n\n if (logs)\n payload.logger.info(\n `✅ Successfully deleted product with Stripe ID: ${stripeProductID}`\n );\n }\n } catch (error) {\n payload.logger.error(`- Error deleting product: ${error}`);\n throw error;\n }\n};\n","import { COLLECTION_SLUG_CUSTOMERS } from \"../../../model/index.js\";\nimport { Payload } from \"payload\";\n\nexport async function syncCustomerByEmail({ email, payload }: { email: string, payload: Payload }) {\n const customers = await payload.find({\n collection: COLLECTION_SLUG_CUSTOMERS,\n where: { email: { equals: email } },\n });\n const customerId = customers.docs?.[0]?.id;\n\n await payload.update({\n collection: \"users\",\n data: {\n customer: customerId,\n },\n where: { email: { equals: email } },\n });\n}\n","import { COLLECTION_SLUG_CUSTOMERS, generateCustomerInventory } from \"../../../model/index.js\";\nimport type { CustomerInventory } from \"../../../types/index.js\";\nimport { syncCustomerByEmail } from \"./sync-customer-by-email.js\";\nimport { payloadUpsert } from \"./upsert.js\";\nimport { Payload } from \"payload\";\n\nexport async function upsertCustomerInventoryAndSyncWithUser(\n payload: Payload,\n inventory: CustomerInventory | null | undefined,\n email: string,\n stripeCustomerId?: string | null\n) {\n await payloadUpsert({\n payload,\n collection: COLLECTION_SLUG_CUSTOMERS,\n data: {\n email: email,\n stripeId: stripeCustomerId,\n inventory: inventory ?? generateCustomerInventory(),\n },\n where: { email: { equals: email } },\n });\n await syncCustomerByEmail({ email, payload });\n}\n","import { COLLECTION_SLUG_USER } from \"../../../model/index.js\";\nimport { Payload } from \"payload\";\n\ninterface Props {\n email: string;\n payload: Payload;\n}\n\n/**\n * Gets a user ID by email address using Payload's find method\n * @param email - The email address to search for\n * @returns The user ID if found, null otherwise\n */\nexport async function getUserIdByEmail({email, payload}: Props): Promise<string | null | undefined> {\n const userQuery = await payload.find({\n collection: COLLECTION_SLUG_USER,\n where: {\n email: { equals: email },\n },\n });\n\n const user = userQuery.docs?.[0];\n return user?.id as string | null;\n}\n","import Stripe from \"stripe\";\nimport { stripeBuilder } from \"./stripe-builder.js\";\n\nexport async function getCustomer({\n stripe,\n email,\n}: {\n stripe?: Stripe;\n email: string;\n}): Promise<Stripe.Customer | null> {\n stripe = stripe ?? stripeBuilder();\n const customers = await stripe.customers.search({\n query: `email:'${email}'`,\n });\n return customers.data.length ? customers.data[0] as Stripe.Customer : null;\n \n}\n\nexport async function resolveStripeCustomer({ customer }: {\n customer: string | Stripe.Customer | Stripe.DeletedCustomer | null\n}): Promise<Stripe.Customer | Stripe.DeletedCustomer | null> {\n const stripe = stripeBuilder();\n if (typeof customer === \"string\") {\n return await stripe.customers.retrieve(customer);\n }\n return customer;\n}","import { Payload } from \"payload\";\nimport { COLLECTION_SLUG_CUSTOMERS } from \"../../../model/index.js\";\n\nexport async function removeCustomerByStripeId({\n stripeId,\n payload,\n}: {\n stripeId: string;\n payload: Payload;\n}) {\n await payload.delete({\n collection: COLLECTION_SLUG_CUSTOMERS,\n where: { stripeId: { equals: stripeId } },\n });\n payload.logger.info(`✅ Successfully removed customer with Stripe ID: ${stripeId}`);\n}","import { Payload } from \"payload\";\nimport {\n COLLECTION_SLUG_CUSTOMERS,\n generateCustomerInventory,\n} from \"../../../model/index.js\";\nimport { Customer, CustomerInventory } from \"../../../types/index.js\";\n\ninterface FindOrCreateCustomerProps {\n email: string;\n payload: Payload;\n stripeId?: string;\n}\n\n/**\n * Finds a customer by email address in the customers collection, or creates one if not found\n * @param email - The email address to search for\n * @param payload - Payload instance\n * @param stripeId - Optional Stripe customer ID to set when creating\n * @returns The customer document (found or created)\n */\nexport async function findOrCreateCustomer({\n email,\n payload,\n stripeId,\n}: FindOrCreateCustomerProps): Promise<Customer | null> {\n if (!email) {\n payload.logger.error(\"Email is required to find or create customer\");\n return null;\n }\n\n try {\n const userQuery = await payload.find({\n collection: COLLECTION_SLUG_CUSTOMERS,\n where: {\n email: { equals: email },\n },\n });\n\n let existingCustomer: Customer | null = userQuery.docs?.[0] as unknown as Customer | null;\n if (existingCustomer) {\n existingCustomer.inventory = existingCustomer?.inventory\n ? (existingCustomer.inventory as unknown as CustomerInventory)\n : generateCustomerInventory();\n return existingCustomer;\n }\n\n payload.logger.info(`Creating new customer for email: ${email}`);\n\n const newCustomer = await payload.create({\n collection: COLLECTION_SLUG_CUSTOMERS,\n data: {\n email,\n stripeId: stripeId || \"\",\n inventory: generateCustomerInventory() as unknown as [k: string],\n },\n });\n\n payload.logger.info(`✅ Successfully created customer for email: ${email}`);\n return newCustomer as unknown as Customer;\n } catch (error) {\n payload.logger.error(\n `Error finding or creating customer for email ${email}: ${error}`\n );\n throw error;\n }\n}\n","import { Payload } from \"payload\";\nimport type Stripe from \"stripe\";\nimport { COLLECTION_SLUG_PRODUCTS } from \"../../model/index.js\";\nimport { getPermissionsSlugs } from \"../../model/permissions.js\";\nimport type { CustomerInventory } from \"../../types/index.js\";\nimport { upsertCustomerInventoryAndSyncWithUser } from \"../utils/payload/upsert-customer-inventory-and-sync-with-user.js\";\nimport { getUserIdByEmail } from \"../utils/payload/get-userId-by-email.js\";\nimport { resolveStripeCustomer } from \"../utils/stripe/get-customer.js\";\nimport { removeCustomerByStripeId } from \"../utils/payload/remove-customer-by-stripe-id.js\";\nimport { findOrCreateCustomer } from \"../utils/payload/find-or-create-customer.js\";\n\nexport const subscriptionUpsert = async (\n subscription: Stripe.Subscription,\n payload: Payload,\n onSubscriptionUpdate: (\n type: \"create\" | \"delete\",\n userId: string\n ) => Promise<void>\n) => {\n const { id: stripeID, status, customer: stripeCustomer } = subscription;\n const customer = await resolveStripeCustomer({ customer: stripeCustomer });\n const error = (message: string) =>\n payload.logger.error(\"Subscription Upsert: \", message as any);\n const info = (message: string) =>\n payload.logger.info(\"Subscription Upsert: \", message as any);\n\n if (!customer) {\n error(\"No stripe customer found for subscription\");\n return;\n }\n if (customer.deleted) {\n await removeCustomerByStripeId({ stripeId: customer.id, payload });\n return;\n }\n if (!customer.email) {\n error(\"No email found for stripe customer\");\n return;\n }\n const email = customer.email;\n const stripeId = customer.id;\n\n try {\n const customer = await findOrCreateCustomer({\n email,\n payload,\n stripeId,\n });\n\n const item = subscription.items.data.at(0);\n if (!item || !customer) {\n error(`No item ${item} or customer ${customer} found`);\n return;\n }\n\n const { docs: products } = await payload.find({\n collection: COLLECTION_SLUG_PRODUCTS,\n where: { stripeID: { equals: item.price.product } },\n });\n const product = products.at(0);\n if (!product) return;\n\n const inventory = customer.inventory;\n inventory.subscriptions[stripeID] = {\n ...subscription,\n permissions: getPermissionsSlugs({ permissions: product.roles }),\n };\n info(`INVENTORY OF THE SUBSCRIPTION ${inventory}`);\n await upsertCustomerInventoryAndSyncWithUser(payload, inventory, email, stripeId);\n\n if ([\"active\", \"trialing\"].includes(status)) {\n const userId = await getUserIdByEmail({ email, payload });\n if (!userId) return;\n await onSubscriptionUpdate(\"create\", userId);\n }\n info(\n `✅ Successfully updated subscription with ID: ${stripeID} for user: ${email}`\n );\n } catch (e) {\n error(`- Error managing subscription: ${e}`);\n throw e;\n }\n};\n\nexport const subscriptionDeleted = async (\n subscription: Stripe.Subscription,\n payload: Payload,\n onSubscriptionUpdate: (\n type: \"create\" | \"delete\",\n userId: string\n ) => Promise<void>\n) => {\n const { id, customer: customerId } = subscription;\n const customer = await resolveStripeCustomer({ customer: customerId });\n const stripeId = customer?.id;\n if (!customer) {\n payload.logger.error(\"No stripe customer found for subscription\");\n return;\n } \n if (customer.deleted) {\n await removeCustomerByStripeId({ stripeId: customer.id, payload });\n return;\n }\n if (!customer.email) {\n payload.logger.error(\"No email found for stripe customer\");\n return;\n }\n const email = customer.email;\n try {\n const customer = await findOrCreateCustomer({\n email,\n payload,\n stripeId\n });\n if (!customer) {\n payload.logger.error(\"No customer found for subscription\");\n return;\n }\n\n const inventory = customer.inventory as unknown as CustomerInventory;\n delete inventory.subscriptions[id];\n\n await upsertCustomerInventoryAndSyncWithUser(payload, inventory, email, stripeId);\n const userId = await getUserIdByEmail({ email, payload });\n if (!userId) {\n payload.logger.error(\"No user found for subscription\");\n return;\n }\n await onSubscriptionUpdate(\"delete\", userId);\n\n payload.logger.info(\n `✅ Successfully deleted subscription: ${id} for user: ${email}`\n );\n } catch (error) {\n payload.logger.error(`- Error deleting subscription: ${error}`);\n throw error;\n }\n};\n","import { Payload } from \"payload\";\nimport type Stripe from \"stripe\";\nimport { COLLECTION_SLUG_CUSTOMERS } from \"../../model/index.js\";\nimport { resolveStripeCustomer } from \"../utils/stripe/get-customer.js\";\nimport { findOrCreateCustomer } from \"../utils/payload/find-or-create-customer.js\";\nimport { removeCustomerByStripeId } from \"../utils/payload/remove-customer-by-stripe-id.js\";\n\nexport const paymentSucceeded = async (\n paymentIntent: Stripe.PaymentIntent,\n payload: Payload\n) => {\n const { id, customer: paymentCustomer } = paymentIntent;\n const stripeCustomer = await resolveStripeCustomer({ customer: paymentCustomer });\n if (!stripeCustomer) {\n payload.logger.error(\"No stripe customer found for payment\");\n return\n }\n if (stripeCustomer.deleted) {\n await removeCustomerByStripeId({ stripeId: stripeCustomer.id, payload });\n return;\n }\n if (!stripeCustomer.email) {\n payload.logger.error(\"No email found for stripe customer\");\n return;\n }\n\n try {\n const customer = await findOrCreateCustomer({\n email: stripeCustomer.email,\n payload,\n stripeId: stripeCustomer.id,\n });\n if (!customer) return;\n\n if (!customer) {\n payload.logger.error(`User not found for payment: ${stripeCustomer.email}`);\n return;\n }\n\n let inventory = customer.inventory\n inventory.payments[id] = paymentIntent;\n\n await payload.update({\n collection: COLLECTION_SLUG_CUSTOMERS,\n data: { inventory: inventory as unknown as { [x: string]: {} } },\n where: { email: { equals: stripeCustomer.email } },\n });\n\n payload.logger.info(\n `✅ Successfully recorded ${stripeCustomer.metadata?.type ?? \"subscription\"} with Payment Intent ID: ${id} for user: ${stripeCustomer.email}`\n );\n } catch (error) {\n payload.logger.error(`- Error recording payment: ${error}`);\n throw error;\n }\n};\n","import { Payload } from \"payload\";\nimport type Stripe from \"stripe\";\nimport { COLLECTION_SLUG_CUSTOMERS } from \"../../model/index.js\";\nimport { findOrCreateCustomer } from \"../utils/payload/find-or-create-customer.js\";\nimport { resolveStripeCustomer } from \"../utils/stripe/get-customer.js\";\nimport { removeCustomerByStripeId } from \"../utils/payload/remove-customer-by-stripe-id.js\";\n\nexport const invoiceSucceeded = async (\n invoiceIntent: Stripe.Invoice,\n payload: Payload\n) => {\n const { id, customer: paymentCustomer } = invoiceIntent;\n const stripeCustomer = await resolveStripeCustomer({ customer: paymentCustomer });\n if (!stripeCustomer) {\n payload.logger.error(\"No stripe customer found for payment\");\n return\n }\n if (stripeCustomer.deleted) {\n await removeCustomerByStripeId({ stripeId: stripeCustomer.id, payload });\n return;\n }\n if (!stripeCustomer.email) {\n payload.logger.error(\"No email found for stripe customer\");\n return;\n }\n\n try {\n const customer = await findOrCreateCustomer({\n email: stripeCustomer.email,\n payload,\n stripeId: stripeCustomer.id,\n });\n if (!customer) return;\n\n let inventory = customer.inventory\n inventory.invoices[id] = invoiceIntent;\n\n await payload.update({\n collection: COLLECTION_SLUG_CUSTOMERS,\n data: { inventory: inventory as unknown as { [x: string]: {} } },\n where: { email: { equals: stripeCustomer.email } },\n });\n\n payload.logger.info(\n `✅ Successfully recorded ${stripeCustomer.metadata?.type ?? \"subscription\"} with Payment Intent ID: ${id} for user: ${stripeCustomer.email}`\n );\n } catch (error) {\n payload.logger.error(`- Error recording payment: ${error}`);\n throw error;\n }\n};\n","import { Payload } from \"payload\";\nimport Stripe from \"stripe\";\nimport { COLLECTION_SLUG_CUSTOMERS } from \"../../index.js\";\n\nexport const customerDeleted = async (\n customer: Stripe.Customer,\n payload: Payload,\n ) => {\n const { id, email } = customer;\n try { \n await payload.delete({\n collection: COLLECTION_SLUG_CUSTOMERS,\n where: { email: { equals: email } },\n });\n payload.logger.info(\n `✅ Successfully deleted customer with Stripe ID: ${id}`\n );\n } catch (error) {\n payload.logger.error(`- Error deleting subscription: ${error}`);\n throw error;\n }\n };\n ","import { Payload } from \"payload\";\nimport {\n checkIfUserCanUnlockQuery,\n COLLECTION_SLUG_USER,\n countWeeklyUnlocksQuery,\n MAX_UNLOCKS_PER_WEEK,\n} from \"../../model/index.js\";\nimport { generateUserInventory } from \"../../model/builders.js\";\nimport { getPermissionsSlugs } from \"../../model/permissions.js\";\nimport type { BaseUser, UnlockItem, UserInventory } from \"../../types/index.js\";\n\nexport type Result<T, E = string> = {\n data: T;\n error?: never;\n} | {\n data?: never;\n error: E;\n}\n\n\nconst addUniqueUnlock = (\n unlocks: UnlockItem[],\n collection: string,\n contentId: number\n): UnlockItem[] => {\n const isDuplicate = unlocks.some(\n unlock => unlock.collection === collection && unlock.id === contentId\n );\n\n if (isDuplicate) {\n return unlocks;\n }\n return [\n ...unlocks,\n {\n collection,\n id: contentId,\n dateUnlocked: new Date(),\n },\n ];\n};\n\n/**\n * Unlocks an item for a user, adding it to their inventory.\n *\n * @param payload - The Payload instance\n * @param user - The authenticated user\n * @param collection - The collection slug of the item to unlock\n * @param contentId - The ID of the item to unlock\n * @returns Result indicating success or error message\n */\nexport const unlockItemForUser = async (\n payload: Payload,\n user: BaseUser,\n collection: string,\n contentId: number\n): Promise<Result<boolean>> => {\n if (!user || !user.id) {\n return { error: \"Usuario no válido\" };\n }\n const item = await payload.findByID({\n collection: collection as any,\n id: contentId.toString(),\n });\n\n if (!item) {\n return { error: \"Elemento no encontrado\" };\n }\n const permissions = getPermissionsSlugs({ permissions: item.permissions });\n\n if (!checkIfUserCanUnlockQuery(user, permissions)) {\n return { error: \"No tienes permisos para desbloquear este elemento\" };\n }\n\n const weeklyUnlocks = countWeeklyUnlocksQuery(user);\n if (weeklyUnlocks >= MAX_UNLOCKS_PER_WEEK) {\n return {\n error: `Has alcanzado el límite de ${MAX_UNLOCKS_PER_WEEK} desbloqueos para esta semana`,\n };\n }\n\n const inventory =\n (user.inventory as UserInventory) ?? generateUserInventory();\n\n const updatedUnlocks = addUniqueUnlock(\n inventory.unlocks,\n collection,\n contentId\n );\n\n if (updatedUnlocks.length === inventory.unlocks.length) {\n return { data: true };\n }\n\n try {\n await payload.update({\n collection: COLLECTION_SLUG_USER,\n id: user.id.toString(),\n data: {\n inventory: {\n ...inventory,\n unlocks: updatedUnlocks,\n },\n },\n });\n\n return { data: true };\n } catch (error) {\n console.error(\"Error al actualizar el inventario del usuario:\", error);\n return { error: \"Error al actualizar el inventario del usuario\" };\n }\n};\n","\"use server\";\n\nimport { updatePrices } from \"./price.js\";\nimport { updateProducts } from \"./product.js\";\nimport { Payload } from \"payload\";\n\nexport async function updateProductsAndPrices(payload: Payload) {\n await updateProducts(payload);\n await updatePrices(payload);\n}\n","import Stripe from \"stripe\";\nimport { stripeBuilder } from \"./stripe-builder.js\";\n\nexport async function createCustomerAtStripe({\n stripe,\n email,\n name,\n}: {\n stripe?: Stripe;\n email: string;\n name?: string;\n}) {\n stripe = stripe ?? stripeBuilder();\n return await stripe.customers.create({\n email: email,\n name: name || undefined,\n });\n}\n","import { createCustomerAtStripe } from \"./create-customer-at-stripe.js\";\nimport { getCustomer } from \"./get-customer.js\";\nimport { stripeBuilder } from \"./stripe-builder.js\";\n\nexport async function getCustomerFromStripeOrCreate(\n email: string,\n name?: string\n): Promise<string> {\n const stripe = stripeBuilder();\n let customer = await getCustomer({ stripe, email });\n if (!customer) {\n customer = await createCustomerAtStripe({ stripe, email, name });\n }\n return customer.id;\n}\n","import type { Payload, PayloadRequest } from \"payload\";\nimport type { BaseUser } from \"../../../types/index.js\";\nimport type { StripeEndpointConfig } from \"../../plugin/stripe-inventory-types.js\";\n\n/**\n * Creates a JSON response using Web API Response\n */\nexport function jsonResponse(data: unknown, options?: ResponseInit): Response {\n return new Response(JSON.stringify(data), {\n headers: { \"Content-Type\": \"application/json\" },\n ...options,\n });\n}\n\n/**\n * Creates a redirect response using Web API Response\n * @param url - The URL to redirect to\n * @param status - HTTP status code (default: 303 See Other)\n */\nexport function redirectResponse(url: string, status: number = 303): Response {\n return new Response(null, {\n status,\n headers: { Location: url },\n });\n}\n\n/**\n * Creates an error response\n */\nexport function errorResponse(\n message: string,\n status: number = 400\n): Response {\n return jsonResponse({ error: message }, { status });\n}\n\n/**\n * Result type for validateAuthenticatedRequest\n */\nexport type AuthenticatedRequestResult =\n | { success: false; error: Response }\n | {\n success: true;\n user: BaseUser;\n payload: Payload;\n };\n\n/**\n * Validates that the request has an authenticated user\n * Uses the config's resolveUser if provided, otherwise uses request.user\n */\nexport async function validateAuthenticatedRequest(\n request: PayloadRequest,\n config: StripeEndpointConfig\n): Promise<AuthenticatedRequestResult> {\n // Check custom permissions if provided\n if (config.checkPermissions) {\n const hasPermission = await config.checkPermissions(request);\n if (!hasPermission) {\n return {\n success: false,\n error: errorResponse(\"Permission denied\", 403),\n };\n }\n }\n\n // Resolve user\n let user: BaseUser | null = null;\n\n if (config.resolveUser) {\n user = await config.resolveUser(request);\n } else {\n user = request.user as BaseUser | null;\n }\n\n if (!user) {\n return {\n success: false,\n error: errorResponse(\"You must be logged in to access this endpoint\", 401),\n };\n }\n\n if (!user.email) {\n return {\n success: false,\n error: errorResponse(\"User email is required\", 400),\n };\n }\n\n return {\n success: true,\n user,\n payload: request.payload,\n };\n}\n","import type { PayloadHandler, PayloadRequest } from \"payload\";\nimport type Stripe from \"stripe\";\nimport type { StripeEndpointConfig } from \"../../plugin/stripe-inventory-types.js\";\nimport { upsertCustomerInventoryAndSyncWithUser } from \"../../utils/payload/upsert-customer-inventory-and-sync-with-user.js\";\nimport { getCustomerFromStripeOrCreate } from \"../../utils/stripe/get-customer-from-stripe-or-create.js\";\nimport { stripeBuilder } from \"../../utils/stripe/stripe-builder.js\";\nimport {\n errorResponse,\n redirectResponse,\n validateAuthenticatedRequest,\n} from \"../validators/request-validator.js\";\n\n/**\n * Creates a handler for Stripe checkout sessions (subscriptions)\n *\n * @param config - Endpoint configuration\n * @returns PayloadHandler for checkout endpoint\n */\nexport function createCheckoutHandler(config: StripeEndpointConfig): PayloadHandler {\n return async (request: PayloadRequest): Promise<Response> => {\n try {\n // Validate authenticated user\n const validated = await validateAuthenticatedRequest(request, config);\n if (!validated.success) {\n return validated.error;\n }\n\n const { user, payload } = validated;\n\n // Extract priceId from query params\n const url = new URL(request.url || \"\");\n const priceId = url.searchParams.get(\"priceId\");\n\n if (!priceId) {\n return errorResponse(\"priceId is required\", 400);\n }\n\n const stripe = stripeBuilder();\n\n // Get or create Stripe customer\n const customerId = await getCustomerFromStripeOrCreate(\n user.email!,\n user.name\n );\n\n // Sync customer inventory\n await upsertCustomerInventoryAndSyncWithUser(\n payload,\n user.customer?.inventory,\n user.email!,\n customerId\n );\n\n // Prepare checkout session\n const metadata: Stripe.MetadataParam = {\n type: \"subscription\",\n };\n\n const checkoutResult = await stripe.checkout.sessions.create({\n success_url: `${process.env.DOMAIN}${config.routes.subscriptionPageHref}?success=${Date.now()}`,\n cancel_url: `${process.env.DOMAIN}${config.routes.subscriptionPageHref}?error=${Date.now()}`,\n mode: \"subscription\",\n customer: customerId,\n client_reference_id: String(user.id),\n line_items: [{ price: priceId, quantity: 1 }],\n metadata,\n tax_id_collection: { enabled: true },\n customer_update: {\n name: \"auto\",\n address: \"auto\",\n shipping: \"auto\",\n },\n subscription_data: { metadata },\n });\n\n if (checkoutResult.url) {\n return redirectResponse(checkoutResult.url, 303);\n }\n\n return errorResponse(\"Failed to create checkout URL\", 406);\n } catch (error) {\n console.error(\"[Stripe Checkout Error]\", error);\n return errorResponse(\n error instanceof Error ? error.message : \"Unknown error occurred\",\n 500\n );\n }\n };\n}\n","import type { PayloadHandler, PayloadRequest } from \"payload\";\nimport type Stripe from \"stripe\";\nimport type { StripeEndpointConfig } from \"../../plugin/stripe-inventory-types.js\";\nimport { upsertCustomerInventoryAndSyncWithUser } from \"../../utils/payload/upsert-customer-inventory-and-sync-with-user.js\";\nimport { getCustomerFromStripeOrCreate } from \"../../utils/stripe/get-customer-from-stripe-or-create.js\";\nimport { stripeBuilder } from \"../../utils/stripe/stripe-builder.js\";\nimport {\n errorResponse,\n jsonResponse,\n validateAuthenticatedRequest,\n} from \"../validators/request-validator.js\";\n\n/**\n * Creates a handler for one-time donation payments\n *\n * @param config - Endpoint configuration\n * @returns PayloadHandler for donation endpoint\n */\nexport function createDonationHandler(config: StripeEndpointConfig): PayloadHandler {\n return async (request: PayloadRequest): Promise<Response> => {\n try {\n // Validate authenticated user\n const validated = await validateAuthenticatedRequest(request, config);\n if (!validated.success) {\n return validated.error;\n }\n\n const { user, payload } = validated;\n\n // Extract amount from query params\n const url = new URL(request.url || \"\");\n const amountParam = url.searchParams.get(\"amount\");\n\n if (!amountParam) {\n return errorResponse(\"amount is required\", 400);\n }\n\n const amount = parseInt(amountParam, 10);\n\n if (isNaN(amount) || amount < 100) {\n return errorResponse(\"Minimum donation amount is 1 EUR (100 cents)\", 400);\n }\n\n const stripe = stripeBuilder();\n\n // Get or create Stripe customer\n const customerId = await getCustomerFromStripeOrCreate(\n user.email!,\n user.name\n );\n\n // Sync customer inventory\n await upsertCustomerInventoryAndSyncWithUser(\n payload,\n user.customer?.inventory,\n user.email!,\n customerId\n );\n\n // Determine redirect URLs\n const donationPageHref = config.routes.donationPageHref || config.routes.subscriptionPageHref;\n\n // Prepare metadata\n const metadata: Stripe.MetadataParam = {\n type: \"donation\",\n };\n\n // Create checkout session for one-time payment\n const session = await stripe.checkout.sessions.create({\n customer: customerId,\n payment_method_types: [\"card\"],\n line_items: [\n {\n price_data: {\n currency: \"eur\",\n product_data: {\n name: \"Donation\",\n description: \"One-time donation\",\n },\n unit_amount: amount,\n },\n quantity: 1,\n },\n ],\n mode: \"payment\",\n success_url: `${process.env.DOMAIN}${donationPageHref}?success=donation`,\n cancel_url: `${process.env.DOMAIN}${donationPageHref}?error=donation_cancelled`,\n metadata,\n payment_intent_data: { metadata },\n invoice_creation: { enabled: true, invoice_data: { metadata } },\n });\n\n return jsonResponse({ url: session.url });\n } catch (error) {\n console.error(\"[Stripe Donation Error]\", error);\n return errorResponse(\n error instanceof Error ? error.message : \"Unknown error occurred\",\n 500\n );\n }\n };\n}\n","import type { PayloadHandler, PayloadRequest } from \"payload\";\nimport type Stripe from \"stripe\";\nimport type { StripeEndpointConfig } from \"../../plugin/stripe-inventory-types.js\";\nimport { upsertCustomerInventoryAndSyncWithUser } from \"../../utils/payload/upsert-customer-inventory-and-sync-with-user.js\";\nimport { getCustomerFromStripeOrCreate } from \"../../utils/stripe/get-customer-from-stripe-or-create.js\";\nimport { stripeBuilder } from \"../../utils/stripe/stripe-builder.js\";\nimport {\n errorResponse,\n redirectResponse,\n validateAuthenticatedRequest,\n} from \"../validators/request-validator.js\";\n\n/**\n * Creates a handler for Stripe Billing Portal access\n *\n * @param config - Endpoint configuration\n * @returns PayloadHandler for portal endpoint\n */\nexport function createPortalHandler(config: StripeEndpointConfig): PayloadHandler {\n return async (request: PayloadRequest): Promise<Response> => {\n try {\n // Validate authenticated user\n const validated = await validateAuthenticatedRequest(request, config);\n if (!validated.success) {\n return validated.error;\n }\n\n const { user, payload } = validated;\n\n // Extract optional params for subscription actions\n const url = new URL(request.url || \"\");\n const cancelSubscriptionId = url.searchParams.get(\"cancelSubscriptionId\");\n const updateSubscriptionId = url.searchParams.get(\"updateSubscriptionId\");\n\n // Build flow data if subscription action is requested\n let flowData: Stripe.BillingPortal.SessionCreateParams.FlowData | undefined;\n\n if (cancelSubscriptionId) {\n flowData = {\n type: \"subscription_cancel\",\n subscription_cancel: { subscription: cancelSubscriptionId },\n };\n } else if (updateSubscriptionId) {\n flowData = {\n type: \"subscription_update\",\n subscription_update: { subscription: updateSubscriptionId },\n };\n }\n\n const stripe = stripeBuilder();\n\n // Get or create Stripe customer\n const customerId = await getCustomerFromStripeOrCreate(\n user.email!,\n user.name\n );\n\n // Sync customer inventory\n await upsertCustomerInventoryAndSyncWithUser(\n payload,\n user.customer?.inventory,\n user.email!,\n customerId\n );\n\n // Create billing portal session\n const session = await stripe.billingPortal.sessions.create({\n flow_data: flowData,\n customer: customerId,\n return_url: `${process.env.DOMAIN}${config.routes.subscriptionPageHref}`,\n });\n\n return redirectResponse(session.url, 303);\n } catch (error) {\n console.error(\"[Stripe Portal Error]\", error);\n return errorResponse(\n error instanceof Error ? error.message : \"Unknown error occurred\",\n 500\n );\n }\n };\n}\n","import type { PayloadHandler, PayloadRequest } from \"payload\";\nimport type { Customer, CustomerInventory } from \"../../../types/index.js\";\nimport type { StripeEndpointConfig } from \"../../plugin/stripe-inventory-types.js\";\nimport { upsertCustomerInventoryAndSyncWithUser } from \"../../utils/payload/upsert-customer-inventory-and-sync-with-user.js\";\nimport { stripeBuilder } from \"../../utils/stripe/stripe-builder.js\";\nimport {\n errorResponse,\n redirectResponse,\n validateAuthenticatedRequest,\n} from \"../validators/request-validator.js\";\n\n/**\n * Creates a handler for updating Stripe subscriptions (cancel at period end)\n *\n * @param config - Endpoint configuration\n * @returns PayloadHandler for update endpoint\n */\nexport function createUpdateHandler(config: StripeEndpointConfig): PayloadHandler {\n return async (request: PayloadRequest): Promise<Response> => {\n try {\n // Validate authenticated user\n const validated = await validateAuthenticatedRequest(request, config);\n if (!validated.success) {\n return validated.error;\n }\n\n const { user, payload } = validated;\n\n // Extract params\n const url = new URL(request.url || \"\");\n const subscriptionId = url.searchParams.get(\"subscriptionId\");\n const cancelAtPeriodEnd = url.searchParams.get(\"cancelAtPeriodEnd\") === \"true\";\n\n if (!subscriptionId) {\n return errorResponse(\"subscriptionId is required\", 400);\n }\n\n const stripe = stripeBuilder();\n\n // Update subscription in Stripe\n await stripe.subscriptions.update(subscriptionId, {\n cancel_at_period_end: cancelAtPeriodEnd,\n });\n\n // Update local inventory\n const customer = user.customer as Customer | undefined;\n const inventory = customer?.inventory as CustomerInventory | null;\n\n if (inventory?.subscriptions?.[subscriptionId]) {\n inventory.subscriptions[subscriptionId].cancel_at_period_end = cancelAtPeriodEnd;\n }\n\n // Sync inventory\n if (customer?.email) {\n await upsertCustomerInventoryAndSyncWithUser(\n payload,\n inventory,\n customer.email\n );\n }\n\n // Redirect back to subscription page\n return redirectResponse(\n `${process.env.DOMAIN}${config.routes.subscriptionPageHref}?refresh=${Date.now()}`,\n 303\n );\n } catch (error) {\n console.error(\"[Stripe Update Error]\", error);\n return errorResponse(\n error instanceof Error ? error.message : \"Unknown error occurred\",\n 500\n );\n }\n };\n}\n","import type { Endpoint } from \"payload\";\nimport type { StripeEndpointConfig } from \"../plugin/stripe-inventory-types.js\";\nimport { createCheckoutHandler } from \"./handlers/checkout-handler.js\";\nimport { createDonationHandler } from \"./handlers/donation-handler.js\";\nimport { createPortalHandler } from \"./handlers/portal-handler.js\";\nimport { createUpdateHandler } from \"./handlers/update-handler.js\";\n\nexport * from \"./handlers/checkout-handler.js\";\nexport * from \"./handlers/donation-handler.js\";\nexport * from \"./handlers/portal-handler.js\";\nexport * from \"./handlers/update-handler.js\";\nexport * from \"./validators/index.js\";\n\n/**\n * Creates all Stripe inventory endpoints\n *\n * @param config - Endpoint configuration\n * @param basePath - Base path for endpoints (default: '/stripe')\n * @returns Array of Payload endpoints\n *\n * @example\n * ```typescript\n * const endpoints = createStripeEndpoints({\n * routes: { subscriptionPageHref: '/account/subscription' },\n * });\n * // Endpoints:\n * // GET /api/stripe/checkout?priceId={id}\n * // GET /api/stripe/portal\n * // GET /api/stripe/update?subscriptionId={id}&cancelAtPeriodEnd={bool}\n * // GET /api/stripe/donation?amount={cents}\n * ```\n */\nexport function createStripeEndpoints(\n config: StripeEndpointConfig,\n basePath: string = \"/stripe\"\n): Endpoint[] {\n return [\n {\n path: `${basePath}/checkout`,\n method: \"get\",\n handler: createCheckoutHandler(config),\n },\n {\n path: `${basePath}/portal`,\n method: \"get\",\n handler: createPortalHandler(config),\n },\n {\n path: `${basePath}/update`,\n method: \"get\",\n handler: createUpdateHandler(config),\n },\n {\n path: `${basePath}/donation`,\n method: \"get\",\n handler: createDonationHandler(config),\n },\n ];\n}\n","/**\n * Stripe Inventory Plugin Factory for Payload CMS\n *\n * This plugin automatically registers Stripe endpoints and webhook handlers.\n * It replaces the need for manual Next.js route handlers.\n *\n * @example\n * ```typescript\n * // payload.config.ts\n * import { createStripeInventoryPlugin } from '@nexo-labs/payload-stripe-inventory/server';\n *\n * export default buildConfig({\n * plugins: [\n * createStripeInventoryPlugin({\n * routes: { subscriptionPageHref: '/account/subscription' },\n * onSubscriptionUpdate: async (type, userId) => {\n * console.log(`Subscription ${type} for user ${userId}`);\n * },\n * }),\n * ],\n * });\n * ```\n */\n\nimport type { Config, Plugin } from \"payload\";\nimport { stripePlugin } from \"@payloadcms/plugin-stripe\";\nimport {\n priceDeleted,\n subscriptionUpsert,\n subscriptionDeleted,\n productDeleted,\n paymentSucceeded,\n invoiceSucceeded,\n customerDeleted,\n} from \"../actions/index.js\";\nimport { createStripeEndpoints } from \"../endpoints/index.js\";\nimport type {\n StripeEndpointConfig,\n StripeInventoryPluginConfig,\n} from \"./stripe-inventory-types.js\";\n\nexport type { StripeInventoryPluginConfig, StripeEndpointConfig };\nexport { createStripeEndpoints };\n\n/**\n * Creates the Stripe Inventory plugin for Payload CMS\n *\n * This plugin:\n * - Registers REST endpoints for checkout, portal, update, and donation\n * - Sets up Stripe webhook handlers for subscription and payment events\n * - Syncs customer data between Stripe and Payload\n *\n * @param config - Plugin configuration\n * @returns A Payload plugin function\n *\n * Endpoints registered:\n * - GET /api{basePath}/checkout?priceId={id} - Redirect to Stripe Checkout\n * - GET /api{basePath}/portal - Redirect to Stripe Billing Portal\n * - GET /api{basePath}/update?subscriptionId={id}&cancelAtPeriodEnd={bool} - Update subscription\n * - GET /api{basePath}/donation?amount={cents} - Returns JSON with checkout URL\n */\nexport function createStripeInventoryPlugin(\n config: StripeInventoryPluginConfig\n): Plugin {\n const basePath = config.basePath || \"/stripe\";\n\n // Build endpoint configuration\n const endpointConfig: StripeEndpointConfig = {\n routes: config.routes,\n checkPermissions: config.checkPermissions,\n resolveUser: config.resolveUser,\n };\n\n // Callback for subscription updates (defaults to no-op)\n const onSubscriptionUpdate =\n config.onSubscriptionUpdate ||\n (async () => {\n /* no-op */\n });\n\n return (incomingConfig: Config): Config => {\n // 1. Create and register Stripe endpoints\n const stripeEndpoints = createStripeEndpoints(endpointConfig, basePath);\n\n const configWithEndpoints: Config = {\n ...incomingConfig,\n endpoints: [...(incomingConfig.endpoints || []), ...stripeEndpoints],\n };\n\n // 2. Apply the base Stripe plugin with webhook handlers\n const stripePluginInstance = stripePlugin({\n isTestKey: process.env.STRIPE_SECRET_KEY?.includes(\"sk_test\"),\n stripeSecretKey: process.env.STRIPE_SECRET_KEY || \"\",\n stripeWebhooksEndpointSecret: process.env.STRIPE_WEBHOOK_SECRET,\n webhooks: {\n \"price.deleted\": async ({ event, payload }) =>\n await priceDeleted(event.data.object, payload),\n \"customer.subscription.created\": async ({ event, payload }) =>\n await subscriptionUpsert(\n event.data.object,\n payload,\n onSubscriptionUpdate\n ),\n \"customer.subscription.paused\": async ({ event, payload }) =>\n await subscriptionUpsert(\n event.data.object,\n payload,\n onSubscriptionUpdate\n ),\n \"customer.subscription.updated\": async ({ event, payload }) =>\n await subscriptionUpsert(\n event.data.object,\n payload,\n onSubscriptionUpdate\n ),\n \"customer.subscription.deleted\": async ({ event, payload }) =>\n await subscriptionDeleted(\n event.data.object,\n payload,\n onSubscriptionUpdate\n ),\n \"customer.deleted\": async ({ event, payload }) =>\n await customerDeleted(event.data.object, payload),\n \"product.deleted\": async ({ event, payload }) =>\n await productDeleted(event.data.object, payload),\n \"payment_intent.succeeded\": async ({ event, payload }) => {\n await paymentSucceeded(event.data.object, payload);\n },\n \"invoice.paid\": async ({ event, payload }) => {\n await invoiceSucceeded(event.data.object, payload);\n },\n },\n });\n\n // 3. Apply the Stripe plugin to the config with endpoints\n return stripePluginInstance(configWithEndpoints);\n };\n}\n","import { Access } from \"payload\";\nimport { permissionSlugs } from \"../../model/constants.js\";\n\nexport const isAdmin: Access = ({ req }) => {\n return req?.user?.roles?.includes(permissionSlugs.webAdmin) || false;\n};\n\nexport const isAnyone: Access = () => true;\n\nexport const isAdminOrCurrentUser: Access = ({ req }) => {\n if (req?.user?.roles?.includes(permissionSlugs.webAdmin)) return true;\n return { id: { equals: req.user?.id } };\n};\n\nexport const isAdminOrPublished: Access = ({ req: { user } }) => {\n if (user && user?.roles?.includes(permissionSlugs.webAdmin)) {\n return true;\n }\n\n return {\n _status: {\n equals: \"published\",\n },\n };\n};\n\nexport const isAdminOrStripeActive: Access = ({ req: { user } }) => {\n if (user && user?.roles?.includes(permissionSlugs.webAdmin)) {\n return true;\n }\n\n return {\n active: {\n equals: true,\n },\n };\n};\n\nexport const isAdminOrUserFieldMatchingCurrentUser: Access = ({\n req: { user },\n}) => {\n if (user) {\n if (user?.roles?.includes(permissionSlugs.webAdmin)) return true;\n return {\n user: {\n equals: user?.id,\n },\n };\n }\n return false;\n};\n\nexport const loggedInOrPublished: Access = ({ req: { user } }) => {\n if (user) {\n return true;\n }\n\n return {\n _status: {\n equals: \"published\",\n },\n };\n};\n","import type { PayloadRequest } from \"payload\";\nimport type { BaseUser } from \"../../types/index.js\";\n\n/**\n * Gets the current user from a PayloadRequest without depending on next/headers.\n * This is the recommended way to get the user in Payload endpoint handlers.\n *\n * @param request - The PayloadRequest object\n * @returns The user object or null if not authenticated\n */\nexport function getUserFromRequest(request: PayloadRequest): BaseUser | null {\n return request.user as BaseUser | null;\n}\n","import { CollectionConfig } from \"payload\";\nimport { isAdmin } from \"../access/index.js\";\nimport { COLLECTION_SLUG_CUSTOMERS } from \"../../model/index.js\";\n\nexport const customers: CollectionConfig = {\n slug: COLLECTION_SLUG_CUSTOMERS,\n admin: {\n useAsTitle: \"email\",\n group: \"Stripe\",\n defaultColumns: [\"email\", \"stripeId\", \"createdAt\"],\n },\n access: {\n read: () => true,\n create: () => false,\n update: () => false,\n delete: isAdmin,\n },\n fields: [\n {\n name: \"email\",\n type: \"email\",\n required: true,\n unique: true,\n admin: {\n position: \"sidebar\",\n },\n },\n {\n name: \"stripeId\",\n type: \"text\",\n required: true,\n unique: true,\n admin: {\n position: \"sidebar\",\n readOnly: true,\n },\n },\n {\n name: \"inventory\",\n type: \"json\",\n label: \"Inventario\",\n admin: {\n description: \"Datos de inventario de Stripe almacenados como JSON\",\n readOnly: true,\n },\n },\n ],\n};\n","import { COLLECTION_SLUG_TAXONOMY } from \"@nexo-labs/payload-taxonomies\";\nimport { Field } from \"payload\";\n\nexport const permissionEvaluationField: Field = {\n type: 'row',\n fields: [\n {\n type: 'select',\n name: 'type_of_permissions',\n options: [\n { label: 'Todos', value: 'all' },\n { label: 'Permisos por roles', value: 'roles' },\n { label: 'Solo para usuarios sin roles', value: 'only_no_roles' },\n { label: 'Solo invitados', value: 'only_guess' },\n ],\n defaultValue: 'all',\n label: 'Tipo de permisos',\n },\n {\n type: 'relationship',\n name: 'permissions',\n relationTo: [COLLECTION_SLUG_TAXONOMY],\n hasMany: false,\n admin: {\n condition: (_, siblingData) => siblingData.type_of_permissions === 'roles',\n }\n }\n ]\n}","import { CollectionConfig } from \"payload\";\nimport {\n COLLECTION_SLUG_PRICES,\n COLLECTION_SLUG_PRODUCTS,\n PricingPlanInterval,\n PricingType,\n formatOptions,\n} from \"../../model/index.js\";\nimport { isAdmin, isAdminOrStripeActive } from \"../access/index.js\";\n\nexport const prices: CollectionConfig = {\n slug: COLLECTION_SLUG_PRICES,\n admin: {\n useAsTitle: \"unitAmount\",\n group: \"Stripe\",\n },\n access: {\n read: isAdminOrStripeActive,\n create: () => false,\n update: () => false,\n delete: isAdmin,\n },\n fields: [\n {\n name: \"stripeID\",\n label: \"Stripe ID\",\n type: \"text\",\n required: true,\n admin: { position: \"sidebar\", readOnly: true },\n },\n {\n name: \"stripeProductId\",\n type: \"text\",\n required: true,\n admin: { position: \"sidebar\", readOnly: true },\n },\n {\n name: \"product\",\n type: \"join\",\n collection: COLLECTION_SLUG_PRODUCTS,\n on: \"prices\",\n hasMany: false,\n },\n {\n name: \"active\",\n type: \"checkbox\",\n required: true,\n admin: { position: \"sidebar\" },\n },\n { name: \"description\", type: \"textarea\" },\n {\n type: \"row\",\n fields: [\n { name: \"unitAmount\", type: \"number\", required: true },\n { name: \"currency\", type: \"text\", required: true },\n {\n name: \"type\",\n type: \"select\",\n options: formatOptions(PricingType),\n required: true,\n },\n ],\n },\n {\n type: \"row\",\n fields: [\n {\n name: \"interval\",\n type: \"select\",\n options: formatOptions(PricingPlanInterval),\n },\n { name: \"intervalCount\", type: \"number\" },\n { name: \"trialPeriodDays\", type: \"number\" },\n ],\n },\n { name: \"metadata\", type: \"json\", label: \"Metadata\" },\n ],\n};\n","import { buildTaxonomyRelationship } from \"@nexo-labs/payload-taxonomies\";\nimport { CollectionConfig } from \"payload\";\nimport { COLLECTION_SLUG_PRICES, COLLECTION_SLUG_PRODUCTS } from \"../../model/index.js\";\nimport { isAdminOrStripeActive } from \"../access/index.js\";\n\nexport const products: CollectionConfig = {\n slug: COLLECTION_SLUG_PRODUCTS,\n admin: {\n useAsTitle: \"name\",\n group: \"Stripe\",\n },\n access: {\n read: isAdminOrStripeActive,\n create: () => false,\n },\n fields: [\n {\n name: \"stripeID\",\n label: \"Stripe ID\",\n type: \"text\",\n required: true,\n admin: { position: \"sidebar\", readOnly: true },\n },\n {\n name: \"type\",\n type: \"select\",\n options: [\n { value: \"good\", label: \"Bienes\" },\n { value: \"service\", label: \"Service\" },\n ],\n },\n {\n name: \"active\",\n type: \"checkbox\",\n required: true,\n admin: { position: \"sidebar\" },\n },\n {\n name: \"show\",\n type: \"checkbox\",\n defaultValue: false,\n admin: { position: \"sidebar\" },\n },\n { name: \"name\", type: \"text\", required: true },\n { name: \"description\", type: \"textarea\" },\n { name: \"images\", type: \"array\", fields: [{ type: \"text\", name: \"url\" }] },\n {\n name: \"prices\",\n type: \"relationship\",\n relationTo: COLLECTION_SLUG_PRICES,\n hasMany: true,\n required: false,\n },\n { name: \"metadata\", type: \"json\", label: \"Metadata\" },\n {\n type: \"array\",\n name: \"features\",\n fields: [{ type: \"text\", name: \"title\" }],\n },\n buildTaxonomyRelationship({\n name: \"roles\",\n label: \"Roles\",\n defaultValue: [],\n filterOptions: () => {\n return {\n \"payload.types\": { in: [\"role\"] },\n };\n },\n required: false,\n }),\n ],\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexo-labs/payload-stripe-inventory",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.12",
|
|
4
4
|
"description": "Sistema de inventario y suscripciones con Stripe para Payload CMS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"payload-cms",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"README.md"
|
|
39
39
|
],
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"@payloadcms/plugin-stripe": "^3.
|
|
41
|
+
"@payloadcms/plugin-stripe": "^3.72.0",
|
|
42
42
|
"next": "15.4.8",
|
|
43
|
-
"payload": "^3.
|
|
43
|
+
"payload": "^3.72.0",
|
|
44
44
|
"react": "^19.0.0",
|
|
45
45
|
"stripe": "17.2.1",
|
|
46
|
-
"@nexo-labs/payload-taxonomies": "1.6.
|
|
46
|
+
"@nexo-labs/payload-taxonomies": "1.6.12"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/node": "^22.0.0",
|