@sponson/adapters 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/README.md +1 -1
  2. package/dist/algolia.d.ts +6 -0
  3. package/dist/algolia.js +151 -0
  4. package/dist/algolia.js.map +1 -0
  5. package/dist/clerk.js +1 -1
  6. package/dist/clerk.js.map +1 -1
  7. package/dist/cloudflare.d.ts +25 -0
  8. package/dist/cloudflare.js +310 -0
  9. package/dist/cloudflare.js.map +1 -0
  10. package/dist/common.d.ts +2 -6
  11. package/dist/common.js.map +1 -1
  12. package/dist/digest.d.ts +46 -0
  13. package/dist/digest.js +129 -0
  14. package/dist/digest.js.map +1 -0
  15. package/dist/digitalocean.d.ts +5 -0
  16. package/dist/digitalocean.js +243 -0
  17. package/dist/digitalocean.js.map +1 -0
  18. package/dist/http-adapter-action.d.ts +63 -0
  19. package/dist/http-adapter-action.js +369 -0
  20. package/dist/http-adapter-action.js.map +1 -0
  21. package/dist/http-adapter-auth.d.ts +88 -0
  22. package/dist/http-adapter-auth.js +437 -0
  23. package/dist/http-adapter-auth.js.map +1 -0
  24. package/dist/http-adapter-client.d.ts +51 -0
  25. package/dist/http-adapter-client.js +156 -0
  26. package/dist/http-adapter-client.js.map +1 -0
  27. package/dist/http-adapter-graphql.d.ts +39 -0
  28. package/dist/http-adapter-graphql.js +157 -0
  29. package/dist/http-adapter-graphql.js.map +1 -0
  30. package/dist/http-adapter-list.d.ts +33 -0
  31. package/dist/http-adapter-list.js +421 -0
  32. package/dist/http-adapter-list.js.map +1 -0
  33. package/dist/http-adapter-resource.d.ts +29 -0
  34. package/dist/http-adapter-resource.js +462 -0
  35. package/dist/http-adapter-resource.js.map +1 -0
  36. package/dist/http-adapter-spec.d.ts +216 -0
  37. package/dist/http-adapter-spec.js +660 -0
  38. package/dist/http-adapter-spec.js.map +1 -0
  39. package/dist/http-adapter.d.ts +16 -0
  40. package/dist/http-adapter.js +28 -0
  41. package/dist/http-adapter.js.map +1 -0
  42. package/dist/http.d.ts +61 -2
  43. package/dist/http.js +79 -18
  44. package/dist/http.js.map +1 -1
  45. package/dist/index.d.ts +12 -0
  46. package/dist/index.js +24 -2
  47. package/dist/index.js.map +1 -1
  48. package/dist/launchdarkly.d.ts +15 -0
  49. package/dist/launchdarkly.js +337 -0
  50. package/dist/launchdarkly.js.map +1 -0
  51. package/dist/manual.d.ts +13 -0
  52. package/dist/manual.js +201 -0
  53. package/dist/manual.js.map +1 -0
  54. package/dist/neon.js +1 -1
  55. package/dist/neon.js.map +1 -1
  56. package/dist/netlify.d.ts +18 -0
  57. package/dist/netlify.js +436 -0
  58. package/dist/netlify.js.map +1 -0
  59. package/dist/planetscale.d.ts +10 -0
  60. package/dist/planetscale.js +311 -0
  61. package/dist/planetscale.js.map +1 -0
  62. package/dist/providers.d.ts +26 -0
  63. package/dist/providers.js +36 -0
  64. package/dist/providers.js.map +1 -0
  65. package/dist/recipes.d.ts +167 -0
  66. package/dist/recipes.js +246 -0
  67. package/dist/recipes.js.map +1 -0
  68. package/dist/secrets.d.ts +44 -0
  69. package/dist/secrets.js +279 -0
  70. package/dist/secrets.js.map +1 -1
  71. package/dist/sigv4.d.ts +56 -0
  72. package/dist/sigv4.js +118 -0
  73. package/dist/sigv4.js.map +1 -0
  74. package/dist/supabase.d.ts +9 -0
  75. package/dist/supabase.js +385 -0
  76. package/dist/supabase.js.map +1 -0
  77. package/dist/vercel.js +1 -1
  78. package/dist/vercel.js.map +1 -1
  79. package/dist/xata.d.ts +8 -0
  80. package/dist/xata.js +142 -0
  81. package/dist/xata.js.map +1 -0
  82. package/dist/xml.d.ts +25 -0
  83. package/dist/xml.js +211 -0
  84. package/dist/xml.js.map +1 -0
  85. package/package.json +11 -4
  86. package/recipes/amplify.yaml +147 -0
  87. package/recipes/auth0.yaml +178 -0
  88. package/recipes/azure_swa.yaml +116 -0
  89. package/recipes/cloud_run.yaml +97 -0
  90. package/recipes/cloudflare.yaml +108 -0
  91. package/recipes/cockroachdb.yaml +132 -0
  92. package/recipes/configcat.yaml +123 -0
  93. package/recipes/datadog.yaml +136 -0
  94. package/recipes/firebase.yaml +84 -0
  95. package/recipes/flagsmith.yaml +98 -0
  96. package/recipes/fly.yaml +97 -0
  97. package/recipes/fly_machines.yaml +67 -0
  98. package/recipes/gcs.yaml +102 -0
  99. package/recipes/github.yaml +123 -0
  100. package/recipes/growthbook.yaml +124 -0
  101. package/recipes/heroku.yaml +98 -0
  102. package/recipes/honeycomb.yaml +89 -0
  103. package/recipes/inngest.yaml +97 -0
  104. package/recipes/kinde.yaml +120 -0
  105. package/recipes/mongodb_atlas.yaml +119 -0
  106. package/recipes/okta.yaml +177 -0
  107. package/recipes/posthog.yaml +127 -0
  108. package/recipes/postmark.yaml +105 -0
  109. package/recipes/postmark_server.yaml +93 -0
  110. package/recipes/prisma.yaml +150 -0
  111. package/recipes/qstash.yaml +134 -0
  112. package/recipes/railway.yaml +130 -0
  113. package/recipes/render.yaml +103 -0
  114. package/recipes/resend.yaml +130 -0
  115. package/recipes/s3.yaml +108 -0
  116. package/recipes/sendgrid.yaml +165 -0
  117. package/recipes/sentry.yaml +158 -0
  118. package/recipes/split.yaml +121 -0
  119. package/recipes/statsig.yaml +124 -0
  120. package/recipes/stripe.yaml +310 -0
  121. package/recipes/stytch.yaml +113 -0
  122. package/recipes/svix.yaml +109 -0
  123. package/recipes/turso.yaml +98 -0
  124. package/recipes/unleash.yaml +149 -0
  125. package/recipes/upstash.yaml +130 -0
  126. package/recipes/vercel.yaml +116 -0
  127. package/recipes/workos.yaml +70 -0
@@ -0,0 +1,149 @@
1
+ # yaml-language-server: $schema=../../../schema/recipe.schema.json
2
+ # Unleash Admin API recipes. Format and checklist: docs/adr/0020-recipes.md, CONTRIBUTING.md "Adding a recipe".
3
+ provider: unleash
4
+ title: Unleash
5
+ category: flags
6
+ verified_on: "2026-10-11"
7
+ docs:
8
+ - title: Admin API overview (authorization, base URL)
9
+ url: https://docs.getunleash.io/reference/api/unleash
10
+ - title: Add a strategy to a flag in an environment
11
+ url: https://docs.getunleash.io/reference/api/unleash/add-feature-strategy
12
+ - title: Get feature flag strategies
13
+ url: https://docs.getunleash.io/reference/api/unleash/get-feature-strategies
14
+ - title: Update a strategy (replace)
15
+ url: https://docs.getunleash.io/reference/api/unleash/update-feature-strategy
16
+ - title: Delete a strategy
17
+ url: https://docs.getunleash.io/reference/api/unleash/delete-feature-strategy
18
+ - title: API tokens and client keys
19
+ url: https://docs.getunleash.io/reference/api-tokens-and-client-keys
20
+ # Every Unleash instance has its own URL (self-hosted, or https://<region>.app.unleash-hosted.com/<instance>):
21
+ # everything before `/api`.
22
+ base_url_example: https://unleash.example.com
23
+ api:
24
+ base_url_env: UNLEASH_API_URL
25
+ auth: { header: Authorization, value_env: UNLEASH_AUTH_TOKEN }
26
+ detect:
27
+ deps: [unleash-client, unleash-proxy-client, "@unleash/"]
28
+ env: ["UNLEASH_*"]
29
+ starter:
30
+ - op: flag_strategy
31
+ values: { title: "preview ${ctx.scope}", values: ["${ctx.scope}"] }
32
+ where:
33
+ base_url: "your Unleash instance's URL (`https://<instance>`)"
34
+ assumptions:
35
+ - id: UN1
36
+ verified: true
37
+ text: "Every request carries the token as it is in `Authorization` (`Authorization: <token>`, no `Bearer`); a personal access token or service account token (admin tokens are deprecated) reaches the Admin API. The spec also lists a Bearer scheme, but the server does not strip a `Bearer ` prefix, so the bare form is used."
38
+ source: https://docs.getunleash.io/reference/api/unleash
39
+ - id: UN2
40
+ verified: true
41
+ text: "`POST /api/admin/projects/{projectId}/features/{featureName}/environments/{environment}/strategies` with `name`, `title`, `disabled`, `constraints` and `parameters` adds a strategy and answers it bare, with its server-assigned `id` (a UUID)."
42
+ source: https://docs.getunleash.io/reference/api/unleash/add-feature-strategy
43
+ - id: UN3
44
+ verified: true
45
+ text: "`GET` on the same path answers a bare array of the environment's strategies (the source returns `FeatureStrategySchema[]`; the docs page's schema shows a single strategy, which is wrong)."
46
+ source: https://github.com/Unleash/unleash/blob/main/src/lib/features/feature-toggle/feature-toggle-controller.ts
47
+ - id: UN4
48
+ verified: true
49
+ text: "`PUT .../strategies/{strategyId}` replaces a strategy's configuration (so it sends `name`, `title` and every compared field); `DELETE` on the same path removes it."
50
+ source: https://docs.getunleash.io/reference/api/unleash/update-feature-strategy
51
+ - id: UN5
52
+ verified: true
53
+ text: "A constraint is `{ contextName, operator, values, caseInsensitive, inverted }` (`caseInsensitive` and `inverted` default to false, and are written explicitly so the comparison does not depend on defaults); `parameters` is a map of strings (`rollout: \"100\"`)."
54
+ source: https://docs.getunleash.io/reference/api/unleash/add-feature-strategy
55
+ - id: UN6
56
+ verified: false
57
+ text: "`title` is optional and not unique on the server: the strategy is identified by its title in the environment, and two strategies with that title are PARAM_INVALID rather than a guess."
58
+ source: https://docs.getunleash.io/reference/api/unleash/add-feature-strategy
59
+ - id: UN7
60
+ verified: false
61
+ text: "A strategy is read back with `constraints` and `parameters` exactly as written (no extra keys such as `value: \"\"`); otherwise every plan shows it as changed."
62
+ - id: UN8
63
+ verified: true
64
+ text: "Deleting a strategy that is gone already answers 200 (nothing to do). Deleting the last strategy of an environment turns the flag off in that environment (the service calls `disableEnvironmentIfNoStrategies`). Adding a strategy does not turn the environment on."
65
+ source: https://github.com/Unleash/unleash/blob/main/src/lib/features/feature-toggle/feature-toggle-service.ts
66
+ - id: UN9
67
+ verified: true
68
+ text: "With change requests enabled for the environment, these writes are refused unless the caller may bypass them; the refusal fails the apply."
69
+ source: https://github.com/Unleash/unleash/blob/main/src/lib/features/feature-toggle/feature-toggle-service.ts
70
+ ops:
71
+ flag_strategy:
72
+ kind: resource
73
+ title: Flag strategy with constraints
74
+ summary: "A `flexibleRollout` strategy on a flag in one environment, constrained to the preview (such as `preview IN [pr-42]`). Located by its title in the environment's strategies; a console edit of its constraints, rollout parameters or `disabled` is drift. Destroy deletes it; if it was the environment's last strategy, Unleash turns the flag off there (UN8). The environment itself must be enabled for the flag to be served."
75
+ covers: [unleash-strategy]
76
+ params:
77
+ project:
78
+ type: string
79
+ default: default
80
+ description: The project id.
81
+ feature:
82
+ type: string
83
+ required: true
84
+ description: The flag's name; also the rollout's `groupId`.
85
+ example: new-checkout
86
+ environment:
87
+ type: string
88
+ required: true
89
+ description: The environment the strategy is added in.
90
+ example: development
91
+ title:
92
+ type: string
93
+ required: true
94
+ description: The strategy's title, unique among the environment's strategies; it identifies the strategy.
95
+ example: "preview ${ctx.scope}"
96
+ context_name:
97
+ type: string
98
+ required: true
99
+ description: The context field the constraint tests (a custom context field such as `preview`, or `environment`, `userId`, …).
100
+ example: preview
101
+ operator:
102
+ type: string
103
+ default: IN
104
+ enum: [IN, NOT_IN, STR_ENDS_WITH, STR_STARTS_WITH, STR_CONTAINS]
105
+ description: The constraint's operator.
106
+ values:
107
+ type: list
108
+ required: true
109
+ description: The values the context field is compared with.
110
+ example: ["${ctx.scope}"]
111
+ rollout:
112
+ type: string
113
+ default: "100"
114
+ pattern: "^(100|[1-9]?[0-9])$"
115
+ description: The share of matching users the strategy enables, as a string (0–100).
116
+ stickiness:
117
+ type: string
118
+ default: default
119
+ description: The rollout's stickiness (`default`, `userId`, `sessionId`, `random`, or a context field).
120
+ disabled:
121
+ type: boolean
122
+ default: false
123
+ description: Keep the strategy but switch it off.
124
+ http:
125
+ find:
126
+ path: "/api/admin/projects/{project}/features/{feature}/environments/{environment}/strategies"
127
+ match: { title: { param: title } }
128
+ create:
129
+ path: "/api/admin/projects/{project}/features/{feature}/environments/{environment}/strategies"
130
+ body: { name: flexibleRollout }
131
+ update:
132
+ method: PUT
133
+ path: "/api/admin/projects/{project}/features/{feature}/environments/{environment}/strategies/{id}"
134
+ body: { name: flexibleRollout }
135
+ delete: { path: "/api/admin/projects/{project}/features/{feature}/environments/{environment}/strategies/{id}" }
136
+ fields:
137
+ disabled: { param: disabled }
138
+ constraints:
139
+ - contextName: { param: context_name }
140
+ operator: { param: operator }
141
+ values: { param: values }
142
+ caseInsensitive: false
143
+ inverted: false
144
+ parameters:
145
+ rollout: { param: rollout }
146
+ stickiness: { param: stickiness }
147
+ groupId: { param: feature }
148
+ live:
149
+ params: { project: SPONSON_LIVE_UNLEASH_PROJECT, feature: SPONSON_LIVE_UNLEASH_FEATURE, environment: SPONSON_LIVE_UNLEASH_ENVIRONMENT }
@@ -0,0 +1,130 @@
1
+ # yaml-language-server: $schema=../../../schema/recipe.schema.json
2
+ # Upstash Developer API recipes (Redis). QStash has its own API and credential: recipes/qstash.yaml.
3
+ # Format and checklist: docs/adr/0020-recipes.md, CONTRIBUTING.md "Adding a recipe".
4
+ provider: upstash
5
+ title: Upstash Redis
6
+ category: queues
7
+ verified_on: "2026-10-11"
8
+ docs:
9
+ - title: Developer API authentication
10
+ url: https://upstash.com/docs/devops/developer-api/authentication
11
+ - title: Developer API introduction (supported accounts)
12
+ url: https://upstash.com/docs/devops/developer-api/introduction
13
+ - title: Create a Redis database (global)
14
+ url: https://upstash.com/docs/devops/developer-api/redis/create_database_global
15
+ - title: List Redis databases
16
+ url: https://upstash.com/docs/devops/developer-api/redis/list_databases
17
+ - title: Get a Redis database
18
+ url: https://upstash.com/docs/devops/developer-api/redis/get_database
19
+ - title: Delete a Redis database
20
+ url: https://upstash.com/docs/devops/developer-api/redis/delete_database
21
+ - title: Upstash CLI (UPSTASH_EMAIL, UPSTASH_API_KEY)
22
+ url: https://upstash.com/docs/agent-resources/cli
23
+ - title: Terraform upstash_redis_database (exported credentials)
24
+ url: https://upstash.com/docs/devops/terraform/resources/upstash_redis_database
25
+ api:
26
+ base_url: https://api.upstash.com/v2
27
+ base_url_env: UPSTASH_API_URL
28
+ auth: { basic: { user_env: UPSTASH_EMAIL, password_env: UPSTASH_API_KEY } }
29
+ detect:
30
+ deps: ["@upstash/redis"]
31
+ env: ["UPSTASH_REDIS_*"]
32
+ starter:
33
+ - op: redis_database
34
+ values: { name: "app-${ctx.scope}" }
35
+ assumptions:
36
+ - id: UR1
37
+ verified: true
38
+ text: "The Developer API authenticates with HTTP Basic, the account's email as user and an API key as password; the Upstash CLI reads them from `UPSTASH_EMAIL` and `UPSTASH_API_KEY`. Accounts created through Vercel or Fly cannot use it."
39
+ source: https://upstash.com/docs/devops/developer-api/authentication
40
+ - id: UR2
41
+ verified: true
42
+ text: "`POST /v2/redis/database` with `{ database_name, platform, primary_region, read_regions?, plan?, tls?, eviction? }` creates a global database and answers it bare, with `database_id`, `database_name`, `endpoint`, `port` and `state`."
43
+ source: https://upstash.com/docs/devops/developer-api/redis/create_database_global
44
+ - id: UR3
45
+ verified: true
46
+ text: "`GET /v2/redis/databases` answers every database of the account as a bare array (no paging)."
47
+ source: https://upstash.com/docs/devops/developer-api/redis/list_databases
48
+ - id: UR4
49
+ verified: false
50
+ text: "Database names are unique in the account, so `database_name` identifies one; a create whose answer was lost is found by it before another is created. (Not documented: a second database with the same name makes `find.match` ambiguous, which is refused with PARAM_INVALID rather than guessed.)"
51
+ - id: UR5
52
+ verified: true
53
+ text: "`GET /v2/redis/database/{id}` answers the database, with its credentials unless `?credentials=hide` is sent."
54
+ source: https://upstash.com/docs/devops/developer-api/redis/get_database
55
+ - id: UR6
56
+ verified: false
57
+ text: "The credentials are the fields `password` and `rest_token` (the documented schema omits them; the Terraform resource and the CLI expose them), so they are readable on every run, not only from the create: ordinary sensitive outputs, not once-only ones."
58
+ source: https://upstash.com/docs/devops/terraform/resources/upstash_redis_database
59
+ - id: UR7
60
+ verified: true
61
+ text: "`DELETE /v2/redis/database/{id}` deletes the database and answers 200 `\"OK\"`."
62
+ source: https://upstash.com/docs/devops/developer-api/redis/delete_database
63
+ - id: UR8
64
+ verified: false
65
+ text: "A database that is gone answers 404 on GET and DELETE (only 200 is documented)."
66
+ - id: UR9
67
+ verified: false
68
+ text: "The database is usable when the create answers (`state: active` in the documented example); nothing waits for it."
69
+ source: https://upstash.com/docs/devops/developer-api/redis/create_database_global
70
+ - id: UR10
71
+ verified: false
72
+ text: "`endpoint` is the database's host name (`<name>.upstash.io`); the documented example shows only its first label, so check the output before building a URL from it."
73
+ source: https://upstash.com/docs/devops/developer-api/redis/create_database_global
74
+ ops:
75
+ redis_database:
76
+ kind: resource
77
+ title: Redis database
78
+ summary: "A global Redis database per scope, such as `app-pr-42`, with its endpoint, port, password and REST token as outputs (the last two sensitive). Located by name; only its existence is compared for drift (region, plan and TLS are set on create and not compared); destroy deletes it and its data."
79
+ covers: [upstash-redis-database]
80
+ params:
81
+ name:
82
+ type: string
83
+ required: true
84
+ description: The database's name.
85
+ example: "app-${ctx.scope}"
86
+ platform:
87
+ type: string
88
+ default: aws
89
+ enum: [aws, gcp]
90
+ description: The cloud it runs on.
91
+ primary_region:
92
+ type: string
93
+ required: true
94
+ description: The primary region, such as `us-east-1` or `eu-west-1`.
95
+ example: us-east-1
96
+ read_regions:
97
+ type: list
98
+ description: Read replica regions.
99
+ plan:
100
+ type: string
101
+ description: The plan (`free`, `payg`, `fixed_…`); the account's default when left out.
102
+ tls:
103
+ type: boolean
104
+ default: true
105
+ description: Whether TLS is enabled.
106
+ eviction:
107
+ type: boolean
108
+ description: Whether keys are evicted when the database is full.
109
+ http:
110
+ find:
111
+ path: /redis/databases
112
+ match: { database_name: { param: name } }
113
+ read: { path: "/redis/database/{id}" }
114
+ create:
115
+ path: /redis/database
116
+ body:
117
+ platform: { param: platform }
118
+ primary_region: { param: primary_region }
119
+ read_regions: { param: read_regions }
120
+ plan: { param: plan }
121
+ tls: { param: tls }
122
+ eviction: { param: eviction }
123
+ id_path: /database_id
124
+ outputs:
125
+ endpoint: /endpoint
126
+ port: /port
127
+ password: { path: /password, sensitive: true }
128
+ rest_token: { path: /rest_token, sensitive: true }
129
+ live:
130
+ params: { primary_region: SPONSON_LIVE_UPSTASH_REGION }
@@ -0,0 +1,116 @@
1
+ # yaml-language-server: $schema=../../../schema/recipe.schema.json
2
+ # Vercel REST API recipes. Format and checklist: docs/adr/0020-recipes.md, CONTRIBUTING.md "Adding a recipe".
3
+ # Environment variables and deployments have the first-class `vercel` adapter (vercel.env, vercel.deploy).
4
+ provider: vercel
5
+ title: Vercel
6
+ category: dns
7
+ verified_on: "2026-10-11"
8
+ docs:
9
+ - title: Add a domain to a project
10
+ url: https://vercel.com/docs/rest-api/projects/add-a-domain-to-a-project
11
+ - title: Get a project domain
12
+ url: https://vercel.com/docs/rest-api/projects/get-a-project-domain
13
+ - title: Update a project domain
14
+ url: https://vercel.com/docs/rest-api/projects/update-a-project-domain
15
+ - title: Remove a domain from a project
16
+ url: https://vercel.com/docs/rest-api/projects/remove-a-domain-from-a-project
17
+ - title: Errors
18
+ url: https://vercel.com/docs/rest-api/errors
19
+ - title: CLI global options (VERCEL_TOKEN)
20
+ url: https://vercel.com/docs/cli/global-options
21
+ - title: Working with domains (verification)
22
+ url: https://vercel.com/docs/domains/working-with-domains
23
+ api:
24
+ base_url: https://api.vercel.com
25
+ base_url_env: VERCEL_API_URL
26
+ auth: { bearer_env: VERCEL_TOKEN }
27
+ assumptions:
28
+ - id: VD1
29
+ verified: true
30
+ text: "Requests authenticate as `Authorization: Bearer <token>`; the Vercel CLI reads the token from `VERCEL_TOKEN` (the built-in `vercel` adapter uses the same variable)."
31
+ source: https://vercel.com/docs/cli/global-options
32
+ - id: VD2
33
+ verified: true
34
+ text: "`POST /v10/projects/{idOrName}/domains?teamId=` with `{ name, gitBranch, redirect, redirectStatusCode }` adds the domain to the project and answers it bare: `{ name, apexName, projectId, verified, gitBranch, redirect, redirectStatusCode, verification[] }`."
35
+ source: https://vercel.com/docs/rest-api/projects/add-a-domain-to-a-project
36
+ - id: VD3
37
+ verified: true
38
+ text: "`GET /v9/projects/{idOrName}/domains/{domain}?teamId=` answers the same shape; the domain's name identifies it within the project, so the read path names it and a create whose answer was lost is found by it."
39
+ source: https://vercel.com/docs/rest-api/projects/get-a-project-domain
40
+ - id: VD4
41
+ verified: false
42
+ text: "A domain that is not on the project answers 404 on GET and DELETE (documented with no description)."
43
+ source: https://vercel.com/docs/rest-api/projects/get-a-project-domain
44
+ - id: VD5
45
+ verified: true
46
+ text: "`PATCH /v9/projects/{idOrName}/domains/{domain}` changes `gitBranch`, `redirect` and `redirectStatusCode`; `DELETE` on the same path removes the domain from the project (200, `{}`)."
47
+ source: https://vercel.com/docs/rest-api/projects/update-a-project-domain
48
+ - id: VD6
49
+ verified: true
50
+ text: "Adding a domain that is already on a project of the account answers 409 (and, for the same project, the description says 400): someone else's domain is never taken over by name, and the conflict surfaces as an error."
51
+ source: https://vercel.com/docs/rest-api/projects/add-a-domain-to-a-project
52
+ - id: VD7
53
+ verified: true
54
+ text: "`gitBranch` and `redirect` cannot be set together, and the production branch cannot be a `gitBranch` (400)."
55
+ source: https://vercel.com/docs/rest-api/projects/add-a-domain-to-a-project
56
+ - id: VD8
57
+ verified: true
58
+ text: "A domain the account does not own answers `verified: false` with a `verification` challenge (a TXT record) that must be completed before it serves traffic; a domain bought through Vercel needs none."
59
+ source: https://vercel.com/docs/domains/working-with-domains
60
+ - id: VD9
61
+ verified: false
62
+ text: "A free `<name>.vercel.app` domain that no other project uses is verified on the spot (`verified: true`)."
63
+ - id: VD10
64
+ verified: false
65
+ text: "Every account has a team id (personal accounts are Hobby teams), so `teamId` can always be sent; the recipe requires it."
66
+ ops:
67
+ project_domain:
68
+ kind: resource
69
+ title: Branch-bound project domain
70
+ summary: "A domain on a Vercel project that serves one git branch's latest preview, such as `pr-42.preview.example.com` for `feat/x`: a stable preview hostname. Located by name; a console edit of its branch or redirect is drift; destroy removes it from the project. Its `verified` output says whether DNS verification is still needed (VD8)."
71
+ covers: [vercel-domain]
72
+ params:
73
+ project:
74
+ type: string
75
+ required: true
76
+ description: The project's id or name.
77
+ example: prj_12HKQaOmR5t5Uy6vdcQsNIiZgHGB
78
+ team_id:
79
+ type: string
80
+ required: true
81
+ pattern: "^team_[A-Za-z0-9]+$"
82
+ description: The team's id (`team_…`, under Settings → General).
83
+ example: team_1a2b3c4d5e6f7g8h9i0j1k2l
84
+ name:
85
+ type: string
86
+ required: true
87
+ pattern: "^[a-z0-9*.-]+$"
88
+ description: The domain, lower-case.
89
+ example: "${ctx.scope}.preview.example.com"
90
+ git_branch:
91
+ type: string
92
+ description: The git branch whose latest deployment the domain serves.
93
+ example: "${ctx.git.branch}"
94
+ redirect:
95
+ type: string
96
+ description: Redirect to this domain instead of serving a branch (not with `git_branch`).
97
+ redirect_status_code:
98
+ type: integer
99
+ enum: [301, 302, 307, 308]
100
+ description: The redirect's status code.
101
+ http:
102
+ read: { path: "/v9/projects/{project}/domains/{name}?teamId={team_id}" }
103
+ create:
104
+ path: "/v10/projects/{project}/domains?teamId={team_id}"
105
+ body: { name: { param: name } }
106
+ update: { method: PATCH }
107
+ id_path: /name
108
+ fields:
109
+ gitBranch: { param: git_branch }
110
+ redirect: { param: redirect }
111
+ redirectStatusCode: { param: redirect_status_code }
112
+ outputs: { verified: /verified, apex_name: /apexName }
113
+ sim:
114
+ id_from: name
115
+ live:
116
+ params: { project: SPONSON_LIVE_VERCEL_PROJECT, team_id: SPONSON_LIVE_VERCEL_TEAM_ID, name: SPONSON_LIVE_VERCEL_DOMAIN }
@@ -0,0 +1,70 @@
1
+ # yaml-language-server: $schema=../../../schema/recipe.schema.json
2
+ # WorkOS API recipes. Format and checklist: docs/adr/0020-recipes.md, CONTRIBUTING.md "Adding a recipe".
3
+ provider: workos
4
+ title: WorkOS
5
+ category: auth
6
+ verified_on: "2026-10-11"
7
+ docs:
8
+ - title: AuthKit API reference, Redirect URI
9
+ url: https://workos.com/docs/reference/authkit/redirect-uri
10
+ - title: AuthKit, redirect URIs in the Dashboard
11
+ url: https://workos.com/docs/user-management/integrating-with-authkit
12
+ api:
13
+ base_url: https://api.workos.com
14
+ base_url_env: WORKOS_API_URL
15
+ auth: { bearer_env: WORKOS_API_KEY }
16
+ detect:
17
+ deps: ["@workos-inc/"]
18
+ env: ["WORKOS_*"]
19
+ starter:
20
+ - op: redirect_uri
21
+ where:
22
+ uri: "the exact redirect URI AuthKit receives on a preview: its URL plus the callback path (a `{ from }` reference cannot carry a path)"
23
+ assumptions:
24
+ - id: WO1
25
+ verified: true
26
+ text: "`POST /user_management/redirect_uris` with `{ uri }` creates a redirect URI for the environment the API key (`Authorization: Bearer sk_…`) belongs to, and answers the `redirect_uri` object (`id`, `uri`, `default`)."
27
+ source: https://workos.com/docs/reference/authkit/redirect-uri
28
+ - id: WO2
29
+ verified: true
30
+ text: "`GET /user_management/redirect_uris` (`limit` 1–100, cursors `before`/`after`) answers `{ data: [...], list_metadata: { before, after } }`."
31
+ source: https://workos.com/docs/reference/authkit/redirect-uri
32
+ - id: WO3
33
+ verified: true
34
+ text: "`DELETE /user_management/redirect_uris/{id}` removes one and answers an empty body. There is no GET or update by id: a URI is found in the list, and nothing about it is changed in place."
35
+ source: https://workos.com/docs/reference/authkit/redirect-uri
36
+ - id: WO4
37
+ verified: true
38
+ text: "Redirect URIs may contain wildcards, except the default one."
39
+ source: https://workos.com/docs/user-management/integrating-with-authkit
40
+ - id: WO5
41
+ verified: false
42
+ text: "Each URI is its own object (no shared list to rewrite), so concurrent previews need no lock; a URI is returned exactly as it was created, so `uri` identifies it."
43
+ - id: WO6
44
+ verified: false
45
+ text: "Creating a URI that already exists is refused as a conflict (409) rather than duplicated; the line then finds the existing one."
46
+ - id: WO7
47
+ verified: false
48
+ text: "The first redirect URI of an environment becomes its default; a preview's URI is never the first in an environment that has a production URI."
49
+ ops:
50
+ redirect_uri:
51
+ kind: resource
52
+ title: AuthKit redirect URI
53
+ summary: "One redirect URI on the WorkOS environment the API key belongs to, such as the preview's `/callback`: usually `{ from: <vercel.env line>.preview_url }` joined in the app. Found by its URI in the list (following `list_metadata.after`); removed by id on destroy. A URI has nothing else to edit, so the only drift is a URI deleted in the Dashboard, which the next apply creates again."
54
+ covers: [workos-redirect]
55
+ params:
56
+ uri:
57
+ type: string
58
+ required: true
59
+ pattern: "^https?://\\S+$"
60
+ description: "The redirect URI, exactly as AuthKit will receive it (`https://pr-42.preview.example.com/callback`)."
61
+ example: "https://${ctx.scope}.preview.example.com/callback"
62
+ http:
63
+ find:
64
+ path: /user_management/redirect_uris?limit=100
65
+ list_path: /data
66
+ match: { uri: { param: uri } }
67
+ next: /list_metadata/after
68
+ cursor_param: after
69
+ create: { path: /user_management/redirect_uris }
70
+ delete: { path: "/user_management/redirect_uris/{id}" }