@ps-aux/api-client-angular 0.5.0-rc2 → 0.7.0-rc.0
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.
- package/LICENSE +21 -0
- package/README.md +20 -0
- package/dist/index.esm.js +8 -265
- package/dist/index.js +8 -266
- package/package.json +55 -8
- package/dist/AngularApiHttpClient.d.ts +0 -5
- package/dist/_index.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/serializeQuery.d.ts +0 -2
- package/rollup.config.mjs +0 -29
- package/tsconfig.json +0 -11
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 psaux
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# @ps-aux/api-client-angular
|
|
2
|
+
|
|
3
|
+
Angular HttpClient wrapper that implements Observable-based API requests.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
- npm install @ps-aux/api-client-angular
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { HttpClient } from '@angular/common/http'
|
|
12
|
+
import { createHttpClient } from '@ps-aux/api-client-angular'
|
|
13
|
+
|
|
14
|
+
const http = createHttpClient(angularHttpClient)
|
|
15
|
+
|
|
16
|
+
http.request({ path: '/users', method: 'GET' }).subscribe(console.log)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
MIT
|
package/dist/index.esm.js
CHANGED
|
@@ -1,259 +1,4 @@
|
|
|
1
1
|
import { map } from 'rxjs';
|
|
2
|
-
import qs from 'qs';
|
|
3
|
-
|
|
4
|
-
const { isArray } = Array;
|
|
5
|
-
|
|
6
|
-
function fromPairs(listOfPairs){
|
|
7
|
-
const toReturn = {};
|
|
8
|
-
listOfPairs.forEach(([ prop, value ]) => toReturn[ prop ] = value);
|
|
9
|
-
|
|
10
|
-
return toReturn
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function partitionObject(predicate, iterable){
|
|
14
|
-
const yes = {};
|
|
15
|
-
const no = {};
|
|
16
|
-
Object.entries(iterable).forEach(([ prop, value ]) => {
|
|
17
|
-
if (predicate(value, prop)){
|
|
18
|
-
yes[ prop ] = value;
|
|
19
|
-
} else {
|
|
20
|
-
no[ prop ] = value;
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
return [ yes, no ]
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function partitionArray(
|
|
28
|
-
predicate, list, indexed = false
|
|
29
|
-
){
|
|
30
|
-
const yes = [];
|
|
31
|
-
const no = [];
|
|
32
|
-
let counter = -1;
|
|
33
|
-
|
|
34
|
-
while (counter++ < list.length - 1){
|
|
35
|
-
if (
|
|
36
|
-
indexed ? predicate(list[ counter ], counter) : predicate(list[ counter ])
|
|
37
|
-
){
|
|
38
|
-
yes.push(list[ counter ]);
|
|
39
|
-
} else {
|
|
40
|
-
no.push(list[ counter ]);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return [ yes, no ]
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function partition(predicate, iterable){
|
|
48
|
-
if (arguments.length === 1){
|
|
49
|
-
return listHolder => partition(predicate, listHolder)
|
|
50
|
-
}
|
|
51
|
-
if (!isArray(iterable)) return partitionObject(predicate, iterable)
|
|
52
|
-
|
|
53
|
-
return partitionArray(predicate, iterable)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
var flat = flatten$1;
|
|
57
|
-
flatten$1.flatten = flatten$1;
|
|
58
|
-
flatten$1.unflatten = unflatten;
|
|
59
|
-
|
|
60
|
-
function isBuffer (obj) {
|
|
61
|
-
return obj &&
|
|
62
|
-
obj.constructor &&
|
|
63
|
-
(typeof obj.constructor.isBuffer === 'function') &&
|
|
64
|
-
obj.constructor.isBuffer(obj)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function keyIdentity (key) {
|
|
68
|
-
return key
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function flatten$1 (target, opts) {
|
|
72
|
-
opts = opts || {};
|
|
73
|
-
|
|
74
|
-
const delimiter = opts.delimiter || '.';
|
|
75
|
-
const maxDepth = opts.maxDepth;
|
|
76
|
-
const transformKey = opts.transformKey || keyIdentity;
|
|
77
|
-
const output = {};
|
|
78
|
-
|
|
79
|
-
function step (object, prev, currentDepth) {
|
|
80
|
-
currentDepth = currentDepth || 1;
|
|
81
|
-
Object.keys(object).forEach(function (key) {
|
|
82
|
-
const value = object[key];
|
|
83
|
-
const isarray = opts.safe && Array.isArray(value);
|
|
84
|
-
const type = Object.prototype.toString.call(value);
|
|
85
|
-
const isbuffer = isBuffer(value);
|
|
86
|
-
const isobject = (
|
|
87
|
-
type === '[object Object]' ||
|
|
88
|
-
type === '[object Array]'
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
const newKey = prev
|
|
92
|
-
? prev + delimiter + transformKey(key)
|
|
93
|
-
: transformKey(key);
|
|
94
|
-
|
|
95
|
-
if (!isarray && !isbuffer && isobject && Object.keys(value).length &&
|
|
96
|
-
(!opts.maxDepth || currentDepth < maxDepth)) {
|
|
97
|
-
return step(value, newKey, currentDepth + 1)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
output[newKey] = value;
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
step(target);
|
|
105
|
-
|
|
106
|
-
return output
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function unflatten (target, opts) {
|
|
110
|
-
opts = opts || {};
|
|
111
|
-
|
|
112
|
-
const delimiter = opts.delimiter || '.';
|
|
113
|
-
const overwrite = opts.overwrite || false;
|
|
114
|
-
const transformKey = opts.transformKey || keyIdentity;
|
|
115
|
-
const result = {};
|
|
116
|
-
|
|
117
|
-
const isbuffer = isBuffer(target);
|
|
118
|
-
if (isbuffer || Object.prototype.toString.call(target) !== '[object Object]') {
|
|
119
|
-
return target
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// safely ensure that the key is
|
|
123
|
-
// an integer.
|
|
124
|
-
function getkey (key) {
|
|
125
|
-
const parsedKey = Number(key);
|
|
126
|
-
|
|
127
|
-
return (
|
|
128
|
-
isNaN(parsedKey) ||
|
|
129
|
-
key.indexOf('.') !== -1 ||
|
|
130
|
-
opts.object
|
|
131
|
-
) ? key
|
|
132
|
-
: parsedKey
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function addKeys (keyPrefix, recipient, target) {
|
|
136
|
-
return Object.keys(target).reduce(function (result, key) {
|
|
137
|
-
result[keyPrefix + delimiter + key] = target[key];
|
|
138
|
-
|
|
139
|
-
return result
|
|
140
|
-
}, recipient)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function isEmpty (val) {
|
|
144
|
-
const type = Object.prototype.toString.call(val);
|
|
145
|
-
const isArray = type === '[object Array]';
|
|
146
|
-
const isObject = type === '[object Object]';
|
|
147
|
-
|
|
148
|
-
if (!val) {
|
|
149
|
-
return true
|
|
150
|
-
} else if (isArray) {
|
|
151
|
-
return !val.length
|
|
152
|
-
} else if (isObject) {
|
|
153
|
-
return !Object.keys(val).length
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
target = Object.keys(target).reduce(function (result, key) {
|
|
158
|
-
const type = Object.prototype.toString.call(target[key]);
|
|
159
|
-
const isObject = (type === '[object Object]' || type === '[object Array]');
|
|
160
|
-
if (!isObject || isEmpty(target[key])) {
|
|
161
|
-
result[key] = target[key];
|
|
162
|
-
return result
|
|
163
|
-
} else {
|
|
164
|
-
return addKeys(
|
|
165
|
-
key,
|
|
166
|
-
result,
|
|
167
|
-
flatten$1(target[key], opts)
|
|
168
|
-
)
|
|
169
|
-
}
|
|
170
|
-
}, {});
|
|
171
|
-
|
|
172
|
-
Object.keys(target).forEach(function (key) {
|
|
173
|
-
const split = key.split(delimiter).map(transformKey);
|
|
174
|
-
let key1 = getkey(split.shift());
|
|
175
|
-
let key2 = getkey(split[0]);
|
|
176
|
-
let recipient = result;
|
|
177
|
-
|
|
178
|
-
while (key2 !== undefined) {
|
|
179
|
-
if (key1 === '__proto__') {
|
|
180
|
-
return
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const type = Object.prototype.toString.call(recipient[key1]);
|
|
184
|
-
const isobject = (
|
|
185
|
-
type === '[object Object]' ||
|
|
186
|
-
type === '[object Array]'
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
// do not write over falsey, non-undefined values if overwrite is false
|
|
190
|
-
if (!overwrite && !isobject && typeof recipient[key1] !== 'undefined') {
|
|
191
|
-
return
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if ((overwrite && !isobject) || (!overwrite && recipient[key1] == null)) {
|
|
195
|
-
recipient[key1] = (
|
|
196
|
-
typeof key2 === 'number' &&
|
|
197
|
-
!opts.object ? [] : {}
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
recipient = recipient[key1];
|
|
202
|
-
if (split.length > 0) {
|
|
203
|
-
key1 = getkey(split.shift());
|
|
204
|
-
key2 = getkey(split[0]);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// unflatten again for 'messy objects'
|
|
209
|
-
recipient[key1] = unflatten(target[key], opts);
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
return result
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Brings the 1st level to the 0th level.
|
|
217
|
-
* Flats the object by nesting with '.' path separator.
|
|
218
|
-
*/
|
|
219
|
-
const serializeQueryForSpringBoot = (obj) => {
|
|
220
|
-
const parts = [];
|
|
221
|
-
Object.entries(obj).forEach(([key, val]) => {
|
|
222
|
-
if (Array.isArray(val)) {
|
|
223
|
-
val.forEach((v) => {
|
|
224
|
-
parts.push([key, v]);
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
else if (typeof val === 'object') {
|
|
228
|
-
objectToParams(val).forEach(([key, val]) => {
|
|
229
|
-
parts.push([key, val.toString()]);
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
parts.push([key, val]);
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
return parts.map((p) => `${p[0]}=${p[1]}`).join('&');
|
|
237
|
-
};
|
|
238
|
-
const flatten = (obj) => {
|
|
239
|
-
const r = flat.flatten(obj);
|
|
240
|
-
// { empty: {} } would be { empty: {} } instead of empty array
|
|
241
|
-
return Object.entries(r).filter(([k, v]) => typeof v !== 'object');
|
|
242
|
-
};
|
|
243
|
-
const objectToParams = (obj) => {
|
|
244
|
-
const [arrayProps, nonArrayProps] = partition((e) => Array.isArray(e[1]), Object.entries(obj));
|
|
245
|
-
const withoutArrayProps = fromPairs(nonArrayProps);
|
|
246
|
-
const res = flatten(withoutArrayProps);
|
|
247
|
-
arrayProps.forEach(([k, vals]) => {
|
|
248
|
-
vals.forEach((v) => res.push([k, v]));
|
|
249
|
-
});
|
|
250
|
-
return res;
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
// @ts-ignore
|
|
254
|
-
const serializeQueryWithQs = (obj) => {
|
|
255
|
-
return qs.stringify(obj);
|
|
256
|
-
};
|
|
257
2
|
|
|
258
3
|
const fileResFilenameRegex = /filename="([^"]+)"/;
|
|
259
4
|
const getFileNameFromContentDispositionHeader = (contentDispositionHeader) => {
|
|
@@ -265,25 +10,23 @@ const getFileNameFromContentDispositionHeader = (contentDispositionHeader) => {
|
|
|
265
10
|
};
|
|
266
11
|
|
|
267
12
|
const ContentType = {
|
|
13
|
+
Json: 'application/json',
|
|
268
14
|
FormData: 'multipart/form-data'
|
|
269
15
|
};
|
|
270
16
|
|
|
271
|
-
const
|
|
272
|
-
return {
|
|
273
|
-
url: path + (query ? `?${serializeQueryWithQs(query)}` : '')
|
|
274
|
-
};
|
|
275
|
-
};
|
|
276
|
-
const springBootUrlConverter = () => ({ query, path }) => {
|
|
17
|
+
const noOpUrlConverter = () => ({ query, path }) => {
|
|
277
18
|
return {
|
|
278
|
-
url: path
|
|
19
|
+
url: path,
|
|
20
|
+
params: query
|
|
279
21
|
};
|
|
280
22
|
};
|
|
281
|
-
const createHttpClient = (client, urlConverter =
|
|
23
|
+
const createHttpClient = (client, urlConverter = noOpUrlConverter()) => {
|
|
282
24
|
return {
|
|
283
25
|
request: (req) => {
|
|
284
26
|
const { url, params } = urlConverter(req);
|
|
285
27
|
const isBlob = req.format === 'document';
|
|
286
28
|
const obs = client.request(req.method, url, {
|
|
29
|
+
headers: req.headers,
|
|
287
30
|
params,
|
|
288
31
|
body: prepareBody(req.body, req.type),
|
|
289
32
|
responseType: (isBlob ? 'blob' : 'json'),
|
|
@@ -311,7 +54,7 @@ const prepareBody = (payload, type) => {
|
|
|
311
54
|
const convertToFormData = (payload) => {
|
|
312
55
|
const formData = new FormData();
|
|
313
56
|
const addProp = (key, val) => {
|
|
314
|
-
if (Array.isArray(val) || val instanceof FileList) {
|
|
57
|
+
if (Array.isArray(val) || (typeof FileList !== 'undefined' && val instanceof FileList)) {
|
|
315
58
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
316
59
|
// @ts-ignore - seems that FileList is iterable despite the warning
|
|
317
60
|
// TODO change to other iteration method if this is not true
|
|
@@ -330,4 +73,4 @@ const convertToFormData = (payload) => {
|
|
|
330
73
|
return formData;
|
|
331
74
|
};
|
|
332
75
|
|
|
333
|
-
export {
|
|
76
|
+
export { ContentType, createHttpClient };
|
package/dist/index.js
CHANGED
|
@@ -1,261 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var rxjs = require('rxjs');
|
|
4
|
-
var qs = require('qs');
|
|
5
|
-
|
|
6
|
-
const { isArray } = Array;
|
|
7
|
-
|
|
8
|
-
function fromPairs(listOfPairs){
|
|
9
|
-
const toReturn = {};
|
|
10
|
-
listOfPairs.forEach(([ prop, value ]) => toReturn[ prop ] = value);
|
|
11
|
-
|
|
12
|
-
return toReturn
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function partitionObject(predicate, iterable){
|
|
16
|
-
const yes = {};
|
|
17
|
-
const no = {};
|
|
18
|
-
Object.entries(iterable).forEach(([ prop, value ]) => {
|
|
19
|
-
if (predicate(value, prop)){
|
|
20
|
-
yes[ prop ] = value;
|
|
21
|
-
} else {
|
|
22
|
-
no[ prop ] = value;
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
return [ yes, no ]
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function partitionArray(
|
|
30
|
-
predicate, list, indexed = false
|
|
31
|
-
){
|
|
32
|
-
const yes = [];
|
|
33
|
-
const no = [];
|
|
34
|
-
let counter = -1;
|
|
35
|
-
|
|
36
|
-
while (counter++ < list.length - 1){
|
|
37
|
-
if (
|
|
38
|
-
indexed ? predicate(list[ counter ], counter) : predicate(list[ counter ])
|
|
39
|
-
){
|
|
40
|
-
yes.push(list[ counter ]);
|
|
41
|
-
} else {
|
|
42
|
-
no.push(list[ counter ]);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return [ yes, no ]
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function partition(predicate, iterable){
|
|
50
|
-
if (arguments.length === 1){
|
|
51
|
-
return listHolder => partition(predicate, listHolder)
|
|
52
|
-
}
|
|
53
|
-
if (!isArray(iterable)) return partitionObject(predicate, iterable)
|
|
54
|
-
|
|
55
|
-
return partitionArray(predicate, iterable)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
var flat = flatten$1;
|
|
59
|
-
flatten$1.flatten = flatten$1;
|
|
60
|
-
flatten$1.unflatten = unflatten;
|
|
61
|
-
|
|
62
|
-
function isBuffer (obj) {
|
|
63
|
-
return obj &&
|
|
64
|
-
obj.constructor &&
|
|
65
|
-
(typeof obj.constructor.isBuffer === 'function') &&
|
|
66
|
-
obj.constructor.isBuffer(obj)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function keyIdentity (key) {
|
|
70
|
-
return key
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function flatten$1 (target, opts) {
|
|
74
|
-
opts = opts || {};
|
|
75
|
-
|
|
76
|
-
const delimiter = opts.delimiter || '.';
|
|
77
|
-
const maxDepth = opts.maxDepth;
|
|
78
|
-
const transformKey = opts.transformKey || keyIdentity;
|
|
79
|
-
const output = {};
|
|
80
|
-
|
|
81
|
-
function step (object, prev, currentDepth) {
|
|
82
|
-
currentDepth = currentDepth || 1;
|
|
83
|
-
Object.keys(object).forEach(function (key) {
|
|
84
|
-
const value = object[key];
|
|
85
|
-
const isarray = opts.safe && Array.isArray(value);
|
|
86
|
-
const type = Object.prototype.toString.call(value);
|
|
87
|
-
const isbuffer = isBuffer(value);
|
|
88
|
-
const isobject = (
|
|
89
|
-
type === '[object Object]' ||
|
|
90
|
-
type === '[object Array]'
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
const newKey = prev
|
|
94
|
-
? prev + delimiter + transformKey(key)
|
|
95
|
-
: transformKey(key);
|
|
96
|
-
|
|
97
|
-
if (!isarray && !isbuffer && isobject && Object.keys(value).length &&
|
|
98
|
-
(!opts.maxDepth || currentDepth < maxDepth)) {
|
|
99
|
-
return step(value, newKey, currentDepth + 1)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
output[newKey] = value;
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
step(target);
|
|
107
|
-
|
|
108
|
-
return output
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function unflatten (target, opts) {
|
|
112
|
-
opts = opts || {};
|
|
113
|
-
|
|
114
|
-
const delimiter = opts.delimiter || '.';
|
|
115
|
-
const overwrite = opts.overwrite || false;
|
|
116
|
-
const transformKey = opts.transformKey || keyIdentity;
|
|
117
|
-
const result = {};
|
|
118
|
-
|
|
119
|
-
const isbuffer = isBuffer(target);
|
|
120
|
-
if (isbuffer || Object.prototype.toString.call(target) !== '[object Object]') {
|
|
121
|
-
return target
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// safely ensure that the key is
|
|
125
|
-
// an integer.
|
|
126
|
-
function getkey (key) {
|
|
127
|
-
const parsedKey = Number(key);
|
|
128
|
-
|
|
129
|
-
return (
|
|
130
|
-
isNaN(parsedKey) ||
|
|
131
|
-
key.indexOf('.') !== -1 ||
|
|
132
|
-
opts.object
|
|
133
|
-
) ? key
|
|
134
|
-
: parsedKey
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function addKeys (keyPrefix, recipient, target) {
|
|
138
|
-
return Object.keys(target).reduce(function (result, key) {
|
|
139
|
-
result[keyPrefix + delimiter + key] = target[key];
|
|
140
|
-
|
|
141
|
-
return result
|
|
142
|
-
}, recipient)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function isEmpty (val) {
|
|
146
|
-
const type = Object.prototype.toString.call(val);
|
|
147
|
-
const isArray = type === '[object Array]';
|
|
148
|
-
const isObject = type === '[object Object]';
|
|
149
|
-
|
|
150
|
-
if (!val) {
|
|
151
|
-
return true
|
|
152
|
-
} else if (isArray) {
|
|
153
|
-
return !val.length
|
|
154
|
-
} else if (isObject) {
|
|
155
|
-
return !Object.keys(val).length
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
target = Object.keys(target).reduce(function (result, key) {
|
|
160
|
-
const type = Object.prototype.toString.call(target[key]);
|
|
161
|
-
const isObject = (type === '[object Object]' || type === '[object Array]');
|
|
162
|
-
if (!isObject || isEmpty(target[key])) {
|
|
163
|
-
result[key] = target[key];
|
|
164
|
-
return result
|
|
165
|
-
} else {
|
|
166
|
-
return addKeys(
|
|
167
|
-
key,
|
|
168
|
-
result,
|
|
169
|
-
flatten$1(target[key], opts)
|
|
170
|
-
)
|
|
171
|
-
}
|
|
172
|
-
}, {});
|
|
173
|
-
|
|
174
|
-
Object.keys(target).forEach(function (key) {
|
|
175
|
-
const split = key.split(delimiter).map(transformKey);
|
|
176
|
-
let key1 = getkey(split.shift());
|
|
177
|
-
let key2 = getkey(split[0]);
|
|
178
|
-
let recipient = result;
|
|
179
|
-
|
|
180
|
-
while (key2 !== undefined) {
|
|
181
|
-
if (key1 === '__proto__') {
|
|
182
|
-
return
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const type = Object.prototype.toString.call(recipient[key1]);
|
|
186
|
-
const isobject = (
|
|
187
|
-
type === '[object Object]' ||
|
|
188
|
-
type === '[object Array]'
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
// do not write over falsey, non-undefined values if overwrite is false
|
|
192
|
-
if (!overwrite && !isobject && typeof recipient[key1] !== 'undefined') {
|
|
193
|
-
return
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if ((overwrite && !isobject) || (!overwrite && recipient[key1] == null)) {
|
|
197
|
-
recipient[key1] = (
|
|
198
|
-
typeof key2 === 'number' &&
|
|
199
|
-
!opts.object ? [] : {}
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
recipient = recipient[key1];
|
|
204
|
-
if (split.length > 0) {
|
|
205
|
-
key1 = getkey(split.shift());
|
|
206
|
-
key2 = getkey(split[0]);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// unflatten again for 'messy objects'
|
|
211
|
-
recipient[key1] = unflatten(target[key], opts);
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
return result
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Brings the 1st level to the 0th level.
|
|
219
|
-
* Flats the object by nesting with '.' path separator.
|
|
220
|
-
*/
|
|
221
|
-
const serializeQueryForSpringBoot = (obj) => {
|
|
222
|
-
const parts = [];
|
|
223
|
-
Object.entries(obj).forEach(([key, val]) => {
|
|
224
|
-
if (Array.isArray(val)) {
|
|
225
|
-
val.forEach((v) => {
|
|
226
|
-
parts.push([key, v]);
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
else if (typeof val === 'object') {
|
|
230
|
-
objectToParams(val).forEach(([key, val]) => {
|
|
231
|
-
parts.push([key, val.toString()]);
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
parts.push([key, val]);
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
return parts.map((p) => `${p[0]}=${p[1]}`).join('&');
|
|
239
|
-
};
|
|
240
|
-
const flatten = (obj) => {
|
|
241
|
-
const r = flat.flatten(obj);
|
|
242
|
-
// { empty: {} } would be { empty: {} } instead of empty array
|
|
243
|
-
return Object.entries(r).filter(([k, v]) => typeof v !== 'object');
|
|
244
|
-
};
|
|
245
|
-
const objectToParams = (obj) => {
|
|
246
|
-
const [arrayProps, nonArrayProps] = partition((e) => Array.isArray(e[1]), Object.entries(obj));
|
|
247
|
-
const withoutArrayProps = fromPairs(nonArrayProps);
|
|
248
|
-
const res = flatten(withoutArrayProps);
|
|
249
|
-
arrayProps.forEach(([k, vals]) => {
|
|
250
|
-
vals.forEach((v) => res.push([k, v]));
|
|
251
|
-
});
|
|
252
|
-
return res;
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
// @ts-ignore
|
|
256
|
-
const serializeQueryWithQs = (obj) => {
|
|
257
|
-
return qs.stringify(obj);
|
|
258
|
-
};
|
|
259
4
|
|
|
260
5
|
const fileResFilenameRegex = /filename="([^"]+)"/;
|
|
261
6
|
const getFileNameFromContentDispositionHeader = (contentDispositionHeader) => {
|
|
@@ -267,25 +12,23 @@ const getFileNameFromContentDispositionHeader = (contentDispositionHeader) => {
|
|
|
267
12
|
};
|
|
268
13
|
|
|
269
14
|
const ContentType = {
|
|
15
|
+
Json: 'application/json',
|
|
270
16
|
FormData: 'multipart/form-data'
|
|
271
17
|
};
|
|
272
18
|
|
|
273
|
-
const
|
|
274
|
-
return {
|
|
275
|
-
url: path + (query ? `?${serializeQueryWithQs(query)}` : '')
|
|
276
|
-
};
|
|
277
|
-
};
|
|
278
|
-
const springBootUrlConverter = () => ({ query, path }) => {
|
|
19
|
+
const noOpUrlConverter = () => ({ query, path }) => {
|
|
279
20
|
return {
|
|
280
|
-
url: path
|
|
21
|
+
url: path,
|
|
22
|
+
params: query
|
|
281
23
|
};
|
|
282
24
|
};
|
|
283
|
-
const createHttpClient = (client, urlConverter =
|
|
25
|
+
const createHttpClient = (client, urlConverter = noOpUrlConverter()) => {
|
|
284
26
|
return {
|
|
285
27
|
request: (req) => {
|
|
286
28
|
const { url, params } = urlConverter(req);
|
|
287
29
|
const isBlob = req.format === 'document';
|
|
288
30
|
const obs = client.request(req.method, url, {
|
|
31
|
+
headers: req.headers,
|
|
289
32
|
params,
|
|
290
33
|
body: prepareBody(req.body, req.type),
|
|
291
34
|
responseType: (isBlob ? 'blob' : 'json'),
|
|
@@ -313,7 +56,7 @@ const prepareBody = (payload, type) => {
|
|
|
313
56
|
const convertToFormData = (payload) => {
|
|
314
57
|
const formData = new FormData();
|
|
315
58
|
const addProp = (key, val) => {
|
|
316
|
-
if (Array.isArray(val) || val instanceof FileList) {
|
|
59
|
+
if (Array.isArray(val) || (typeof FileList !== 'undefined' && val instanceof FileList)) {
|
|
317
60
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
318
61
|
// @ts-ignore - seems that FileList is iterable despite the warning
|
|
319
62
|
// TODO change to other iteration method if this is not true
|
|
@@ -332,6 +75,5 @@ const convertToFormData = (payload) => {
|
|
|
332
75
|
return formData;
|
|
333
76
|
};
|
|
334
77
|
|
|
78
|
+
exports.ContentType = ContentType;
|
|
335
79
|
exports.createHttpClient = createHttpClient;
|
|
336
|
-
exports.qsUrlConverter = qsUrlConverter;
|
|
337
|
-
exports.springBootUrlConverter = springBootUrlConverter;
|
package/package.json
CHANGED
|
@@ -1,23 +1,70 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ps-aux/api-client-angular",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0-rc.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "rollup -c",
|
|
9
9
|
"dev": "rollup -c --watch",
|
|
10
|
+
"test": "vitest",
|
|
10
11
|
"pub": "npm run build && npm --access public publish",
|
|
11
12
|
"tc": "tsc"
|
|
12
13
|
},
|
|
13
|
-
"author": "",
|
|
14
|
-
"license": "
|
|
14
|
+
"author": "psaux",
|
|
15
|
+
"license": "MIT",
|
|
15
16
|
"dependencies": {
|
|
16
|
-
"
|
|
17
|
-
|
|
17
|
+
"@local/shared": "*"
|
|
18
|
+
},
|
|
19
|
+
"bundledDependencies": [
|
|
20
|
+
"@local/shared"
|
|
21
|
+
],
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@angular/common": "^19.0.0 || ^20.0.0",
|
|
24
|
+
"@angular/compiler": "^19.0.0 || ^20.0.0"
|
|
18
25
|
},
|
|
19
26
|
"peerDependencies": {
|
|
20
|
-
"
|
|
21
|
-
"@angular/
|
|
22
|
-
|
|
27
|
+
"@angular/core": "^19.0.0 || ^20.0.0",
|
|
28
|
+
"@angular/common": "^19.0.0 || ^20.0.0",
|
|
29
|
+
"rxjs": "^7.8.1"
|
|
30
|
+
},
|
|
31
|
+
"description": "Angular HttpClient wrapper that implements Observable-based API requests.",
|
|
32
|
+
"keywords": [
|
|
33
|
+
"openapi",
|
|
34
|
+
"api",
|
|
35
|
+
"client",
|
|
36
|
+
"angular",
|
|
37
|
+
"http",
|
|
38
|
+
"rxjs",
|
|
39
|
+
"typescript"
|
|
40
|
+
],
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git+https://github.com/ps-aux/api-tests.git",
|
|
44
|
+
"directory": "packages/api-client-angular"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/ps-aux/api-tests",
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/ps-aux/api-tests/issues"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=18.0.0"
|
|
52
|
+
},
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"access": "public"
|
|
55
|
+
},
|
|
56
|
+
"files": [
|
|
57
|
+
"dist/index.js",
|
|
58
|
+
"dist/index.esm.js",
|
|
59
|
+
"dist/index.d.ts",
|
|
60
|
+
"README.md"
|
|
61
|
+
],
|
|
62
|
+
"exports": {
|
|
63
|
+
".": {
|
|
64
|
+
"types": "./dist/index.d.ts",
|
|
65
|
+
"import": "./dist/index.esm.js",
|
|
66
|
+
"require": "./dist/index.js"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"sideEffects": false
|
|
23
70
|
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { HttpClient as AngularHttpClient } from '@angular/common/http';
|
|
2
|
-
import { UrlConverter, ObservableHttpClient } from '@ps-aux/api-client-common';
|
|
3
|
-
export declare const qsUrlConverter: () => UrlConverter;
|
|
4
|
-
export declare const springBootUrlConverter: () => UrlConverter;
|
|
5
|
-
export declare const createHttpClient: (client: AngularHttpClient, urlConverter?: UrlConverter) => ObservableHttpClient<never>;
|
package/dist/_index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createHttpClient, springBootUrlConverter, qsUrlConverter } from './AngularApiHttpClient';
|
package/dist/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createHttpClient, springBootUrlConverter, qsUrlConverter } from './AngularApiHttpClient';
|
package/dist/serializeQuery.d.ts
DELETED
package/rollup.config.mjs
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import typescript from 'rollup-plugin-typescript2'
|
|
2
|
-
import resolve from '@rollup/plugin-node-resolve'
|
|
3
|
-
import commonjs from '@rollup/plugin-commonjs'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @type {import('rollup').RollupOptions}
|
|
7
|
-
*/
|
|
8
|
-
const config = {
|
|
9
|
-
input: 'src/index.ts',
|
|
10
|
-
output: [
|
|
11
|
-
{
|
|
12
|
-
file: `dist/index.js`,
|
|
13
|
-
format: 'cjs',
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
file: `dist/index.esm.js`,
|
|
17
|
-
format: 'es',
|
|
18
|
-
},
|
|
19
|
-
],
|
|
20
|
-
plugins: [
|
|
21
|
-
typescript(),
|
|
22
|
-
resolve(),
|
|
23
|
-
commonjs(),
|
|
24
|
-
],
|
|
25
|
-
external: ['qs', 'rxjs'],
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
export default config
|
|
29
|
-
|