react-ui-basics 0.0.183 → 0.0.184

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/index.js CHANGED
@@ -23,6 +23,8 @@ export { default as Dropzone } from './Dropzone.js';
23
23
  export { default as FilteredList } from './FilteredList.js';
24
24
  export { default as FloatingActionButton } from './FloatingActionButton.js';
25
25
  export { default as FormUploadProgress } from './FormUploadProgress.js';
26
+ import * as HttpTools from './HttpTools.js';
27
+ export { HttpTools };
26
28
  export { default as ImageGallery, ImageGalleryContainer } from './ImageGallery.js';
27
29
  export { default as MaterialIcon } from './MaterialIcon.js';
28
30
  export { default as Modal } from './Modal.js';
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-ui-basics",
3
- "version": "0.0.183",
3
+ "version": "0.0.184",
4
4
  "description": "",
5
5
  "module": "index.js",
6
6
  "_main": "index.cjs.js",
@@ -0,0 +1,257 @@
1
+ import {orNoop} from "./Tools";
2
+
3
+ const CONTENT_TYPE_APPLICATION_JSON = 'application/json';
4
+
5
+ const toKeyValue = (key, value) => key && (encodeURIComponent(key) + '=' + encodeURIComponent(value !== null && typeof value === 'object' ? JSON.stringify(value) : value));
6
+
7
+ export const toRequestParams = (params) => (params && Object.keys(params).map(key => {
8
+ const value = params[key];
9
+ if (Array.isArray(value))
10
+ return value.map(it => toKeyValue(key, it)).join('&')
11
+ else
12
+ return toKeyValue(key, value);
13
+ }).join('&')) || '';
14
+
15
+ export type Method = 'GET' | 'DELETE' | 'POST' | 'PUT'
16
+
17
+ export class FetchOptions {
18
+ method?: Method = 'GET'
19
+ headers?: ({ [name: string]: string })
20
+ params?: ({ [name: string]: any }) | FormData | Blob
21
+ multipart?: boolean = false
22
+ async?: boolean = true
23
+ withCredentials?: boolean = true
24
+ timeout?: number
25
+ onTimeout?: ((ev: ProgressEvent) => any)
26
+ onSuccess?: ((t: any) => void)
27
+ onError?: ((e: any, status: number) => void)
28
+ onProgress?: ((ev: ProgressEvent) => any)
29
+ provideCancel?: ((cancelFunction: () => void) => void)
30
+ }
31
+
32
+ const DEFAULT_OPTIONS = new FetchOptions()
33
+
34
+ export const fetch = <T>(url, options: FetchOptions = DEFAULT_OPTIONS) => {
35
+ const method = options.method || 'GET'
36
+ const params = options.params || {};
37
+ if (method === 'GET' || method === 'DELETE') {
38
+ const serializedData = toRequestParams(params);
39
+ if (serializedData)
40
+ url = url + "?" + serializedData;
41
+ }
42
+
43
+ const headers = {
44
+ 'Accept': CONTENT_TYPE_APPLICATION_JSON,
45
+ ...(options.headers || {})
46
+ };
47
+
48
+ let body: FormData | string | Blob
49
+
50
+ if (method === 'POST' || method === 'PUT') {
51
+ if (options.multipart) {
52
+ let formData;
53
+ if (params instanceof FormData) {
54
+ formData = params;
55
+ } else {
56
+ formData = new FormData();
57
+ Object.keys(params).forEach(name => {
58
+ let value = params[name];
59
+ if (Array.isArray(value)) {
60
+ value.forEach(it => formData.append(name, it))
61
+ } else if (value != null)
62
+ formData.append(name, value);
63
+ });
64
+ }
65
+ body = formData;
66
+ } else if (params instanceof Blob || params instanceof FormData) {
67
+ body = params;
68
+ } else {
69
+ headers['Content-Type'] = CONTENT_TYPE_APPLICATION_JSON;
70
+ body = JSON.stringify(params || {}, (key, value) => {
71
+ if (value !== null)
72
+ return value
73
+ });
74
+ }
75
+ }
76
+
77
+ let makeRequest = (success, error) => {
78
+ const request = new XMLHttpRequest();
79
+
80
+ const data = body;
81
+
82
+ if (!!(options.withCredentials === void 0 ? true : options.withCredentials))
83
+ request.withCredentials = true;
84
+
85
+ const async = !!(options.async === void 0 ? true : options.async);
86
+ request.open(method, url, async);
87
+
88
+ Object.keys(headers).forEach(key =>
89
+ request.setRequestHeader(key, headers[key])
90
+ );
91
+ const onError = orNoop(error);
92
+
93
+ if (options.timeout && async) {
94
+ request.timeout = options.timeout;
95
+ request.ontimeout = (e) => (options.onTimeout || onError)(e);
96
+ }
97
+
98
+ const onProgress = options.onProgress;
99
+ if (onProgress) {
100
+ request.upload.onprogress = e => {
101
+ if (e.lengthComputable)
102
+ onProgress(e);
103
+ };
104
+ request.onprogress = onProgress;
105
+ }
106
+
107
+ request.onload = () => {
108
+ const responseText = request.responseText;
109
+ const status = request.status;
110
+ if (status >= 200 && status < 400) {
111
+ try {
112
+ orNoop(success)(JSON.parse(responseText || "{}"));
113
+ } catch (e) {
114
+ const message = `Unexpected exception while processing response for ${method} ${url}, status: ${status}, response: '${responseText}', exception:`;
115
+ console.log(message, e)
116
+ onError(new FetchError(message, status, responseText))
117
+ }
118
+ } else {
119
+ const message = `Not ok response for ${method} ${url}, status: ${status}, response: '${responseText}'`;
120
+ console.log(message);
121
+ onError(new FetchError(message, status, responseText))
122
+ }
123
+ };
124
+
125
+ request.onerror = onError;
126
+
127
+ try {
128
+ if (method === 'POST') {
129
+ if (typeof data === 'string' || data instanceof Blob || data instanceof FormData)
130
+ request.send(data);
131
+ else
132
+ request.send(toRequestParams(data));
133
+ } else
134
+ request.send();
135
+ } catch (e) {
136
+ onError(e);
137
+ }
138
+
139
+ if (options.provideCancel) {
140
+ options.provideCancel(() => request.abort());
141
+ }
142
+ return request
143
+ };
144
+
145
+ // if (!window.Promise)
146
+ // return makeRequest(options.onSuccess, options.onError);
147
+
148
+ return new Promise<T>((resolve, reject) => {
149
+ const success = data => (options.onSuccess || resolve)(data);
150
+ const error = (e, status) => (options.onError || reject)(e, status);
151
+ makeRequest(success, error);
152
+ });
153
+ };
154
+
155
+ class FetchError extends Error {
156
+ status: number;
157
+ responseText?: string;
158
+
159
+ constructor(message, status: number, responseText?: string) {
160
+ super(message);
161
+ this.status = status;
162
+ this.responseText = responseText;
163
+ }
164
+ }
165
+
166
+
167
+ export type Params = { [id: string]: any };
168
+ export type UrlRenderer = (params: Params) => string;
169
+
170
+ const variablePatter = /\{(\w+)\}/g;
171
+ export const createUrlRenderer = (template: string, deleteVars: boolean = false): UrlRenderer => {
172
+ let parts = [];
173
+ let variables = [];
174
+
175
+ let find;
176
+ let prevIndex = 0;
177
+ while ((find = variablePatter.exec(template)) !== null) {
178
+ variables.push(find[1]);
179
+ parts.push(template.substring(prevIndex, find.index));
180
+ prevIndex = find.index + find[0].length;
181
+ }
182
+ if (prevIndex === 0)
183
+ return () => template;
184
+
185
+ parts.push(template.substring(prevIndex, template.length));
186
+
187
+ const m = parts;
188
+ const v = variables;
189
+ return function (params: any) {
190
+ const length = Math.max(m.length, v.length);
191
+ let s = '';
192
+ for (let i = 0; i < length; i++) {
193
+ if (m[i] !== null)
194
+ s += m[i];
195
+ let param = params[v[i]];
196
+ if (params && v[i] !== null && param != null) {
197
+ s += encodeURIComponent(param);
198
+ if (deleteVars)
199
+ delete params[v[i]]
200
+ }
201
+ }
202
+ return s;
203
+ };
204
+ }
205
+
206
+ const lazy = <T extends Function>(f: ((...any) => T), ...args): any => {
207
+ let result: T;
208
+ return function (): any {
209
+ if (!result)
210
+ result = f.apply(null, args) as T
211
+
212
+ return result.apply(null, arguments)
213
+ };
214
+ }
215
+
216
+ let baseurl = window.location.origin
217
+ export const setBaseUrl = url => baseurl = url
218
+
219
+ export const createGET = <R>(template: string) => {
220
+ let urlMaker: (UrlRenderer) = lazy(createUrlRenderer, template, true);
221
+ return async (params?: Params,) => fetch<R>(`${baseurl}${urlMaker(params)}`, {params});
222
+ };
223
+
224
+
225
+ export const createPOST = <R, P extends Params>(template: string) => {
226
+ let urlMaker: (UrlRenderer) = lazy(createUrlRenderer, template);
227
+ return async (params?: P,) => fetch<R>(`${baseurl}${urlMaker(params)}`, {params, method: "POST"});
228
+ };
229
+
230
+ const createBinaryPOST = <R>(template: string) => {
231
+ let urlMaker: (UrlRenderer) = lazy(createUrlRenderer, template, true);
232
+ return async (pathVariables: Params, options: FetchOptions) => {
233
+ let url = `${baseurl}${urlMaker(pathVariables)}`;
234
+ if (Object.keys(pathVariables).length > 0) {
235
+ url += '?' + toRequestParams(pathVariables)
236
+ }
237
+ return fetch<R>(url, options);
238
+ };
239
+ };
240
+
241
+ export const createDELETE = <R>(template: string) => {
242
+ let urlMaker: (UrlRenderer) = lazy(createUrlRenderer, template, true);
243
+ return async (params?: Params,) => fetch<R>(`${baseurl}${urlMaker(params)}`, {params, method: "DELETE"});
244
+ };
245
+
246
+ export interface MultipartOptions {
247
+ onProgress?: ((ev: ProgressEvent) => any)
248
+ provideCancel?: ((cancelFunction: () => void) => void)
249
+ }
250
+
251
+ export const createMultipart = <R>(template: string) => {
252
+ let urlMaker: (UrlRenderer) = lazy(createUrlRenderer, template);
253
+ return async (params: any, options?: MultipartOptions) => {
254
+ let url = `${baseurl}${urlMaker(params)}`;
255
+ return fetch<R>(url, {params, method: "POST", multipart: true, ...options});
256
+ };
257
+ };
package/src/index.js CHANGED
@@ -21,6 +21,7 @@ import Dropzone from "./Dropzone";
21
21
  import FilteredList from "./FilteredList";
22
22
  import FloatingActionButton from "./FloatingActionButton";
23
23
  import FormUploadProgress from "./FormUploadProgress";
24
+ import * as HttpTools from "./HttpTools";
24
25
  import ImageGallery from "./ImageGallery";
25
26
  import {ImageGalleryContainer} from "./ImageGallery";
26
27
  import MaterialIcon from "./MaterialIcon";
@@ -63,6 +64,7 @@ export {
63
64
  FilteredList,
64
65
  FloatingActionButton,
65
66
  FormUploadProgress,
67
+ HttpTools,
66
68
  ImageGallery,
67
69
  ImageGalleryContainer,
68
70
  MaterialIcon,