- Add migration 023: delete 67 fake colors, rename IronGray typo, add 16 missing real colors from spreadsheet - Fix frontend color mappings: remove typo duplicates, rename Silk prefixed colors to match catalog - Add Translucent Teal, Phantom Blue, Mystic Magenta mappings - Remove non-existent ABS GF, TPU 95A HF entries - Update tests for corrected color names
408 lines
15 KiB
TypeScript
408 lines
15 KiB
TypeScript
// Master Bambu Lab product catalog — single source of truth
|
|
// Material → Finish → Color[] with refill/spool availability
|
|
|
|
export interface CatalogColorEntry {
|
|
name: string;
|
|
refill: boolean;
|
|
spool: boolean;
|
|
}
|
|
|
|
export interface CatalogFinish {
|
|
colors: CatalogColorEntry[];
|
|
}
|
|
|
|
export type BambuLabCatalog = Record<string, Record<string, CatalogFinish>>;
|
|
|
|
export const BAMBU_LAB_CATALOG: BambuLabCatalog = {
|
|
PLA: {
|
|
Basic: {
|
|
colors: [
|
|
{ name: 'Jade White', refill: true, spool: true },
|
|
{ name: 'Black', refill: true, spool: true },
|
|
{ name: 'Red', refill: true, spool: true },
|
|
{ name: 'Bambu Green', refill: true, spool: true },
|
|
{ name: 'Blue', refill: true, spool: true },
|
|
{ name: 'Scarlet Red', refill: true, spool: true },
|
|
{ name: 'Lemon Yellow', refill: true, spool: true },
|
|
{ name: 'Cyan', refill: true, spool: true },
|
|
{ name: 'Sakura Pink', refill: true, spool: true },
|
|
{ name: 'Cobalt Blue', refill: true, spool: true },
|
|
{ name: 'Mistletoe Green', refill: true, spool: true },
|
|
{ name: 'Dark Red', refill: true, spool: true },
|
|
{ name: 'Hot Pink', refill: true, spool: true },
|
|
{ name: 'Lavender', refill: true, spool: true },
|
|
{ name: 'Light Blue', refill: true, spool: true },
|
|
{ name: 'Sky Blue', refill: true, spool: true },
|
|
{ name: 'Sunflower Yellow', refill: true, spool: true },
|
|
{ name: 'Pumpkin Orange', refill: true, spool: true },
|
|
{ name: 'Lime', refill: true, spool: true },
|
|
{ name: 'Blue Grey', refill: true, spool: false },
|
|
{ name: 'Beige', refill: true, spool: false },
|
|
{ name: 'Light Gray', refill: true, spool: false },
|
|
{ name: 'Yellow', refill: true, spool: false },
|
|
{ name: 'Orange', refill: true, spool: false },
|
|
{ name: 'Gold', refill: true, spool: false },
|
|
{ name: 'Bright Green', refill: true, spool: false },
|
|
{ name: 'Pink', refill: true, spool: false },
|
|
{ name: 'Magenta', refill: true, spool: false },
|
|
{ name: 'Maroon Red', refill: true, spool: false },
|
|
{ name: 'Purple', refill: true, spool: false },
|
|
{ name: 'Turquoise', refill: true, spool: false },
|
|
{ name: 'Brown', refill: true, spool: false },
|
|
{ name: 'Bronze', refill: true, spool: false },
|
|
{ name: 'Silver', refill: true, spool: false },
|
|
{ name: 'Dark Gray', refill: true, spool: false },
|
|
],
|
|
},
|
|
'Basic Gradient': {
|
|
colors: [
|
|
{ name: 'Neon City', refill: false, spool: true },
|
|
{ name: 'Midnight Blaze', refill: false, spool: true },
|
|
{ name: 'South Beach', refill: false, spool: true },
|
|
{ name: 'Arctic Whisper', refill: false, spool: true },
|
|
{ name: 'Cotton Candy Cloud', refill: false, spool: true },
|
|
{ name: 'Ocean to Meadow', refill: false, spool: true },
|
|
{ name: 'Solar Breeze', refill: false, spool: true },
|
|
{ name: 'Velvet Eclipse', refill: false, spool: true },
|
|
{ name: 'Dawn Radiance', refill: false, spool: true },
|
|
{ name: 'Dusk Glare', refill: false, spool: true },
|
|
{ name: 'Blueberry Bubblegum', refill: false, spool: true },
|
|
{ name: 'Blue Hawaii', refill: false, spool: true },
|
|
{ name: 'Gilded Rose', refill: false, spool: true },
|
|
{ name: 'Pink Citrus', refill: false, spool: true },
|
|
{ name: 'Mint Lime', refill: false, spool: true },
|
|
],
|
|
},
|
|
Matte: {
|
|
colors: [
|
|
{ name: 'Matte Ivory White', refill: true, spool: false },
|
|
{ name: 'Matte Charcoal', refill: true, spool: false },
|
|
{ name: 'Matte Scarlet Red', refill: true, spool: false },
|
|
{ name: 'Matte Marine Blue', refill: true, spool: false },
|
|
{ name: 'Matte Mandarin Orange', refill: true, spool: false },
|
|
{ name: 'Matte Ash Gray', refill: true, spool: false },
|
|
{ name: 'Matte Desert Tan', refill: true, spool: false },
|
|
{ name: 'Matte Nardo Gray', refill: true, spool: false },
|
|
{ name: 'Matte Apple Green', refill: true, spool: false },
|
|
{ name: 'Matte Bone White', refill: true, spool: false },
|
|
{ name: 'Matte Caramel', refill: true, spool: false },
|
|
{ name: 'Matte Dark Blue', refill: true, spool: false },
|
|
{ name: 'Matte Dark Brown', refill: true, spool: false },
|
|
{ name: 'Matte Dark Chocolate', refill: true, spool: false },
|
|
{ name: 'Matte Dark Green', refill: true, spool: false },
|
|
{ name: 'Matte Dark Red', refill: true, spool: false },
|
|
{ name: 'Matte Grass Green', refill: true, spool: false },
|
|
{ name: 'Matte Ice Blue', refill: true, spool: false },
|
|
{ name: 'Matte Lemon Yellow', refill: true, spool: false },
|
|
{ name: 'Matte Lilac Purple', refill: true, spool: false },
|
|
{ name: 'Matte Plum', refill: true, spool: false },
|
|
{ name: 'Matte Sakura Pink', refill: true, spool: false },
|
|
{ name: 'Matte Sky Blue', refill: true, spool: false },
|
|
{ name: 'Matte Latte Brown', refill: true, spool: false },
|
|
{ name: 'Matte Terracotta', refill: true, spool: false },
|
|
],
|
|
},
|
|
'Silk+': {
|
|
colors: [
|
|
{ name: 'Candy Green', refill: false, spool: true },
|
|
{ name: 'Candy Red', refill: false, spool: true },
|
|
{ name: 'Mint', refill: false, spool: true },
|
|
{ name: 'Titan Gray', refill: false, spool: true },
|
|
{ name: 'Rose Gold', refill: false, spool: true },
|
|
{ name: 'Champagne', refill: false, spool: true },
|
|
{ name: 'Baby Blue', refill: false, spool: true },
|
|
],
|
|
},
|
|
'Silk Multi-Color': {
|
|
colors: [
|
|
{ name: 'Aurora Purple', refill: false, spool: true },
|
|
{ name: 'Phantom Blue', refill: false, spool: true },
|
|
{ name: 'Mystic Magenta', refill: false, spool: true },
|
|
],
|
|
},
|
|
Metal: {
|
|
colors: [
|
|
{ name: 'Iron Gray Metallic', refill: false, spool: true },
|
|
{ name: 'Iridium Gold Metallic', refill: false, spool: true },
|
|
{ name: 'Cobalt Blue Metallic', refill: false, spool: true },
|
|
{ name: 'Copper Brown Metallic', refill: false, spool: true },
|
|
{ name: 'Oxide Green Metallic', refill: false, spool: true },
|
|
],
|
|
},
|
|
Sparkle: {
|
|
colors: [
|
|
{ name: 'Onyx Black Sparkle', refill: false, spool: true },
|
|
{ name: 'Classic Gold Sparkle', refill: false, spool: true },
|
|
{ name: 'Crimson Red Sparkle', refill: false, spool: true },
|
|
{ name: 'Royal Purple Sparkle', refill: false, spool: true },
|
|
{ name: 'Slate Gray Sparkle', refill: false, spool: true },
|
|
{ name: 'Alpine Green Sparkle', refill: false, spool: true },
|
|
],
|
|
},
|
|
Galaxy: {
|
|
colors: [
|
|
{ name: 'Nebulae', refill: true, spool: true },
|
|
],
|
|
},
|
|
Marble: {
|
|
colors: [
|
|
{ name: 'White Marble', refill: false, spool: true },
|
|
{ name: 'Red Granite', refill: false, spool: true },
|
|
],
|
|
},
|
|
Glow: {
|
|
colors: [
|
|
{ name: 'Glow Blue', refill: false, spool: true },
|
|
{ name: 'Glow Green', refill: false, spool: true },
|
|
{ name: 'Glow Orange', refill: false, spool: true },
|
|
{ name: 'Glow Pink', refill: false, spool: true },
|
|
{ name: 'Glow Yellow', refill: false, spool: true },
|
|
],
|
|
},
|
|
Wood: {
|
|
colors: [
|
|
{ name: 'Ochre Yellow', refill: false, spool: true },
|
|
{ name: 'White Oak', refill: false, spool: true },
|
|
{ name: 'Clay Brown', refill: false, spool: true },
|
|
],
|
|
},
|
|
'Tough+': {
|
|
colors: [
|
|
{ name: 'Black', refill: true, spool: true },
|
|
],
|
|
},
|
|
CF: {
|
|
colors: [
|
|
{ name: 'Black', refill: false, spool: true },
|
|
{ name: 'Burgundy Red', refill: false, spool: true },
|
|
{ name: 'Jeans Blue', refill: false, spool: true },
|
|
{ name: 'Lava Gray', refill: false, spool: true },
|
|
{ name: 'Matcha Green', refill: false, spool: true },
|
|
{ name: 'Royal Blue', refill: false, spool: true },
|
|
{ name: 'Iris Purple', refill: false, spool: true },
|
|
],
|
|
},
|
|
},
|
|
PETG: {
|
|
HF: {
|
|
colors: [
|
|
{ name: 'Jade White', refill: true, spool: true },
|
|
{ name: 'Black', refill: true, spool: true },
|
|
{ name: 'Red', refill: true, spool: true },
|
|
{ name: 'Green', refill: true, spool: true },
|
|
{ name: 'Blue', refill: true, spool: true },
|
|
{ name: 'Gray', refill: true, spool: true },
|
|
{ name: 'Orange', refill: true, spool: true },
|
|
{ name: 'Cream', refill: true, spool: true },
|
|
{ name: 'Forest Green', refill: true, spool: true },
|
|
{ name: 'Lake Blue', refill: true, spool: true },
|
|
{ name: 'Lime Green', refill: true, spool: true },
|
|
{ name: 'Peanut Brown', refill: true, spool: true },
|
|
],
|
|
},
|
|
Translucent: {
|
|
colors: [
|
|
{ name: 'Clear', refill: false, spool: true },
|
|
{ name: 'Translucent Gray', refill: false, spool: true },
|
|
{ name: 'Translucent Brown', refill: false, spool: true },
|
|
{ name: 'Translucent Purple', refill: false, spool: true },
|
|
{ name: 'Translucent Orange', refill: false, spool: true },
|
|
{ name: 'Translucent Olive', refill: false, spool: true },
|
|
{ name: 'Translucent Pink', refill: false, spool: true },
|
|
{ name: 'Translucent Light Blue', refill: false, spool: true },
|
|
{ name: 'Translucent Tea', refill: false, spool: true },
|
|
],
|
|
},
|
|
CF: {
|
|
colors: [
|
|
{ name: 'Black', refill: false, spool: true },
|
|
{ name: 'Brick Red', refill: false, spool: true },
|
|
{ name: 'Indigo Blue', refill: false, spool: true },
|
|
{ name: 'Malachite Green', refill: false, spool: true },
|
|
{ name: 'Titan Gray', refill: false, spool: true },
|
|
{ name: 'Violet Purple', refill: false, spool: true },
|
|
],
|
|
},
|
|
},
|
|
ABS: {
|
|
Basic: {
|
|
colors: [
|
|
{ name: 'ABS Azure', refill: true, spool: true },
|
|
{ name: 'ABS Black', refill: true, spool: true },
|
|
{ name: 'ABS Blue', refill: true, spool: true },
|
|
{ name: 'ABS Olive', refill: true, spool: true },
|
|
{ name: 'ABS Tangerine Yellow', refill: true, spool: true },
|
|
{ name: 'ABS Navy Blue', refill: true, spool: true },
|
|
{ name: 'ABS Orange', refill: true, spool: true },
|
|
{ name: 'ABS Bambu Green', refill: true, spool: true },
|
|
{ name: 'ABS Red', refill: true, spool: true },
|
|
{ name: 'ABS White', refill: true, spool: true },
|
|
{ name: 'ABS Silver', refill: true, spool: true },
|
|
],
|
|
},
|
|
GF: {
|
|
colors: [
|
|
{ name: 'ABS GF Yellow', refill: true, spool: false },
|
|
{ name: 'ABS GF Orange', refill: true, spool: false },
|
|
],
|
|
},
|
|
},
|
|
TPU: {
|
|
'85A': {
|
|
colors: [
|
|
{ name: 'Black', refill: false, spool: true },
|
|
{ name: 'White', refill: false, spool: true },
|
|
{ name: 'Flesh', refill: false, spool: true },
|
|
{ name: 'Light Cyan', refill: false, spool: true },
|
|
{ name: 'Neon Orange', refill: false, spool: true },
|
|
],
|
|
},
|
|
'90A': {
|
|
colors: [
|
|
{ name: 'Black', refill: false, spool: true },
|
|
{ name: 'White', refill: false, spool: true },
|
|
{ name: 'Red', refill: false, spool: true },
|
|
{ name: 'Blaze', refill: false, spool: true },
|
|
{ name: 'Frozen', refill: false, spool: true },
|
|
{ name: 'Grape Jelly', refill: false, spool: true },
|
|
{ name: 'Crystal Blue', refill: false, spool: true },
|
|
{ name: 'Quicksilver', refill: false, spool: true },
|
|
{ name: 'Cocoa Brown', refill: false, spool: true },
|
|
],
|
|
},
|
|
'95A HF': {
|
|
colors: [
|
|
{ name: 'Black', refill: true, spool: false },
|
|
{ name: 'White', refill: true, spool: false },
|
|
{ name: 'TPU 95A HF Yellow', refill: true, spool: false },
|
|
],
|
|
},
|
|
},
|
|
ASA: {
|
|
Basic: {
|
|
colors: [
|
|
{ name: 'Black', refill: true, spool: true },
|
|
{ name: 'Blue', refill: true, spool: true },
|
|
{ name: 'Gray', refill: true, spool: true },
|
|
{ name: 'Green', refill: true, spool: true },
|
|
{ name: 'Red', refill: true, spool: true },
|
|
{ name: 'White', refill: true, spool: true },
|
|
],
|
|
},
|
|
CF: {
|
|
colors: [
|
|
{ name: 'Black', refill: false, spool: true },
|
|
],
|
|
},
|
|
Aero: {
|
|
colors: [
|
|
{ name: 'White', refill: false, spool: true },
|
|
],
|
|
},
|
|
},
|
|
PA6: {
|
|
GF: {
|
|
colors: [
|
|
{ name: 'Black', refill: false, spool: true },
|
|
],
|
|
},
|
|
},
|
|
PAHT: {
|
|
CF: {
|
|
colors: [
|
|
{ name: 'Black', refill: false, spool: true },
|
|
],
|
|
},
|
|
},
|
|
PC: {
|
|
Basic: {
|
|
colors: [
|
|
{ name: 'Clear Black', refill: false, spool: true },
|
|
{ name: 'Transparent', refill: false, spool: true },
|
|
],
|
|
},
|
|
FR: {
|
|
colors: [
|
|
{ name: 'Black', refill: false, spool: true },
|
|
],
|
|
},
|
|
},
|
|
PET: {
|
|
CF: {
|
|
colors: [
|
|
{ name: 'Black', refill: false, spool: true },
|
|
],
|
|
},
|
|
},
|
|
PPA: {
|
|
CF: {
|
|
colors: [
|
|
{ name: 'Black', refill: false, spool: true },
|
|
],
|
|
},
|
|
},
|
|
PPS: {
|
|
CF: {
|
|
colors: [
|
|
{ name: 'Black', refill: false, spool: true },
|
|
],
|
|
},
|
|
},
|
|
};
|
|
|
|
// Helper functions
|
|
|
|
export function getMaterialOptions(): string[] {
|
|
return Object.keys(BAMBU_LAB_CATALOG).sort();
|
|
}
|
|
|
|
export function getFinishesForMaterial(material: string): string[] {
|
|
const materialData = BAMBU_LAB_CATALOG[material];
|
|
if (!materialData) return [];
|
|
return Object.keys(materialData).sort();
|
|
}
|
|
|
|
export function getAllFinishes(): string[] {
|
|
const finishes = new Set<string>();
|
|
for (const material of Object.values(BAMBU_LAB_CATALOG)) {
|
|
for (const finish of Object.keys(material)) {
|
|
finishes.add(finish);
|
|
}
|
|
}
|
|
return [...finishes].sort();
|
|
}
|
|
|
|
export function getColorsForMaterialFinish(material: string, finish: string): CatalogColorEntry[] {
|
|
return BAMBU_LAB_CATALOG[material]?.[finish]?.colors ?? [];
|
|
}
|
|
|
|
export function getColorsForMaterial(material: string): CatalogColorEntry[] {
|
|
const materialData = BAMBU_LAB_CATALOG[material];
|
|
if (!materialData) return [];
|
|
const seen = new Set<string>();
|
|
const result: CatalogColorEntry[] = [];
|
|
for (const finish of Object.values(materialData)) {
|
|
for (const color of finish.colors) {
|
|
if (!seen.has(color.name)) {
|
|
seen.add(color.name);
|
|
result.push(color);
|
|
}
|
|
}
|
|
}
|
|
return result.sort((a, b) => a.name.localeCompare(b.name));
|
|
}
|
|
|
|
export function catalogIsSpoolOnly(material: string, finish: string, color: string): boolean {
|
|
const entry = BAMBU_LAB_CATALOG[material]?.[finish]?.colors.find(c => c.name === color);
|
|
return entry ? (entry.spool && !entry.refill) : false;
|
|
}
|
|
|
|
export function catalogIsRefillOnly(material: string, finish: string, color: string): boolean {
|
|
const entry = BAMBU_LAB_CATALOG[material]?.[finish]?.colors.find(c => c.name === color);
|
|
return entry ? (entry.refill && !entry.spool) : false;
|
|
}
|
|
|
|
export function getFinishOptionsForType(type: string): string[] {
|
|
return getFinishesForMaterial(type);
|
|
}
|