👁️
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

known values for format, kitchen table and draft

+151 -21
+34 -4
lexicons/com/deckbelcher/deck/list.json
··· 15 15 "description": "Name of the decklist." 16 16 }, 17 17 "format": { 18 - "type": "string", 19 - "maxLength": 320, 20 - "maxGraphemes": 32, 21 - "description": "Format of the deck (e.g., \"commander\", \"cube\", \"pauper\")." 18 + "type": "ref", 19 + "ref": "#format", 20 + "description": "Format of the deck." 22 21 }, 23 22 "primer": { 24 23 "type": "union", ··· 119 118 "quantity", 120 119 "section" 121 120 ] 121 + }, 122 + "format": { 123 + "type": "string", 124 + "knownValues": [ 125 + "standard", 126 + "pioneer", 127 + "modern", 128 + "legacy", 129 + "vintage", 130 + "pauper", 131 + "commander", 132 + "duel", 133 + "paupercommander", 134 + "predh", 135 + "oathbreaker", 136 + "brawl", 137 + "standardbrawl", 138 + "historic", 139 + "timeless", 140 + "alchemy", 141 + "gladiator", 142 + "premodern", 143 + "oldschool", 144 + "draft", 145 + "penny", 146 + "cube", 147 + "kitchentable" 148 + ], 149 + "maxLength": 320, 150 + "maxGraphemes": 32, 151 + "description": "Game format for a deck." 122 152 }, 123 153 "section": { 124 154 "type": "string",
+12
src/lib/deck-validation/presets.ts
··· 145 145 rules: SIXTY_CARD_RULES, 146 146 config: { legalityField: "penny", minDeckSize: 60, sideboardSize: 15 }, 147 147 }, 148 + 149 + // Limited 150 + draft: { 151 + rules: ["deckSizeMin"] as const, 152 + config: { minDeckSize: 40 }, 153 + }, 154 + 155 + // Casual 156 + kitchentable: { 157 + rules: [] as const, 158 + config: {}, 159 + }, 148 160 } as const satisfies Record<string, Preset<RuleId>>; 149 161 150 162 export type FormatId = keyof typeof PRESETS;
+14 -3
src/lib/deck-validation/rules/base.ts
··· 26 26 description: "Card must be legal in format", 27 27 validate(ctx: ValidationContext): Violation[] { 28 28 const { deck, cardLookup, config } = ctx; 29 - const violations: Violation[] = []; 30 29 const field = config.legalityField; 30 + 31 + // Formats without a legality field (draft, kitchentable) skip this check 32 + if (!field) return []; 33 + 34 + const violations: Violation[] = []; 31 35 32 36 // For PDH, commanders are validated by commanderUncommon rule instead 33 37 const skipCommanderLegality = field === "paupercommander"; ··· 74 78 description: "Card is banned in format", 75 79 validate(ctx: ValidationContext): Violation[] { 76 80 const { deck, cardLookup, config } = ctx; 81 + const field = config.legalityField; 82 + 83 + // Formats without a legality field (draft, kitchentable) skip this check 84 + if (!field) return []; 85 + 77 86 const violations: Violation[] = []; 78 - const field = config.legalityField; 79 87 80 88 for (const entry of deck.cards) { 81 89 if (entry.section === "maybeboard") continue; ··· 118 126 description: "Restricted cards limited to 1 copy", 119 127 validate(ctx: ValidationContext): Violation[] { 120 128 const { deck, oracleLookup, config } = ctx; 121 - const violations: Violation[] = []; 122 129 const field = config.legalityField; 123 130 131 + // Formats without a legality field (draft, kitchentable) skip this check 132 + if (!field) return []; 133 + 134 + const violations: Violation[] = []; 124 135 const oracleCounts = new Map<OracleId, number>(); 125 136 126 137 for (const entry of deck.cards) {
+1 -1
src/lib/deck-validation/types.ts
··· 68 68 * Per-format configuration parameters 69 69 */ 70 70 export interface FormatConfig { 71 - legalityField: string; 71 + legalityField?: string; 72 72 minDeckSize?: number; 73 73 deckSize?: number; 74 74 sideboardSize?: number;
+11
src/lib/format-utils.ts
··· 56 56 premodern: "1995–2003 cards", 57 57 oldschool: "1993–1994 cards", 58 58 59 + // Limited 60 + draft: "40-card · Drafted cards + basic lands", 61 + 59 62 // Other 60 63 penny: "Budget · Rotating cheapest", 61 64 cube: "Draft · Custom card pool", 65 + 66 + // Casual 67 + kitchentable: "Anything goes", 62 68 }; 63 69 64 70 /** ··· 171 177 ], 172 178 }, 173 179 { 180 + label: "Limited", 181 + formats: [{ value: "draft", label: "Draft" }], 182 + }, 183 + { 174 184 label: "Other", 175 185 formats: [ 176 186 { value: "penny", label: "Penny Dreadful" }, 177 187 { value: "cube", label: "Cube" }, 188 + { value: "kitchentable", label: "Kitchen Table" }, 178 189 ], 179 190 }, 180 191 ];
+40 -9
src/lib/lexicons/types/com/deckbelcher/deck/list.ts
··· 44 44 ), 45 45 ), 46 46 }); 47 + const _formatSchema = /*#__PURE__*/ v.constrain( 48 + /*#__PURE__*/ v.string< 49 + | "alchemy" 50 + | "brawl" 51 + | "commander" 52 + | "cube" 53 + | "draft" 54 + | "duel" 55 + | "gladiator" 56 + | "historic" 57 + | "kitchentable" 58 + | "legacy" 59 + | "modern" 60 + | "oathbreaker" 61 + | "oldschool" 62 + | "pauper" 63 + | "paupercommander" 64 + | "penny" 65 + | "pioneer" 66 + | "predh" 67 + | "premodern" 68 + | "standard" 69 + | "standardbrawl" 70 + | "timeless" 71 + | "vintage" 72 + | (string & {}) 73 + >(), 74 + [ 75 + /*#__PURE__*/ v.stringLength(0, 320), 76 + /*#__PURE__*/ v.stringGraphemes(0, 32), 77 + ], 78 + ); 47 79 const _mainSchema = /*#__PURE__*/ v.record( 48 80 /*#__PURE__*/ v.tidString(), 49 81 /*#__PURE__*/ v.object({ ··· 59 91 */ 60 92 createdAt: /*#__PURE__*/ v.datetimeString(), 61 93 /** 62 - * Format of the deck (e.g., "commander", "cube", "pauper"). 63 - * @maxLength 320 64 - * @maxGraphemes 32 94 + * Format of the deck. 65 95 */ 66 - format: /*#__PURE__*/ v.optional( 67 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 68 - /*#__PURE__*/ v.stringLength(0, 320), 69 - /*#__PURE__*/ v.stringGraphemes(0, 32), 70 - ]), 71 - ), 96 + get format() { 97 + return /*#__PURE__*/ v.optional(formatSchema); 98 + }, 72 99 /** 73 100 * Name of the decklist. 74 101 * @maxLength 1280 ··· 128 155 ); 129 156 130 157 type card$schematype = typeof _cardSchema; 158 + type format$schematype = typeof _formatSchema; 131 159 type main$schematype = typeof _mainSchema; 132 160 type primerRef$schematype = typeof _primerRefSchema; 133 161 type primerUri$schematype = typeof _primerUriSchema; 134 162 type section$schematype = typeof _sectionSchema; 135 163 136 164 export interface cardSchema extends card$schematype {} 165 + export interface formatSchema extends format$schematype {} 137 166 export interface mainSchema extends main$schematype {} 138 167 export interface primerRefSchema extends primerRef$schematype {} 139 168 export interface primerUriSchema extends primerUri$schematype {} 140 169 export interface sectionSchema extends section$schematype {} 141 170 142 171 export const cardSchema = _cardSchema as cardSchema; 172 + export const formatSchema = _formatSchema as formatSchema; 143 173 export const mainSchema = _mainSchema as mainSchema; 144 174 export const primerRefSchema = _primerRefSchema as primerRefSchema; 145 175 export const primerUriSchema = _primerUriSchema as primerUriSchema; 146 176 export const sectionSchema = _sectionSchema as sectionSchema; 147 177 148 178 export interface Card extends v.InferInput<typeof cardSchema> {} 179 + export type Format = v.InferInput<typeof formatSchema>; 149 180 export interface Main extends v.InferInput<typeof mainSchema> {} 150 181 export interface PrimerRef extends v.InferInput<typeof primerRefSchema> {} 151 182 export interface PrimerUri extends v.InferInput<typeof primerUriSchema> {}
+39 -4
typelex/deck-list.tsp
··· 13 13 @maxLength(1280) 14 14 name: string; 15 15 16 - /** Format of the deck (e.g., "commander", "cube", "pauper"). */ 17 - @maxGraphemes(32) 18 - @maxLength(320) 19 - format?: string; 16 + /** Format of the deck. */ 17 + format?: Format; 20 18 21 19 /** Deck primer with strategy, combos, and card choices. */ 22 20 primer?: Primer; ··· 55 53 model PrimerRef { 56 54 @required 57 55 ref: com.atproto.repo.strongRef.Main; 56 + } 57 + 58 + /** Game format for a deck. */ 59 + @maxGraphemes(32) 60 + @maxLength(320) 61 + union Format { 62 + // Constructed 63 + "standard", 64 + "pioneer", 65 + "modern", 66 + "legacy", 67 + "vintage", 68 + "pauper", 69 + // Commander 70 + "commander", 71 + "duel", 72 + "paupercommander", 73 + "predh", 74 + "oathbreaker", 75 + // Brawl 76 + "brawl", 77 + "standardbrawl", 78 + // Arena 79 + "historic", 80 + "timeless", 81 + "alchemy", 82 + "gladiator", 83 + // Retro 84 + "premodern", 85 + "oldschool", 86 + // Limited 87 + "draft", 88 + // Other 89 + "penny", 90 + "cube", 91 + "kitchentable", 92 + string, 58 93 } 59 94 60 95 /** A tag annotation for a card. */