Last active 1720890582

func.ts Raw
1export interface DispatchType {
2 // The type of the input
3 type: string;
4 // The minimum length of the input
5 minlength: number | undefined;
6 // The maximum length of the input
7 maxlength: number | undefined;
8 // The allowed values of the input
9 allowed_values: { [label: string]: string } | undefined;
10 // If bitflag, then the values of the bitflag
11 bitflag_values: { [label: string]: bigint } | undefined;
12}
13
14// Returns the type to be dispatched to InputDispatcher
15export const getDispatchType = (fields: Record<string, any>, column: CanonicalColumn): DispatchType => {
16 const _setOnDispatchType = <T extends keyof DispatchType>(
17 dispatchType: DispatchType,
18 key: T,
19 value: DispatchType[T]
20 ) => {
21 if (!dispatchType[key] || (Array.isArray(dispatchType[key]) && dispatchType[key].length == 0)) {
22 dispatchType[key] = value;
23 }
24 return dispatchType;
25 };
26
27 // Check for __{}_displaytype
28
29 /*
30 "channel" => return format!("<#{}>", value),
31 "role" => return format!("<@&{}>", value),
32 "user" => return format!("<@{}>", value),
33 */
34
35 let dispatchType: DispatchType = {
36 type: '',
37 minlength: undefined,
38 maxlength: undefined,
39 allowed_values: undefined,
40 bitflag_values: undefined
41 };
42
43 if (fields[`__${column.id}_displaytype`]) {
44 // Set the dispatch type to string:displaytype
45 _setOnDispatchType(dispatchType, 'type', `string:${fields[`__${column.id}_displaytype`]}`);
46 }
47
48 const handleInner = (
49 dispatchType: DispatchType,
50 inner: CanonicalInnerColumnType
51 ): DispatchType => {
52 /*
53#[derive(Debug, Clone, PartialEq)]
54#[allow(dead_code)]
55pub enum InnerColumnType {
56Uuid {},
57String {
58 min_length: Option<usize>,
59 max_length: Option<usize>,
60 allowed_values: Vec<&'static str>, // If empty, all values are allowed
61 kind: InnerColumnTypeStringKind,
62},
63Timestamp {},
64TimestampTz {},
65Integer {},
66Float {},
67BitFlag {
68 /// The bit flag values
69 values: indexmap::IndexMap<&'static str, i64>,
70},
71Boolean {},
72Json {},
73}
74 */
75
76 if (inner.String) {
77 _setOnDispatchType(dispatchType, 'minlength', inner.String.min_length);
78 _setOnDispatchType(dispatchType, 'maxlength', inner.String.max_length);
79
80 if (inner.String.allowed_values) {
81 // Set the allowed values
82 let allowedValues: { [label: string]: string } = {};
83 inner.String.allowed_values.forEach((value) => {
84 allowedValues[value] = value;
85 });
86 _setOnDispatchType(dispatchType, 'allowed_values', allowedValues);
87 }
88
89 // Handle the kind
90 if (inner.String.kind == 'Normal') {
91 _setOnDispatchType(dispatchType, 'type', 'string');
92 } else if (inner.String.kind == 'User') {
93 _setOnDispatchType(dispatchType, 'type', 'string:user');
94 } else if (inner.String.kind == 'Channel') {
95 _setOnDispatchType(dispatchType, 'type', 'string:channel');
96 } else if (inner.String.kind == 'Role') {
97 _setOnDispatchType(dispatchType, 'type', 'string:role');
98 } else if (inner.String.kind == 'Emoji') {
99 _setOnDispatchType(dispatchType, 'type', 'string:emoji');
100 } else if (inner.String.kind == 'Message') {
101 _setOnDispatchType(dispatchType, 'type', 'string:message');
102 } else if (inner.String.kind == 'Template') {
103 _setOnDispatchType(dispatchType, 'type', 'string:template');
104 } else {
105 _setOnDispatchType(
106 dispatchType,
107 'type',
108 inner.String.kind ? `string:${inner.String.kind?.toLowerCase()}` : 'string'
109 );
110 }
111 } else if (inner.Uuid) {
112 _setOnDispatchType(dispatchType, 'type', 'uuid');
113 } else if (inner.Timestamp) {
114 _setOnDispatchType(dispatchType, 'type', 'timestamp');
115 } else if (inner.TimestampTz) {
116 _setOnDispatchType(dispatchType, 'type', 'timestamptz');
117 } else if (inner.Integer) {
118 _setOnDispatchType(dispatchType, 'type', 'integer');
119 } else if (inner.Float) {
120 _setOnDispatchType(dispatchType, 'type', 'float');
121 } else if (inner.Boolean) {
122 _setOnDispatchType(dispatchType, 'type', 'boolean');
123 } else if (inner.BitFlag) {
124 _setOnDispatchType(dispatchType, 'type', 'bitflag');
125
126 // Until the rust server code can handle bigint correctly, convert them here ourselves
127 let values: { [label: string]: bigint } = {};
128
129 Object.keys(inner.BitFlag.values).forEach((value) => {
130 if (!inner.BitFlag) return; // TS can't infer that inner.BitFlag is still not null here
131 values[value] = BigInt(inner.BitFlag.values[value]);
132 });
133
134 _setOnDispatchType(dispatchType, 'bitflag_values', values);
135 } else if (inner.Json) {
136 _setOnDispatchType(dispatchType, 'type', 'json');
137 } else {
138 _setOnDispatchType(dispatchType, 'type', Object.keys(inner)[0].toLowerCase());
139 }
140
141 return dispatchType;
142 };
143
144 if (column.column_type.Scalar) {
145 return handleInner(dispatchType, column.column_type.Scalar.column_type);
146 } else if (column.column_type.Array) {
147 return handleInner(dispatchType, column.column_type.Array.inner);
148 } else {
149 return dispatchType;
150 }
151};
152