@faable/deploy-sdk 2.16.0 → 2.17.1

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@faable/deploy-sdk",
3
3
  "description": "Codebase for SDK building",
4
- "version": "2.16.0",
4
+ "version": "2.17.1",
5
5
  "author": "Marc Pomar <marc@faable.com>",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
package/spec/openapi.json CHANGED
@@ -856,6 +856,9 @@
856
856
  "type": "string"
857
857
  }
858
858
  }
859
+ },
860
+ "dockerfile_ignored": {
861
+ "type": "boolean"
859
862
  }
860
863
  }
861
864
  },
@@ -963,6 +966,17 @@
963
966
  ],
964
967
  "description": "Success deploy emails (first deploy + every promote). Absent/null = enabled; false = muted. Failure emails are never gated by this."
965
968
  },
969
+ "http3": {
970
+ "anyOf": [
971
+ {
972
+ "type": "boolean"
973
+ },
974
+ {
975
+ "type": "null"
976
+ }
977
+ ],
978
+ "description": "Whether HTTP/3 is advertised for this app. Absent/null = advertised; false = not advertised. Note it controls the advertisement, not the listener: clients that already discovered HTTP/3 may keep using it until the advertisement expires, and the server does not refuse it."
979
+ },
966
980
  "status": {
967
981
  "$ref": "#/components/schemas/AppStatus"
968
982
  },
@@ -1162,14 +1176,14 @@
1162
1176
  "type": "string"
1163
1177
  },
1164
1178
  "notify_deploy_success": {
1165
- "anyOf": [
1166
- {
1167
- "type": "boolean"
1168
- },
1169
- {
1170
- "type": "null"
1171
- }
1172
- ]
1179
+ "type": "boolean",
1180
+ "nullable": true,
1181
+ "default": null
1182
+ },
1183
+ "http3": {
1184
+ "type": "boolean",
1185
+ "nullable": true,
1186
+ "default": null
1173
1187
  }
1174
1188
  },
1175
1189
  "additionalProperties": false
@@ -1184,9 +1198,19 @@
1184
1198
  "type": "boolean"
1185
1199
  },
1186
1200
  "code": {
1187
- "type": "string",
1188
- "enum": [
1189
- "repository_already_linked"
1201
+ "anyOf": [
1202
+ {
1203
+ "type": "string",
1204
+ "enum": [
1205
+ "repository_already_linked"
1206
+ ]
1207
+ },
1208
+ {
1209
+ "type": "string",
1210
+ "enum": [
1211
+ "repository_taken_down"
1212
+ ]
1213
+ }
1190
1214
  ]
1191
1215
  },
1192
1216
  "message": {
@@ -1690,6 +1714,76 @@
1690
1714
  "type": "boolean"
1691
1715
  }
1692
1716
  }
1717
+ },
1718
+ "images": {
1719
+ "type": "object",
1720
+ "properties": {
1721
+ "deviceSizes": {
1722
+ "type": "array",
1723
+ "items": {
1724
+ "type": "integer",
1725
+ "minimum": 1,
1726
+ "maximum": 16384
1727
+ },
1728
+ "maxItems": 256
1729
+ },
1730
+ "imageSizes": {
1731
+ "type": "array",
1732
+ "items": {
1733
+ "type": "integer",
1734
+ "minimum": 1,
1735
+ "maximum": 16384
1736
+ },
1737
+ "maxItems": 256
1738
+ },
1739
+ "formats": {
1740
+ "type": "array",
1741
+ "items": {
1742
+ "type": "string",
1743
+ "maxLength": 64
1744
+ },
1745
+ "maxItems": 8
1746
+ },
1747
+ "qualities": {
1748
+ "type": "array",
1749
+ "items": {
1750
+ "type": "integer",
1751
+ "minimum": 1,
1752
+ "maximum": 100
1753
+ },
1754
+ "maxItems": 100
1755
+ },
1756
+ "minimumCacheTTL": {
1757
+ "type": "integer",
1758
+ "minimum": 0
1759
+ },
1760
+ "unoptimized": {
1761
+ "type": "boolean"
1762
+ },
1763
+ "loader": {
1764
+ "type": "string",
1765
+ "maxLength": 64
1766
+ },
1767
+ "path": {
1768
+ "type": "string",
1769
+ "maxLength": 512
1770
+ },
1771
+ "basePath": {
1772
+ "type": "string",
1773
+ "maxLength": 512
1774
+ },
1775
+ "assetPrefix": {
1776
+ "type": "boolean"
1777
+ },
1778
+ "dangerouslyAllowSVG": {
1779
+ "type": "boolean"
1780
+ },
1781
+ "remotePatterns": {
1782
+ "type": "integer",
1783
+ "minimum": 0
1784
+ }
1785
+ },
1786
+ "additionalProperties": false
1693
1787
  }
1694
1788
  }
1695
1789
  },
@@ -1719,6 +1813,9 @@
1719
1813
  "type": "string"
1720
1814
  }
1721
1815
  }
1816
+ },
1817
+ "dockerfile_ignored": {
1818
+ "type": "boolean"
1722
1819
  }
1723
1820
  }
1724
1821
  },
@@ -1941,6 +2038,11 @@
1941
2038
  },
1942
2039
  "detected": {
1943
2040
  "$ref": "#/components/schemas/DeploymentDetected"
2041
+ },
2042
+ "plan": {
2043
+ "type": "object",
2044
+ "properties": {},
2045
+ "additionalProperties": true
1944
2046
  }
1945
2047
  }
1946
2048
  },
@@ -1949,8 +2051,11 @@
1949
2051
  "required": [
1950
2052
  "dns_state",
1951
2053
  "dns_checked_at",
2054
+ "dns_last_seen_at",
2055
+ "dns_error_kind",
1952
2056
  "dns_expected",
1953
2057
  "dns_observed",
2058
+ "dns_expected_ips",
1954
2059
  "dns_message",
1955
2060
  "dns_warning"
1956
2061
  ],
@@ -1966,11 +2071,28 @@
1966
2071
  "default": "pending"
1967
2072
  },
1968
2073
  "dns_checked_at": {
2074
+ "type": "string",
2075
+ "description": "ISO timestamp of the last DNS change",
2076
+ "nullable": true,
2077
+ "default": null
2078
+ },
2079
+ "dns_last_seen_at": {
1969
2080
  "type": "string",
1970
2081
  "description": "ISO timestamp of the last DNS check",
1971
2082
  "nullable": true,
1972
2083
  "default": null
1973
2084
  },
2085
+ "dns_error_kind": {
2086
+ "type": "string",
2087
+ "enum": [
2088
+ "transient",
2089
+ "proxy",
2090
+ null
2091
+ ],
2092
+ "description": "Why an `error` verdict could not conclude",
2093
+ "nullable": true,
2094
+ "default": null
2095
+ },
1974
2096
  "dns_expected": {
1975
2097
  "type": "array",
1976
2098
  "items": {
@@ -1987,6 +2109,14 @@
1987
2109
  "description": "CNAME target(s) actually resolved for the fqdn",
1988
2110
  "default": []
1989
2111
  },
2112
+ "dns_expected_ips": {
2113
+ "type": "array",
2114
+ "items": {
2115
+ "type": "string"
2116
+ },
2117
+ "description": "IPv4 address(es) the expected target currently resolves to",
2118
+ "default": []
2119
+ },
1990
2120
  "dns_message": {
1991
2121
  "type": "string",
1992
2122
  "description": "Human-readable diagnostic of the DNS check",
@@ -3672,6 +3802,12 @@
3672
3802
  "enum": [
3673
3803
  "buildkit"
3674
3804
  ]
3805
+ },
3806
+ {
3807
+ "type": "string",
3808
+ "enum": [
3809
+ "detector"
3810
+ ]
3675
3811
  }
3676
3812
  ]
3677
3813
  },
@@ -4020,6 +4156,12 @@
4020
4156
  "enum": [
4021
4157
  "buildkit"
4022
4158
  ]
4159
+ },
4160
+ {
4161
+ "type": "string",
4162
+ "enum": [
4163
+ "detector"
4164
+ ]
4023
4165
  }
4024
4166
  ]
4025
4167
  },
@@ -4264,7 +4406,7 @@
4264
4406
  },
4265
4407
  "ApiErrorCode": {
4266
4408
  "type": "string",
4267
- "description": "Machine-readable error code. One HTTP status per code.\n\n- `bad_request` (400): The request is malformed. `message` says what is wrong.\n- `validation_error` (400): The body, query or path failed schema validation. `details.issues` lists each failing field.\n- `unauthorized` (401): The request carries no valid credentials.\n- `payment_required` (402): The feature is not included in the current plan.\n- `forbidden` (403): The credentials are valid but do not allow this operation.\n- `not_found` (404): The resource does not exist, or not in the caller’s project.\n- `method_not_allowed` (405): The HTTP method is not supported on this path.\n- `conflict` (409): The request conflicts with the current state of the resource.\n- `payload_too_large` (413): The request body exceeds the size limit.\n- `unsupported_media_type` (415): The `Content-Type` is not accepted by this endpoint.\n- `unprocessable_entity` (422): The request is well-formed but cannot be processed.\n- `too_many_requests` (429): Rate limit exceeded. Honour the `Retry-After` header.\n- `internal_error` (500): Unexpected server error. Retry later; the request id is logged.\n- `gone` (410): The resource existed and is gone for good; retrying will not bring it back.\n- `bad_gateway` (502): An upstream the API depends on failed.\n- `service_unavailable` (503): The feature is not configured on this environment, or is temporarily out of service.\n- `already_exists` (400): A resource with the same unique field already exists. `details.fields` names the field.\n- `invalid_id` (400): The id in the path is not a valid id for this resource.\n- `invalid_query` (400): The `?query=` FaableQL expression could not be parsed.\n- `invalid_expand` (400): An `?expand=` path is not allowed on this resource.\n- `search_not_supported` (400): This resource does not support `?q=`.\n- `access_denied` (401): The row exists but does not belong to the caller.\n- `invalid_token` (401): The bearer token is missing, malformed or expired.\n- `invalid_apikey` (401): The API key does not exist or has been revoked.\n- `apikey_expired` (401): The API key predates projects and must be recreated.\n- `invalid_build_token` (401): The build token is not valid for this deployment.\n- `build_token_expired` (401): The build token is past its lifetime.\n- `build_token_unusable` (401): The deployment reached a terminal phase, so its build token no longer works.\n- `build_token_app_missing` (401): The app the build token was minted for no longer exists.\n- `user_token_required` (401): The endpoint acts on behalf of a person and the credential carries no user (an API key or a service account).\n- `team_required` (400): The operation needs a project: send it in the `x-faable-team` header.\n- `team_or_scope_required` (401): Listing needs either a project in `x-faable-team` or a global scope on the token.\n- `user_suspended` (403): The account is suspended. Contact support@faable.com.\n- `superadmin_only` (403): The operation is restricted to platform staff.\n- `project_not_found` (404): No project with that id for this caller.\n- `owner_only` (403): Only the project owner can manage collaborators.\n- `owner_not_removable` (400): The project owner cannot be removed. Delete the project instead.\n- `collaborator_not_found` (404): That user is not a collaborator on the project.\n- `invalid_project_name` (400): The project name is not acceptable. `message` says why.\n- `moderation_hold` (403): The project contains an app disabled by moderation and cannot be deleted. Contact support@faable.com.\n- `app_not_found` (404): No app with that id or slug in this project.\n- `repository_not_linked` (400): The app has no linked repository.\n- `repository_empty` (400): The repository has no commits on the deploy branch yet.\n- `branch_missing` (400): The deploy branch does not exist on the repository. `message` lists the branches that do.\n- `deploy_mode_conflict` (400): The app deploys from its own workflow, so the platform will not create a deployment for it.\n- `deploy_refused` (409): The deploy was refused by quota, plan or an in-flight deployment. `message` says which.\n- `invalid_root_dir` (400): The Root Directory must be a path inside the repository — no leading `/` and no `..`.\n- `root_dir_not_found` (400): The Root Directory does not exist on that ref of the repository.\n- `root_dir_mismatch` (400): The workflow deploys from one directory and platform builds would run from another. Declare `rootDir` in faable.json.\n- `no_workflows` (400): The repository has no GitHub Actions workflows, so a CI gate would never open.\n- `no_deploy_workflow` (400): No workflow in the repository runs `faable deploy`.\n- `invalid_secret_name` (400): Secret names are 1-255 printable ASCII characters and cannot contain '='.\n- `invalid_secret_context` (400): Secrets are scoped to an app or to a profile, nothing else.\n- `app_secrets_only` (400): Only app secrets can be written in bulk.\n- `secrets_access_denied` (401): The caller may not read or write the secrets of that app or profile.\n- `status_forbidden_resource` (403): Only a platform service writes app or domain status.\n- `status_forbidden_field` (403): That field of a deployment status is platform bookkeeping. `message` names it.\n- `status_forbidden_phase` (403): That phase is set by the platform, not by the client.\n- `github_identity_missing` (412): The user has not connected GitHub. Send them through `connect_github`.\n- `github_installation_missing` (412): The Faable GitHub App is not installed on any repository of theirs.\n- `github_repository_not_found` (404): The repository does not exist or the installation cannot see it.\n- `github_token_invalid` (401): The stored GitHub token was rejected; the user must reconnect.\n- `github_permission_denied` (403): The installation lacks a permission this operation needs.\n- `github_installation_suspended` (403): The GitHub App installation is suspended.\n- `github_installation_not_found` (412): The installation id is unknown or the App was uninstalled.\n- `github_repository_blocked` (403): GitHub refuses to serve the source of that repository (403 or 451).\n- `github_error` (502): GitHub failed upstream. `message` carries what it said.\n- `repository_already_linked` (409): The repository is already linked to another app. `details.app_id` / `details.app_name` name it.\n- `invalid_installation_id` (400): The `installation_id` is not a number.\n- `oidc_untrusted` (401): The GitHub Actions OIDC token was rejected. `message` says why.\n- `app_repository_mismatch` (403): The app does not exist or is not linked to the repository the token comes from.\n- `no_app_for_repository` (404): No app is linked to that repository.\n- `ambiguous_app_for_repository` (400): Several apps are linked to that repository; pass `--app-slug`.\n- `app_disabled` (409): The app is disabled, so it cannot be deployed or provisioned. `message` says why when the reason is public.\n- `app_rate_limited` (429): A new account may only create a few apps in its first 24 hours.\n- `plan_required` (403): The build or feature needs a higher plan. `message` says which.\n- `remote_build_disabled` (409): Remote builds are off for this environment or this app. Deploy with a local build instead.\n- `artifact_deploy_disabled` (409): Artifact deploys are not enabled on this environment.\n- `artifact_too_large` (413): The artifact exceeds the size allowed for the plan.\n- `metrics_unavailable` (503): Traffic metrics are temporarily unavailable — this is not an app with no traffic.\n- `transfer_refused` (409): The app cannot be moved to that project. `message` lists the blockers.\n- `user_not_found` (400): No user with that id in Faable Auth.\n- `waf_rule_not_found` (404): No WAF rule with that pattern on this app.\n- `project_rate_limited` (429): A new account may only create a few projects in its first hours. It opens with time, or with a plan.\n- `project_plan_limited` (402): The Free plan project cap is reached. Upgrade to create more.\n- `domain_invalid` (400): Not a valid hostname. No protocol, port or path.\n- `domain_reserved` (403): Hostnames under that domain are assigned by Faable.\n- `domain_taken` (409): That hostname is already registered on Faable.\n- `invalid_json` (400): The request body is not valid JSON.\n- `missing_github_event` (400): The `x-github-event` header is missing.",
4409
+ "description": "Machine-readable error code. One HTTP status per code.\n\n- `bad_request` (400): The request is malformed. `message` says what is wrong.\n- `validation_error` (400): The body, query or path failed schema validation. `details.issues` lists each failing field.\n- `unauthorized` (401): The request carries no valid credentials.\n- `payment_required` (402): The feature is not included in the current plan.\n- `forbidden` (403): The credentials are valid but do not allow this operation.\n- `not_found` (404): The resource does not exist, or not in the caller’s project.\n- `method_not_allowed` (405): The HTTP method is not supported on this path.\n- `conflict` (409): The request conflicts with the current state of the resource.\n- `payload_too_large` (413): The request body exceeds the size limit.\n- `unsupported_media_type` (415): The `Content-Type` is not accepted by this endpoint.\n- `unprocessable_entity` (422): The request is well-formed but cannot be processed.\n- `too_many_requests` (429): Rate limit exceeded. Honour the `Retry-After` header.\n- `internal_error` (500): Unexpected server error. Retry later; the request id is logged.\n- `gone` (410): The resource existed and is gone for good; retrying will not bring it back.\n- `bad_gateway` (502): An upstream the API depends on failed.\n- `service_unavailable` (503): The feature is not configured on this environment, or is temporarily out of service.\n- `already_exists` (400): A resource with the same unique field already exists. `details.fields` names the field.\n- `invalid_id` (400): The id in the path is not a valid id for this resource.\n- `invalid_query` (400): The `?query=` FaableQL expression could not be parsed.\n- `invalid_expand` (400): An `?expand=` path is not allowed on this resource.\n- `search_not_supported` (400): This resource does not support `?q=`.\n- `access_denied` (401): The row exists but does not belong to the caller.\n- `invalid_token` (401): The bearer token is missing, malformed or expired.\n- `invalid_apikey` (401): The API key does not exist or has been revoked.\n- `apikey_expired` (401): The API key predates projects and must be recreated.\n- `invalid_build_token` (401): The build token is not valid for this deployment.\n- `build_token_expired` (401): The build token is past its lifetime.\n- `build_token_unusable` (401): The deployment reached a terminal phase, so its build token no longer works.\n- `build_token_app_missing` (401): The app the build token was minted for no longer exists.\n- `user_token_required` (401): The endpoint acts on behalf of a person and the credential carries no user (an API key or a service account).\n- `team_required` (400): The operation needs a project: send it in the `x-faable-project` header (`project_<id>`).\n- `team_or_scope_required` (401): Listing needs either a project in the `x-faable-project` header or a global scope on the token.\n- `project_access_denied` (403): The caller is not a member of the project named in `x-faable-project`, or the credential belongs to another project.\n- `project_header_conflict` (400): The request names two different projects (`x-faable-project` and the deprecated `x-faable-team`, or a query param). Send only `x-faable-project`.\n- `invalid_project_id` (400): The project in `x-faable-project` is not a valid project id (`project_` followed by 24 hex characters).\n- `user_suspended` (403): The account is suspended. Contact support@faable.com.\n- `superadmin_only` (403): The operation is restricted to platform staff.\n- `project_not_found` (404): No project with that id for this caller.\n- `owner_only` (403): Only the project owner can manage collaborators.\n- `owner_not_removable` (400): The project owner cannot be removed. Delete the project instead.\n- `collaborator_not_found` (404): That user is not a collaborator on the project.\n- `invalid_project_name` (400): The project name is not acceptable. `message` says why.\n- `moderation_hold` (403): The project contains an app disabled by moderation and cannot be deleted. Contact support@faable.com.\n- `app_not_found` (404): No app with that id or slug in this project.\n- `repository_not_linked` (400): The app has no linked repository.\n- `repository_empty` (400): The repository has no commits on the deploy branch yet.\n- `branch_missing` (400): The deploy branch does not exist on the repository. `message` lists the branches that do.\n- `deploy_mode_conflict` (400): The app deploys from its own workflow, so the platform will not create a deployment for it.\n- `deploy_refused` (409): The deploy was refused by quota, plan or an in-flight deployment. `message` says which.\n- `invalid_root_dir` (400): The Root Directory must be a path inside the repository — no leading `/` and no `..`.\n- `root_dir_not_found` (400): The Root Directory does not exist on that ref of the repository.\n- `root_dir_mismatch` (400): The workflow deploys from one directory and platform builds would run from another. Declare `rootDir` in faable.json.\n- `no_workflows` (400): The repository has no GitHub Actions workflows, so a CI gate would never open.\n- `no_deploy_workflow` (400): No workflow in the repository runs `faable deploy`.\n- `invalid_secret_name` (400): Secret names are 1-255 printable ASCII characters and cannot contain '='.\n- `invalid_secret_context` (400): Secrets are scoped to an app or to a profile, nothing else.\n- `app_secrets_only` (400): Only app secrets can be written in bulk.\n- `secrets_access_denied` (401): The caller may not read or write the secrets of that app or profile.\n- `status_forbidden_resource` (403): Only a platform service writes app or domain status.\n- `status_forbidden_field` (403): That field of a deployment status is platform bookkeeping. `message` names it.\n- `status_forbidden_phase` (403): That phase is set by the platform, not by the client.\n- `github_identity_missing` (412): The user has not connected GitHub. Send them through `connect_github`.\n- `github_installation_missing` (412): The Faable GitHub App is not installed on any repository of theirs.\n- `github_repository_not_found` (404): The repository does not exist or the installation cannot see it.\n- `github_token_invalid` (401): The stored GitHub token was rejected; the user must reconnect.\n- `github_permission_denied` (403): The installation lacks a permission this operation needs.\n- `github_installation_suspended` (403): The GitHub App installation is suspended.\n- `github_installation_not_found` (412): The installation id is unknown or the App was uninstalled.\n- `github_repository_blocked` (403): GitHub refuses to serve the source of that repository (403 or 451).\n- `github_rate_limited` (429): GitHub is rate-limiting Faable. Transient: retry after a short wait.\n- `github_token_refresh_failed` (401): GitHub refused to refresh the stored authorization. The user has to reconnect.\n- `github_error` (502): GitHub failed upstream. `message` carries what it said.\n- `repository_already_linked` (409): The repository is already linked to another app. `details.app_id` / `details.app_name` name it.\n- `repository_taken_down` (409): An app built from this repository was taken down for abuse, so the repository cannot be linked again. Not a plan limit — upgrading does not lift it. Restoring the taken-down app does.\n- `invalid_installation_id` (400): The `installation_id` is not a number.\n- `oidc_untrusted` (401): The GitHub Actions OIDC token was rejected. `message` says why.\n- `app_repository_mismatch` (403): The app does not exist or is not linked to the repository the token comes from.\n- `no_app_for_repository` (404): No app is linked to that repository.\n- `ambiguous_app_for_repository` (400): Several apps are linked to that repository; pass `--app-slug`.\n- `app_disabled` (409): The app is disabled, so it cannot be deployed or provisioned. `message` says why when the reason is public.\n- `app_rate_limited` (429): A new account may only create a few apps in its first 24 hours.\n- `plan_required` (403): The build or feature needs a higher plan. `message` says which.\n- `remote_build_disabled` (409): Remote builds are off for this environment or this app. Deploy with a local build instead.\n- `artifact_deploy_disabled` (409): Artifact deploys are not enabled on this environment.\n- `artifact_too_large` (413): The artifact exceeds the size allowed for the plan.\n- `metrics_unavailable` (503): Traffic metrics are temporarily unavailable — this is not an app with no traffic.\n- `transfer_refused` (409): The app cannot be moved to that project. `message` lists the blockers.\n- `user_not_found` (400): No user with that id in Faable Auth.\n- `waf_rule_not_found` (404): No WAF rule with that pattern on this app.\n- `project_rate_limited` (429): A new account may only create a few projects in its first hours. It opens with time, or with a plan.\n- `project_plan_limited` (402): The Free plan project cap is reached. Upgrade to create more.\n- `domain_invalid` (400): Not a valid hostname. No protocol, port or path.\n- `domain_reserved` (403): Hostnames under that domain are assigned by Faable.\n- `domain_taken` (409): That hostname is already registered on Faable.\n- `invalid_json` (400): The request body is not valid JSON.\n- `missing_github_event` (400): The `x-github-event` header is missing.",
4268
4410
  "enum": [
4269
4411
  "bad_request",
4270
4412
  "validation_error",
@@ -4298,6 +4440,9 @@
4298
4440
  "user_token_required",
4299
4441
  "team_required",
4300
4442
  "team_or_scope_required",
4443
+ "project_access_denied",
4444
+ "project_header_conflict",
4445
+ "invalid_project_id",
4301
4446
  "user_suspended",
4302
4447
  "superadmin_only",
4303
4448
  "project_not_found",
@@ -4332,8 +4477,11 @@
4332
4477
  "github_installation_suspended",
4333
4478
  "github_installation_not_found",
4334
4479
  "github_repository_blocked",
4480
+ "github_rate_limited",
4481
+ "github_token_refresh_failed",
4335
4482
  "github_error",
4336
4483
  "repository_already_linked",
4484
+ "repository_taken_down",
4337
4485
  "invalid_installation_id",
4338
4486
  "oidc_untrusted",
4339
4487
  "app_repository_mismatch",
@@ -5134,7 +5282,7 @@
5134
5282
  }
5135
5283
  },
5136
5284
  "401": {
5137
- "description": "`team_or_scope_required` — Listing needs either a project in `x-faable-team` or a global scope on the token.\n\n`unauthorized` — The request carries no valid credentials.\n\n`invalid_token` — The bearer token is missing, malformed or expired.",
5285
+ "description": "`team_or_scope_required` — Listing needs either a project in the `x-faable-project` header or a global scope on the token.\n\n`unauthorized` — The request carries no valid credentials.\n\n`invalid_token` — The bearer token is missing, malformed or expired.",
5138
5286
  "content": {
5139
5287
  "application/json": {
5140
5288
  "schema": {
@@ -5404,7 +5552,7 @@
5404
5552
  }
5405
5553
  },
5406
5554
  "400": {
5407
- "description": "`already_exists` — A resource with the same unique field already exists. `details.fields` names the field.\n\n`validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field.\n\n`team_required` — The operation needs a project: send it in the `x-faable-team` header.",
5555
+ "description": "`already_exists` — A resource with the same unique field already exists. `details.fields` names the field.\n\n`validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field.\n\n`team_required` — The operation needs a project: send it in the `x-faable-project` header (`project_<id>`).",
5408
5556
  "content": {
5409
5557
  "application/json": {
5410
5558
  "schema": {
@@ -6571,7 +6719,7 @@
6571
6719
  }
6572
6720
  },
6573
6721
  "401": {
6574
- "description": "`team_or_scope_required` — Listing needs either a project in `x-faable-team` or a global scope on the token.\n\n`unauthorized` — The request carries no valid credentials.\n\n`invalid_token` — The bearer token is missing, malformed or expired.",
6722
+ "description": "`team_or_scope_required` — Listing needs either a project in the `x-faable-project` header or a global scope on the token.\n\n`unauthorized` — The request carries no valid credentials.\n\n`invalid_token` — The bearer token is missing, malformed or expired.",
6575
6723
  "content": {
6576
6724
  "application/json": {
6577
6725
  "schema": {
@@ -6838,6 +6986,9 @@
6838
6986
  "type": "string"
6839
6987
  }
6840
6988
  }
6989
+ },
6990
+ "dockerfile_ignored": {
6991
+ "type": "boolean"
6841
6992
  }
6842
6993
  }
6843
6994
  },
@@ -6945,6 +7096,17 @@
6945
7096
  ],
6946
7097
  "description": "Success deploy emails (first deploy + every promote). Absent/null = enabled; false = muted. Failure emails are never gated by this."
6947
7098
  },
7099
+ "http3": {
7100
+ "anyOf": [
7101
+ {
7102
+ "type": "boolean"
7103
+ },
7104
+ {
7105
+ "type": "null"
7106
+ }
7107
+ ],
7108
+ "description": "Whether HTTP/3 is advertised for this app. Absent/null = advertised; false = not advertised. Note it controls the advertisement, not the listener: clients that already discovered HTTP/3 may keep using it until the advertisement expires, and the server does not refuse it."
7109
+ },
6948
7110
  "status": {
6949
7111
  "$ref": "#/components/schemas/AppStatus"
6950
7112
  },
@@ -7034,7 +7196,7 @@
7034
7196
  }
7035
7197
  },
7036
7198
  "400": {
7037
- "description": "`already_exists` — A resource with the same unique field already exists. `details.fields` names the field.\n\n`validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field.\n\n`team_required` — The operation needs a project: send it in the `x-faable-team` header.",
7199
+ "description": "`already_exists` — A resource with the same unique field already exists. `details.fields` names the field.\n\n`validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field.\n\n`team_required` — The operation needs a project: send it in the `x-faable-project` header (`project_<id>`).",
7038
7200
  "content": {
7039
7201
  "application/json": {
7040
7202
  "schema": {
@@ -7332,6 +7494,9 @@
7332
7494
  "type": "string"
7333
7495
  }
7334
7496
  }
7497
+ },
7498
+ "dockerfile_ignored": {
7499
+ "type": "boolean"
7335
7500
  }
7336
7501
  }
7337
7502
  },
@@ -7439,6 +7604,17 @@
7439
7604
  ],
7440
7605
  "description": "Success deploy emails (first deploy + every promote). Absent/null = enabled; false = muted. Failure emails are never gated by this."
7441
7606
  },
7607
+ "http3": {
7608
+ "anyOf": [
7609
+ {
7610
+ "type": "boolean"
7611
+ },
7612
+ {
7613
+ "type": "null"
7614
+ }
7615
+ ],
7616
+ "description": "Whether HTTP/3 is advertised for this app. Absent/null = advertised; false = not advertised. Note it controls the advertisement, not the listener: clients that already discovered HTTP/3 may keep using it until the advertisement expires, and the server does not refuse it."
7617
+ },
7442
7618
  "status": {
7443
7619
  "$ref": "#/components/schemas/AppStatus"
7444
7620
  },
@@ -7715,14 +7891,14 @@
7715
7891
  "type": "string"
7716
7892
  },
7717
7893
  "notify_deploy_success": {
7718
- "anyOf": [
7719
- {
7720
- "type": "boolean"
7721
- },
7722
- {
7723
- "type": "null"
7724
- }
7725
- ]
7894
+ "type": "boolean",
7895
+ "nullable": true,
7896
+ "default": null
7897
+ },
7898
+ "http3": {
7899
+ "type": "boolean",
7900
+ "nullable": true,
7901
+ "default": null
7726
7902
  }
7727
7903
  },
7728
7904
  "additionalProperties": false
@@ -7870,6 +8046,9 @@
7870
8046
  "type": "string"
7871
8047
  }
7872
8048
  }
8049
+ },
8050
+ "dockerfile_ignored": {
8051
+ "type": "boolean"
7873
8052
  }
7874
8053
  }
7875
8054
  },
@@ -7977,6 +8156,17 @@
7977
8156
  ],
7978
8157
  "description": "Success deploy emails (first deploy + every promote). Absent/null = enabled; false = muted. Failure emails are never gated by this."
7979
8158
  },
8159
+ "http3": {
8160
+ "anyOf": [
8161
+ {
8162
+ "type": "boolean"
8163
+ },
8164
+ {
8165
+ "type": "null"
8166
+ }
8167
+ ],
8168
+ "description": "Whether HTTP/3 is advertised for this app. Absent/null = advertised; false = not advertised. Note it controls the advertisement, not the listener: clients that already discovered HTTP/3 may keep using it until the advertisement expires, and the server does not refuse it."
8169
+ },
7980
8170
  "status": {
7981
8171
  "$ref": "#/components/schemas/AppStatus"
7982
8172
  },
@@ -8369,6 +8559,9 @@
8369
8559
  "type": "string"
8370
8560
  }
8371
8561
  }
8562
+ },
8563
+ "dockerfile_ignored": {
8564
+ "type": "boolean"
8372
8565
  }
8373
8566
  }
8374
8567
  },
@@ -8476,6 +8669,17 @@
8476
8669
  ],
8477
8670
  "description": "Success deploy emails (first deploy + every promote). Absent/null = enabled; false = muted. Failure emails are never gated by this."
8478
8671
  },
8672
+ "http3": {
8673
+ "anyOf": [
8674
+ {
8675
+ "type": "boolean"
8676
+ },
8677
+ {
8678
+ "type": "null"
8679
+ }
8680
+ ],
8681
+ "description": "Whether HTTP/3 is advertised for this app. Absent/null = advertised; false = not advertised. Note it controls the advertisement, not the listener: clients that already discovered HTTP/3 may keep using it until the advertisement expires, and the server does not refuse it."
8682
+ },
8479
8683
  "status": {
8480
8684
  "$ref": "#/components/schemas/AppStatus"
8481
8685
  },
@@ -10501,7 +10705,7 @@
10501
10705
  }
10502
10706
  },
10503
10707
  "409": {
10504
- "description": "`repository_already_linked` — The repository is already linked to another app. `details.app_id` / `details.app_name` name it.",
10708
+ "description": "`repository_already_linked` — The repository is already linked to another app. `details.app_id` / `details.app_name` name it.\n\n`repository_taken_down` — An app built from this repository was taken down for abuse, so the repository cannot be linked again. Not a plan limit — upgrading does not lift it. Restoring the taken-down app does.",
10505
10709
  "content": {
10506
10710
  "application/json": {
10507
10711
  "schema": {
@@ -10515,7 +10719,8 @@
10515
10719
  "error_code": {
10516
10720
  "type": "string",
10517
10721
  "enum": [
10518
- "repository_already_linked"
10722
+ "repository_already_linked",
10723
+ "repository_taken_down"
10519
10724
  ]
10520
10725
  }
10521
10726
  }
@@ -13766,7 +13971,7 @@
13766
13971
  }
13767
13972
  },
13768
13973
  "401": {
13769
- "description": "`team_or_scope_required` — Listing needs either a project in `x-faable-team` or a global scope on the token.\n\n`unauthorized` — The request carries no valid credentials.\n\n`invalid_token` — The bearer token is missing, malformed or expired.",
13974
+ "description": "`team_or_scope_required` — Listing needs either a project in the `x-faable-project` header or a global scope on the token.\n\n`unauthorized` — The request carries no valid credentials.\n\n`invalid_token` — The bearer token is missing, malformed or expired.",
13770
13975
  "content": {
13771
13976
  "application/json": {
13772
13977
  "schema": {
@@ -14043,7 +14248,7 @@
14043
14248
  }
14044
14249
  },
14045
14250
  "400": {
14046
- "description": "`already_exists` — A resource with the same unique field already exists. `details.fields` names the field.\n\n`validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field.\n\n`team_required` — The operation needs a project: send it in the `x-faable-team` header.",
14251
+ "description": "`already_exists` — A resource with the same unique field already exists. `details.fields` names the field.\n\n`validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field.\n\n`team_required` — The operation needs a project: send it in the `x-faable-project` header (`project_<id>`).",
14047
14252
  "content": {
14048
14253
  "application/json": {
14049
14254
  "schema": {
@@ -14524,6 +14729,11 @@
14524
14729
  },
14525
14730
  "detected": {
14526
14731
  "$ref": "#/components/schemas/DeploymentDetected"
14732
+ },
14733
+ "plan": {
14734
+ "type": "object",
14735
+ "properties": {},
14736
+ "additionalProperties": true
14527
14737
  }
14528
14738
  }
14529
14739
  }
@@ -15764,7 +15974,7 @@
15764
15974
  }
15765
15975
  },
15766
15976
  "401": {
15767
- "description": "`team_or_scope_required` — Listing needs either a project in `x-faable-team` or a global scope on the token.\n\n`unauthorized` — The request carries no valid credentials.\n\n`invalid_token` — The bearer token is missing, malformed or expired.",
15977
+ "description": "`team_or_scope_required` — Listing needs either a project in the `x-faable-project` header or a global scope on the token.\n\n`unauthorized` — The request carries no valid credentials.\n\n`invalid_token` — The bearer token is missing, malformed or expired.",
15768
15978
  "content": {
15769
15979
  "application/json": {
15770
15980
  "schema": {
@@ -15999,7 +16209,7 @@
15999
16209
  }
16000
16210
  },
16001
16211
  "400": {
16002
- "description": "`already_exists` — A resource with the same unique field already exists. `details.fields` names the field.\n\n`validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field.\n\n`team_required` — The operation needs a project: send it in the `x-faable-team` header.\n\n`domain_invalid` — Not a valid hostname. No protocol, port or path.",
16212
+ "description": "`already_exists` — A resource with the same unique field already exists. `details.fields` names the field.\n\n`validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field.\n\n`team_required` — The operation needs a project: send it in the `x-faable-project` header (`project_<id>`).\n\n`domain_invalid` — Not a valid hostname. No protocol, port or path.",
16003
16213
  "content": {
16004
16214
  "application/json": {
16005
16215
  "schema": {