11/* eslint-disable @typescript-eslint/explicit-function-return-type */
22import { Color , Snowflake } from "#common/schema/general.ts" ;
3- import { template } from "#common/schema/template.ts" ;
3+ import { template , type Template } from "#common/schema/template.ts" ;
44import type { ParameterRecord , TemplateSchema } from "#common/template/index.ts" ;
55import { MessageFlags } from "oceanic.js" ;
66import { TomlDate } from "smol-toml" ;
77import { z } from "zod/v4" ;
88
9- export const MessageLiteral = message ( ( ) => z . string ( ) ) ;
10- export type MessageLiteral = z . infer < typeof MessageLiteral > ;
11-
12- export function messageTemplate < S extends TemplateSchema > ( schema : S ) {
13- const result = message ( markdown => template ( schema , markdown ) )
14- . transform ( ( { content, embeds, ...message } ) => ( params : ParameterRecord < S > ) => ( {
15- content : content ?.( params ) ,
16- embeds : embeds ?. map (
17- ( { author, description, fields, footer, image, thumbnail, title, url, ...embed } ) => ( {
18- author : author !== undefined
19- ? {
20- name : author . name ( params ) ,
21- url : author . url ?.( params ) ,
22- iconURL : author . iconURL ?.( params ) ,
23- }
24- : undefined ,
25- description : description ?.( params ) ,
26- fields : fields ?. map ( ( { name, value, ...field } ) => ( {
27- name : name ?.( params ) ,
28- value : value ?.( params ) ,
29- ...field
30- } ) ) ?? [ ] ,
31- footer : footer !== undefined
32- ? { text : footer . text ( params ) , icon : footer . icon ( params ) }
33- : undefined ,
34- image : image !== undefined ? { url : image . url ( params ) } : undefined ,
35- thumbnail : thumbnail !== undefined ? { url : thumbnail . url ( params ) } : undefined ,
36- title : title ?.( params ) ,
37- url : url ?.( params ) ,
38- ...embed
39- } )
40- ) ?? [ ] ,
41- ...message
42- } ) ) ;
43-
44- // @ts -expect-error avoid parsing constantly
45- result . prefault = content => {
46- const parsed = result . parse ( content ) ;
47- return result . default ( ( ) => parsed ) ;
48- } ;
9+ type Message < Z extends z . ZodType > = z . output < ReturnType < typeof message < Z > > > ;
4910
50- return result ;
51- }
52-
53- function message < Z extends z . ZodTypeAny > ( stringType : ( markdown : boolean ) => Z ) {
11+ function message < Z extends z . ZodType > ( stringType : ( markdown : boolean ) => Z ) {
5412 return z . strictObject ( {
5513 content : stringType ( true ) ,
5614 allowed_mentions : z . strictObject ( {
@@ -59,7 +17,7 @@ function message<Z extends z.ZodTypeAny>(stringType: (markdown: boolean) => Z) {
5917 users : z . union ( [ z . boolean ( ) , Snowflake . array ( ) . max ( 100 ) ] ) ,
6018 roles : z . union ( [ z . boolean ( ) , Snowflake . array ( ) . max ( 100 ) ] ) ,
6119 } ) . partial ( ) . transform ( ( { replied_user, ...input } ) => ( {
62- epliedUser : replied_user , ...input
20+ repliedUser : replied_user , ...input
6321 } ) ) ,
6422 embeds : embed ( stringType ) . array ( ) ,
6523 silent : z . boolean ( ) ,
@@ -70,6 +28,8 @@ function message<Z extends z.ZodTypeAny>(stringType: (markdown: boolean) => Z) {
7028 } ) ) ;
7129}
7230
31+ type Embed < Z extends z . ZodType > = z . output < ReturnType < typeof embed < Z > > > ;
32+
7333function embed < Z extends z . ZodType > ( stringType : ( markdown : boolean ) => Z ) {
7434 return z . strictObject ( {
7535 title : stringType ( true ) ,
@@ -93,3 +53,75 @@ function embed<Z extends z.ZodType>(stringType: (markdown: boolean) => Z) {
9353 } ) . partial ( ) ;
9454}
9555
56+ export const MessageLiteral = message ( ( ) => z . string ( ) ) ;
57+ export type MessageLiteral = z . infer < typeof MessageLiteral > ;
58+
59+ export function messageTemplate < S extends TemplateSchema > ( schema : S ) {
60+ const result = message ( markdown => template ( schema , markdown ) )
61+ . transform ( template => {
62+ return {
63+ apply ( params : ParameterRecord < S > ) {
64+ return applyMessageTemplate ( template , params ) ;
65+ }
66+ } ;
67+ } ) ;
68+
69+ // @ts -expect-error avoid parsing constantly
70+ result . prefault = content => {
71+ const parsed = result . parse ( content ) ;
72+ return result . default ( parsed ) ;
73+ } ;
74+
75+ return result ;
76+ }
77+
78+ function applyMessageTemplate < S extends TemplateSchema > ( template : Message < Template < S > > , params : ParameterRecord < S > ) {
79+ return {
80+ ...template ,
81+ content : template . content ?. apply ( params ) ,
82+ embeds : template . embeds ?. map ( embed => applyEmbedTemplate ( embed , params ) ) ,
83+ } ;
84+ }
85+
86+ function applyEmbedTemplate < S extends TemplateSchema > ( template : Embed < Template < S > > , params : ParameterRecord < S > ) {
87+ const author = template . author !== undefined
88+ ? {
89+ name : template . author . name . apply ( params ) ,
90+ url : template . author . url ?. apply ( params ) ,
91+ iconURL : template . author . iconURL ?. apply ( params ) ,
92+ }
93+ : undefined ;
94+
95+ const fields = template . fields ?. map ( ( { name, value, ...field } ) => ( {
96+ name : name ?. apply ( params ) ,
97+ value : value ?. apply ( params ) ,
98+ ...field
99+ } ) ) ;
100+
101+ const footer = template . footer !== undefined
102+ ? {
103+ text : template . footer . text . apply ( params ) ,
104+ icon : template . footer . icon . apply ( params ) ,
105+ }
106+ : undefined ;
107+
108+ const image = template . image !== undefined
109+ ? { url : template . image . url . apply ( params ) }
110+ : undefined ;
111+
112+ const thumbnail = template . thumbnail !== undefined
113+ ? { url : template . thumbnail . url . apply ( params ) }
114+ : undefined ;
115+
116+ return ( {
117+ ...template ,
118+ author,
119+ description : template . description ?. apply ( params ) ,
120+ fields,
121+ footer,
122+ image,
123+ thumbnail,
124+ title : template . title ?. apply ( params ) ,
125+ url : template . url ?. apply ( params )
126+ } ) ;
127+ }
0 commit comments