feat(stripe): Stripe provider with 35 resources - #1280
Conversation
Adds `alchemy/Stripe` — credentials/auth provider, metadata-based ownership branding, and 35 resource providers with tests. Resources are not yet live-tested and no distilled patches are written yet; both are follow-up work.
|
Install the packages built from this commit: Alchemyalchemy bun add https://pkg.ing/alchemy/7328f43@alchemy.run/better-auth bun add https://pkg.ing/@alchemy.run/better-auth/7328f43@alchemy.run/cloudflare-runtime bun add https://pkg.ing/@alchemy.run/cloudflare-runtime/7328f43@alchemy.run/frontend-frameworks bun add https://pkg.ing/@alchemy.run/frontend-frameworks/7328f43@alchemy.run/node-utils bun add https://pkg.ing/@alchemy.run/node-utils/7328f43@alchemy.run/pr-package bun add https://pkg.ing/@alchemy.run/pr-package/7328f43@alchemy.run/floci bun add https://pkg.ing/@alchemy.run/floci/7328f43Distilled@distilled.cloud/core bun add https://pkg.ing/@distilled.cloud/core/e70eb61@distilled.cloud/aws bun add https://pkg.ing/@distilled.cloud/aws/e70eb61@distilled.cloud/axiom bun add https://pkg.ing/@distilled.cloud/axiom/e70eb61@distilled.cloud/cloudflare bun add https://pkg.ing/@distilled.cloud/cloudflare/e70eb61@distilled.cloud/hetzner bun add https://pkg.ing/@distilled.cloud/hetzner/e70eb61@distilled.cloud/neon bun add https://pkg.ing/@distilled.cloud/neon/e70eb61@distilled.cloud/planetscale bun add https://pkg.ing/@distilled.cloud/planetscale/e70eb61 |
|
Is there a companion PR for distilled or was the schema perfect? |
|
Looks like bindings are missing? Each operation that can target a resource needs a Binding. E.g. in AWS, we have Each stripe operation should be encoded as a binding and the process of binding that (creating token, binding that token and resource ID to the host, etc>) should be packaged up. Can mostly look at the Http bindings in Cloudflare and AWS and repeat those patterns |
Adds
alchemy/Stripe— 35 resources with providers, tests, and generated API docs.Resources
Billing & catalog:
Product,Price,Plan,Coupon,PromotionCode,TaxRate,ShippingRate,PaymentLink,Customer,CustomerTaxId,CreditGrant,Meter,Alert,Feature,ProductFeature,BillingPortalConfiguration,WebhookEndpoint,FileLink,AppsSecretPayments & tax:
PaymentMethodConfiguration,PaymentMethodDomain,ApplePayDomain,TaxRegistration,TaxSettingsConnect:
Account,AccountPerson,AccountExternalAccountIssuing:
IssuingCardholder,IssuingCard,IssuingPersonalizationDesignTerminal & Radar:
TerminalLocation,TerminalConfiguration,TerminalReader,RadarValueList,RadarValueListItemOwnership branding
Stripe has no tagging API, so ownership lives in each object's
metadatamap under reserved keys, which is howreadre-adopts a resource whose state row was lost:Metadata.tscentralizes this.metadataUpdatehandles Stripe's unset idiom — a removed key must be posted as"", not omitted — andstripInternalMetadatakeeps the reserved keys out of the user-facing attribute so a no-op deploy shows no drift.Deleting is mostly archiving
Only 13 of the 35 objects have a real DELETE. The rest cannot be deleted, so
deleteperforms the closest teardown Stripe offers and is idempotent:active: false, or a/deactivateendpoint) —Price,TaxRate,ShippingRate,PaymentLink,PromotionCode,BillingPortalConfiguration,Meter,Alert,Feature,PaymentMethodConfiguration,PaymentMethodDomain,IssuingCard,IssuingCardholderFileLink,CreditGrant,TaxRegistrationTaxSettings(an account-level singleton; the first reconcile captures the pre-existing settings so destroy can put them back)IssuingPersonalizationDesignhas no delete, archive, or deactivate endpointEach such resource documents the residue in a caution note. Some sharp edges are permanent and worth knowing before running the suites: a
Meter'sevent_nameand aFeature'slookup_keyare reserved account-wide forever, even after deactivation.Auth
STRIPE_API_KEY, or an interactively-stored key in~/.alchemy/credentials, via the standardAuthProvidershape. Registered inbuiltinAuth.Not in this PR
[UnknownStripeError], and the protocol dispatches on the envelope'serror.typebefore status — so a 404 for a missing object surfaces asInvalidRequestErrorwithcode === "resource_missing", neverNotFound. Providers catch both tags in the meantime; ~130 patch candidates are recorded from the implementation pass.