diff --git a/fluxer_docs/api-reference/openapi.json b/fluxer_docs/api-reference/openapi.json
index cfeebd33..dc972c45 100644
--- a/fluxer_docs/api-reference/openapi.json
+++ b/fluxer_docs/api-reference/openapi.json
@@ -30215,7 +30215,7 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/DiscoveryApplicationResponse"
+ "$ref": "#/components/schemas/DiscoveryStatusResponse"
}
}
}
@@ -30326,7 +30326,7 @@
"title": "Get discovery status"
}
},
- "description": "Get the current discovery status of a guild. Requires MANAGE_GUILD permission.",
+ "description": "Get the current discovery status and eligibility of a guild. Requires MANAGE_GUILD permission.",
"security": [
{
"sessionToken": []
@@ -60261,6 +60261,7 @@
"DISCOVERY_APPLICATION_ALREADY_REVIEWED",
"DISCOVERY_APPLICATION_NOT_FOUND",
"DISCOVERY_DESCRIPTION_REQUIRED",
+ "DISCOVERY_DISABLED",
"DISCOVERY_INSUFFICIENT_MEMBERS",
"DISCOVERY_INVALID_CATEGORY",
"DISCOVERY_NOT_DISCOVERABLE",
@@ -60543,6 +60544,7 @@
"This discovery application has already been reviewed",
"Discovery application not found",
"A description is required for discovery",
+ "",
"Community does not meet the minimum member count for discovery",
"Invalid discovery category",
"This community is not listed in discovery",
@@ -67236,18 +67238,14 @@
"description": "The slot index"
},
"user_id": {
- "anyOf": [
+ "oneOf": [
{
- "oneOf": [
- {
- "$ref": "#/components/schemas/SnowflakeType"
- },
- {
- "type": "string",
- "enum": [
- "-1"
- ]
- }
+ "$ref": "#/components/schemas/SnowflakeType"
+ },
+ {
+ "type": "string",
+ "enum": [
+ "-1"
]
},
{
@@ -67302,18 +67300,14 @@
"description": "Slot index to reserve (must be >= 1)"
},
"user_id": {
- "anyOf": [
+ "oneOf": [
{
- "oneOf": [
- {
- "$ref": "#/components/schemas/SnowflakeType"
- },
- {
- "type": "string",
- "enum": [
- "-1"
- ]
- }
+ "$ref": "#/components/schemas/SnowflakeType"
+ },
+ {
+ "type": "string",
+ "enum": [
+ "-1"
]
},
{
@@ -75272,6 +75266,34 @@
}
}
},
+ "DiscoveryStatusResponse": {
+ "type": "object",
+ "properties": {
+ "application": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/DiscoveryApplicationResponse"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Current discovery application, if any"
+ },
+ "eligible": {
+ "type": "boolean",
+ "description": "Whether the guild meets the requirements to apply for discovery"
+ },
+ "min_member_count": {
+ "type": "number",
+ "description": "Minimum member count required for discovery eligibility"
+ }
+ },
+ "required": [
+ "eligible",
+ "min_member_count"
+ ]
+ },
"GuildEmojiResponse": {
"type": "object",
"properties": {
@@ -81069,20 +81091,16 @@
"type": "object",
"properties": {
"end_time": {
- "anyOf": [
+ "oneOf": [
{
- "oneOf": [
- {
- "type": "string",
- "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?$"
- },
- {
- "type": "integer",
- "minimum": 0,
- "maximum": 8640000000000000,
- "format": "int64"
- }
- ]
+ "type": "string",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?$"
+ },
+ {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 8640000000000000,
+ "format": "int64"
},
{
"type": "null"
@@ -81147,20 +81165,16 @@
"type": "object",
"properties": {
"end_time": {
- "anyOf": [
+ "oneOf": [
{
- "oneOf": [
- {
- "type": "string",
- "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?$"
- },
- {
- "type": "integer",
- "minimum": 0,
- "maximum": 8640000000000000,
- "format": "int64"
- }
- ]
+ "type": "string",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?$"
+ },
+ {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 8640000000000000,
+ "format": "int64"
},
{
"type": "null"
@@ -81213,20 +81227,16 @@
"type": "object",
"properties": {
"end_time": {
- "anyOf": [
+ "oneOf": [
{
- "oneOf": [
- {
- "type": "string",
- "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?$"
- },
- {
- "type": "integer",
- "minimum": 0,
- "maximum": 8640000000000000,
- "format": "int64"
- }
- ]
+ "type": "string",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?$"
+ },
+ {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 8640000000000000,
+ "format": "int64"
},
{
"type": "null"
@@ -82889,20 +82899,16 @@
"$ref": "#/components/schemas/UserStatusType"
},
"status_resets_at": {
- "anyOf": [
+ "oneOf": [
{
- "oneOf": [
- {
- "type": "string",
- "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?$"
- },
- {
- "type": "integer",
- "minimum": 0,
- "maximum": 8640000000000000,
- "format": "int64"
- }
- ]
+ "type": "string",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?$"
+ },
+ {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 8640000000000000,
+ "format": "int64"
},
{
"type": "null"
@@ -83179,20 +83185,16 @@
"description": "Custom status text (max 128 characters)"
},
"expires_at": {
- "anyOf": [
+ "oneOf": [
{
- "oneOf": [
- {
- "type": "string",
- "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?$"
- },
- {
- "type": "integer",
- "minimum": 0,
- "maximum": 8640000000000000,
- "format": "int64"
- }
- ]
+ "type": "string",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?$"
+ },
+ {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 8640000000000000,
+ "format": "int64"
},
{
"type": "null"
diff --git a/fluxer_docs/resources/admin.mdx b/fluxer_docs/resources/admin.mdx
index 2e5f936f..ca1584eb 100644
--- a/fluxer_docs/resources/admin.mdx
+++ b/fluxer_docs/resources/admin.mdx
@@ -648,7 +648,6 @@ description: 'Admin object schemas from the Fluxer API.'
**Related endpoints**
- [`GET /admin/discovery/applications`](/api-reference/admin/list-discovery-applications)
-- [`GET /guilds/{guild_id}/discovery`](/api-reference/discovery/get-discovery-status)
- [`POST /admin/discovery/applications/{guild_id}/approve`](/api-reference/admin/approve-discovery-application)
- [`POST /admin/discovery/applications/{guild_id}/reject`](/api-reference/admin/reject-discovery-application)
- [`POST /admin/discovery/guilds/{guild_id}/remove`](/api-reference/admin/remove-guild-from-discovery)
@@ -2152,7 +2151,7 @@ Type: [MessageShredStatusNotFoundResponse](#messageshredstatusnotfoundresponse)
| Field | Type | Description |
|-------|------|-------------|
| slot_index | integer (int32) | Slot index to reserve (must be >= 1) |
-| user_id | ?[SnowflakeType](#snowflaketype) \| enum<`-1`> | User ID to reserve the slot for, or null to unreserve (special value -1 is also valid) |
+| user_id | [SnowflakeType](#snowflaketype) \| enum<`-1`> \| null | User ID to reserve the slot for, or null to unreserve (special value -1 is also valid) |
diff --git a/fluxer_docs/resources/common.mdx b/fluxer_docs/resources/common.mdx
index cbb6e14a..591ac44b 100644
--- a/fluxer_docs/resources/common.mdx
+++ b/fluxer_docs/resources/common.mdx
@@ -167,6 +167,20 @@ Type: [DiscoveryCategoryResponse](#discoverycategoryresponse)[]
| online_count | number | Approximate online member count |
| verification_level | number | Verification level |
+
+
+## DiscoveryStatusResponse
+
+**Related endpoints**
+
+- [`GET /guilds/{guild_id}/discovery`](/api-reference/discovery/get-discovery-status)
+
+| Field | Type | Description |
+|-------|------|-------------|
+| application? | ?[DiscoveryApplicationResponse](#discoveryapplicationresponse) | Current discovery application, if any |
+| eligible | boolean | Whether the guild meets the requirements to apply for discovery |
+| min_member_count | number | Minimum member count required for discovery eligibility |
+
## DonationCheckoutRequest
diff --git a/fluxer_docs/resources/oauth2.mdx b/fluxer_docs/resources/oauth2.mdx
index e4e44ba3..3b6c7d80 100644
--- a/fluxer_docs/resources/oauth2.mdx
+++ b/fluxer_docs/resources/oauth2.mdx
@@ -68,7 +68,7 @@ Type: [ApplicationResponse](#applicationresponse)[]
|-------|------|-------------|
| bot | ?[ApplicationBotResponse](#applicationbotresponse) | The bot user associated with the application |
| bot_public | boolean | Whether the bot can be invited by anyone |
-| description | null | The description of the application |
+| description | ?string | The description of the application |
| icon | ?string | The icon hash of the application |
| id | [SnowflakeType](#snowflaketype) | The unique identifier of the application |
| name | string | The name of the application |
@@ -109,9 +109,9 @@ Type: [ApplicationResponse](#applicationresponse)[]
| bot? | [ApplicationBotResponse](#applicationbotresponse) | |
| bot_public | boolean | Whether the bot can be invited by anyone |
| bot_require_code_grant | boolean | Whether the bot requires OAuth2 code grant |
-| description | null | The description of the application |
+| description | ?string | The description of the application |
| flags | [ApplicationFlags](#applicationflags) | |
-| icon | null | The icon hash of the application |
+| icon | ?string | The icon hash of the application |
| id | [SnowflakeType](#snowflaketype) | The unique identifier of the application |
| name | string | The name of the application |
@@ -381,7 +381,7 @@ The application that was authorized
| Field | Type | Description |
|-------|------|-------------|
| bot_public | boolean | Whether the bot can be invited by anyone |
-| description | null | The description of the application |
+| description | ?string | The description of the application |
| icon | ?string | The icon hash of the application |
| id | [SnowflakeType](#snowflaketype) | The unique identifier of the application |
| name | string | The name of the application |
@@ -396,9 +396,9 @@ The application associated with the token
|-------|------|-------------|
| bot_public | boolean | Whether the bot can be invited by anyone |
| bot_require_code_grant | boolean | Whether the bot requires OAuth2 code grant |
-| description | null | The description of the application |
+| description | ?string | The description of the application |
| flags | [ApplicationFlags](#applicationflags) | |
-| icon | null | The icon hash of the application |
+| icon | ?string | The icon hash of the application |
| id | [SnowflakeType](#snowflaketype) | The unique identifier of the application |
| name | string | The name of the application |
diff --git a/fluxer_docs/resources/overview.mdx b/fluxer_docs/resources/overview.mdx
index 0d44aa99..c65a9e58 100644
--- a/fluxer_docs/resources/overview.mdx
+++ b/fluxer_docs/resources/overview.mdx
@@ -22,7 +22,7 @@ Resource tables use a compact notation:
- [Auth](/resources/auth) (37 schemas)
- [Billing](/resources/billing) (3 schemas)
- [Channels](/resources/channels) (66 schemas)
-- [Common](/resources/common) (34 schemas)
+- [Common](/resources/common) (35 schemas)
- [Gateway](/resources/gateway) (2 schemas)
- [Gifts](/resources/gifts) (1 schemas)
- [Guilds](/resources/guilds) (63 schemas)
@@ -163,6 +163,7 @@ Resource tables use a compact notation:
- [DiscoveryCategoryResponse](/resources/common#discoverycategoryresponse)
- [DiscoveryGuildListResponse](/resources/common#discoveryguildlistresponse)
- [DiscoveryGuildResponse](/resources/common#discoveryguildresponse)
+- [DiscoveryStatusResponse](/resources/common#discoverystatusresponse)
- [DonationCheckoutRequest](/resources/common#donationcheckoutrequest)
- [DonationCheckoutResponse](/resources/common#donationcheckoutresponse)
- [DonationRequestLinkRequest](/resources/common#donationrequestlinkrequest)
diff --git a/fluxer_docs/resources/premium.mdx b/fluxer_docs/resources/premium.mdx
index 7ba9babd..0bc99340 100644
--- a/fluxer_docs/resources/premium.mdx
+++ b/fluxer_docs/resources/premium.mdx
@@ -26,7 +26,7 @@ description: 'Premium object schemas from the Fluxer API.'
| Field | Type | Description |
|-------|------|-------------|
| slot_index | integer (int32) | The slot index |
-| user_id | ?[SnowflakeType](#snowflaketype) \| enum<`-1`> | User ID that reserved this slot, or null if unreserved (special value -1 is also valid) |
+| user_id | [SnowflakeType](#snowflaketype) \| enum<`-1`> \| null | User ID that reserved this slot, or null if unreserved (special value -1 is also valid) |
diff --git a/fluxer_docs/resources/users.mdx b/fluxer_docs/resources/users.mdx
index 602759c5..06b7fa8f 100644
--- a/fluxer_docs/resources/users.mdx
+++ b/fluxer_docs/resources/users.mdx
@@ -24,7 +24,7 @@ description: 'Users object schemas from the Fluxer API.'
|-------|------|-------------|
| emoji_id? | ?[SnowflakeType](#snowflaketype) | ID of custom emoji to display |
| emoji_name? | ?string | Unicode emoji or custom emoji name |
-| expires_at? | ?string \| integer (int64) | When the custom status expires |
+| expires_at? | string \| integer (int64) \| null | When the custom status expires |
| text? | ?string | Custom status text (max 128 characters) |
@@ -1186,7 +1186,7 @@ Category of the user report
| render_spoilers? | [RenderSpoilers](#renderspoilers) | Spoiler rendering preference |
| restricted_guilds? | [SnowflakeType](#snowflaketype)[] | Guilds with DM restrictions |
| status? | [UserStatusType](#userstatustype) | |
-| status_resets_at? | ?string \| integer (int64) | When status resets |
+| status_resets_at? | string \| integer (int64) \| null | When status resets |
| status_resets_to? | ?[UserStatusType](#userstatustype) | |
| theme? | [UserThemeType](#userthemetype) | |
| time_format? | [TimeFormatTypes](#timeformattypes) | Time format preference |
@@ -1394,7 +1394,7 @@ Guild mute configuration
| Field | Type | Description |
|-------|------|-------------|
-| end_time? | ?string \| integer (int64) | When the mute expires |
+| end_time? | string \| integer (int64) \| null | When the mute expires |
| selected_time_window | integer (int53) | Selected mute duration |
diff --git a/packages/openapi/src/converters/ZodToOpenAPI.tsx b/packages/openapi/src/converters/ZodToOpenAPI.tsx
index ad0a539a..58f4b58d 100644
--- a/packages/openapi/src/converters/ZodToOpenAPI.tsx
+++ b/packages/openapi/src/converters/ZodToOpenAPI.tsx
@@ -1017,6 +1017,19 @@ function isOpenAPISchema(schema: OpenAPISchemaOrRef): schema is OpenAPISchema {
}
function makeNullableSchema(inner: OpenAPISchemaOrRef): OpenAPISchema {
+ if (isOpenAPISchema(inner)) {
+ const keys = Object.keys(inner).filter((k) => k !== 'description');
+ if (inner.oneOf && keys.length === 1) {
+ const result: OpenAPISchema = {oneOf: [...inner.oneOf, {type: 'null'}]};
+ if (inner.description) result.description = inner.description;
+ return result;
+ }
+ if (inner.anyOf && keys.length === 1) {
+ const result: OpenAPISchema = {anyOf: [...inner.anyOf, {type: 'null'}]};
+ if (inner.description) result.description = inner.description;
+ return result;
+ }
+ }
return {
anyOf: [inner, {type: 'null'}],
};