diff --git a/assets/openapi.json b/assets/openapi.json
index 59552ffbf..49255837c 100644
Binary files a/assets/openapi.json and b/assets/openapi.json differ
diff --git a/assets/schemas.json b/assets/schemas.json
index 91a55209a..47643545f 100644
Binary files a/assets/schemas.json and b/assets/schemas.json differ
diff --git a/scripts/schemaExclusions.json b/scripts/schemaExclusions.json
index 5b9eb6530..5e2fbe017 100644
--- a/scripts/schemaExclusions.json
+++ b/scripts/schemaExclusions.json
@@ -414,6 +414,10 @@
{
"value": "SKUSchema",
"reason": "Self-reference only schema"
+ },
+ {
+ "value": "CollectibleProductSchema",
+ "reason": "Self-reference only schema"
}
]
}
\ No newline at end of file
diff --git a/src/schemas/api/index.ts b/src/schemas/api/index.ts
index f8d9a9357..57f56b809 100644
--- a/src/schemas/api/index.ts
+++ b/src/schemas/api/index.ts
@@ -22,3 +22,4 @@ export * from "./entitlements";
export * from "./guilds";
export * from "./messages";
export * from "./users";
+export * from "./store";
diff --git a/src/schemas/api/store/AnyCollectiblesShopBlock.ts b/src/schemas/api/store/AnyCollectiblesShopBlock.ts
new file mode 100644
index 000000000..fd64fdea5
--- /dev/null
+++ b/src/schemas/api/store/AnyCollectiblesShopBlock.ts
@@ -0,0 +1,38 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import { CountdownTimerShopBlockSchema } from "./CountdownTimerShopBlockSchema";
+import { FeaturedShopBlockSchema } from "./FeaturedShopBlockSchema";
+import { FeedShopBlockSchema } from "./FeedShopBlockSchema";
+import { HeroShopBlockSchema } from "./HeroShopBlockSchema";
+import { ImmersiveBannerShopBlockSchema } from "./ImmersiveBannerShopBlockSchema";
+import { RewardHeroShopBlockSchema } from "./RewardHeroShoppBlockSchema";
+import { ShelfShopBlockSchema } from "./ShelfShopBlockSchema";
+import { SubBlockSchema } from "./SubBlockSchema";
+import { WideBannerShopBlockSchema } from "./WideBannerShopBlockSchema";
+
+export type AnyCollectiblesShopBlock =
+ | HeroShopBlockSchema
+ | FeaturedShopBlockSchema
+ | SubBlockSchema
+ | FeedShopBlockSchema
+ | WideBannerShopBlockSchema
+ | ShelfShopBlockSchema
+ | CountdownTimerShopBlockSchema
+ | ImmersiveBannerShopBlockSchema
+ | RewardHeroShopBlockSchema;
diff --git a/src/schemas/api/store/CollectibleAssetConfigSchema.ts b/src/schemas/api/store/CollectibleAssetConfigSchema.ts
new file mode 100644
index 000000000..f77ee05b5
--- /dev/null
+++ b/src/schemas/api/store/CollectibleAssetConfigSchema.ts
@@ -0,0 +1,28 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+export interface CollectibleAssetConfigSchema {
+ /**
+ * The URL of the animated image (in APNG format)
+ */
+ animated: string | null;
+ /**
+ * The URL of the static image
+ */
+ static: string;
+}
diff --git a/src/schemas/api/store/CollectibleBannerAssetSchema.ts b/src/schemas/api/store/CollectibleBannerAssetSchema.ts
new file mode 100644
index 000000000..86d1327e3
--- /dev/null
+++ b/src/schemas/api/store/CollectibleBannerAssetSchema.ts
@@ -0,0 +1,36 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+export interface CollectibleBannerAssetSchema {
+ /**
+ * The CSS the web client should use
+ */
+ background_style: string | null;
+ /**
+ * Max height of the banner on desktop
+ */
+ desktop_max_height?: number | null;
+ /**
+ * Max height of the banner on mobile
+ */
+ mobile_max_height?: number | null;
+ /**
+ * Whether the banner is responsive
+ */
+ responsive: boolean | null;
+}
diff --git a/src/schemas/api/store/CollectibleItemSchema.ts b/src/schemas/api/store/CollectibleItemSchema.ts
new file mode 100644
index 000000000..7dc758915
--- /dev/null
+++ b/src/schemas/api/store/CollectibleItemSchema.ts
@@ -0,0 +1,204 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import { CollectibleItemType } from "./CollectibleItemType";
+import { CollectibleNameplateColorPalette } from "./CollectibleNameplateColorPalette";
+import { CollectibleProfileEffectAnimationType } from "./CollectibleProfileEffectAnimationType";
+
+export interface CollectibleItemAssetsSchema {
+ /**
+ * The URL for the static image of the collectible
+ */
+ static_image_url: string;
+ /**
+ * The URL for the animated image of the collectible (in APNG format)
+ */
+ animated_image_url: string;
+ /**
+ * The URL for the video of the collectible
+ */
+ video_url?: string;
+}
+
+export interface CollectibleProfileEffectPosition {
+ /**
+ * The x-coordinate of the animation frame
+ */
+ x: number;
+ /**
+ * The y-coordinate of the animation frame
+ */
+ y: number;
+}
+
+export interface CollectibleProfileEffectSource {
+ /**
+ * The URL of the animation image (in APNG format)
+ */
+ src: string;
+}
+
+export interface CollectibleProfileEffectAnimation {
+ /**
+ * The URL of the animation image (in APNG format)
+ */
+ src: string;
+ /**
+ * Whether the animation frame should loop
+ */
+ loop: boolean;
+ /**
+ * The height of the animation image
+ */
+ height: number;
+ /**
+ * The width of the animation image
+ */
+ width: number;
+ /**
+ * The duration of the animation frame (in milliseconds)
+ */
+ duration: number;
+ /**
+ * The start time of the animation frame (in milliseconds)
+ */
+ start: number;
+ /**
+ * The delay between loops of the animation frame (in milliseconds)
+ */
+ loopDelay: number;
+ /**
+ * The position of the animation frame
+ */
+ position: CollectibleProfileEffectPosition;
+ /**
+ * The z-index of the animation frame
+ */
+ zIndex: number;
+ /**
+ * The sources to randomize the src from
+ */
+ randomizedSources: CollectibleProfileEffectSource[];
+}
+
+export interface CollectibleAvatarDecorationSchema {
+ /**
+ * The type of collectible
+ */
+ type: CollectibleItemType;
+ /**
+ * The ID of the avatar decoration
+ */
+ id: string;
+ /**
+ * The SKU ID of the avatar decoration
+ */
+ sku_id: string;
+ /**
+ * The asset hash of the avatar decoration
+ */
+ asset: string;
+ /**
+ * The URLs for the static and animated images of the avatar decoration
+ */
+ assets: CollectibleItemAssetsSchema;
+ /**
+ * The avatar decoration accessibility description
+ */
+ label: string;
+}
+
+export interface CollectibleProfileEffectSchema {
+ /**
+ * The type of collectible
+ */
+ type: CollectibleItemType;
+ /**
+ * The ID of the profile effect
+ */
+ id: string;
+ /**
+ * The ID of the profile effect SKU
+ */
+ sku_id: string;
+ /**
+ * The title of the profile effect
+ */
+ title: string;
+ /**
+ * The description of the profile effect
+ */
+ description: string;
+ /**
+ * An accessible description of the profile effect
+ */
+ accessibilityLabel: string;
+ /**
+ * The type of animation used by the profile effect
+ */
+ animationType: CollectibleProfileEffectAnimationType;
+ /**
+ * The URL of the profile effect's thumbnail preview image (in APNG format)
+ */
+ thumbnailPreviewSrc: string;
+ /**
+ * A URL of the profile effect with reduced motion (in APNG format)
+ */
+ reducedMotionSrc: string;
+ /**
+ * The URL of the static frame of the profile effect (in PNG format)
+ */
+ staticFrameSrc: string;
+ /**
+ * The animation frames for the profile effect
+ */
+ effects: CollectibleProfileEffectAnimation[];
+}
+
+export interface CollectibleNameplateSchema {
+ /**
+ * The type of collectible
+ */
+ type: CollectibleItemType;
+ /**
+ * The ID of the nameplate
+ */
+ id: string;
+ /**
+ * The SKU ID of the nameplate
+ */
+ sku_id: string;
+ /**
+ * The nameplate's color palette
+ */
+ palette: CollectibleNameplateColorPalette;
+ /**
+ * The nameplate asset path
+ */
+ asset: string;
+ /**
+ * The URLs for the static and animated images of the nameplate
+ */
+ assets: CollectibleItemAssetsSchema;
+ /**
+ * The nameplate accessibility description
+ */
+ label: string;
+}
+
+export type AnyCollectibleItem = CollectibleAvatarDecorationSchema | CollectibleProfileEffectSchema | CollectibleNameplateSchema;
diff --git a/src/schemas/api/store/CollectibleItemType.ts b/src/schemas/api/store/CollectibleItemType.ts
new file mode 100644
index 000000000..26c1fff4c
--- /dev/null
+++ b/src/schemas/api/store/CollectibleItemType.ts
@@ -0,0 +1,63 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+export enum CollectibleItemType {
+ /**
+ * An avatar decoration
+ *
+ * Value: 0
+ * Name: AVATAR_DECORATION
+ */
+ AVATAR_DECORATION = 0,
+ /**
+ * A profile effect
+ *
+ * Value: 1
+ * Name: PROFILE_EFFECT
+ */
+ PROFILE_EFFECT = 1,
+ /**
+ * A nameplate
+ *
+ * Value: 2
+ * Name: NAMEPLATE
+ */
+ NAMEPLATE = 2,
+ NONE = 100,
+ /**
+ * A bundle of collectibles
+ *
+ * Value: 1000
+ * Name: BUNDLE
+ */
+ BUNDLE = 1000,
+ /**
+ * A group of variants
+ *
+ * Value: 2000
+ * Name: VARIANTS_GROUP
+ */
+ VARIANTS_GROUP = 2000,
+ /**
+ * A non-collectible SKU (e.g. fractional premium)
+ *
+ * Value: 3000
+ * Name: EXTERNAL_SKU
+ */
+ EXTERNAL_SKU = 3000,
+}
diff --git a/src/schemas/api/store/CollectibleNameplateColorPalette.ts b/src/schemas/api/store/CollectibleNameplateColorPalette.ts
new file mode 100644
index 000000000..4ac9d9236
--- /dev/null
+++ b/src/schemas/api/store/CollectibleNameplateColorPalette.ts
@@ -0,0 +1,92 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+export enum CollectibleNameplateColorPalette {
+ /**
+ * None
+ *
+ * Value: none
+ */
+ none,
+ /**
+ * Crimson
+ *
+ * Value: crimson
+ */
+ crimson,
+ /**
+ * Berry
+ *
+ * Value: berry
+ */
+ berry,
+ /**
+ * Sky
+ *
+ * Value: sky
+ */
+ sky,
+ /**
+ * Teal
+ *
+ * Value: teal
+ */
+ teal,
+ /**
+ * Forest
+ *
+ * Value: forest
+ */
+ forest,
+ /**
+ * BubbleGum
+ *
+ * Value: bubble_gum
+ */
+ bubble_gum,
+ /**
+ * Violet
+ *
+ * Value: violet
+ */
+ violet,
+ /**
+ * Cobalt
+ *
+ * Value: cobalt
+ */
+ cobalt,
+ /**
+ * Clover
+ *
+ * Value: clover
+ */
+ clover,
+ /**
+ * Lemon
+ *
+ * Value: lemon
+ */
+ lemon,
+ /**
+ * White
+ *
+ * Value: white
+ */
+ white,
+}
diff --git a/src/schemas/api/store/CollectibleProductSchema.ts b/src/schemas/api/store/CollectibleProductSchema.ts
new file mode 100644
index 000000000..7238dfb9e
--- /dev/null
+++ b/src/schemas/api/store/CollectibleProductSchema.ts
@@ -0,0 +1,109 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import { AnyCollectibleItem } from "./CollectibleItemSchema";
+import { CollectibleItemType } from "./CollectibleItemType";
+import { CollectibleStyleSchema } from "./CollectibleStyleSchema";
+import { SubscriptionPricesSchema } from "./SubscriptionPricesSchema";
+
+export interface CollectibleProductSchema {
+ /**
+ * The SKU ID of the collectible product
+ */
+ sku_id: string;
+ /**
+ * The store listing ID associated with the collectible product
+ */
+ store_listing_id: string;
+ /**
+ * The type of collectible
+ */
+ type: CollectibleItemType;
+ /**
+ * The bundled products included in the collectible product
+ */
+ bundled_products?: CollectibleProductSchema[];
+ /**
+ * The category SKU ID of the collectible product
+ */
+ category_sku_id: string;
+ /**
+ * The Google SKU IDs for the collectible per purchase type
+ */
+ google_sku_ids?: Record;
+ /**
+ * The items included in the collectible product
+ */
+ items: AnyCollectibleItem[];
+ /**
+ * The name of the collectible product
+ */
+ name: string;
+ /**
+ * The premium type required to purchase the collectible product
+ */
+ premium_type: number;
+ /**
+ * The prices for the collectible per purchase type
+ */
+ prices?: Record;
+ /**
+ * The colors to use in the client
+ */
+ styles: CollectibleStyleSchema;
+ /**
+ * A description of the collectible product
+ */
+ summary: string;
+ /**
+ * When the collectible product should be unpublished
+ */
+ unpublished_at: string | null;
+ /**
+ * The name of the base variant of the collectible product
+ */
+ base_variant_name?: string;
+ /**
+ * The SKU ID of the base variant of the collectible product
+ */
+ base_variant_sku_id?: string;
+ /**
+ * When the collectible product expires
+ */
+ expires_at?: string | null;
+ /**
+ * The purchase type of the collectible product
+ */
+ purchase_type?: number;
+ /**
+ * When the collectible product was purchased
+ */
+ purchased_at?: string;
+ /**
+ * The label for the variant of the collectible product
+ */
+ variant_label?: string;
+ /**
+ * The hex value of the color for the variant of the collectible product
+ */
+ variant_value?: string;
+ /**
+ * The variants of the collectible product
+ */
+ variants?: CollectibleProductSchema[];
+}
diff --git a/src/schemas/api/store/CollectibleProfileEffectAnimationType.ts b/src/schemas/api/store/CollectibleProfileEffectAnimationType.ts
new file mode 100644
index 000000000..ec93dbc28
--- /dev/null
+++ b/src/schemas/api/store/CollectibleProfileEffectAnimationType.ts
@@ -0,0 +1,41 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+export enum CollectibleProfileEffectAnimationType {
+ /**
+ * The animation type is unspecified
+ *
+ * Value: 0
+ * Name: UNSPECIFIED
+ */
+ UNSPECIFIED = 0,
+ /**
+ * The animation type is persistent
+ *
+ * Value: 1
+ * Name: PERSISTENT
+ */
+ PERSISTENT = 1,
+ /**
+ * The animation type is intermittent
+ *
+ * Value: 2
+ * Name: INTERMITTENT
+ */
+ INTERMITTENT = 2,
+}
diff --git a/src/schemas/api/store/CollectibleStyleSchema.ts b/src/schemas/api/store/CollectibleStyleSchema.ts
new file mode 100644
index 000000000..e659412c1
--- /dev/null
+++ b/src/schemas/api/store/CollectibleStyleSchema.ts
@@ -0,0 +1,32 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+export interface CollectibleStyleSchema {
+ /**
+ * An array of background colors
+ */
+ background_colors: number[];
+ /**
+ * An array of button colors
+ */
+ button_colors: number[];
+ /**
+ * An array of confetti colors
+ */
+ confetti_colors: number[];
+}
diff --git a/src/schemas/api/store/CollectibleUserDiscountSchema.ts b/src/schemas/api/store/CollectibleUserDiscountSchema.ts
new file mode 100644
index 000000000..e746a6c3d
--- /dev/null
+++ b/src/schemas/api/store/CollectibleUserDiscountSchema.ts
@@ -0,0 +1,31 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+export interface CollectibleUserDiscountSchema {
+ /**
+ * How much the discount is
+ */
+ amount: number;
+ /**
+ * The discount ID
+ */
+ discount_id: string;
+ /**
+ * When the discount expires
+ */
+ expires_at: string | null;
+}
diff --git a/src/schemas/api/store/CountdownTimerShopBlockSchema.ts b/src/schemas/api/store/CountdownTimerShopBlockSchema.ts
new file mode 100644
index 000000000..53bd8084b
--- /dev/null
+++ b/src/schemas/api/store/CountdownTimerShopBlockSchema.ts
@@ -0,0 +1,45 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+import { ShopBlockType } from "./ShopBlockType";
+
+export interface CountdownTimerShopBlockSchema {
+ /**
+ * The shop block type
+ */
+ type: ShopBlockType;
+ /**
+ * The title of the countdown timer
+ */
+ title: string;
+ /**
+ * The body text of the countdown timer
+ */
+ body: string;
+ /**
+ * The URL of the countdown timer banner
+ */
+ banner_url: string;
+ /**
+ * The end time of the countdown timer
+ */
+ end_time: string;
+ /**
+ * The hex color code of the text
+ */
+ text_color: string;
+}
diff --git a/src/schemas/api/store/CountryPricesSchema.ts b/src/schemas/api/store/CountryPricesSchema.ts
new file mode 100644
index 000000000..7d67d1794
--- /dev/null
+++ b/src/schemas/api/store/CountryPricesSchema.ts
@@ -0,0 +1,29 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+import { UnitPriceSchema } from "./UnitPriceSchema";
+
+export interface CountryPricesSchema {
+ /**
+ * The ISO 3166-1 alpha-2 country code
+ */
+ country_code: string;
+ /**
+ * The prices for the plan in the given country
+ */
+ prices: UnitPriceSchema[];
+}
diff --git a/src/schemas/api/store/FeaturedShopBlockSchema.ts b/src/schemas/api/store/FeaturedShopBlockSchema.ts
new file mode 100644
index 000000000..4109bb3d6
--- /dev/null
+++ b/src/schemas/api/store/FeaturedShopBlockSchema.ts
@@ -0,0 +1,30 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+import { ShopBlockType } from "./ShopBlockType";
+import { SubBlockSchema } from "./SubBlockSchema";
+
+export interface FeaturedShopBlockSchema {
+ /**
+ * The list of sub-blocks in the featured shop block
+ */
+ subblocks: SubBlockSchema[];
+ /**
+ * The shop block type
+ */
+ type: ShopBlockType;
+}
diff --git a/src/schemas/api/store/FeedShopBlockSchema.ts b/src/schemas/api/store/FeedShopBlockSchema.ts
new file mode 100644
index 000000000..6b986b288
--- /dev/null
+++ b/src/schemas/api/store/FeedShopBlockSchema.ts
@@ -0,0 +1,35 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import { ShopBlockType } from "./ShopBlockType";
+import { SortedSKUIDsSchema } from "./SortedSKUIDsSchema";
+
+export interface FeedShopBlockSchema {
+ /**
+ * All SKU IDs ranked by popularity
+ */
+ ranked_sku_ids: string[];
+ /**
+ * The sorted SKU IDs
+ */
+ sorted_sku_ids: SortedSKUIDsSchema;
+ /**
+ * The shop block type
+ */
+ type: ShopBlockType;
+}
diff --git a/src/schemas/api/store/HeroShopBlockSchema.ts b/src/schemas/api/store/HeroShopBlockSchema.ts
new file mode 100644
index 000000000..837ed7392
--- /dev/null
+++ b/src/schemas/api/store/HeroShopBlockSchema.ts
@@ -0,0 +1,100 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import { CollectibleAssetConfigSchema } from "./CollectibleAssetConfigSchema";
+import { CollectibleBannerAssetSchema } from "./CollectibleBannerAssetSchema";
+import { ShopBlockType } from "./ShopBlockType";
+
+export interface HeroShopBlockSchema {
+ /**
+ * The shop block type
+ */
+ type: ShopBlockType;
+ /**
+ * The collectible category SKU ID
+ */
+ category_sku_id: string;
+ /**
+ * The collectible category store listing ID
+ */
+ category_store_listing_id: string;
+ /**
+ * The banner asset
+ */
+ banner_asset: CollectibleAssetConfigSchema;
+ /**
+ * The display configuration
+ */
+ banner_display_config: CollectibleBannerAssetSchema;
+ /**
+ * The hex color code for the banner text
+ */
+ banner_text_color?: string;
+ /**
+ * The URL of the hero logo image
+ */
+ hero_logo_url: string;
+ /**
+ * The URL of the hero Rive animation
+ */
+ hero_rive_url?: string;
+ /**
+ * The shop block logo display config
+ */
+ logo_display_config: CollectibleBannerAssetSchema;
+ /**
+ * The URL of the hero logo image
+ */
+ logo_url: string;
+ /**
+ * The name of the shop block
+ */
+ name: string;
+ /**
+ * The title to be displayed on mobile devices
+ */
+ mobile_title?: string;
+ /**
+ * The summary to be displayed on mobile devices
+ */
+ mobile_summary?: string;
+ /**
+ * The products title to be displayed on mobile devices
+ */
+ mobile_products_title?: string;
+ /**
+ * The URL of the mobile hero banner image
+ */
+ mobile_hero_url?: string;
+ /**
+ * The URL of the mobile animated hero banner image
+ */
+ mobile_hero_animated_url?: string;
+ /**
+ * The SKU IDs ranked by popularity in the collectible category
+ */
+ ranked_sku_ids: string[];
+ /**
+ * A description of the collectible category
+ */
+ summary: string;
+ /**
+ * When the collectible category should be unpublished
+ */
+ unpublished_at: string | null;
+}
diff --git a/src/schemas/api/store/ImmersiveBannerShopBlockSchema.ts b/src/schemas/api/store/ImmersiveBannerShopBlockSchema.ts
new file mode 100644
index 000000000..10aa8cb65
--- /dev/null
+++ b/src/schemas/api/store/ImmersiveBannerShopBlockSchema.ts
@@ -0,0 +1,51 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import { CollectibleAssetConfigSchema } from "./CollectibleAssetConfigSchema";
+import { ShopBlockType } from "./ShopBlockType";
+
+export interface ImmersiveBannerShopBlockSchema {
+ /**
+ * The shop block type
+ */
+ type: ShopBlockType;
+ /**
+ * The title of the immersive banner
+ */
+ title: string;
+ /**
+ * The body text of the immersive banner
+ */
+ body: string;
+ /**
+ * The URL to the help center article
+ */
+ help_center_url: string;
+ /**
+ * The hex color code of the text
+ */
+ text_color: string;
+ /**
+ * The end time of the immersive banner
+ */
+ end_time: string | null;
+ /**
+ * The banner asset
+ */
+ banner_asset: CollectibleAssetConfigSchema;
+}
diff --git a/src/schemas/api/store/RewardHeroShoppBlockSchema.ts b/src/schemas/api/store/RewardHeroShoppBlockSchema.ts
new file mode 100644
index 000000000..6501ca63f
--- /dev/null
+++ b/src/schemas/api/store/RewardHeroShoppBlockSchema.ts
@@ -0,0 +1,115 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+import { CollectibleAssetConfigSchema } from "./CollectibleAssetConfigSchema";
+import { CollectibleBannerAssetSchema } from "./CollectibleBannerAssetSchema";
+import { ShopBlockType } from "./ShopBlockType";
+
+export interface RewardHeroShopBlockSchema {
+ /**
+ * The shop block type
+ */
+ type: ShopBlockType;
+ /**
+ * The collectible category SKU ID
+ */
+ category_sku_id?: string;
+ /**
+ * The collectible category store listing ID
+ */
+ category_store_listing_id: string;
+ /**
+ * The name of the shop block
+ */
+ name: string;
+ /**
+ * A description of the collectible category
+ */
+ summary: string;
+ /**
+ * The banner asset
+ */
+ banner_asset: CollectibleAssetConfigSchema;
+ /**
+ * The URL of the hero logo image
+ */
+ logo_url: string;
+ /**
+ * The title of the reward hero shop block
+ */
+ title: string;
+ /**
+ * The hex color code for the banner text
+ */
+ banner_text_color?: string;
+ /**
+ * The display configuration
+ */
+ banner_display_config: CollectibleBannerAssetSchema;
+ /**
+ * The URL of the hero Rive animation
+ */
+ hero_rive_url?: string;
+ /**
+ * The shop block logo display config
+ */
+ logo_display_config: CollectibleBannerAssetSchema;
+ /**
+ * The title to be displayed on mobile devices
+ */
+ mobile_title?: string;
+ /**
+ * The summary to be displayed on mobile devices
+ */
+ mobile_summary?: string;
+ /**
+ * The products title to be displayed on mobile devices
+ */
+ mobile_products_title?: string;
+ /**
+ * The URL of the hero banner image
+ */
+ hero_banner_url: string;
+ /**
+ * The URL of the hero animated banner image
+ */
+ hero_banner_animated_url: string;
+ /**
+ * The URL of the hero logo image
+ */
+ hero_logo_url: string;
+ /**
+ * The URL of the mobile hero banner image
+ */
+ mobile_hero_url?: string;
+ /**
+ * The URL of the mobile animated hero banner image
+ */
+ mobile_hero_animated_url?: string;
+ /**
+ * The SKU IDs ranked by popularity in the collectible category
+ */
+ ranked_sku_ids: string[];
+ /**
+ * When the collectible category should be unpublished
+ */
+ unpublished_at: string | null;
+ /**
+ * The SKU ID of the reward collectible
+ */
+ reward_sku_id: string;
+}
diff --git a/src/schemas/api/store/ShelfShopBlockSchema.ts b/src/schemas/api/store/ShelfShopBlockSchema.ts
new file mode 100644
index 000000000..d9362c24f
--- /dev/null
+++ b/src/schemas/api/store/ShelfShopBlockSchema.ts
@@ -0,0 +1,37 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+import { ShopBlockType } from "./ShopBlockType";
+
+export interface ShelfShopBlockSchema {
+ /**
+ * The shop block type
+ */
+ type: ShopBlockType;
+ /**
+ * The collectible category SKU ID
+ */
+ category_sku_id?: string;
+ /**
+ * The name of the shop block
+ */
+ name: string;
+ /**
+ * The SKU IDs ranked by popularity in the collectible category
+ */
+ ranked_sku_ids: string[];
+}
diff --git a/src/schemas/api/store/ShopBlockType.ts b/src/schemas/api/store/ShopBlockType.ts
new file mode 100644
index 000000000..667b6d99a
--- /dev/null
+++ b/src/schemas/api/store/ShopBlockType.ts
@@ -0,0 +1,76 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+export enum ShopBlockType {
+ /**
+ * A hero shop block
+ *
+ * Value: 0
+ * Name: HERO
+ */
+ HERO = 0,
+ /**
+ * A featured shop block
+ *
+ * Value: 1
+ * Name: FEATURED
+ */
+ FEATURED = 1,
+ /**
+ * A feed shop block
+ *
+ * Value: 2
+ * Name: FEED
+ */
+ FEED = 2,
+ /**
+ * A wide banner shop block
+ *
+ * Value: 3
+ * Name: WIDE_BANNER
+ */
+ WIDE_BANNER = 3,
+ /**
+ * A shelf shop block
+ *
+ * Value: 4
+ * Name: SHELF
+ */
+ SHELF = 4,
+ /**
+ * A countdown timer shop block
+ *
+ * Value: 5
+ * Name: COUNTDOWN_TIMER
+ */
+ COUNTDOWN_TIMER = 5,
+ /**
+ * An immersive banner shop block
+ *
+ * Value: 6
+ * Name: IMMERSIVE_BANNER
+ */
+ IMMERSIVE_BANNER = 6,
+ /**
+ * A reward hero shop block
+ *
+ * Value: 7
+ * Name: REWARD HERO
+ */
+ REWARD = 7,
+}
diff --git a/src/schemas/api/store/SortedSKUIDsSchema.ts b/src/schemas/api/store/SortedSKUIDsSchema.ts
new file mode 100644
index 000000000..312ef6eac
--- /dev/null
+++ b/src/schemas/api/store/SortedSKUIDsSchema.ts
@@ -0,0 +1,27 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+export interface SortedSKUIDsSchema {
+ /**
+ * The SKU IDs sorted by popularity
+ */
+ popular: string[];
+ /**
+ * The SKU IDs sorted by recommendation
+ */
+ recommended: string[];
+}
diff --git a/src/schemas/api/store/SubBlockSchema.ts b/src/schemas/api/store/SubBlockSchema.ts
new file mode 100644
index 000000000..c925cf400
--- /dev/null
+++ b/src/schemas/api/store/SubBlockSchema.ts
@@ -0,0 +1,62 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+export enum ShopSubBlockType {
+ /**
+ * A category subblock
+ *
+ * Value: 0
+ * Name: CATEGORY
+ */
+ CATEGORY = 0,
+}
+
+export interface SubBlockSchema {
+ /**
+ * The subblock type
+ */
+ type: ShopSubBlockType;
+ /**
+ * The collectible category store listing ID
+ */
+ category_store_listing_id: string;
+ /**
+ * The URL of the shop block asset
+ */
+ asset_url: string;
+ /**
+ * The hex color code of the banner text
+ */
+ banner_text_color: string | null;
+ /**
+ * The URL of the banner image
+ */
+ banner_url: string;
+ /**
+ * The body text of the shop block
+ */
+ body_text: string | null;
+ /**
+ * The name of the shop block
+ */
+ name: string;
+ /**
+ * When the collectible category should be unpublished
+ */
+ unpublished_at: string | null;
+}
diff --git a/src/schemas/api/store/SubscriptionPlanPurchaseType.ts b/src/schemas/api/store/SubscriptionPlanPurchaseType.ts
new file mode 100644
index 000000000..ffc9ca901
--- /dev/null
+++ b/src/schemas/api/store/SubscriptionPlanPurchaseType.ts
@@ -0,0 +1,75 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+export enum SubscriptionPlanPurchaseType {
+ /**
+ * Default pricing
+ *
+ * Value: 0
+ * Name: DEFAULT
+ */
+ DEFAULT = 0,
+ /**
+ * Gift purchase pricing
+ *
+ * Value: 1
+ * Name: GIFT
+ */
+ GIFT = 1,
+ /**
+ * Sale pricing
+ *
+ * Value: 2
+ * Name: SALE
+ */
+ SALE = 2,
+ /**
+ * Nitro Classic subscriber pricing
+ *
+ * Value: 3
+ * Name: PREMIUM_TIER_1
+ */
+ PREMIUM_TIER_1 = 3,
+ /**
+ * Nitro subscriber pricing
+ *
+ * Value: 4
+ * Name: PREMIUM_TIER_2
+ */
+ PREMIUM_TIER_2 = 4,
+ /**
+ * Mobile purchase pricing
+ *
+ * Value: 5
+ * Name: MOBILE
+ */
+ MOBILE = 5,
+ /**
+ * Nitro Basic subscriber pricing
+ *
+ * Value: 6
+ * Name: PREMIUM_TIER_0
+ */
+ PREMIUM_TIER_0 = 6,
+ /**
+ * Mobile Nitro subscriber pricing
+ *
+ * Value: 7
+ * Name: MOBILE_PREMIUM_TIER_2
+ */
+ MOBILE_PREMIUM_TIER_2 = 7,
+}
diff --git a/src/schemas/api/store/SubscriptionPricesSchema.ts b/src/schemas/api/store/SubscriptionPricesSchema.ts
new file mode 100644
index 000000000..1761cedcf
--- /dev/null
+++ b/src/schemas/api/store/SubscriptionPricesSchema.ts
@@ -0,0 +1,31 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import { CountryPricesSchema } from "./CountryPricesSchema";
+import { UnitPriceSchema } from "./UnitPriceSchema";
+
+export interface SubscriptionPricesSchema {
+ /**
+ * The prices for the plan for the given country
+ */
+ country_prices: CountryPricesSchema;
+ /**
+ * The prices for the plan per user payment source ID
+ */
+ payment_source_prices?: Record;
+}
diff --git a/src/schemas/api/store/UnitPriceSchema.ts b/src/schemas/api/store/UnitPriceSchema.ts
new file mode 100644
index 000000000..37f3f350a
--- /dev/null
+++ b/src/schemas/api/store/UnitPriceSchema.ts
@@ -0,0 +1,31 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+export interface UnitPriceSchema {
+ /**
+ * The lower-cased ISO 4217 currency code
+ */
+ currency: string;
+ /**
+ * The price amount in the smallest currency unit
+ */
+ amount: number;
+ /**
+ * The exponent to convert the amount to the displayed currency unit
+ */
+ exponent: number;
+}
diff --git a/src/schemas/api/store/WideBannerShopBlockSchema.ts b/src/schemas/api/store/WideBannerShopBlockSchema.ts
new file mode 100644
index 000000000..b140e0c58
--- /dev/null
+++ b/src/schemas/api/store/WideBannerShopBlockSchema.ts
@@ -0,0 +1,79 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2025 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import { CollectibleAssetConfigSchema } from "./CollectibleAssetConfigSchema";
+import { ShopBlockType } from "./ShopBlockType";
+
+export interface WideBannerShopBlockSchema {
+ /**
+ * The shop block type
+ */
+ type: ShopBlockType;
+ /**
+ * The collectible category store listing ID
+ */
+ category_store_listing_id: string;
+ /**
+ * The banner asset
+ */
+ banner_asset: CollectibleAssetConfigSchema;
+ /**
+ * The URL of the wide banner logo image
+ */
+ logo_url: string;
+ /**
+ * The title of the wide banner
+ */
+ title: string;
+ /**
+ * The body text of the wide banner
+ */
+ body: string;
+ /**
+ * The hex color code of the banner text
+ */
+ banner_text_color: string | null;
+ /**
+ * Whether to disable the CTA for the wide banner
+ */
+ disable_cta: boolean;
+ /**
+ * The CTA text for the wide banner
+ */
+ cta_text: string;
+ /**
+ * The CTA route for the wide banner
+ */
+ cta_route: string;
+ /**
+ * Whether the wide banner is dismissible
+ */
+ is_dismissible: boolean;
+ /**
+ * The version of the dismissible content
+ */
+ dismissible_content_version: number;
+ /**
+ * The URL of the wide banner image
+ */
+ wide_banner_url: string;
+ /**
+ * The URL of the animated wide banner image
+ */
+ wide_banner_animated_url?: string;
+}
diff --git a/src/schemas/api/store/index.ts b/src/schemas/api/store/index.ts
index ae81256e5..246729344 100644
--- a/src/schemas/api/store/index.ts
+++ b/src/schemas/api/store/index.ts
@@ -44,3 +44,27 @@ export * from "./SKUTenantMetadataSchema";
export * from "./SKUType";
export * from "./SocialLayerMetadataSchema";
export * from "./StoreCarouselItemSchema";
+export * from "./CollectibleBannerAssetSchema";
+export * from "./CollectibleProductSchema";
+export * from "./CollectibleStyleSchema";
+export * from "./CountryPricesSchema";
+export * from "./SubscriptionPricesSchema";
+export * from "./UnitPriceSchema";
+export * from "./CollectibleItemSchema";
+export * from "./ShopBlockType";
+export * from "./CollectibleAssetConfigSchema";
+export * from "./HeroShopBlockSchema";
+export * from "./FeaturedShopBlockSchema";
+export * from "./SubBlockSchema";
+export * from "./FeedShopBlockSchema";
+export * from "./WideBannerShopBlockSchema";
+export * from "./ShelfShopBlockSchema";
+export * from "./CountdownTimerShopBlockSchema";
+export * from "./ImmersiveBannerShopBlockSchema";
+export * from "./AnyCollectiblesShopBlock";
+export * from "./CollectibleUserDiscountSchema";
+export * from "./CollectibleItemType";
+export * from "./CollectibleProfileEffectAnimationType";
+export * from "./CollectibleNameplateColorPalette";
+export * from "./SortedSKUIDsSchema";
+export * from "./SubscriptionPlanPurchaseType";
diff --git a/src/schemas/responses/CollectiblesCategoriesResponse.ts b/src/schemas/responses/CollectiblesCategoriesResponse.ts
index 2b93ffd01..9aaf558b0 100644
--- a/src/schemas/responses/CollectiblesCategoriesResponse.ts
+++ b/src/schemas/responses/CollectiblesCategoriesResponse.ts
@@ -16,105 +16,166 @@
along with this program. If not, see .
*/
-// TODO: Clean up
-import { StringStringDictionary } from "@spacebar/schemas";
+import { CollectibleAssetConfigSchema, CollectibleBannerAssetSchema, CollectibleProductSchema, CollectibleStyleSchema, StringStringDictionary } from "@spacebar/schemas";
-export type CollectiblesCategoriesResponse = CollectiblesCategoryItem[];
+export type CollectiblesCategoriesResponse = CollectibleCategorySchema[];
-export interface CollectiblesCategoryStyle {
- background_colors: number[];
- button_colors: number[];
- confetti_colors: number[];
-}
-
-export interface CollectiblesCategoryItem {
+export interface CollectibleCategorySchema {
+ /**
+ * The SKU ID of the collectible category
+ */
sku_id: string;
- name: string;
- summary: string;
+ /**
+ * The store listing ID associated with the collectible category
+ */
store_listing_id: string;
- banner: string;
+ /**
+ * The color of the banner text as a hexadecimal color string
+ */
+ banner_text_color?: string;
+ /**
+ * The catalog banner asset
+ */
+ catalog_banner_asset?: CollectibleAssetConfigSchema;
+ /**
+ * The hero banner asset
+ */
+ hero_banner_asset?: CollectibleAssetConfigSchema;
+ /**
+ * The body text for the featured block
+ */
+ featured_block_body?: string;
+ /**
+ * The URL of the featured block image
+ */
+ featured_block_url?: string;
+ /**
+ * The hero banner asset. might be legacy in favor of hero_banner_asset?
+ */
+ hero_banner_config_asset?: CollectibleBannerAssetSchema;
+ /**
+ * The display configuration for the hero banner
+ */
+ hero_banner_display_config?: CollectibleBannerAssetSchema;
+ /**
+ * The display configuration for the hero banner. might be legacy in favor of hero_banner_display_config?
+ */
+ hero_banner_config?: CollectibleBannerAssetSchema;
+ /**
+ * The title text for the hero block
+ */
+ hero_block_title?: string;
+ /**
+ * The display configuration for the hero logo
+ */
+ hero_logo_display_config?: CollectibleAssetConfigSchema;
+ /**
+ * The URL of the hero logo image
+ */
+ hero_logo_url?: string;
+ /**
+ * The popularity ranking of SKU IDs within the collectible category
+ */
+ hero_ranking: string[];
+ /**
+ * The URL of the Rive hero animation
+ */
+ hero_rive_url?: string;
+ /**
+ * The URL of the logo image
+ */
+ logo_url: string;
+ /**
+ * The URL of the mobile banner image
+ */
+ mobile_banner_url?: string;
+ /**
+ * The URL of the mobile background image
+ */
+ mobile_bg_url?: string;
+ /**
+ * The title text for the mobile hero block
+ */
+ mobile_hero_block_title?: string;
+ /**
+ * The title text for the mobile products section
+ */
+ mobile_products_title?: string;
+ /**
+ * The summary text for the mobile products section
+ */
+ mobile_summary: string;
+ /**
+ * The name of the collectible category
+ */
+ name: string;
+ /**
+ * The URL of the product display page background image
+ */
+ pdp_bg_url: string;
+ /**
+ * The list of products in the collectible category
+ */
+ products: CollectibleProductSchema[];
+ /**
+ * The colors to use in the client
+ */
+ styles: CollectibleStyleSchema;
+ /**
+ * A description of the collectible category
+ */
+ summary: string;
+ /**
+ * The time at which the collectible category should be unpublished
+ */
unpublished_at: string | null;
- styles: CollectiblesCategoryStyle;
- logo: string;
- hero_ranking: string[] | null;
- mobile_bg: string | null;
- pdp_bg: string | null;
- success_modal_bg: string | null;
- mobile_banner: string | null;
- featured_block: string | null;
- hero_banner: string | null;
- wide_banner: string | null;
- hero_logo: string | null;
- products: CollectiblesCategoryProductItem[];
- banner_asset?: StaticAnimatedAsset;
- hero_banner_asset?: StaticAnimatedAsset;
-}
-
-export interface StaticAnimatedAsset {
- // CDN URLs
- animated: string | null;
- static: string;
-}
-
-export interface CollectiblesCategoryProductItem {
- sku_id: string;
- name: string;
- summary: string;
- store_listing_id: string;
- banner: string;
- unpublished_at: string | null;
- styles: CollectiblesCategoryStyle;
- prices: PriceMap;
- items: ProductItem[];
- type: number;
- premium_type: number;
- category_sku_id: string;
- google_sku_ids: StringStringDictionary;
- variants?: ProductItemVariant[];
-}
-
-export interface ProductItemVariant {
- sku_id: string;
- name: string;
- name_localizations: null;
- summary: string;
- summary_localizations: null;
- store_listing_id: string;
- banner?: string;
- unpublished_at?: string | null;
- styles?: CollectiblesCategoryStyle;
- prices: PriceMap;
- items: ProductItem[];
- type: number;
- premium_type: number;
- category_sku_id: string;
- google_sku_ids?: StringStringDictionary;
- base_variant_sku_id: string;
- base_variant_name: string;
- variant_label: string;
- variant_value: string; // hex string
-}
-
-export interface ProductItem {
- type: number;
- id: string;
- sku_id: string;
- asset?: string;
- label?: string;
- palette?: string;
-}
-
-export type PriceMap = {
- [key: string]: { country_prices: CountryPrice };
-};
-
-export interface CountryPrice {
- country_code: string;
- prices: PriceEntry[];
-}
-
-export interface PriceEntry {
- amount: number;
- currency: string;
- exponent: number;
+ /**
+ * The wide banner asset config
+ */
+ wide_banner_asset?: CollectibleAssetConfigSchema;
+ /**
+ * The body text for the wide banner
+ */
+ wide_banner_body?: string;
+ /**
+ * The title text for the wide banner
+ */
+ wide_banner_title?: string;
+ /**
+ * The ID of the logo image
+ */
+ logo?: string | null;
+ /**
+ * The ID of the mobile background image
+ */
+ mobile_bg?: string | null;
+ /**
+ * The ID of the product display page background image
+ */
+ pdp_bg?: string | null;
+ /**
+ * The ID of the mobile banner image
+ */
+ mobile_banner?: string | null;
+ featured_block?: string;
+ /**
+ * The ID of the hero logo image
+ */
+ hero_logo?: string | null;
+ /**
+ * The URL of the hero banner
+ */
+ hero_banner_url?: string | null;
+ /**
+ * The URL of the animated hero banner
+ */
+ hero_banner_animated_url?: string | null;
+ /**
+ * The URL of the catalog banner
+ */
+ catalog_banner_url?: string | null;
+ /**
+ * The URL of the wide banner
+ */
+ wide_banner_url?: string | null;
}
diff --git a/src/schemas/responses/CollectiblesShopResponse.ts b/src/schemas/responses/CollectiblesShopResponse.ts
index b739fe0cf..004b43dfe 100644
--- a/src/schemas/responses/CollectiblesShopResponse.ts
+++ b/src/schemas/responses/CollectiblesShopResponse.ts
@@ -16,51 +16,11 @@
along with this program. If not, see .
*/
-import { CollectiblesCategoryItem, StaticAnimatedAsset } from "./CollectiblesCategoriesResponse";
+import { AnyCollectiblesShopBlock, CollectibleUserDiscountSchema } from "@spacebar/schemas";
+import { CollectibleCategorySchema } from "./CollectiblesCategoriesResponse";
export interface CollectiblesShopResponse {
- shop_blocks: AnyShopBlock[];
- categories: CollectiblesCategoryItem[];
-}
-
-export type AnyShopBlock = ItemRowShopBlock | BundleTileRowShopBlock | ItemCollectionShopBlock;
-
-export interface BaseShopBlock {
- type: number;
-}
-
-export interface ItemRowShopBlock extends BaseShopBlock {
- type: 0;
- category_sku_id: string;
- name: string;
- category_store_listing_id: string;
- banner_asset: StaticAnimatedAsset;
- logo_url: string;
- unpublished_at: string | null;
- summary: string;
- ranked_sku_ids: string[];
-}
-
-export interface BundleTileRowShopBlock extends BaseShopBlock {
- type: 1;
- subblocks: ShopBlockSubBlock[];
-}
-
-export interface ShopBlockSubBlock {
- type: number;
- category_store_listing_id: string;
- name: string;
- unpublished_at: string | null;
- banner_url: string;
- body_text: string | null;
- banner_text_color: number | null;
-}
-
-export interface ItemCollectionShopBlock extends BaseShopBlock {
- type: 2;
- ranked_sku_ids: string[];
- sorted_sku_ids: {
- recommended: string[] | null;
- popular: string[];
- };
+ shop_blocks: AnyCollectiblesShopBlock[];
+ categories: CollectibleCategorySchema[];
+ user_discounts?: CollectibleUserDiscountSchema[];
}