flamerest 1.0.20 → 1.0.23

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 (3) hide show
  1. package/REST.d.ts +62 -45
  2. package/REST.js +145 -82
  3. package/package.json +1 -1
package/REST.d.ts CHANGED
@@ -1,53 +1,70 @@
1
- /**
2
- *
3
- * @param {string} url Адрес
4
- * @param {object|string} params Параметры, которые надо передать, могут быть в виде объекта или строки
5
- * @param {string} type Тип
6
- * @param {string} responseType Тип ответа: json или blob
7
- */
8
- export function request(url: string, params: object|string, type:string = 'GET', responseType:string = 'json'): object
1
+ /**
2
+ *
3
+ * @param {string} url Адрес
4
+ * @param {object|string} params Параметры, которые надо передать, могут быть в виде объекта или строки
5
+ * @param {string} type Тип
6
+ * @param {string} responseType Тип ответа: json или blob
7
+ */
8
+ export function request(url: string, params: object | string, type: string, responseType: string): object
9
+
10
+ /**
11
+ * Получить выборку из таблицы через REST
12
+ * @param table
13
+ * @param fields
14
+ * @param where Позволяет делать выборку из связанных таблиц, надо только их указать через название таблицы sites.id=5, и указать колонку в expand
15
+ * @param expand Устаревшая механика, оставлена для совместимости
16
+ * @param sortfields
17
+ * @param page
18
+ * @param perPage
19
+ * @param RemoveDuplicates
20
+ * @param format
21
+ * @param titles Это чтобы мы могли контроллить какие названия полей мы будет загружать при экспорте, чтобы они были как в таблице
22
+ * @return Promise<object>
23
+ */
24
+ export function get(table: string, where: object | string | null, expand: object | string | null, fields: object | Array<string> | string | null, sortfields: object | Array<string> | string | null, page: number, perPage: number, RemoveDuplicates, format, titles): object
9
25
 
10
- /**
11
- * Получить выборку из таблицы через REST
12
- * @param table
13
- * @param fields
14
- * @param where Позволяет делать выборку из связанных таблиц, надо только их указать через название таблицы sites.id=5, и указать колонку в expand
15
- * @param expand
16
- * @param sortfields
17
- * @param page
18
- * @param perPage
19
- * @param RemoveDuplicates
20
- * @param format
21
- * @param titles Это чтобы мы могли контроллить какие названия полей мы будет загружать при экспорте, чтобы они были как в таблице
22
- * @return Promise<>
23
- */
24
- export function get(table: string, where, expand, fields, sortfields, page, perPage, RemoveDuplicates, format, titles): object
26
+ /**
27
+ * Получить все записи по запросу [постранично]
28
+ * @param {string} table
29
+ * @param {object} params
30
+ * @returns
31
+ */
32
+ export function all(table: string, params: {where: object, fields: object|Array<string>, sort: Array<string>, page: number, perPage: number}): object;
33
+
34
+ /**
35
+ * Получить одну запись по её ID
36
+ * @param table
37
+ * @param id
38
+ * @param fields
39
+ * @param primaryKeyName
40
+ */
41
+ export function one(table: string, id: number|string, fields: object|Array<string>, primaryKeyName: string): object;
25
42
 
26
- /**
27
- * Создать новую запись
28
- * @param table
29
- * @param values
30
- */
43
+ /**
44
+ * Создать новую запись
45
+ * @param table
46
+ * @param values
47
+ */
31
48
  export function create(table: string, values: object)
32
49
 
33
- /**
34
- * Удалить запись
35
- * @param table
36
- * @param id
37
- */
38
- export function remove(table, id)
50
+ /**
51
+ * Удалить запись
52
+ * @param table
53
+ * @param id
54
+ */
55
+ export function remove(table: string, id: number | string)
39
56
 
40
- /**
41
- * Редактировать значения
42
- * @param table
43
- * @param ID
44
- * @param values
45
- */
46
- export function edit(table, ID, values)
57
+ /**
58
+ * Редактировать значения
59
+ * @param table
60
+ * @param ID
61
+ * @param values
62
+ */
63
+ export function edit(table: string, ID: number | string, values: object)
47
64
 
48
- /**
49
- * Получить схемы всех таблиц
50
- */
65
+ /**
66
+ * Получить схемы всех таблиц
67
+ */
51
68
  export function getCRUDInfo(): object
52
69
 
53
70
  /**
@@ -62,7 +79,7 @@ export function auth(username: string, password: string);
62
79
  * @param username
63
80
  * @param password
64
81
  */
65
- export function signup(username, password);
82
+ export function signup(username: string, password: string);
66
83
 
67
84
  /**
68
85
  * Выйти из системы
package/REST.js CHANGED
@@ -1,18 +1,18 @@
1
1
 
2
2
  class FLAMEREST {
3
3
 
4
- constructor(server_address, localhost_endpoint, unauthorized_callback){
4
+ constructor(server_address, localhost_endpoint, unauthorized_callback) {
5
5
 
6
6
  /**
7
7
  * Адрес серва
8
8
  * @type {string}
9
9
  */
10
- if(typeof window === 'undefined' && server_address === undefined) this.SERVER = "http://localhost/";
11
- if(typeof window !== 'undefined' && server_address === undefined) this.SERVER = window.location.protocol + "//" + window.location.host;
12
- if(server_address !== undefined) this.SERVER = server_address;
13
- this.SERVER = this.SERVER.substr(this.SERVER.length-2, 1) === '/' ? this.SERVER.substr(0,this.SERVER.length-1) : this.SERVER;
10
+ if (typeof window === 'undefined' && server_address === undefined) this.SERVER = "http://localhost/";
11
+ if (typeof window !== 'undefined' && server_address === undefined) this.SERVER = window.location.protocol + "//" + window.location.host;
12
+ if (server_address !== undefined) this.SERVER = server_address;
13
+ this.SERVER = this.SERVER.substr(this.SERVER.length - 2, 1) === '/' ? this.SERVER.substr(0, this.SERVER.length - 1) : this.SERVER;
14
14
 
15
- if(typeof window !== 'undefined' && window.location.hostname === 'localhost' && localhost_endpoint !== undefined) this.SERVER = localhost_endpoint;
15
+ if (typeof window !== 'undefined' && window.location.hostname === 'localhost' && localhost_endpoint !== undefined) this.SERVER = localhost_endpoint;
16
16
 
17
17
  /**
18
18
  * Стандартное число запросов на страницу
@@ -49,50 +49,66 @@ class FLAMEREST {
49
49
  let that = this;
50
50
 
51
51
  // Фетч поддерживается - получаем через него, это быстрее
52
- if(typeof fetch === "function") {
52
+ if (typeof fetch === "function") {
53
53
 
54
- return new Promise(async (resolve,reject)=>{
54
+ return new Promise(async (resolve, reject) => {
55
55
 
56
- // Тело ответа формируется в два этапа: сперва заголовки, затем ответ
57
- let ResolveBody = {};
56
+ try {
58
57
 
59
- // Тело запроса
60
- let requestBody = {
61
- method: type,
62
- mode: 'cors',
63
- headers: {
64
- 'Content-type': 'application/json; charset=utf-8'
65
- }
66
- };
58
+ // Тело запроса
59
+ let requestBody = {
60
+ method: type,
61
+ mode: 'cors',
62
+ headers: {
63
+ 'Content-type': 'application/json; charset=utf-8'
64
+ }
65
+ };
67
66
 
68
- if(type!=='GET')
69
- requestBody.body = params;
67
+ if (type !== 'GET')
68
+ requestBody.body = params;
70
69
 
71
- // Делаем запрос
72
- fetch(url, requestBody)
73
- .then(response=>{
70
+ // Делаем запрос
71
+ let response = await fetch(url, requestBody);
74
72
 
75
- // Ответ получен
73
+ // Тело ответа формируется в два этапа: сперва заголовки, затем ответ
74
+ let ResolveBody = {
75
+ status: response.status,
76
+ ok: response.ok
77
+ };
76
78
 
77
79
  // Ответ с ошибкой
78
80
  if (!response.ok) {
79
81
 
80
82
  // Тело ошибки
81
- let error_body = null;
83
+ ResolveBody.message = response.statusText;
84
+
82
85
  try {
83
- error_body = response.json();
86
+
87
+ ResolveBody.errors = await response.json();
88
+
89
+ // Ошибки
90
+ switch (ResolveBody.status) {
91
+
92
+ // Ошибка валидации: Собираем все ошибки полей
93
+ case 422:
94
+ let Errs = {};
95
+ for(let err of ResolveBody.errors) {
96
+ Errs[err['field']] = Errs[err['field']] === undefined ? err['message'] : Errs[err['field']] + ". " + err['message']
97
+ }
98
+ ResolveBody.errors = Errs;
99
+ }
100
+
84
101
  }
85
- catch (exjson){
86
- error_body = response.text();
102
+ catch (exjson) {
103
+ ResolveBody.errors = await response.text();
87
104
  }
88
105
 
89
- console.log('Ошибка загрузки [' + response.status + '] ' + url + ": " + response.statusText);
106
+ // Рапортуем об ошибке
107
+ console.error('Ошибка загрузки [' + response.status + '] ' + url + ": " + response.statusText, ResolveBody, ResolveBody.errors);
90
108
 
91
- throw {
92
- status: response.status,
93
- message: response.statusText,
94
- body: error_body
95
- }
109
+ // Возвращаем управление, которое работает без блока catch, достаточно проверить на if(response.errors)
110
+ resolve(ResolveBody);
111
+ return;
96
112
 
97
113
  }
98
114
 
@@ -110,65 +126,74 @@ class FLAMEREST {
110
126
  }
111
127
 
112
128
  // Заполняем тело ответа заголовками
113
- ResolveBody = {
114
- status: response.status,
115
- type: "json",
116
- data: {},
117
- pages: pages
118
- };
129
+ ResolveBody.type = "json";
130
+ ResolveBody.data = {};
131
+ ResolveBody.pages = pages;
119
132
 
120
133
  // Получаем тело ответа
121
134
  switch (responseType) {
122
- case 'json': return response.text();
135
+ case 'json': ResolveBody.data = await response.text(); break;
123
136
  case 'blob': {
124
137
  // Записываем имя файла и mime-тип
125
138
  ResolveBody.filename = 'file'; //response.headers.get('content-disposition').split('filename=')[1];
126
139
  ResolveBody.MimeType = response.headers.get('content-Type');
127
- return response.blob();
140
+ ResolveBody.data = await response.blob();
141
+
142
+ // Если ответ в виде блоба, сразу его отдаём без декодировки
143
+ resolve(ResolveBody);
144
+ return;
128
145
  }
129
146
  }
130
147
 
131
- }).then(response=>{
132
-
133
148
  // Декодируем тело ответа, если оно есть
134
- if(response===undefined) throw "ERR";
135
- if(response==="") response = "{}";
136
-
137
- // Если ответ в виде блоба, сразу его отдаём без декодировки
138
- if(responseType === 'blob') {
139
- ResolveBody.data = response;
149
+ if (ResolveBody.data === undefined) {
150
+ ResolveBody.errors = ["Принятый ответ пуст"];
151
+ console.error("Принятый ответ пуст", ResolveBody);
140
152
  resolve(ResolveBody);
141
153
  return;
142
- }
154
+ };
143
155
 
156
+ // Пустой ответ конвертируем в валидный пустой объект
157
+ if (ResolveBody.data === "") ResolveBody.data = "{}";
158
+
159
+ // Декодируем
144
160
  try {
145
- response = JSON.parse(response);
161
+ ResolveBody.data = JSON.parse(ResolveBody.data);
146
162
  } catch (ex) {
147
- throw "ERR";
163
+ ResolveBody.errors = ["Ошибка декодирования"];
164
+ console.error("Ошибка декодирования", ResolveBody);
165
+ reject(ResolveBody);
166
+ return;
148
167
  }
149
168
 
169
+ // Декодинг успешен
170
+
150
171
  // Если пришёл ответ: неавторизовано, и указан коллбек авторизации - запускаем его
151
- if(response.Auth === false) {
152
- if(that.unauthorized_callback !== undefined) {that.unauthorized_callback(); resolve(response); return;}
172
+ if (response.Auth === false) {
173
+ if (that.unauthorized_callback !== undefined) { that.unauthorized_callback(); resolve(response); return; }
153
174
  }
154
175
 
176
+
155
177
  // Возвращаем успешную загрузку
156
- ResolveBody.data = response;
157
178
  resolve(ResolveBody);
158
179
 
159
- }).catch(async err=>{
180
+ return;
181
+
182
+ }
183
+
184
+ catch (err) {
160
185
 
161
186
  // Ошибка загрузки любого типа
162
187
  // TODO: на этом этапе стоит сделать, чтобы он пробовал повторить запрос, если это GET
163
188
 
164
- if(typeof err !== 'object' || err.message === undefined) {
189
+ if (typeof err !== 'object' || err.message === undefined) {
165
190
  err = {
166
191
  status: 0,
167
192
  message: '',
168
193
  };
169
194
  }
170
195
 
171
- if(typeof err.body === 'object') {
196
+ if (typeof err.body === 'object') {
172
197
  err.body = await err.body;
173
198
  }
174
199
 
@@ -176,7 +201,7 @@ class FLAMEREST {
176
201
 
177
202
  reject(err);
178
203
 
179
- })
204
+ }
180
205
 
181
206
  });
182
207
 
@@ -270,7 +295,7 @@ class FLAMEREST {
270
295
  get(table, where, expand, fields, sortfields, page, perPage, RemoveDuplicates, format, titles) {
271
296
 
272
297
  // Нормализуем имена таблиц
273
- table = table.replace(/_/g,"");
298
+ table = table.replace(/_/g, "");
274
299
 
275
300
  let responseType = "json";
276
301
 
@@ -280,25 +305,25 @@ class FLAMEREST {
280
305
  let json = {};
281
306
 
282
307
  // Генерим условия
283
- if(where!==undefined && where!==null)
308
+ if (where !== undefined && where !== null)
284
309
  json.where = where;
285
310
 
286
- if(fields !== undefined && fields!==null)
311
+ if (fields !== undefined && fields !== null)
287
312
  json.fields = fields;
288
313
 
289
- if(titles !== undefined && titles!==null)
314
+ if (titles !== undefined && titles !== null)
290
315
  json.titles = titles;
291
316
 
292
- if(sortfields !== undefined && sortfields!==null)
317
+ if (sortfields !== undefined && sortfields !== null)
293
318
  json.sort = sortfields;
294
319
 
295
- if(expand !== undefined && expand!==null)
320
+ if (expand !== undefined && expand !== null)
296
321
  json.expand = expand;
297
322
 
298
- if(RemoveDuplicates !== undefined && RemoveDuplicates!==null)
323
+ if (RemoveDuplicates !== undefined && RemoveDuplicates !== null)
299
324
  json.RemoveDuplicates = true;
300
325
 
301
- if(format !== undefined && format!==null) {
326
+ if (format !== undefined && format !== null) {
302
327
  json.format = format;
303
328
  responseType = "blob";
304
329
  }
@@ -313,6 +338,31 @@ class FLAMEREST {
313
338
 
314
339
  }
315
340
 
341
+ /**
342
+ * Получить все записи по запросу [постранично]
343
+ * @param {string} table
344
+ * @param {object} params
345
+ * @returns {object}
346
+ */
347
+ all(table, params) {
348
+ return this.get(table, params.where, null, params.fields, params.sort, params.page, params.perPage);
349
+ }
350
+
351
+ /**
352
+ * Получить одну запись по ID
353
+ * @param {string} table
354
+ * @param {number|string} id
355
+ * @param {object|Array} fields
356
+ * @param {string} primaryKeyName
357
+ * @returns {object}
358
+ */
359
+ async one(table, id, fields = null, primaryKeyName = 'id') {
360
+ let resp = await this.get(table, {[primaryKeyName]:id}, null, fields, null, 1, 1);
361
+ if(resp.errors) return resp;
362
+ if(resp.data.length === 0) return resp;
363
+ return resp.data[0];
364
+ }
365
+
316
366
  /**
317
367
  * Создать новую запись
318
368
  * @param table
@@ -321,7 +371,20 @@ class FLAMEREST {
321
371
  create(table, values) {
322
372
 
323
373
  // Нормализуем имена таблиц
324
- table = table.replace(/_/g,"");
374
+ table = table.replace(/_/g, "");
375
+
376
+ // Если в один из параметров передан FileList, т.е. нужно загрузить файлы
377
+ for (let val in values)
378
+ if (val instanceof FileList) {
379
+ let newValues = [];
380
+ for (let file in val) {
381
+ newValues.push({
382
+ 'mime': 'jpg',
383
+ 'size': 23,
384
+ 'data': btoa(val)
385
+ });
386
+ }
387
+ }
325
388
 
326
389
  return this.request(this.SERVER + '/api/' + table + '/create', JSON.stringify(values), 'POST');
327
390
 
@@ -335,9 +398,9 @@ class FLAMEREST {
335
398
  remove(table, id) {
336
399
 
337
400
  // Нормализуем имена таблиц
338
- table = table.replace(/_/g,"");
401
+ table = table.replace(/_/g, "");
339
402
 
340
- return this.request(this.SERVER + '/api/' + table + '/delete?id=' + id , '{}', 'DELETE');
403
+ return this.request(this.SERVER + '/api/' + table + '/delete?id=' + id, '{}', 'DELETE');
341
404
 
342
405
  }
343
406
 
@@ -350,7 +413,7 @@ class FLAMEREST {
350
413
  edit(table, ID, values) {
351
414
 
352
415
  // Нормализуем имена таблиц
353
- table = table.replace(/_/g,"");
416
+ table = table.replace(/_/g, "");
354
417
 
355
418
  return this.request(this.SERVER + '/api/' + table + '/update?id=' + ID, JSON.stringify(values), 'PATCH');
356
419
  }
@@ -359,24 +422,24 @@ class FLAMEREST {
359
422
  * Получить схемы всех таблиц
360
423
  */
361
424
  getCRUDInfo() {
362
- if(window.sessionStorage.getItem("crudschema") === null) {
425
+ if (window.sessionStorage.getItem("crudschema") === null) {
363
426
  return this.request(this.SERVER + '/site/crudschema', {}, 'GET')
364
- .then(res => {
365
- // Кешируем схему в браузере на время текущей сессии (в пределах ОДНОЙ вкладки)
366
- window.sessionStorage.setItem("crudschema", JSON.stringify(res));
367
- return res;
368
- });
427
+ .then(res => {
428
+ // Кешируем схему в браузере на время текущей сессии (в пределах ОДНОЙ вкладки)
429
+ window.sessionStorage.setItem("crudschema", JSON.stringify(res));
430
+ return res;
431
+ });
369
432
  }
370
433
  else
371
- return new Promise((resolve,reject)=>{ resolve(JSON.parse(window.sessionStorage.getItem("crudschema")))});
434
+ return new Promise((resolve, reject) => { resolve(JSON.parse(window.sessionStorage.getItem("crudschema"))) });
372
435
  }
373
436
 
374
437
  auth(username, password) {
375
- return this.request(this.SERVER + '/auth/auth', JSON.stringify({login: username, password: password}), 'POST');
438
+ return this.request(this.SERVER + '/auth/auth', JSON.stringify({ login: username, password: password }), 'POST');
376
439
  }
377
440
 
378
441
  signup(username, password) {
379
- return this.request(this.SERVER + '/auth/signup', JSON.stringify({login: username, password: password}), 'POST');
442
+ return this.request(this.SERVER + '/auth/signup', JSON.stringify({ login: username, password: password }), 'POST');
380
443
  }
381
444
 
382
445
  logout() {
@@ -386,7 +449,7 @@ class FLAMEREST {
386
449
  }
387
450
 
388
451
 
389
- if(!window.REST) {
452
+ if (!window.REST) {
390
453
  window.REST = new FLAMEREST();
391
454
  }
392
455
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flamerest",
3
- "version": "1.0.20",
3
+ "version": "1.0.23",
4
4
  "description": "",
5
5
  "main": "REST.js",
6
6
  "typings": "./REST.d.ts",