@sponson/adapters 0.4.0 → 0.6.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 (129) 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/cloud_run.d.ts +12 -0
  8. package/dist/cloud_run.js +469 -0
  9. package/dist/cloud_run.js.map +1 -0
  10. package/dist/cloudflare.d.ts +25 -0
  11. package/dist/cloudflare.js +310 -0
  12. package/dist/cloudflare.js.map +1 -0
  13. package/dist/common.d.ts +2 -6
  14. package/dist/common.js.map +1 -1
  15. package/dist/digest.d.ts +46 -0
  16. package/dist/digest.js +129 -0
  17. package/dist/digest.js.map +1 -0
  18. package/dist/digitalocean.d.ts +5 -0
  19. package/dist/digitalocean.js +243 -0
  20. package/dist/digitalocean.js.map +1 -0
  21. package/dist/http-adapter-action.d.ts +63 -0
  22. package/dist/http-adapter-action.js +369 -0
  23. package/dist/http-adapter-action.js.map +1 -0
  24. package/dist/http-adapter-auth.d.ts +94 -0
  25. package/dist/http-adapter-auth.js +440 -0
  26. package/dist/http-adapter-auth.js.map +1 -0
  27. package/dist/http-adapter-client.d.ts +57 -0
  28. package/dist/http-adapter-client.js +163 -0
  29. package/dist/http-adapter-client.js.map +1 -0
  30. package/dist/http-adapter-graphql.d.ts +39 -0
  31. package/dist/http-adapter-graphql.js +157 -0
  32. package/dist/http-adapter-graphql.js.map +1 -0
  33. package/dist/http-adapter-list.d.ts +33 -0
  34. package/dist/http-adapter-list.js +421 -0
  35. package/dist/http-adapter-list.js.map +1 -0
  36. package/dist/http-adapter-resource.d.ts +29 -0
  37. package/dist/http-adapter-resource.js +462 -0
  38. package/dist/http-adapter-resource.js.map +1 -0
  39. package/dist/http-adapter-spec.d.ts +216 -0
  40. package/dist/http-adapter-spec.js +660 -0
  41. package/dist/http-adapter-spec.js.map +1 -0
  42. package/dist/http-adapter.d.ts +16 -0
  43. package/dist/http-adapter.js +28 -0
  44. package/dist/http-adapter.js.map +1 -0
  45. package/dist/http.d.ts +61 -2
  46. package/dist/http.js +79 -18
  47. package/dist/http.js.map +1 -1
  48. package/dist/index.d.ts +13 -0
  49. package/dist/index.js +26 -2
  50. package/dist/index.js.map +1 -1
  51. package/dist/launchdarkly.d.ts +15 -0
  52. package/dist/launchdarkly.js +337 -0
  53. package/dist/launchdarkly.js.map +1 -0
  54. package/dist/manual.d.ts +13 -0
  55. package/dist/manual.js +201 -0
  56. package/dist/manual.js.map +1 -0
  57. package/dist/neon.js +1 -1
  58. package/dist/neon.js.map +1 -1
  59. package/dist/netlify.d.ts +18 -0
  60. package/dist/netlify.js +436 -0
  61. package/dist/netlify.js.map +1 -0
  62. package/dist/planetscale.d.ts +10 -0
  63. package/dist/planetscale.js +311 -0
  64. package/dist/planetscale.js.map +1 -0
  65. package/dist/providers.d.ts +28 -0
  66. package/dist/providers.js +41 -0
  67. package/dist/providers.js.map +1 -0
  68. package/dist/recipes.d.ts +167 -0
  69. package/dist/recipes.js +246 -0
  70. package/dist/recipes.js.map +1 -0
  71. package/dist/secrets.d.ts +44 -0
  72. package/dist/secrets.js +279 -0
  73. package/dist/secrets.js.map +1 -1
  74. package/dist/sigv4.d.ts +56 -0
  75. package/dist/sigv4.js +118 -0
  76. package/dist/sigv4.js.map +1 -0
  77. package/dist/supabase.d.ts +9 -0
  78. package/dist/supabase.js +385 -0
  79. package/dist/supabase.js.map +1 -0
  80. package/dist/vercel.js +1 -1
  81. package/dist/vercel.js.map +1 -1
  82. package/dist/xata.d.ts +8 -0
  83. package/dist/xata.js +142 -0
  84. package/dist/xata.js.map +1 -0
  85. package/dist/xml.d.ts +25 -0
  86. package/dist/xml.js +211 -0
  87. package/dist/xml.js.map +1 -0
  88. package/package.json +11 -4
  89. package/recipes/amplify.yaml +147 -0
  90. package/recipes/auth0.yaml +178 -0
  91. package/recipes/azure_swa.yaml +116 -0
  92. package/recipes/cloudflare.yaml +108 -0
  93. package/recipes/cockroachdb.yaml +132 -0
  94. package/recipes/configcat.yaml +123 -0
  95. package/recipes/datadog.yaml +136 -0
  96. package/recipes/firebase.yaml +84 -0
  97. package/recipes/flagsmith.yaml +98 -0
  98. package/recipes/fly.yaml +97 -0
  99. package/recipes/fly_machines.yaml +67 -0
  100. package/recipes/gcs.yaml +102 -0
  101. package/recipes/github.yaml +124 -0
  102. package/recipes/growthbook.yaml +124 -0
  103. package/recipes/heroku.yaml +98 -0
  104. package/recipes/honeycomb.yaml +89 -0
  105. package/recipes/inngest.yaml +97 -0
  106. package/recipes/kinde.yaml +120 -0
  107. package/recipes/mongodb_atlas.yaml +119 -0
  108. package/recipes/okta.yaml +177 -0
  109. package/recipes/posthog.yaml +127 -0
  110. package/recipes/postmark.yaml +105 -0
  111. package/recipes/postmark_server.yaml +93 -0
  112. package/recipes/prisma.yaml +150 -0
  113. package/recipes/qstash.yaml +134 -0
  114. package/recipes/railway.yaml +130 -0
  115. package/recipes/render.yaml +103 -0
  116. package/recipes/resend.yaml +130 -0
  117. package/recipes/s3.yaml +108 -0
  118. package/recipes/sendgrid.yaml +165 -0
  119. package/recipes/sentry.yaml +158 -0
  120. package/recipes/split.yaml +121 -0
  121. package/recipes/statsig.yaml +124 -0
  122. package/recipes/stripe.yaml +310 -0
  123. package/recipes/stytch.yaml +113 -0
  124. package/recipes/svix.yaml +109 -0
  125. package/recipes/turso.yaml +98 -0
  126. package/recipes/unleash.yaml +149 -0
  127. package/recipes/upstash.yaml +130 -0
  128. package/recipes/vercel.yaml +116 -0
  129. package/recipes/workos.yaml +70 -0
@@ -0,0 +1,132 @@
1
+ # yaml-language-server: $schema=../../../schema/recipe.schema.json
2
+ # CockroachDB Cloud API recipes (service account API key, bearer). Format and checklist: docs/adr/0020-recipes.md,
3
+ # CONTRIBUTING.md "Adding a recipe".
4
+ provider: cockroachdb
5
+ title: CockroachDB Cloud
6
+ category: databases
7
+ verified_on: "2026-10-11"
8
+ docs:
9
+ - title: Cloud API OpenAPI document (version 2026-09-15)
10
+ url: https://cockroachlabs.cloud/assets/docs/api/latest/openapi.json
11
+ - title: Use the CockroachDB Cloud API
12
+ url: https://docs.cockroachlabs.com/docs/cockroachcloud/cloud-api
13
+ api:
14
+ base_url: https://cockroachlabs.cloud/api/v1
15
+ base_url_env: COCKROACH_API_URL
16
+ auth: { bearer_env: COCKROACH_API_KEY }
17
+ headers: { Cc-Version: "2024-09-16" }
18
+ detect:
19
+ env: ["COCKROACH_*"]
20
+ db_hosts: [.cockroachlabs.cloud]
21
+ starter:
22
+ - op: database
23
+ values: { name: "app_${ctx.scope}" }
24
+ where:
25
+ cluster_id: "CockroachDB Cloud Console → your cluster (the UUID in its URL), or `ccloud cluster list`"
26
+ assumptions:
27
+ - id: CR1
28
+ verified: true
29
+ text: "The Cloud API authenticates with a service account's secret key as `Authorization: Bearer`; the key has the service account's roles."
30
+ source: https://docs.cockroachlabs.com/docs/cockroachcloud/cloud-api
31
+ - id: CR2
32
+ verified: true
33
+ text: "`Cc-Version` pins the API version (`YYYY-MM-DD`); without it the latest version answers, which may change under a client. The guide documents `2024-09-16`."
34
+ source: https://docs.cockroachlabs.com/docs/cockroachcloud/cloud-api
35
+ - id: CR3
36
+ verified: true
37
+ text: "`POST /clusters/{cluster_id}/databases` with `{ name }` creates a database and answers `{ name, table_count }`; `GET` on the same path lists `{ databases: [{ name, table_count }], pagination: { next_page } }`, paged with `pagination.page`; `DELETE /clusters/{cluster_id}/databases/{name}` deletes one. There is no GET of a single database."
38
+ source: https://cockroachlabs.cloud/assets/docs/api/latest/openapi.json
39
+ - id: CR4
40
+ verified: true
41
+ text: "`POST /clusters/{cluster_id}/sql-users` with `{ name, password }` (both required) creates a SQL user; `GET` on the same path lists `{ users: [{ name }], pagination: { next_page } }`; `DELETE /clusters/{cluster_id}/sql-users/{name}` deletes one. The password cannot be read back; `PUT …/sql-users/{name}/password` changes it."
42
+ source: https://cockroachlabs.cloud/assets/docs/api/latest/openapi.json
43
+ - id: CR5
44
+ verified: true
45
+ text: "A SQL user created through the API gets the SQL `admin` role by default, which the guide advises against for anything but administration."
46
+ source: https://docs.cockroachlabs.com/docs/cockroachcloud/cloud-api
47
+ - id: CR6
48
+ verified: true
49
+ text: "Creating or deleting databases and SQL users needs a cluster-level role of the service account (Cluster Admin, Cluster Operator or Cluster Data Accessor for databases; Cluster Admin for SQL users)."
50
+ source: https://cockroachlabs.cloud/assets/docs/api/latest/openapi.json
51
+ - id: CR7
52
+ verified: false
53
+ text: "`COCKROACH_API_KEY` is the variable the CockroachDB Terraform provider and `ccloud` read the key from."
54
+ - id: CR8
55
+ verified: false
56
+ text: "A second create of an existing database or SQL user is refused with 409 (ALREADY_EXISTS), and deleting one that is gone answers 404."
57
+ - id: CR9
58
+ verified: false
59
+ text: "Deleting a database drops it with its tables (CASCADE); the API offers no way to refuse when it holds data."
60
+ - id: CR10
61
+ verified: false
62
+ text: "The API takes database and user names that need quoting in SQL (`app_pr-42`, from a scope with `-`) and quotes them itself."
63
+ ops:
64
+ database:
65
+ kind: resource
66
+ title: Database in a cluster
67
+ summary: "A database per scope in a shared CockroachDB Cloud cluster, such as `app_pr_42`, instead of a cluster per preview. Located by its name in the cluster's list; only its existence is compared (the API exposes nothing else to set); destroy drops it with its data (CR9)."
68
+ covers: [cockroachdb-database]
69
+ params:
70
+ cluster_id:
71
+ type: string
72
+ required: true
73
+ description: The cluster's id (a UUID, shown in the Cloud Console's URL).
74
+ example: 9e3f1a52-63d1-4a4c-9b8f-2c8b7a0e5d11
75
+ name:
76
+ type: string
77
+ required: true
78
+ pattern: "^[A-Za-z_][A-Za-z0-9_.-]{0,62}$"
79
+ description: "The database's name; its identity. A name with `-` (a scope such as `pr-42`) needs quoting in SQL (CR10)."
80
+ example: "app_${ctx.scope}"
81
+ http:
82
+ find:
83
+ path: "/clusters/{cluster_id}/databases"
84
+ list_path: /databases
85
+ match: { name: { param: name } }
86
+ next: /pagination/next_page
87
+ cursor_param: pagination.page
88
+ create: { path: "/clusters/{cluster_id}/databases" }
89
+ delete: { path: "/clusters/{cluster_id}/databases/{id}" }
90
+ id_path: /name
91
+ sim:
92
+ id_from: name
93
+ live:
94
+ params: { cluster_id: SPONSON_LIVE_COCKROACH_CLUSTER_ID }
95
+ sql_user:
96
+ kind: resource
97
+ title: SQL user in a cluster
98
+ summary: "A SQL user per scope in a shared CockroachDB Cloud cluster, such as `app_pr_42`, with its password as an input (`{ secret: … }`, or a sensitive output of another line), sent on create only and never compared. It gets the SQL `admin` role (CR5): grant narrower privileges in SQL if previews must not administer the cluster. Located by its name; destroy deletes the user."
99
+ covers: []
100
+ params:
101
+ cluster_id:
102
+ type: string
103
+ required: true
104
+ description: The cluster's id (a UUID, shown in the Cloud Console's URL).
105
+ example: 9e3f1a52-63d1-4a4c-9b8f-2c8b7a0e5d11
106
+ name:
107
+ type: string
108
+ required: true
109
+ pattern: "^[A-Za-z_][A-Za-z0-9_.-]{0,62}$"
110
+ description: The user's name; its identity.
111
+ example: "app_${ctx.scope}"
112
+ password:
113
+ type: string
114
+ required: true
115
+ description: "The user's password, as a reference (`{ secret: env://… }`, or `{ from: <line>.<output> }` of a sensitive output); sent on create only (CR4)."
116
+ example: { secret: "env://PREVIEW_DB_PASSWORD" }
117
+ http:
118
+ find:
119
+ path: "/clusters/{cluster_id}/sql-users"
120
+ list_path: /users
121
+ match: { name: { param: name } }
122
+ next: /pagination/next_page
123
+ cursor_param: pagination.page
124
+ create:
125
+ path: "/clusters/{cluster_id}/sql-users"
126
+ body: { password: { param: password } }
127
+ delete: { path: "/clusters/{cluster_id}/sql-users/{id}" }
128
+ id_path: /name
129
+ sim:
130
+ id_from: name
131
+ live:
132
+ params: { cluster_id: SPONSON_LIVE_COCKROACH_CLUSTER_ID }
@@ -0,0 +1,123 @@
1
+ # yaml-language-server: $schema=../../../schema/recipe.schema.json
2
+ # ConfigCat Public Management API recipes. Format and checklist: docs/adr/0020-recipes.md, CONTRIBUTING.md "Adding a recipe".
3
+ provider: configcat
4
+ title: ConfigCat
5
+ category: flags
6
+ verified_on: "2026-10-11"
7
+ docs:
8
+ - title: Public Management API
9
+ url: https://api.configcat.com/docs/
10
+ - title: OpenAPI spec (get value v2, replace value v2, targeting rule models)
11
+ url: https://api.configcat.com/docs/v1/swagger.json
12
+ - title: Terraform provider (credential variable names)
13
+ url: https://github.com/configcat/terraform-provider-configcat/blob/main/docs/index.md
14
+ api:
15
+ base_url: https://api.configcat.com
16
+ base_url_env: CONFIGCAT_API_URL
17
+ auth: { basic: { user_env: CONFIGCAT_BASIC_AUTH_USERNAME, password_env: CONFIGCAT_BASIC_AUTH_PASSWORD } }
18
+ detect:
19
+ deps: [configcat-js, configcat-js-ssr, configcat-js-full, configcat-node, configcat-react]
20
+ env: ["CONFIGCAT_*"]
21
+ starter:
22
+ - op: targeting_rule
23
+ values: { match: "${ctx.scope}" }
24
+ where:
25
+ environment_id: "ConfigCat Dashboard → your product → Environments → the preview environment's ID"
26
+ setting_id: "ConfigCat Public Management API `GET /v1/configs/{configId}/settings`: the flag's `settingId`"
27
+ assumptions:
28
+ - id: CC1
29
+ verified: true
30
+ text: "The API is at `https://api.configcat.com`, authenticated with Basic auth from Public API credentials (the Terraform provider's `CONFIGCAT_BASIC_AUTH_USERNAME` / `CONFIGCAT_BASIC_AUTH_PASSWORD`)."
31
+ source: https://api.configcat.com/docs/v1/swagger.json
32
+ - id: CC2
33
+ verified: true
34
+ text: "`GET /v2/environments/{environmentId}/settings/{settingId}/value` answers the setting's value in the environment bare: `defaultValue`, `targetingRules`, `percentageEvaluationAttribute` and read-only fields."
35
+ source: https://api.configcat.com/docs/v1/swagger.json
36
+ - id: CC3
37
+ verified: true
38
+ text: "`PUT` on the same path replaces the value: only `defaultValue`, `targetingRules` and `percentageEvaluationAttribute` can be set, and one not sent is reset. So those three are sent, as read, with the rule list changed (`parent.send`)."
39
+ source: https://api.configcat.com/docs/v1/swagger.json
40
+ - id: CC4
41
+ verified: true
42
+ text: "A targeting rule is `{ conditions: [{ userCondition: { comparisonAttribute, comparator, comparisonValue: { stringValue, doubleValue, listValue: [{ value, hint }] } } }], value | percentageOptions }`; rules have no id and are evaluated in order. `isOneOf` and `sensitiveIsOneOf` compare a user attribute with a list."
43
+ source: https://api.configcat.com/docs/v1/swagger.json
44
+ - id: CC5
45
+ verified: true
46
+ text: "Answers carry every member of a value (`boolValue`, `stringValue`, `intValue`, `doubleValue`, `predefinedVariationId`) and of a comparison value, the unused ones null; the rule is written with the same nulls so that it reads back equal."
47
+ source: https://api.configcat.com/docs/v1/swagger.json
48
+ - id: CC6
49
+ verified: false
50
+ text: "A condition is read back with `segmentCondition` and `prerequisiteFlagCondition` null and each list value's `hint` null, exactly as written; otherwise every plan shows the rule as changed."
51
+ - id: CC7
52
+ verified: false
53
+ text: "In a product with \"Config changes require a reason\" or approvals turned on, the PUT without `reason` / `bypassApproval` is refused (the query parameters are not sent); the apply then fails."
54
+ source: https://api.configcat.com/docs/v1/swagger.json
55
+ ops:
56
+ targeting_rule:
57
+ kind: list_item
58
+ title: Feature flag targeting rule
59
+ summary: "A targeting rule on a boolean feature flag in one environment that serves a value to the preview, such as `IF Preview IS ONE OF [pr-42] THEN true`. Added after the flag's other rules (evaluated in order: an earlier matching rule wins); the default value and the other rules are written back as read. Identified by the matched value; a console edit of its condition or served value is drift. Destroy removes the rule."
60
+ covers: [configcat-rule]
61
+ params:
62
+ environment_id:
63
+ type: string
64
+ required: true
65
+ description: The environment's id (a UUID).
66
+ example: 08d8becf-d4d9-4c66-8b48-6ac74cd95fba
67
+ setting_id:
68
+ type: string
69
+ required: true
70
+ pattern: "^[0-9]+$"
71
+ description: The feature flag's numeric setting id.
72
+ example: "12345"
73
+ attribute:
74
+ type: string
75
+ required: true
76
+ description: The user attribute the rule compares (a custom attribute such as `Preview`, or `Identifier`, `Email`).
77
+ example: Preview
78
+ comparator:
79
+ type: string
80
+ default: isOneOf
81
+ enum: [isOneOf, sensitiveIsOneOf]
82
+ description: "`isOneOf`, or `sensitiveIsOneOf` (hashed in the config JSON)."
83
+ match:
84
+ type: string
85
+ required: true
86
+ description: The attribute value that is the preview; it identifies the rule.
87
+ example: "${ctx.scope}"
88
+ serve:
89
+ type: boolean
90
+ default: true
91
+ description: The value the flag serves to the preview.
92
+ http:
93
+ parent:
94
+ path: "/v2/environments/{environment_id}/settings/{setting_id}/value"
95
+ method: PUT
96
+ send: [defaultValue, percentageEvaluationAttribute]
97
+ list_path: /targetingRules
98
+ key_field: /conditions/0/userCondition/comparisonValue/listValue/0/value
99
+ item:
100
+ conditions:
101
+ - userCondition:
102
+ comparisonAttribute: { param: attribute }
103
+ comparator: { param: comparator }
104
+ comparisonValue:
105
+ stringValue: null
106
+ doubleValue: null
107
+ listValue: [{ value: { param: match }, hint: null }]
108
+ segmentCondition: null
109
+ prerequisiteFlagCondition: null
110
+ value:
111
+ boolValue: { param: serve }
112
+ stringValue: null
113
+ intValue: null
114
+ doubleValue: null
115
+ predefinedVariationId: null
116
+ sim:
117
+ objects:
118
+ "/v2/environments/{environment_id}/settings/{setting_id}/value":
119
+ defaultValue: { boolValue: false, stringValue: null, intValue: null, doubleValue: null, predefinedVariationId: null }
120
+ targetingRules: []
121
+ percentageEvaluationAttribute: null
122
+ live:
123
+ params: { environment_id: SPONSON_LIVE_CONFIGCAT_ENVIRONMENT_ID, setting_id: SPONSON_LIVE_CONFIGCAT_SETTING_ID }
@@ -0,0 +1,136 @@
1
+ # yaml-language-server: $schema=../../../schema/recipe.schema.json
2
+ # Datadog API recipes: every request carries the API key and the application key. Format and checklist:
3
+ # docs/adr/0020-recipes.md, CONTRIBUTING.md "Adding a recipe".
4
+ provider: datadog
5
+ title: Datadog
6
+ category: observability
7
+ verified_on: "2026-10-11"
8
+ docs:
9
+ - title: Synthetics API reference
10
+ url: https://docs.datadoghq.com/api/latest/synthetics/
11
+ - title: API authentication (keys, sites)
12
+ url: https://docs.datadoghq.com/api/latest/authentication/
13
+ - title: Datadog API v1 OpenAPI document (datadog-api-client)
14
+ url: https://github.com/DataDog/datadog-api-client-typescript/blob/master/.generator/schemas/v1/openapi.yaml
15
+ api:
16
+ base_url: https://api.datadoghq.com/api/v1
17
+ base_url_env: DATADOG_API_URL
18
+ auth:
19
+ headers:
20
+ - { header: DD-API-KEY, value_env: DD_API_KEY }
21
+ - { header: DD-APPLICATION-KEY, value_env: DD_APP_KEY }
22
+ detect:
23
+ deps: [dd-trace, "@datadog/"]
24
+ env: ["DD_*", "DATADOG_*"]
25
+ starter:
26
+ - op: synthetic_api_test
27
+ preview_url: url
28
+ values: { name: "preview ${ctx.scope}", locations: ["aws:us-east-2"] }
29
+ assumptions:
30
+ - id: DD1
31
+ verified: true
32
+ text: "Requests carry the API key in `DD-API-KEY` and the application key in `DD-APPLICATION-KEY`; Datadog's clients read them from `DD_API_KEY` and `DD_APP_KEY`. Reading needs the application key too."
33
+ source: https://github.com/DataDog/datadog-api-client-typescript/blob/master/.generator/schemas/v1/openapi.yaml
34
+ - id: DD2
35
+ verified: true
36
+ text: "Each Datadog site has its own API host (`https://api.datadoghq.eu`, `https://api.us3.datadoghq.com`, …): outside US1, set `base_url` in the provider block."
37
+ source: https://docs.datadoghq.com/api/latest/authentication/
38
+ - id: DD3
39
+ verified: true
40
+ text: "`POST /synthetics/tests/api` creates an API test from `name`, `type` (`api`), `config` (`request` with `method` and `url`, `assertions`), `locations`, `options` and `message` (all required), with `subtype` (`http`), `status` (`live` or `paused`) and `tags`, answering it with its `public_id`."
41
+ source: https://github.com/DataDog/datadog-api-client-typescript/blob/master/.generator/schemas/v1/openapi.yaml
42
+ - id: DD4
43
+ verified: true
44
+ text: "`GET /synthetics/tests/api/{public_id}` answers one API test; `PUT` on the same path replaces its configuration with a whole test definition."
45
+ source: https://github.com/DataDog/datadog-api-client-typescript/blob/master/.generator/schemas/v1/openapi.yaml
46
+ - id: DD5
47
+ verified: true
48
+ text: "`GET /synthetics/tests` lists every test as `{ tests: [...] }` (`page_size` and `page_number` are optional); `POST /synthetics/tests/delete` with `{ public_ids: [...] }` deletes tests."
49
+ source: https://github.com/DataDog/datadog-api-client-typescript/blob/master/.generator/schemas/v1/openapi.yaml
50
+ - id: DD6
51
+ verified: false
52
+ text: "Without `page_size` the list answers every test of the organisation, and a test name identifies one test (two with one name make `find` refuse with PARAM_INVALID)."
53
+ - id: DD7
54
+ verified: false
55
+ text: "The fields compared (`config.request`, `config.assertions`, `locations`, `options.tick_every`, `message`, `status`, `tags`) are answered as they were sent, in order."
56
+ - id: DD8
57
+ verified: false
58
+ text: "Deleting a test that is already gone answers 404 (destroy treats it as done)."
59
+ - id: DD9
60
+ verified: false
61
+ text: "Deployment events (`datadog-ci deployment mark`, the DORA deployments API) are not a recipe: they are listed with a POST over a time window and cannot be deleted, so a later run could not find the one it made."
62
+ ops:
63
+ synthetic_api_test:
64
+ kind: resource
65
+ title: Synthetic API test against a preview
66
+ summary: "A Synthetic HTTP test per scope that checks the preview's URL from Datadog's locations, such as `preview pr-42` asserting status 200, with its own monitor. Located by its name; a console edit of its request, assertions, locations, frequency, message, status or tags is drift; destroy deletes the test (and its monitor)."
67
+ covers: [datadog-marker]
68
+ params:
69
+ name:
70
+ type: string
71
+ required: true
72
+ description: The test's name; its identity (DD6).
73
+ example: "preview ${ctx.scope}"
74
+ url:
75
+ type: string
76
+ required: true
77
+ pattern: "^https?://\\S+$"
78
+ description: The URL to request (the preview's URL, or a health path on it).
79
+ example: "https://${ctx.scope}.preview.example.app/api/health"
80
+ method:
81
+ type: string
82
+ default: GET
83
+ enum: [GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS]
84
+ description: The HTTP method.
85
+ assertions:
86
+ type: list
87
+ default: [{ type: statusCode, operator: is, target: 200 }]
88
+ description: "The assertions, each `{ type, operator, target }` (`statusCode`, `responseTime`, `body`, `header`)."
89
+ locations:
90
+ type: list
91
+ required: true
92
+ description: "The managed locations to run from, such as `aws:us-east-2` or `aws:eu-central-1`."
93
+ example: ["aws:us-east-2"]
94
+ tick_every:
95
+ type: integer
96
+ default: 300
97
+ description: How often the test runs, in seconds.
98
+ message:
99
+ type: string
100
+ default: Preview check managed by Sponson
101
+ description: The notification message of the test's monitor.
102
+ status:
103
+ type: string
104
+ default: live
105
+ enum: [live, paused]
106
+ description: "`paused` keeps the test without running it."
107
+ tags:
108
+ type: list
109
+ default: ["managed-by:sponson"]
110
+ description: The test's tags.
111
+ http:
112
+ find:
113
+ path: /synthetics/tests
114
+ list_path: /tests
115
+ match: { name: { param: name } }
116
+ read: { path: "/synthetics/tests/api/{id}" }
117
+ create:
118
+ path: /synthetics/tests/api
119
+ body: { type: api, subtype: http }
120
+ update:
121
+ method: PUT
122
+ body: { type: api, subtype: http }
123
+ delete:
124
+ method: POST
125
+ path: /synthetics/tests/delete
126
+ body: { public_ids: ["{id}"] }
127
+ id_path: /public_id
128
+ fields:
129
+ /config/request/method: { param: method }
130
+ /config/request/url: { param: url }
131
+ /config/assertions: { param: assertions }
132
+ locations: { param: locations }
133
+ /options/tick_every: { param: tick_every }
134
+ message: { param: message }
135
+ status: { param: status }
136
+ tags: { param: tags }
@@ -0,0 +1,84 @@
1
+ # yaml-language-server: $schema=../../../schema/recipe.schema.json
2
+ # Firebase Authentication (Identity Toolkit admin API) recipes. Format and checklist: docs/adr/0020-recipes.md,
3
+ # CONTRIBUTING.md "Adding a recipe".
4
+ provider: firebase
5
+ title: Firebase Authentication
6
+ category: auth
7
+ verified_on: "2026-10-11"
8
+ docs:
9
+ - title: Identity Toolkit API v2, projects.getConfig
10
+ url: https://docs.cloud.google.com/identity-platform/docs/reference/rest/v2/projects/getConfig
11
+ - title: Identity Toolkit API v2, projects.updateConfig
12
+ url: https://docs.cloud.google.com/identity-platform/docs/reference/rest/v2/projects/updateConfig
13
+ - title: Identity Toolkit API v2, Config
14
+ url: https://docs.cloud.google.com/identity-platform/docs/reference/rest/v2/Config
15
+ - title: Authenticate for using REST
16
+ url: https://docs.cloud.google.com/docs/authentication/rest
17
+ api:
18
+ base_url: https://identitytoolkit.googleapis.com/admin/v2
19
+ base_url_env: FIREBASE_API_URL
20
+ auth: { command: [gcloud, auth, print-access-token] }
21
+ detect:
22
+ deps: [firebase, firebase-admin]
23
+ env: ["FIREBASE_*"]
24
+ files: [firebase.json, .firebaserc]
25
+ starter:
26
+ - op: authorized_domain
27
+ where:
28
+ project: "`projects.default` in .firebaserc, or `firebase projects:list`"
29
+ domain: "the preview's host name without `https://` (Firebase takes a domain, so a `{ from }` URL cannot be used)"
30
+ assumptions:
31
+ - id: FB1
32
+ verified: true
33
+ text: "`GET https://identitytoolkit.googleapis.com/admin/v2/projects/{project}/config` answers the project's Auth `Config`."
34
+ source: https://docs.cloud.google.com/identity-platform/docs/reference/rest/v2/projects/getConfig
35
+ - id: FB2
36
+ verified: true
37
+ text: "`PATCH …/admin/v2/projects/{project}/config?updateMask=authorizedDomains` updates the config with a `Config` body; fields set in the body but not named in `updateMask` are ignored, so the write changes the authorized domains only. It needs one of the `identitytoolkit`, `firebase` or `cloud-platform` OAuth scopes."
38
+ source: https://docs.cloud.google.com/identity-platform/docs/reference/rest/v2/projects/updateConfig
39
+ - id: FB3
40
+ verified: true
41
+ text: "`authorizedDomains` is a list of strings, the domains authorized for OAuth redirects; the masked field is replaced by the list sent, so the recipe sends the whole list read just before with one domain added or removed."
42
+ source: https://docs.cloud.google.com/identity-platform/docs/reference/rest/v2/Config
43
+ - id: FB4
44
+ verified: true
45
+ text: "`gcloud auth print-access-token` prints an access token for the signed-in credentials, used as `Authorization: Bearer`. With user credentials some APIs also need the quota project in `x-goog-user-project`: add `headers: { x-goog-user-project: <project> }` to the `providers.http.firebase` block (not needed with a service account; a block's headers are part of its identity)."
46
+ source: https://docs.cloud.google.com/docs/authentication/rest
47
+ - id: FB5
48
+ verified: false
49
+ text: "The config has no precondition the update honours (no etag in `Config`): the line locks the project's config (`lockOn`) against other Sponson runs; a console edit made between the read and the write can still be lost."
50
+ - id: FB6
51
+ verified: false
52
+ text: "An authorized domain is a host name without scheme, port or path, and is read back exactly as written."
53
+ - id: FB7
54
+ verified: false
55
+ text: "The same admin v2 config holds the authorized domains of a Firebase Authentication project with or without the Identity Platform upgrade."
56
+ ops:
57
+ authorized_domain:
58
+ kind: list_item
59
+ title: Authorized domain
60
+ summary: "One domain in Firebase Authentication's authorized domains (Authentication, Settings, Authorized domains), which OAuth sign-in redirects and email links require, such as the preview deployment's host. Read-modify-write of the list with `updateMask=authorizedDomains` under a lock on the project's config; removed on destroy; every other domain (localhost, the Firebase hosting domains) is left as it is."
61
+ covers: [firebase-auth-domains]
62
+ params:
63
+ project:
64
+ type: string
65
+ required: true
66
+ description: The Google Cloud / Firebase project id.
67
+ example: demo-project
68
+ domain:
69
+ type: string
70
+ required: true
71
+ pattern: "^[A-Za-z0-9.-]+$"
72
+ description: "The domain, a host name without scheme or path (`pr-42.preview.example.app`, `my-app-git-feat-x.vercel.app`)."
73
+ example: "${ctx.scope}.preview.example.app"
74
+ http:
75
+ parent:
76
+ path: "/projects/{project}/config?updateMask=authorizedDomains"
77
+ read_path: "/projects/{project}/config"
78
+ list_path: /authorizedDomains
79
+ item: { param: domain }
80
+ sim:
81
+ objects:
82
+ "/projects/{project}/config": { name: projects/demo-project/config, authorizedDomains: [localhost, demo-project.firebaseapp.com, demo-project.web.app] }
83
+ live:
84
+ params: { project: SPONSON_LIVE_FIREBASE_PROJECT }
@@ -0,0 +1,98 @@
1
+ # yaml-language-server: $schema=../../../schema/recipe.schema.json
2
+ # Flagsmith Admin (management) API recipes, authenticated by an organisation API key. Format and checklist:
3
+ # docs/adr/0020-recipes.md, CONTRIBUTING.md "Adding a recipe".
4
+ provider: flagsmith
5
+ title: Flagsmith
6
+ category: flags
7
+ verified_on: "2026-10-11"
8
+ docs:
9
+ - title: Admin API authentication
10
+ url: https://docs.flagsmith.com/integrating-with-flagsmith/flagsmith-api-overview/admin-api/authentication
11
+ - title: Admin API overview
12
+ url: https://docs.flagsmith.com/integrating-with-flagsmith/flagsmith-api-overview/admin-api
13
+ - title: Flagsmith API OpenAPI document
14
+ url: https://api.flagsmith.com/api/v1/swagger.json
15
+ api:
16
+ base_url: https://api.flagsmith.com/api/v1
17
+ base_url_env: FLAGSMITH_API_URL
18
+ auth: { header: Authorization, value_env: FLAGSMITH_MASTER_API_KEY, prefix: "Api-Key " }
19
+ detect:
20
+ deps: [flagsmith, flagsmith-nodejs, react-native-flagsmith]
21
+ env: ["FLAGSMITH_*"]
22
+ starter:
23
+ - op: environment
24
+ values: { name: "preview-${ctx.scope}" }
25
+ where:
26
+ project_id: "Flagsmith → your project: the number in its URL (`/project/<id>/…`)"
27
+ assumptions:
28
+ - id: FS1
29
+ verified: true
30
+ text: "The Admin API authenticates with an organisation API key as `Authorization: Api-Key <key>`; Bearer is only for short-lived OIDC-exchanged tokens."
31
+ source: https://docs.flagsmith.com/integrating-with-flagsmith/flagsmith-api-overview/admin-api/authentication
32
+ - id: FS2
33
+ verified: true
34
+ text: "`POST /environments/` creates an environment from `name` and `project` (both required) and optional `description`, answering it (201) with its integer `id` and its `api_key`, the client-side environment key SDKs use."
35
+ source: https://api.flagsmith.com/api/v1/swagger.json
36
+ - id: FS3
37
+ verified: true
38
+ text: "`GET /environments/?project=<id>` lists a project's environments as `{ count, next, previous, results: [...] }`."
39
+ source: https://api.flagsmith.com/api/v1/swagger.json
40
+ - id: FS4
41
+ verified: true
42
+ text: "`GET`, `PATCH` and `DELETE /environments/{api_key}/` read, update and delete one environment (DELETE answers 204)."
43
+ source: https://api.flagsmith.com/api/v1/swagger.json
44
+ - id: FS5
45
+ verified: false
46
+ text: "A project has fewer environments than one page of the list holds, so `find` sees them all (`next` is a URL, which the http adapter does not follow)."
47
+ - id: FS6
48
+ verified: false
49
+ text: "A new environment starts with every feature of the project at its default state, and environment names are unique in a project in practice (two with one name make `find` refuse with PARAM_INVALID)."
50
+ - id: FS7
51
+ verified: false
52
+ text: "`description` is answered as sent; `FLAGSMITH_MASTER_API_KEY` is the variable Flagsmith's Terraform provider reads the key from."
53
+ - id: FS8
54
+ verified: false
55
+ text: "Identity and segment overrides are not recipes: Edge projects (Flagsmith SaaS's default) address identities by UUID through `edge-identities`, and a segment override is two objects (a feature segment, then a feature state) created in order."
56
+ - id: FS9
57
+ verified: false
58
+ text: "The create takes the project id as a string of digits (`\"1234\"`) as well as a number, as Django REST Framework's primary-key fields do."
59
+ ops:
60
+ environment:
61
+ kind: resource
62
+ title: Environment per preview
63
+ summary: "A Flagsmith environment per scope in a project, such as `preview-pr-42`, starting from the project's default flag states; its client-side environment key is the output `api_key` for the preview's SDK configuration. Located by name in the project; a console edit of its description is drift; destroy deletes the environment with its flag states and identities."
64
+ covers: [flagsmith-override]
65
+ params:
66
+ project_id:
67
+ type: string
68
+ required: true
69
+ pattern: "^[0-9]+$"
70
+ description: The project's id, digits as a string (FS9).
71
+ example: "1234"
72
+ name:
73
+ type: string
74
+ required: true
75
+ description: The environment's name; its identity in the project (FS6).
76
+ example: "preview-${ctx.scope}"
77
+ description:
78
+ type: string
79
+ default: Preview environment managed by Sponson
80
+ description: The environment's description.
81
+ http:
82
+ find:
83
+ path: "/environments/?project={project_id}"
84
+ list_path: /results
85
+ match: { name: { param: name } }
86
+ read: { path: "/environments/{id}/" }
87
+ create:
88
+ path: /environments/
89
+ body: { project: { param: project_id } }
90
+ update: { method: PATCH }
91
+ id_path: /api_key
92
+ fields:
93
+ description: { param: description }
94
+ outputs:
95
+ api_key: /api_key
96
+ environment_id: /id
97
+ live:
98
+ params: { project_id: SPONSON_LIVE_FLAGSMITH_PROJECT_ID }