func.ts
· 5.5 KiB · TypeScript
Sin formato
export interface DispatchType {
// The type of the input
type: string;
// The minimum length of the input
minlength: number | undefined;
// The maximum length of the input
maxlength: number | undefined;
// The allowed values of the input
allowed_values: { [label: string]: string } | undefined;
// If bitflag, then the values of the bitflag
bitflag_values: { [label: string]: bigint } | undefined;
}
// Returns the type to be dispatched to InputDispatcher
export const getDispatchType = (fields: Record<string, any>, column: CanonicalColumn): DispatchType => {
const _setOnDispatchType = <T extends keyof DispatchType>(
dispatchType: DispatchType,
key: T,
value: DispatchType[T]
) => {
if (!dispatchType[key] || (Array.isArray(dispatchType[key]) && dispatchType[key].length == 0)) {
dispatchType[key] = value;
}
return dispatchType;
};
// Check for __{}_displaytype
/*
"channel" => return format!("<#{}>", value),
"role" => return format!("<@&{}>", value),
"user" => return format!("<@{}>", value),
*/
let dispatchType: DispatchType = {
type: '',
minlength: undefined,
maxlength: undefined,
allowed_values: undefined,
bitflag_values: undefined
};
if (fields[`__${column.id}_displaytype`]) {
// Set the dispatch type to string:displaytype
_setOnDispatchType(dispatchType, 'type', `string:${fields[`__${column.id}_displaytype`]}`);
}
const handleInner = (
dispatchType: DispatchType,
inner: CanonicalInnerColumnType
): DispatchType => {
/*
#[derive(Debug, Clone, PartialEq)]
#[allow(dead_code)]
pub enum InnerColumnType {
Uuid {},
String {
min_length: Option<usize>,
max_length: Option<usize>,
allowed_values: Vec<&'static str>, // If empty, all values are allowed
kind: InnerColumnTypeStringKind,
},
Timestamp {},
TimestampTz {},
Integer {},
Float {},
BitFlag {
/// The bit flag values
values: indexmap::IndexMap<&'static str, i64>,
},
Boolean {},
Json {},
}
*/
if (inner.String) {
_setOnDispatchType(dispatchType, 'minlength', inner.String.min_length);
_setOnDispatchType(dispatchType, 'maxlength', inner.String.max_length);
if (inner.String.allowed_values) {
// Set the allowed values
let allowedValues: { [label: string]: string } = {};
inner.String.allowed_values.forEach((value) => {
allowedValues[value] = value;
});
_setOnDispatchType(dispatchType, 'allowed_values', allowedValues);
}
// Handle the kind
if (inner.String.kind == 'Normal') {
_setOnDispatchType(dispatchType, 'type', 'string');
} else if (inner.String.kind == 'User') {
_setOnDispatchType(dispatchType, 'type', 'string:user');
} else if (inner.String.kind == 'Channel') {
_setOnDispatchType(dispatchType, 'type', 'string:channel');
} else if (inner.String.kind == 'Role') {
_setOnDispatchType(dispatchType, 'type', 'string:role');
} else if (inner.String.kind == 'Emoji') {
_setOnDispatchType(dispatchType, 'type', 'string:emoji');
} else if (inner.String.kind == 'Message') {
_setOnDispatchType(dispatchType, 'type', 'string:message');
} else if (inner.String.kind == 'Template') {
_setOnDispatchType(dispatchType, 'type', 'string:template');
} else {
_setOnDispatchType(
dispatchType,
'type',
inner.String.kind ? `string:${inner.String.kind?.toLowerCase()}` : 'string'
);
}
} else if (inner.Uuid) {
_setOnDispatchType(dispatchType, 'type', 'uuid');
} else if (inner.Timestamp) {
_setOnDispatchType(dispatchType, 'type', 'timestamp');
} else if (inner.TimestampTz) {
_setOnDispatchType(dispatchType, 'type', 'timestamptz');
} else if (inner.Integer) {
_setOnDispatchType(dispatchType, 'type', 'integer');
} else if (inner.Float) {
_setOnDispatchType(dispatchType, 'type', 'float');
} else if (inner.Boolean) {
_setOnDispatchType(dispatchType, 'type', 'boolean');
} else if (inner.BitFlag) {
_setOnDispatchType(dispatchType, 'type', 'bitflag');
// Until the rust server code can handle bigint correctly, convert them here ourselves
let values: { [label: string]: bigint } = {};
Object.keys(inner.BitFlag.values).forEach((value) => {
if (!inner.BitFlag) return; // TS can't infer that inner.BitFlag is still not null here
values[value] = BigInt(inner.BitFlag.values[value]);
});
_setOnDispatchType(dispatchType, 'bitflag_values', values);
} else if (inner.Json) {
_setOnDispatchType(dispatchType, 'type', 'json');
} else {
_setOnDispatchType(dispatchType, 'type', Object.keys(inner)[0].toLowerCase());
}
return dispatchType;
};
if (column.column_type.Scalar) {
return handleInner(dispatchType, column.column_type.Scalar.column_type);
} else if (column.column_type.Array) {
return handleInner(dispatchType, column.column_type.Array.inner);
} else {
return dispatchType;
}
};
1 | export 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 |
15 | export 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)] |
55 | pub enum InnerColumnType { |
56 | Uuid {}, |
57 | String { |
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 | }, |
63 | Timestamp {}, |
64 | TimestampTz {}, |
65 | Integer {}, |
66 | Float {}, |
67 | BitFlag { |
68 | /// The bit flag values |
69 | values: indexmap::IndexMap<&'static str, i64>, |
70 | }, |
71 | Boolean {}, |
72 | Json {}, |
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 |