From 24a90dfdfecf3d985a37f5b62e28d458e493fd87 Mon Sep 17 00:00:00 2001 From: kitsuyui Date: Wed, 27 May 2026 00:45:48 +0900 Subject: [PATCH 1/2] fix(message-builder): replace as-cast with explicit type annotation for defaultRules --- src/message_builder.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/message_builder.ts b/src/message_builder.ts index 2c5b548..9fc0cfa 100644 --- a/src/message_builder.ts +++ b/src/message_builder.ts @@ -113,7 +113,7 @@ class MessageBuilder { } } -const defaultRules = { +const defaultRules: { [key in RulesKey]: boolean } = { pr_reaches_contain_only_one_nonzero_digit: true, pr_reaches_power_of_2: true, pr_reaches_777: true, @@ -122,7 +122,7 @@ const defaultRules = { commit_hits_123: true, commit_hits_hexspeak: true, commit_hits_666: true, -} as { [key in RulesKey]: boolean } +} /** * CustomMessageBuilder is a class to build a message for a pull request with custom rules From fd6ce4e61695d87261d7847b5cc1b87dad68135a Mon Sep 17 00:00:00 2001 From: kitsuyui Date: Wed, 27 May 2026 05:27:19 +0900 Subject: [PATCH 2/2] chore(dist): regenerate message_builder.mjs.map after defaultRules type annotation change Source map drift detected by test job's git diff --exit-code -- dist guard. The defaultRules as-cast removal in src/message_builder.ts caused the source map to be regenerated by tsdown but the new map was not included in the original commit. --- dist/message_builder.mjs.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/message_builder.mjs.map b/dist/message_builder.mjs.map index 19407ff..b4bf9fa 100644 --- a/dist/message_builder.mjs.map +++ b/dist/message_builder.mjs.map @@ -1 +1 @@ -{"version":3,"file":"message_builder.mjs","names":["Mustache"],"sources":["../src/message_builder.ts"],"sourcesContent":["import Mustache from 'mustache'\n\nimport type {\n LuckyJudgeContext,\n MessageContext,\n MessageForRule,\n} from './interfaces'\nimport { isRareEnough } from './rarity'\nimport { Rules, type RulesKey } from './rules'\n\n/**\n * MessageBuilder is a class to build a message for a pull request\n *\n * It has two kinds of rules, one is for pull request, the other is for commit.\n */\nclass MessageBuilder {\n rules: MessageForRule[]\n baseTemplate: string\n\n constructor(rules: MessageForRule[], baseTemplate: string) {\n this.rules = rules\n this.baseTemplate = baseTemplate\n }\n\n prRules(): MessageForRule[] {\n return this.rules.filter((rule) => rule.kind === 'pr')\n }\n\n commitRules(): MessageForRule[] {\n return this.rules.filter((rule) => rule.kind === 'commit')\n }\n\n private canRenderRule(\n expectedOccurrences: MessageForRule['expectedOccurrences'],\n context: LuckyJudgeContext\n ): boolean {\n return (\n !expectedOccurrences ||\n isRareEnough(expectedOccurrences(context), context.maxExpectedOccurrences)\n )\n }\n\n private renderMessage<\n T extends Record,\n >(\n ruleConfig: MessageForRule,\n value: T,\n valueName: keyof T,\n context: LuckyJudgeContext\n ): string | null {\n const target = value[valueName]\n if (typeof target !== 'string') {\n return null\n }\n\n const matched = target.match(ruleConfig.rule)\n if (\n !matched ||\n !this.canRenderRule(ruleConfig.expectedOccurrences, context)\n ) {\n return null\n }\n\n return Mustache.render(ruleConfig.message, {\n ...value,\n matched: matched[0],\n })\n }\n\n private renderMessages<\n T extends Record,\n >(\n rules: MessageForRule[],\n values: T[],\n valueName: keyof T,\n context: LuckyJudgeContext\n ): string[] {\n return rules.flatMap((ruleConfig) =>\n values.flatMap((value) => {\n const message = this.renderMessage(\n ruleConfig,\n value,\n valueName,\n context\n )\n return message ? [message] : []\n })\n )\n }\n\n build(context: LuckyJudgeContext): MessageContext {\n const { commitIds, prNum } = context\n const messages = [\n ...this.renderMessages(\n this.prRules(),\n [{ prNum: prNum.toString() }],\n 'prNum',\n context\n ),\n ...this.renderMessages(\n this.commitRules(),\n commitIds.map((commitId) => ({ commitId })),\n 'commitId',\n context\n ),\n ]\n\n const body = Mustache.render(this.baseTemplate, { messages })\n return {\n lucky: messages.length > 0,\n body,\n }\n }\n}\n\nconst defaultRules = {\n pr_reaches_contain_only_one_nonzero_digit: true,\n pr_reaches_power_of_2: true,\n pr_reaches_777: true,\n commit_hits_777: true,\n commit_hits_same_numbers: true,\n commit_hits_123: true,\n commit_hits_hexspeak: true,\n commit_hits_666: true,\n} as { [key in RulesKey]: boolean }\n\n/**\n * CustomMessageBuilder is a class to build a message for a pull request with custom rules\n */\nexport class CustomMessageBuilder {\n builder: MessageBuilder\n\n constructor(\n message: string,\n overrides: { [key in RulesKey]?: boolean } = {},\n additionalRules: MessageForRule[] = []\n ) {\n const rules: MessageForRule[] = [...additionalRules].concat(\n Object.entries(Rules)\n .filter(([key]) => {\n if (key in overrides) {\n return overrides[key as RulesKey]\n }\n return defaultRules[key as RulesKey]\n })\n .map(([, value]) => value)\n )\n this.builder = new MessageBuilder(rules, message)\n }\n\n build(context: LuckyJudgeContext): MessageContext {\n return this.builder.build(context)\n }\n}\n"],"mappings":"uJAeA,IAAM,EAAN,KAAqB,CACnB,MACA,aAEA,YAAY,EAAyB,EAAsB,CACzD,KAAK,MAAQ,EACb,KAAK,aAAe,EAGtB,SAA4B,CAC1B,OAAO,KAAK,MAAM,OAAQ,GAAS,EAAK,OAAS,KAAK,CAGxD,aAAgC,CAC9B,OAAO,KAAK,MAAM,OAAQ,GAAS,EAAK,OAAS,SAAS,CAG5D,cACE,EACA,EACS,CACT,MACE,CAAC,GACD,EAAa,EAAoB,EAAQ,CAAE,EAAQ,uBAAuB,CAI9E,cAGE,EACA,EACA,EACA,EACe,CACf,IAAM,EAAS,EAAM,GACrB,GAAI,OAAO,GAAW,SACpB,OAAO,KAGT,IAAM,EAAU,EAAO,MAAM,EAAW,KAAK,CAQ7C,MANE,CAAC,GACD,CAAC,KAAK,cAAc,EAAW,oBAAqB,EAAQ,CAErD,KAGFA,EAAS,OAAO,EAAW,QAAS,CACzC,GAAG,EACH,QAAS,EAAQ,GAClB,CAAC,CAGJ,eAGE,EACA,EACA,EACA,EACU,CACV,OAAO,EAAM,QAAS,GACpB,EAAO,QAAS,GAAU,CACxB,IAAM,EAAU,KAAK,cACnB,EACA,EACA,EACA,EACD,CACD,OAAO,EAAU,CAAC,EAAQ,CAAG,EAAE,EAC/B,CACH,CAGH,MAAM,EAA4C,CAChD,GAAM,CAAE,YAAW,SAAU,EACvB,EAAW,CACf,GAAG,KAAK,eACN,KAAK,SAAS,CACd,CAAC,CAAE,MAAO,EAAM,UAAU,CAAE,CAAC,CAC7B,QACA,EACD,CACD,GAAG,KAAK,eACN,KAAK,aAAa,CAClB,EAAU,IAAK,IAAc,CAAE,WAAU,EAAE,CAC3C,WACA,EACD,CACF,CAEK,EAAOA,EAAS,OAAO,KAAK,aAAc,CAAE,WAAU,CAAC,CAC7D,MAAO,CACL,MAAO,EAAS,OAAS,EACzB,OACD,GAIL,MAAM,EAAe,CACnB,0CAA2C,GAC3C,sBAAuB,GACvB,eAAgB,GAChB,gBAAiB,GACjB,yBAA0B,GAC1B,gBAAiB,GACjB,qBAAsB,GACtB,gBAAiB,GAClB,CAKD,IAAa,EAAb,KAAkC,CAChC,QAEA,YACE,EACA,EAA6C,EAAE,CAC/C,EAAoC,EAAE,CACtC,CAWA,KAAK,QAAU,IAAI,EAVa,CAAC,GAAG,EAAgB,CAAC,OACnD,OAAO,QAAQ,EAAM,CAClB,QAAQ,CAAC,KACJ,KAAO,EACF,EAAU,GAEZ,EAAa,GACpB,CACD,KAAK,EAAG,KAAW,EAAM,CAC7B,CACwC,EAAQ,CAGnD,MAAM,EAA4C,CAChD,OAAO,KAAK,QAAQ,MAAM,EAAQ"} \ No newline at end of file +{"version":3,"file":"message_builder.mjs","names":["Mustache"],"sources":["../src/message_builder.ts"],"sourcesContent":["import Mustache from 'mustache'\n\nimport type {\n LuckyJudgeContext,\n MessageContext,\n MessageForRule,\n} from './interfaces'\nimport { isRareEnough } from './rarity'\nimport { Rules, type RulesKey } from './rules'\n\n/**\n * MessageBuilder is a class to build a message for a pull request\n *\n * It has two kinds of rules, one is for pull request, the other is for commit.\n */\nclass MessageBuilder {\n rules: MessageForRule[]\n baseTemplate: string\n\n constructor(rules: MessageForRule[], baseTemplate: string) {\n this.rules = rules\n this.baseTemplate = baseTemplate\n }\n\n prRules(): MessageForRule[] {\n return this.rules.filter((rule) => rule.kind === 'pr')\n }\n\n commitRules(): MessageForRule[] {\n return this.rules.filter((rule) => rule.kind === 'commit')\n }\n\n private canRenderRule(\n expectedOccurrences: MessageForRule['expectedOccurrences'],\n context: LuckyJudgeContext\n ): boolean {\n return (\n !expectedOccurrences ||\n isRareEnough(expectedOccurrences(context), context.maxExpectedOccurrences)\n )\n }\n\n private renderMessage<\n T extends Record,\n >(\n ruleConfig: MessageForRule,\n value: T,\n valueName: keyof T,\n context: LuckyJudgeContext\n ): string | null {\n const target = value[valueName]\n if (typeof target !== 'string') {\n return null\n }\n\n const matched = target.match(ruleConfig.rule)\n if (\n !matched ||\n !this.canRenderRule(ruleConfig.expectedOccurrences, context)\n ) {\n return null\n }\n\n return Mustache.render(ruleConfig.message, {\n ...value,\n matched: matched[0],\n })\n }\n\n private renderMessages<\n T extends Record,\n >(\n rules: MessageForRule[],\n values: T[],\n valueName: keyof T,\n context: LuckyJudgeContext\n ): string[] {\n return rules.flatMap((ruleConfig) =>\n values.flatMap((value) => {\n const message = this.renderMessage(\n ruleConfig,\n value,\n valueName,\n context\n )\n return message ? [message] : []\n })\n )\n }\n\n build(context: LuckyJudgeContext): MessageContext {\n const { commitIds, prNum } = context\n const messages = [\n ...this.renderMessages(\n this.prRules(),\n [{ prNum: prNum.toString() }],\n 'prNum',\n context\n ),\n ...this.renderMessages(\n this.commitRules(),\n commitIds.map((commitId) => ({ commitId })),\n 'commitId',\n context\n ),\n ]\n\n const body = Mustache.render(this.baseTemplate, { messages })\n return {\n lucky: messages.length > 0,\n body,\n }\n }\n}\n\nconst defaultRules: { [key in RulesKey]: boolean } = {\n pr_reaches_contain_only_one_nonzero_digit: true,\n pr_reaches_power_of_2: true,\n pr_reaches_777: true,\n commit_hits_777: true,\n commit_hits_same_numbers: true,\n commit_hits_123: true,\n commit_hits_hexspeak: true,\n commit_hits_666: true,\n}\n\n/**\n * CustomMessageBuilder is a class to build a message for a pull request with custom rules\n */\nexport class CustomMessageBuilder {\n builder: MessageBuilder\n\n constructor(\n message: string,\n overrides: { [key in RulesKey]?: boolean } = {},\n additionalRules: MessageForRule[] = []\n ) {\n const rules: MessageForRule[] = [...additionalRules].concat(\n Object.entries(Rules)\n .filter(([key]) => {\n if (key in overrides) {\n return overrides[key as RulesKey]\n }\n return defaultRules[key as RulesKey]\n })\n .map(([, value]) => value)\n )\n this.builder = new MessageBuilder(rules, message)\n }\n\n build(context: LuckyJudgeContext): MessageContext {\n return this.builder.build(context)\n }\n}\n"],"mappings":"uJAeA,IAAM,EAAN,KAAqB,CACnB,MACA,aAEA,YAAY,EAAyB,EAAsB,CACzD,KAAK,MAAQ,EACb,KAAK,aAAe,EAGtB,SAA4B,CAC1B,OAAO,KAAK,MAAM,OAAQ,GAAS,EAAK,OAAS,KAAK,CAGxD,aAAgC,CAC9B,OAAO,KAAK,MAAM,OAAQ,GAAS,EAAK,OAAS,SAAS,CAG5D,cACE,EACA,EACS,CACT,MACE,CAAC,GACD,EAAa,EAAoB,EAAQ,CAAE,EAAQ,uBAAuB,CAI9E,cAGE,EACA,EACA,EACA,EACe,CACf,IAAM,EAAS,EAAM,GACrB,GAAI,OAAO,GAAW,SACpB,OAAO,KAGT,IAAM,EAAU,EAAO,MAAM,EAAW,KAAK,CAQ7C,MANE,CAAC,GACD,CAAC,KAAK,cAAc,EAAW,oBAAqB,EAAQ,CAErD,KAGFA,EAAS,OAAO,EAAW,QAAS,CACzC,GAAG,EACH,QAAS,EAAQ,GAClB,CAAC,CAGJ,eAGE,EACA,EACA,EACA,EACU,CACV,OAAO,EAAM,QAAS,GACpB,EAAO,QAAS,GAAU,CACxB,IAAM,EAAU,KAAK,cACnB,EACA,EACA,EACA,EACD,CACD,OAAO,EAAU,CAAC,EAAQ,CAAG,EAAE,EAC/B,CACH,CAGH,MAAM,EAA4C,CAChD,GAAM,CAAE,YAAW,SAAU,EACvB,EAAW,CACf,GAAG,KAAK,eACN,KAAK,SAAS,CACd,CAAC,CAAE,MAAO,EAAM,UAAU,CAAE,CAAC,CAC7B,QACA,EACD,CACD,GAAG,KAAK,eACN,KAAK,aAAa,CAClB,EAAU,IAAK,IAAc,CAAE,WAAU,EAAE,CAC3C,WACA,EACD,CACF,CAEK,EAAOA,EAAS,OAAO,KAAK,aAAc,CAAE,WAAU,CAAC,CAC7D,MAAO,CACL,MAAO,EAAS,OAAS,EACzB,OACD,GAIL,MAAM,EAA+C,CACnD,0CAA2C,GAC3C,sBAAuB,GACvB,eAAgB,GAChB,gBAAiB,GACjB,yBAA0B,GAC1B,gBAAiB,GACjB,qBAAsB,GACtB,gBAAiB,GAClB,CAKD,IAAa,EAAb,KAAkC,CAChC,QAEA,YACE,EACA,EAA6C,EAAE,CAC/C,EAAoC,EAAE,CACtC,CAWA,KAAK,QAAU,IAAI,EAVa,CAAC,GAAG,EAAgB,CAAC,OACnD,OAAO,QAAQ,EAAM,CAClB,QAAQ,CAAC,KACJ,KAAO,EACF,EAAU,GAEZ,EAAa,GACpB,CACD,KAAK,EAAG,KAAW,EAAM,CAC7B,CACwC,EAAQ,CAGnD,MAAM,EAA4C,CAChD,OAAO,KAAK,QAAQ,MAAM,EAAQ"} \ No newline at end of file