-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathpayload-value-converter.ts
149 lines (130 loc) · 3.79 KB
/
payload-value-converter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* eslint-disable valid-jsdoc */
import BigNumber from 'bignumber.js';
import moment from 'moment';
import { Time, EdmTypeShared } from '../odata-common';
import {
deserializersCommon,
serializersCommom
} from '../odata-common/payload-value-converter';
import { EdmTypeV2 } from './edm-types';
/**
* @hidden
*/
export function edmToTsV2<T extends EdmTypeV2>(
value: any,
edmType: EdmTypeShared<'v2'>
): EdmToPrimitiveV2<T> {
if (value === null || typeof value === 'undefined') {
return value;
}
if (deserializers[edmType]) {
return deserializers[edmType](value);
}
return value;
}
/**
* @hidden
*/
export function tsToEdmV2(value: any, edmType: EdmTypeShared<'v2'>): any {
if (value === null) {
return 'null';
}
if (serializers[edmType]) {
return serializers[edmType](value);
}
return value;
}
type EdmTypeMapping = { [key in EdmTypeV2]: (value: any) => any };
const toTime = (value: string): Time => {
const timeComponents = /PT(\d{1,2})H(\d{1,2})M(\d{1,2})S/.exec(value);
if (!timeComponents) {
throw new Error(`Failed to parse the value: ${value} to time.`);
}
return {
hours: parseInt(timeComponents[1], 10),
minutes: parseInt(timeComponents[2], 10),
seconds: parseInt(timeComponents[3], 10)
};
};
/**
* @hidden
* This function can be used for both Edm.DateTime and and Edm.DateTimeOffset.
*/
export function edmDateTimeToMoment(edmDateTime: string): moment.Moment {
const dateTimeOffsetComponents = /.*\((-?\d+)(?:([\+-])(\d{4})\))?/.exec(
edmDateTime
);
if (!dateTimeOffsetComponents) {
throw new Error(`Failed to parse edmDateTime: ${edmDateTime} to moment.`);
}
const timestamp = moment(parseInt(dateTimeOffsetComponents[1]));
if (dateTimeOffsetComponents[2] && dateTimeOffsetComponents[3]) {
const offsetMultiplier = dateTimeOffsetComponents[2] === '+' ? 1 : -1;
const offsetInMinutes = parseInt(dateTimeOffsetComponents[3]);
return timestamp.utc().utcOffset(offsetMultiplier * offsetInMinutes);
}
return timestamp;
}
/**
* @hidden
* This function can be used for both Edm.DateTime and and Edm.DateTimeOffset.
*/
export function momentToEdmDateTime(momentInstance: moment.Moment): string {
const timestamp = momentInstance.unix() * 1000;
// For some reason isUtc() returns wrong values here, so we use the internal flag directly
if (momentInstance['_isUTC']) {
const offset = Math.abs(momentInstance.utcOffset());
const operator = momentInstance.utcOffset() >= 0 ? '+' : '-';
return `/Date(${timestamp}${operator}${leftpad(offset, 4)})/`;
}
return `/Date(${timestamp})/`;
}
const fromTime = (value: Time): string =>
'PT' +
leftpad(value.hours, 2) +
'H' +
leftpad(value.minutes, 2) +
'M' +
leftpad(value.seconds, 2) +
'S';
function leftpad(value: any, targetLength: number): string {
const str = value.toString();
if (str.length >= targetLength) {
return str;
}
return '0'.repeat(targetLength - str.length) + str;
}
export type EdmToPrimitiveV2<T extends EdmTypeV2> = T extends
| 'Edm.Int16'
| 'Edm.Int32'
| 'Edm.Single'
| 'Edm.Double'
| 'Edm.Float'
| 'Edm.Byte'
| 'Edm.SByte'
? number
: T extends 'Edm.Decimal' | 'Edm.Int64'
? BigNumber
: T extends 'Edm.DateTime' | 'Edm.DateTimeOffset'
? moment.Moment
: T extends 'Edm.String' | 'Edm.Guid'
? string
: T extends 'Edm.Boolean'
? boolean
: T extends 'Edm.Time'
? Time
: any;
const deserializers: EdmTypeMapping = {
...deserializersCommon,
'Edm.DateTime': edmDateTimeToMoment,
'Edm.DateTimeOffset': edmDateTimeToMoment,
'Edm.Time': toTime
};
const serializers: EdmTypeMapping = {
...serializersCommom,
'Edm.DateTime': momentToEdmDateTime,
'Edm.DateTimeOffset': momentToEdmDateTime,
'Edm.Time': fromTime
};
export { EdmToPrimitiveV2 as EdmToPrimitive };
export { edmToTsV2 as edmToTs };