Skip to content

Commit a1d92ea

Browse files
Extend number with double type, added decimal as new type
1 parent 78664ed commit a1d92ea

File tree

3 files changed

+58
-23
lines changed

3 files changed

+58
-23
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,22 @@ const filter = f().eq('TypeId', '1')
329329
.toString();
330330
buildQuery({ filter })
331331
```
332+
#### Numbers
333+
Number can be represented as integer or double.
334+
335+
Integer:
336+
```js
337+
const filter = { NumberProp: 1 };
338+
buildQuery({ filter })
339+
=> '?$filter=NumberProp eq 1';
340+
```
341+
Double:
342+
```js
343+
const filter = { NumberProp: 1.23 };
344+
buildQuery({ filter })
345+
=> '?$filter=NumberProp eq 1.23d';
346+
```
347+
332348

333349
#### Data types
334350
GUID:
@@ -351,6 +367,14 @@ const filter = { "someProp": { eq: { type: 'binary', value: 'YmluYXJ5RGF0YQ==' }
351367
buildQuery({ filter })
352368
=> "?$filter=someProp eq binary'YmluYXJ5RGF0YQ=='"
353369
```
370+
371+
Decimal:
372+
```js
373+
const filter = { "someProp": { eq: { type: 'decimal', value: '12.3456789' } } };
374+
buildQuery({ filter })
375+
=> "?$filter=someProp eq '12.3456789M'"
376+
```
377+
354378
Note that as per OData specification, binary data is transmitted as a base64 encoded string. Refer to [Primitive Types in JSON Format](https://www.odata.org/documentation/odata-version-2-0/json-format/), and [binary representation](https://www.odata.org/documentation/odata-version-2-0/overview/).
355379

356380
Other types coming soon

src/index.ts

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,16 @@ export type Duration = { type: 'duration'; value: any; }
5757
export type Binary = { type: 'binary'; value: any; }
5858
export type Json = { type: 'json'; value: any; }
5959
export type Alias = { type: 'alias'; name: string; value: any; }
60-
export type Value = string | Date | number | boolean | Raw | Guid | Duration | Binary | Json | Alias;
60+
export type Decimal = { type: 'decimal'; value: any; }
61+
export type Value = string | Date | number | boolean | Raw | Guid | Duration | Binary | Json | Alias | Decimal;
6162

6263
export const raw = (value: string): Raw => ({ type: 'raw', value });
6364
export const guid = (value: string): Guid => ({ type: 'guid', value });
6465
export const duration = (value: string): Duration => ({ type: 'duration', value });
6566
export const binary = (value: string): Binary => ({ type: 'binary', value });
6667
export const json = (value: PlainObject): Json => ({ type: 'json', value });
6768
export const alias = (name: string, value: PlainObject): Alias => ({ type: 'alias', name, value });
69+
export const decimal = (value: string): Decimal => ({ type: 'decimal', value });
6870

6971
export type QueryOptions<T> = ExpandOptions<T> & {
7072
search: string;
@@ -363,36 +365,38 @@ function handleValue(value: Value, aliases?: Alias[]): any {
363365
return value.toISOString();
364366
} else if (typeof value === 'number') {
365367
// Number.isInteger(value) is not supported by IE11
366-
const isDecimal = value % 1 !== 0;
367-
return isDecimal ? `${value}M`: value;
368+
const isDouble = value % 1 !== 0;
369+
return isDouble ? `${value}d`: value;
368370
} else if (Array.isArray(value)) {
369371
return `[${value.map(d => handleValue(d)).join(',')}]`;
370372
} else if (value === null) {
371373
return value;
372374
} else if (typeof value === 'object') {
373-
if (value.type === 'raw') {
374-
return value.value;
375-
} else if (value.type === 'guid') {
375+
switch (value.type) {
376+
case 'raw':
377+
case 'guid':
376378
return value.value;
377-
} else if (value.type === 'duration') {
379+
case 'duration':
378380
return `duration'${value.value}'`;
379-
} else if (value.type === 'binary') {
381+
case 'binary':
380382
return `binary'${value.value}'`;
381-
} else if (value.type === 'alias') {
382-
// Store
383-
if (Array.isArray(aliases))
384-
aliases.push(value as Alias);
385-
return `@${(value as Alias).name}`;
386-
} else if (value.type === 'json') {
383+
case 'alias':
384+
// Store
385+
if (Array.isArray(aliases))
386+
aliases.push(value as Alias);
387+
return `@${(value as Alias).name}`;
388+
case 'json':
387389
return escape(JSON.stringify(value.value));
388-
} else {
389-
return Object.entries(value)
390-
.filter(([, v]) => v !== undefined)
391-
.map(([k, v]) => `${k}=${handleValue(v as Value, aliases)}`).join(',');
392-
}
390+
case 'decimal':
391+
return `${value.value}M`;
392+
default:
393+
return Object.entries(value)
394+
.filter(([, v]) => v !== undefined)
395+
.map(([k, v]) => `${k}=${handleValue(v as Value, aliases)}`).join(',');
393396
}
394-
return value;
395397
}
398+
return value;
399+
}
396400

397401
function buildExpand<T>(expands: Expand<T>): string {
398402
if (typeof expands === 'number') {

test/index.test.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import buildQuery, {Expand, OrderBy, alias, json, ITEM_ROOT} from '../src/index';
1+
import buildQuery, {Expand, OrderBy, alias, json, ITEM_ROOT, decimal} from '../src/index';
22

33
it('should return an empty string by default', () => {
44
expect(buildQuery()).toEqual('');
@@ -751,9 +751,16 @@ describe('filter', () => {
751751
expect(actual).toEqual(expected);
752752
});
753753

754-
it('should handle a decimal number', () => {
754+
it('should handle double number', () => {
755755
const filter = { NumberProp: 1.23 };
756-
const expected = '?$filter=NumberProp eq 1.23M';
756+
const expected = '?$filter=NumberProp eq 1.23d';
757+
const actual = buildQuery({ filter });
758+
expect(actual).toEqual(expected);
759+
});
760+
761+
it('should handle decimal number', () => {
762+
const filter = { NumberProp: decimal('1.23456789') };
763+
const expected = '?$filter=NumberProp eq 1.23456789M';
757764
const actual = buildQuery({ filter });
758765
expect(actual).toEqual(expected);
759766
});

0 commit comments

Comments
 (0)