@utiliread/http 1.11.0 → 1.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.vscode/settings.json +2 -2
  2. package/dist/cjs/events.js +19 -85
  3. package/dist/cjs/events.js.map +1 -1
  4. package/dist/cjs/index.js +3 -1
  5. package/dist/cjs/index.js.map +1 -1
  6. package/dist/cjs/msgpack.js +17 -0
  7. package/dist/cjs/msgpack.js.map +1 -1
  8. package/dist/esm/events.d.ts +7 -21
  9. package/dist/esm/events.js +17 -84
  10. package/dist/esm/events.js.map +1 -1
  11. package/dist/esm/index.d.ts +2 -1
  12. package/dist/esm/index.js +1 -0
  13. package/dist/esm/index.js.map +1 -1
  14. package/dist/esm/msgpack.d.ts +1 -0
  15. package/dist/esm/msgpack.js +18 -1
  16. package/dist/esm/msgpack.js.map +1 -1
  17. package/karma.config.js +30 -30
  18. package/package.json +1 -1
  19. package/src/event-aggregator.ts +31 -31
  20. package/src/events.ts +39 -0
  21. package/src/helpers.ts +13 -13
  22. package/src/http-builder.ts +254 -254
  23. package/src/http-error.ts +25 -25
  24. package/src/http-response.ts +55 -55
  25. package/src/http.spec.ts +104 -104
  26. package/src/http.ts +121 -121
  27. package/src/index.ts +17 -16
  28. package/src/json.ts +138 -138
  29. package/src/mapping.ts +42 -42
  30. package/src/msgpack.ts +63 -48
  31. package/src/pagination.ts +25 -25
  32. package/src/problem-details.ts +7 -7
  33. package/src/query-string.spec.ts +62 -62
  34. package/src/query-string.ts +69 -69
  35. package/src/timeout-error.ts +10 -10
  36. package/tsconfig.cjs.json +8 -8
  37. package/tsconfig.json +13 -13
  38. package/dist/cjs/settings.js +0 -3
  39. package/dist/cjs/settings.js.map +0 -1
  40. package/dist/cjs/utils.js +0 -8
  41. package/dist/cjs/utils.js.map +0 -1
  42. package/dist/esm/settings.d.ts +0 -6
  43. package/dist/esm/settings.js +0 -2
  44. package/dist/esm/settings.js.map +0 -1
  45. package/dist/esm/utils.d.ts +0 -3
  46. package/dist/esm/utils.js +0 -4
  47. package/dist/esm/utils.js.map +0 -1
package/src/json.ts CHANGED
@@ -1,138 +1,138 @@
1
- import { HttpBuilder, HttpBuilderOfT } from "./http-builder";
2
- import { InfinitePaginationResult, PaginationResult } from "./pagination";
3
- import { deserialize, serialize } from "@utiliread/json";
4
- import { getMapper, getNullableMapper, Mapper, Type } from "./mapping";
5
- import type { Operation } from "@utiliread/jsonpatch";
6
-
7
- type TypeOrMapper<T> = Type<T> | Mapper<T>;
8
-
9
- declare module "./http-builder" {
10
- interface HttpBuilder {
11
- withJson(content: any): this;
12
- withJsonPatch(operations: Operation[]): this;
13
-
14
- expectJson<T>(typeOrMapper?: TypeOrMapper<T>): HttpBuilderOfT<T>;
15
- expectJsonArray<T>(typeOrMapper: TypeOrMapper<T>): HttpBuilderOfT<T[]>;
16
- expectJsonNullableArray<T>(
17
- typeOrMapper: TypeOrMapper<T>
18
- ): HttpBuilderOfT<(T | null)[]>;
19
- expectJsonPaginationResult<T>(
20
- typeOrMapper: TypeOrMapper<T>
21
- ): HttpBuilderOfT<PaginationResult<T>>;
22
- expectJsonInfinitePaginationResult<T>(
23
- typeOrMapper: TypeOrMapper<T>
24
- ): HttpBuilderOfT<InfinitePaginationResult<T>>;
25
- }
26
- interface HttpBuilderOfT<T> {
27
- withJson(content: any): this;
28
- withJsonPatch(operations: Operation[]): this;
29
- }
30
- }
31
-
32
- HttpBuilder.prototype.withJson = function (this: HttpBuilder, content: any) {
33
- this.message.content = serialize(content);
34
- this.message.contentType = "application/json";
35
- return this;
36
- };
37
-
38
- HttpBuilder.prototype.withJsonPatch = function (
39
- this: HttpBuilder,
40
- operations: Operation[]
41
- ) {
42
- this.message.content = serialize(operations);
43
- this.message.contentType = "application/json-patch+json";
44
- return this;
45
- };
46
-
47
- HttpBuilderOfT.prototype.withJson = function <T>(
48
- this: HttpBuilderOfT<T>,
49
- content: any
50
- ) {
51
- this.message.content = serialize(content);
52
- this.message.contentType = "application/json";
53
- return this;
54
- };
55
-
56
- HttpBuilderOfT.prototype.withJsonPatch = function <T>(
57
- this: HttpBuilderOfT<T>,
58
- operations: Operation[]
59
- ) {
60
- this.message.content = serialize(operations);
61
- this.message.contentType = "application/json-patch+json";
62
- return this;
63
- };
64
-
65
- HttpBuilder.prototype.expectJson = function <T>(
66
- this: HttpBuilder,
67
- typeOrMapper?: TypeOrMapper<T>
68
- ) {
69
- this.message.headers.set("Accept", "application/json");
70
- return this.useHandler((response) => {
71
- return response.json().then((x) => getMapper(deserialize, typeOrMapper)(x));
72
- });
73
- };
74
-
75
- HttpBuilder.prototype.expectJsonArray = function <T>(
76
- this: HttpBuilder,
77
- typeOrMapper: TypeOrMapper<T>
78
- ) {
79
- this.message.headers.set("Accept", "application/json");
80
- return this.useHandler((response) => {
81
- return response.json().then((x: any[]) => {
82
- const itemFactory = getMapper(deserialize, typeOrMapper);
83
- return x.map(itemFactory);
84
- });
85
- });
86
- };
87
-
88
- HttpBuilder.prototype.expectJsonNullableArray = function <T>(
89
- this: HttpBuilder,
90
- typeOrMapper: TypeOrMapper<T>
91
- ): HttpBuilderOfT<(T | null)[]> {
92
- this.message.headers.set("Accept", "application/json");
93
- return this.useHandler((response) => {
94
- return response.json().then((x: any[]) => {
95
- const itemFactory = getNullableMapper(deserialize, typeOrMapper);
96
- return x.map(itemFactory);
97
- });
98
- });
99
- };
100
-
101
- HttpBuilder.prototype.expectJsonPaginationResult = function <T>(
102
- this: HttpBuilder,
103
- typeOrMapper: TypeOrMapper<T>
104
- ) {
105
- this.message.headers.set("Accept", "application/json");
106
- return this.useHandler((response) => {
107
- return response.json().then((x: PaginationResult<any>) => {
108
- const itemFactory = getMapper(deserialize, typeOrMapper);
109
- return {
110
- meta: {
111
- pageCount: x.meta.pageCount,
112
- pageSize: x.meta.pageSize,
113
- totalItems: x.meta.totalItems,
114
- },
115
- data: x.data.map(itemFactory),
116
- };
117
- });
118
- });
119
- };
120
-
121
- HttpBuilder.prototype.expectJsonInfinitePaginationResult = function <T>(
122
- this: HttpBuilder,
123
- typeOrMapper: TypeOrMapper<T>
124
- ) {
125
- this.message.headers.set("Accept", "application/json");
126
- return this.useHandler((response) => {
127
- return response.json().then((x: InfinitePaginationResult<any>) => {
128
- const itemFactory = getMapper(deserialize, typeOrMapper);
129
- return {
130
- meta: {
131
- pageSize: x.meta.pageSize,
132
- continuationToken: x.meta.continuationToken,
133
- },
134
- data: x.data.map(itemFactory),
135
- };
136
- });
137
- });
138
- };
1
+ import { HttpBuilder, HttpBuilderOfT } from "./http-builder";
2
+ import { InfinitePaginationResult, PaginationResult } from "./pagination";
3
+ import { deserialize, serialize } from "@utiliread/json";
4
+ import { getMapper, getNullableMapper, Mapper, Type } from "./mapping";
5
+ import type { Operation } from "@utiliread/jsonpatch";
6
+
7
+ type TypeOrMapper<T> = Type<T> | Mapper<T>;
8
+
9
+ declare module "./http-builder" {
10
+ interface HttpBuilder {
11
+ withJson(content: any): this;
12
+ withJsonPatch(operations: Operation[]): this;
13
+
14
+ expectJson<T>(typeOrMapper?: TypeOrMapper<T>): HttpBuilderOfT<T>;
15
+ expectJsonArray<T>(typeOrMapper: TypeOrMapper<T>): HttpBuilderOfT<T[]>;
16
+ expectJsonNullableArray<T>(
17
+ typeOrMapper: TypeOrMapper<T>
18
+ ): HttpBuilderOfT<(T | null)[]>;
19
+ expectJsonPaginationResult<T>(
20
+ typeOrMapper: TypeOrMapper<T>
21
+ ): HttpBuilderOfT<PaginationResult<T>>;
22
+ expectJsonInfinitePaginationResult<T>(
23
+ typeOrMapper: TypeOrMapper<T>
24
+ ): HttpBuilderOfT<InfinitePaginationResult<T>>;
25
+ }
26
+ interface HttpBuilderOfT<T> {
27
+ withJson(content: any): this;
28
+ withJsonPatch(operations: Operation[]): this;
29
+ }
30
+ }
31
+
32
+ HttpBuilder.prototype.withJson = function (this: HttpBuilder, content: any) {
33
+ this.message.content = serialize(content);
34
+ this.message.contentType = "application/json";
35
+ return this;
36
+ };
37
+
38
+ HttpBuilder.prototype.withJsonPatch = function (
39
+ this: HttpBuilder,
40
+ operations: Operation[]
41
+ ) {
42
+ this.message.content = serialize(operations);
43
+ this.message.contentType = "application/json-patch+json";
44
+ return this;
45
+ };
46
+
47
+ HttpBuilderOfT.prototype.withJson = function <T>(
48
+ this: HttpBuilderOfT<T>,
49
+ content: any
50
+ ) {
51
+ this.message.content = serialize(content);
52
+ this.message.contentType = "application/json";
53
+ return this;
54
+ };
55
+
56
+ HttpBuilderOfT.prototype.withJsonPatch = function <T>(
57
+ this: HttpBuilderOfT<T>,
58
+ operations: Operation[]
59
+ ) {
60
+ this.message.content = serialize(operations);
61
+ this.message.contentType = "application/json-patch+json";
62
+ return this;
63
+ };
64
+
65
+ HttpBuilder.prototype.expectJson = function <T>(
66
+ this: HttpBuilder,
67
+ typeOrMapper?: TypeOrMapper<T>
68
+ ) {
69
+ this.message.headers.set("Accept", "application/json");
70
+ return this.useHandler((response) => {
71
+ return response.json().then((x) => getMapper(deserialize, typeOrMapper)(x));
72
+ });
73
+ };
74
+
75
+ HttpBuilder.prototype.expectJsonArray = function <T>(
76
+ this: HttpBuilder,
77
+ typeOrMapper: TypeOrMapper<T>
78
+ ) {
79
+ this.message.headers.set("Accept", "application/json");
80
+ return this.useHandler((response) => {
81
+ return response.json().then((x: any[]) => {
82
+ const itemFactory = getMapper(deserialize, typeOrMapper);
83
+ return x.map(itemFactory);
84
+ });
85
+ });
86
+ };
87
+
88
+ HttpBuilder.prototype.expectJsonNullableArray = function <T>(
89
+ this: HttpBuilder,
90
+ typeOrMapper: TypeOrMapper<T>
91
+ ): HttpBuilderOfT<(T | null)[]> {
92
+ this.message.headers.set("Accept", "application/json");
93
+ return this.useHandler((response) => {
94
+ return response.json().then((x: any[]) => {
95
+ const itemFactory = getNullableMapper(deserialize, typeOrMapper);
96
+ return x.map(itemFactory);
97
+ });
98
+ });
99
+ };
100
+
101
+ HttpBuilder.prototype.expectJsonPaginationResult = function <T>(
102
+ this: HttpBuilder,
103
+ typeOrMapper: TypeOrMapper<T>
104
+ ) {
105
+ this.message.headers.set("Accept", "application/json");
106
+ return this.useHandler((response) => {
107
+ return response.json().then((x: PaginationResult<any>) => {
108
+ const itemFactory = getMapper(deserialize, typeOrMapper);
109
+ return {
110
+ meta: {
111
+ pageCount: x.meta.pageCount,
112
+ pageSize: x.meta.pageSize,
113
+ totalItems: x.meta.totalItems,
114
+ },
115
+ data: x.data.map(itemFactory),
116
+ };
117
+ });
118
+ });
119
+ };
120
+
121
+ HttpBuilder.prototype.expectJsonInfinitePaginationResult = function <T>(
122
+ this: HttpBuilder,
123
+ typeOrMapper: TypeOrMapper<T>
124
+ ) {
125
+ this.message.headers.set("Accept", "application/json");
126
+ return this.useHandler((response) => {
127
+ return response.json().then((x: InfinitePaginationResult<any>) => {
128
+ const itemFactory = getMapper(deserialize, typeOrMapper);
129
+ return {
130
+ meta: {
131
+ pageSize: x.meta.pageSize,
132
+ continuationToken: x.meta.continuationToken,
133
+ },
134
+ data: x.data.map(itemFactory),
135
+ };
136
+ });
137
+ });
138
+ };
package/src/mapping.ts CHANGED
@@ -1,43 +1,43 @@
1
- type DeserializeFn<T> = (source: any, type: Type<T>) => T | null | undefined;
2
- export type Type<T> = { new(): T };
3
- export type Mapper<T> = ((source: any) => T);
4
-
5
- export function getNullableMapper<T>(deserialize: DeserializeFn<T>, typeOrMap: Type<T> | Mapper<T> | undefined): Mapper<T | null> {
6
- if (!typeOrMap) {
7
- return (x: any) => <T>x;
8
- }
9
-
10
- if (isZeroArgumentFunction(typeOrMap)) {
11
- // It cannot be a factory function if it takes no arguments,
12
- // so it must be a (zero argument) type (constructor)
13
- return (x: any) => {
14
- const bound = deserialize(x, typeOrMap);
15
-
16
- // The server cannot produce the undefined result
17
- if (bound === undefined) {
18
- throw Error("The model factory created a undefined result");
19
- }
20
-
21
- return bound;
22
- }
23
- }
24
-
25
- return typeOrMap;
26
- }
27
-
28
- export function getMapper<T>(deserialize: DeserializeFn<T>, typeOrMap: Type<T> | Mapper<T> | undefined): Mapper<T> {
29
- const nullableFactory = getNullableMapper(deserialize, typeOrMap);
30
- return (x: any) => {
31
- const result = nullableFactory(x);
32
-
33
- if (result === null) {
34
- throw Error("The model factory created a null result");
35
- }
36
-
37
- return result;
38
- };
39
- }
40
-
41
- function isZeroArgumentFunction<T>(typeCtor: Function): typeCtor is { new(): T } {
42
- return typeCtor.length === 0;
1
+ type DeserializeFn<T> = (source: any, type: Type<T>) => T | null | undefined;
2
+ export type Type<T> = { new(): T };
3
+ export type Mapper<T> = ((source: any) => T);
4
+
5
+ export function getNullableMapper<T>(deserialize: DeserializeFn<T>, typeOrMap: Type<T> | Mapper<T> | undefined): Mapper<T | null> {
6
+ if (!typeOrMap) {
7
+ return (x: any) => <T>x;
8
+ }
9
+
10
+ if (isZeroArgumentFunction(typeOrMap)) {
11
+ // It cannot be a factory function if it takes no arguments,
12
+ // so it must be a (zero argument) type (constructor)
13
+ return (x: any) => {
14
+ const bound = deserialize(x, typeOrMap);
15
+
16
+ // The server cannot produce the undefined result
17
+ if (bound === undefined) {
18
+ throw Error("The model factory created a undefined result");
19
+ }
20
+
21
+ return bound;
22
+ }
23
+ }
24
+
25
+ return typeOrMap;
26
+ }
27
+
28
+ export function getMapper<T>(deserialize: DeserializeFn<T>, typeOrMap: Type<T> | Mapper<T> | undefined): Mapper<T> {
29
+ const nullableFactory = getNullableMapper(deserialize, typeOrMap);
30
+ return (x: any) => {
31
+ const result = nullableFactory(x);
32
+
33
+ if (result === null) {
34
+ throw Error("The model factory created a null result");
35
+ }
36
+
37
+ return result;
38
+ };
39
+ }
40
+
41
+ function isZeroArgumentFunction<T>(typeCtor: Function): typeCtor is { new(): T } {
42
+ return typeCtor.length === 0;
43
43
  }
package/src/msgpack.ts CHANGED
@@ -1,48 +1,63 @@
1
- import { deserialize } from "@utiliread/msgpack";
2
- import { HttpBuilder } from "./http-builder";
3
- import { decodeArrayStream } from "@msgpack/msgpack";
4
- import { getMapper, Mapper, Type } from "./mapping";
5
-
6
- type TypeOrMapper<T> = Type<T> | Mapper<T>;
7
-
8
- declare module "./http-builder" {
9
- interface HttpBuilder {
10
- expectMessagePackArray<T>(
11
- typeOrMapper?: TypeOrMapper<T>
12
- ): HttpBuilderOfT<T[]>;
13
- streamMessagePackArray<T>(
14
- typeOrMapper?: TypeOrMapper<T>
15
- ): HttpBuilderOfT<AsyncGenerator<T, void, unknown>>;
16
- }
17
- }
18
-
19
- HttpBuilder.prototype.expectMessagePackArray = function <T>(
20
- this: HttpBuilder,
21
- typeOrMapper?: TypeOrMapper<T>
22
- ) {
23
- this.message.headers.set("Accept", "application/x-msgpack");
24
- return this.useHandler(async (response) => {
25
- const items: T[] = [];
26
- const itemFactory = getMapper(deserialize, typeOrMapper);
27
- for await (const item of decodeArrayStream(response.body!)) {
28
- items.push(itemFactory(item));
29
- }
30
- return items;
31
- });
32
- };
33
-
34
- HttpBuilder.prototype.streamMessagePackArray = function <T>(
35
- this: HttpBuilder,
36
- typeOrMapper?: TypeOrMapper<T>
37
- ) {
38
- this.message.headers.set("Accept", "application/x-msgpack");
39
-
40
- async function* handler(response: Response) {
41
- const itemFactory = getMapper(deserialize, typeOrMapper);
42
- for await (const item of decodeArrayStream(response.body!)) {
43
- yield itemFactory(item);
44
- }
45
- }
46
-
47
- return this.useHandler((response) => Promise.resolve(handler(response)));
48
- };
1
+ import { deserialize } from "@utiliread/msgpack";
2
+ import { HttpBuilder } from "./http-builder";
3
+ import { decodeArrayStream, decodeAsync } from "@msgpack/msgpack";
4
+ import { getMapper, Mapper, Type } from "./mapping";
5
+
6
+ type TypeOrMapper<T> = Type<T> | Mapper<T>;
7
+
8
+ declare module "./http-builder" {
9
+ interface HttpBuilder {
10
+ expectMessagePack<T>(
11
+ typeOrMapper?: TypeOrMapper<T>
12
+ ): HttpBuilderOfT<T>;
13
+ expectMessagePackArray<T>(
14
+ typeOrMapper?: TypeOrMapper<T>
15
+ ): HttpBuilderOfT<T[]>;
16
+ streamMessagePackArray<T>(
17
+ typeOrMapper?: TypeOrMapper<T>
18
+ ): HttpBuilderOfT<AsyncGenerator<T, void, unknown>>;
19
+ }
20
+ }
21
+
22
+ HttpBuilder.prototype.expectMessagePack = function <T>(
23
+ this: HttpBuilder,
24
+ typeOrMapper?: TypeOrMapper<T>
25
+ ) {
26
+ this.message.headers.set("Accept", "application/x-msgpack");
27
+ return this.useHandler(async (response) => {
28
+ const itemFactory = getMapper(deserialize, typeOrMapper);
29
+ const decoded = await decodeAsync(response.body!);
30
+ return itemFactory(decoded);
31
+ });
32
+ };
33
+
34
+ HttpBuilder.prototype.expectMessagePackArray = function <T>(
35
+ this: HttpBuilder,
36
+ typeOrMapper?: TypeOrMapper<T>
37
+ ) {
38
+ this.message.headers.set("Accept", "application/x-msgpack");
39
+ return this.useHandler(async (response) => {
40
+ const items: T[] = [];
41
+ const itemFactory = getMapper(deserialize, typeOrMapper);
42
+ for await (const item of decodeArrayStream(response.body!)) {
43
+ items.push(itemFactory(item));
44
+ }
45
+ return items;
46
+ });
47
+ };
48
+
49
+ HttpBuilder.prototype.streamMessagePackArray = function <T>(
50
+ this: HttpBuilder,
51
+ typeOrMapper?: TypeOrMapper<T>
52
+ ) {
53
+ this.message.headers.set("Accept", "application/x-msgpack");
54
+
55
+ async function* handler(response: Response) {
56
+ const itemFactory = getMapper(deserialize, typeOrMapper);
57
+ for await (const item of decodeArrayStream(response.body!)) {
58
+ yield itemFactory(item);
59
+ }
60
+ }
61
+
62
+ return this.useHandler((response) => Promise.resolve(handler(response)));
63
+ };
package/src/pagination.ts CHANGED
@@ -1,26 +1,26 @@
1
- export interface Page {
2
- number: number;
3
- size: number;
4
- }
5
-
6
- export interface PaginationResult<T> {
7
- meta: {
8
- pageCount: number;
9
- pageSize: number;
10
- totalItems: number;
11
- },
12
- data: T[];
13
- }
14
-
15
- export interface InfinitePage {
16
- continuationToken?: string;
17
- size: number;
18
- }
19
-
20
- export interface InfinitePaginationResult<T> {
21
- meta: {
22
- pageSize: number;
23
- continuationToken: string | null;
24
- },
25
- data: T[];
1
+ export interface Page {
2
+ number: number;
3
+ size: number;
4
+ }
5
+
6
+ export interface PaginationResult<T> {
7
+ meta: {
8
+ pageCount: number;
9
+ pageSize: number;
10
+ totalItems: number;
11
+ },
12
+ data: T[];
13
+ }
14
+
15
+ export interface InfinitePage {
16
+ continuationToken?: string;
17
+ size: number;
18
+ }
19
+
20
+ export interface InfinitePaginationResult<T> {
21
+ meta: {
22
+ pageSize: number;
23
+ continuationToken: string | null;
24
+ },
25
+ data: T[];
26
26
  }
@@ -1,8 +1,8 @@
1
- export interface ProblemDetails {
2
- detail?: string;
3
- extensions?: any;
4
- instance?: string;
5
- status?: number;
6
- title?: string;
7
- type: string;
1
+ export interface ProblemDetails {
2
+ detail?: string;
3
+ extensions?: any;
4
+ instance?: string;
5
+ status?: number;
6
+ title?: string;
7
+ type: string;
8
8
  }
@@ -1,63 +1,63 @@
1
- import { DateTime } from 'luxon';
2
- import { QueryString } from './query-string';
3
- import { expect } from 'chai';
4
-
5
- describe("query-string", () => {
6
- it("should handle string", () => {
7
- const qs = QueryString.serialize({
8
- aString: "hello"
9
- });
10
-
11
- expect(qs).to.equal("?aString=hello");
12
- });
13
-
14
- it("should handle string array", () => {
15
- const qs = QueryString.serialize({
16
- aString: ["hello","world"]
17
- });
18
-
19
- expect(qs).to.equal("?aString[0]=hello&aString[1]=world");
20
- });
21
-
22
- it("should handle object array", () => {
23
- const qs = QueryString.serialize({
24
- array: [{a: "hello"}, {b: "world"}]
25
- });
26
-
27
- expect(qs).to.equal("?array[0].a=hello&array[1].b=world");
28
- });
29
-
30
- it("should handle luxon DateTime in local timezone", () => {
31
- const datetime = DateTime.fromObject({year: 2014, month: 11, day: 12, hour: 21, minute: 6});
32
- const qs = QueryString.serialize({
33
- aDateTime: datetime
34
- });
35
-
36
- expect(qs).to.equal("?aDateTime=" + encodeURIComponent("2014-11-12T21:06:00.000+01:00"));
37
- });
38
-
39
- it("should handle luxon DateTime in utc", () => {
40
- const datetime = DateTime.fromObject({year: 2014, month: 11, day: 12, hour: 21, minute: 6}).toUTC();
41
- const qs = QueryString.serialize({
42
- aDateTime: datetime
43
- });
44
-
45
- expect(qs).to.equal("?aDateTime=" + encodeURIComponent("2014-11-12T20:06:00.000Z"));
46
- });
47
-
48
- it("should handle null", () => {
49
- const qs = QueryString.serialize({
50
- null: null
51
- });
52
-
53
- expect(qs).to.equal("?null");
54
- });
55
-
56
- it("should not include undefined", () => {
57
- const qs = QueryString.serialize({
58
- null: undefined
59
- });
60
-
61
- expect(qs).to.equal("");
62
- })
1
+ import { DateTime } from 'luxon';
2
+ import { QueryString } from './query-string';
3
+ import { expect } from 'chai';
4
+
5
+ describe("query-string", () => {
6
+ it("should handle string", () => {
7
+ const qs = QueryString.serialize({
8
+ aString: "hello"
9
+ });
10
+
11
+ expect(qs).to.equal("?aString=hello");
12
+ });
13
+
14
+ it("should handle string array", () => {
15
+ const qs = QueryString.serialize({
16
+ aString: ["hello","world"]
17
+ });
18
+
19
+ expect(qs).to.equal("?aString[0]=hello&aString[1]=world");
20
+ });
21
+
22
+ it("should handle object array", () => {
23
+ const qs = QueryString.serialize({
24
+ array: [{a: "hello"}, {b: "world"}]
25
+ });
26
+
27
+ expect(qs).to.equal("?array[0].a=hello&array[1].b=world");
28
+ });
29
+
30
+ it("should handle luxon DateTime in local timezone", () => {
31
+ const datetime = DateTime.fromObject({year: 2014, month: 11, day: 12, hour: 21, minute: 6});
32
+ const qs = QueryString.serialize({
33
+ aDateTime: datetime
34
+ });
35
+
36
+ expect(qs).to.equal("?aDateTime=" + encodeURIComponent("2014-11-12T21:06:00.000+01:00"));
37
+ });
38
+
39
+ it("should handle luxon DateTime in utc", () => {
40
+ const datetime = DateTime.fromObject({year: 2014, month: 11, day: 12, hour: 21, minute: 6}).toUTC();
41
+ const qs = QueryString.serialize({
42
+ aDateTime: datetime
43
+ });
44
+
45
+ expect(qs).to.equal("?aDateTime=" + encodeURIComponent("2014-11-12T20:06:00.000Z"));
46
+ });
47
+
48
+ it("should handle null", () => {
49
+ const qs = QueryString.serialize({
50
+ null: null
51
+ });
52
+
53
+ expect(qs).to.equal("?null");
54
+ });
55
+
56
+ it("should not include undefined", () => {
57
+ const qs = QueryString.serialize({
58
+ null: undefined
59
+ });
60
+
61
+ expect(qs).to.equal("");
62
+ })
63
63
  });