@digione/node-custom-api 0.2.0-beta1 → 0.2.0-beta10

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.
@@ -1,9 +1,9 @@
1
1
  import { Request, Response } from 'express';
2
2
  export declare const getAuthParam: (req: Request, res: Response, next: any) => void;
3
3
  export declare const getStremParam: (req: Request, res: Response, next: any) => void;
4
- export declare const getQueryParam: (req: Request, res: Response, next: any) => void;
4
+ export declare const getQueryParam: (req: Request, res: Response, next: any) => Promise<void | Response<any, Record<string, any>>>;
5
5
  export declare const getQueryParamCUD: (req: Request, res: Response, next: any) => void;
6
- export declare const getQueryParamFile: (req: Request, res: Response, next: any) => void;
6
+ export declare const getQueryParamFile: (req: Request, res: Response, next: any) => Promise<void | Response<any, Record<string, any>>>;
7
7
  export declare const changeQueryParam: (value?: {}, { skipSystem }?: {
8
8
  skipSystem?: boolean;
9
9
  }) => (req: Request, res: Response, next: any) => any;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.changeConfigParam = exports.changeBodyParam = exports.changeOptionParam = exports.changeQueryParam = exports.getQueryParamFile = exports.getQueryParamCUD = exports.getQueryParam = exports.getStremParam = exports.getAuthParam = void 0;
4
+ const tslib_1 = require("tslib");
4
5
  const helper_1 = require("../utils/helper");
6
+ const errors_1 = require("../errors");
5
7
  const _ = require("lodash");
6
8
  const getAuthParam = (req, res, next) => {
7
9
  res.locals.option['hostname'] = ((0, helper_1.getENV)('NODE_ENV') == 'development' ? 'http' : 'https') + '://' + req.get('host');
@@ -77,7 +79,8 @@ const getStremParam = (req, res, next) => {
77
79
  });
78
80
  };
79
81
  exports.getStremParam = getStremParam;
80
- const getQueryParam = (req, res, next) => {
82
+ const getQueryParam = (req, res, next) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
83
+ let config = res.locals.config || {};
81
84
  res.locals.option = res.locals.option || {};
82
85
  res.locals.option['lang_code'] = 'en';
83
86
  res.locals.option['currency'] = 'thb';
@@ -93,8 +96,20 @@ const getQueryParam = (req, res, next) => {
93
96
  else {
94
97
  res.locals.include = {};
95
98
  }
99
+ if (config['maxQueryLimit']) {
100
+ req.query.limit = req.query.limit || config['maxQueryLimit'];
101
+ }
96
102
  if (req.query.limit) {
97
103
  res.locals.option['limit'] = Number(req.query.limit);
104
+ if (config['maxQueryLimit'] && res.locals.option['limit'] > config['maxQueryLimit']) {
105
+ try {
106
+ yield (0, errors_1.paramError)(`"limit" must be less than or equal to ${config['maxQueryLimit']}`, { field: "limit" });
107
+ }
108
+ catch (err) {
109
+ let error = new errors_1.CustomError(err);
110
+ return res.status(error.code).send(error);
111
+ }
112
+ }
98
113
  }
99
114
  if (req.query.offset) {
100
115
  res.locals.option['offset'] = Number(req.query.offset);
@@ -124,7 +139,7 @@ const getQueryParam = (req, res, next) => {
124
139
  }
125
140
  return next();
126
141
  });
127
- };
142
+ });
128
143
  exports.getQueryParam = getQueryParam;
129
144
  const getQueryParamCUD = (req, res, next) => {
130
145
  let config = res.locals.config || {};
@@ -50,9 +50,6 @@ export declare const UserAttr: {
50
50
  organ_id: {
51
51
  type: sequelize.IntegerDataType;
52
52
  };
53
- member_id: {
54
- type: sequelize.StringDataType;
55
- };
56
53
  provider: sequelize.StringDataType;
57
54
  mobile: sequelize.StringDataType;
58
55
  mobile_code: sequelize.StringDataType;
@@ -58,10 +58,6 @@ exports.UserAttr = {
58
58
  organ_id: {
59
59
  type: sequelize.INTEGER({ length: 11 })
60
60
  },
61
- // points:sequelize.INTEGER({length:11}),
62
- member_id: {
63
- type: sequelize.STRING(100)
64
- },
65
61
  provider: sequelize.STRING(40),
66
62
  mobile: sequelize.STRING(20),
67
63
  mobile_code: sequelize.STRING(10)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digione/node-custom-api",
3
- "version": "0.2.0-beta1",
3
+ "version": "0.2.0-beta10",
4
4
  "description": "Typescript node digione-api",
5
5
  "author": "Monchai Jirayupong <monchai.j@seven.co.th>",
6
6
  "license": "MIT",
package/utils/file.d.ts CHANGED
@@ -62,16 +62,23 @@ export declare class FileUtil {
62
62
  width?: number;
63
63
  height?: number;
64
64
  }): Promise<any>;
65
- beforeFindFile(where?: {}, { tags, group }?: {
65
+ beforeFindFile(where?: {}, { attributes, tags, group, verify }?: {
66
+ attributes?: any;
66
67
  tags?: TagFile;
67
68
  group?: any;
68
- }): {};
69
- findAllFile({ where, folder, full, file_link, thumb, width, height, parent_folder, attributes, limit, offset, tag, tags, group }?: {
69
+ verify?: boolean;
70
+ }): {
71
+ where: {};
72
+ attributes: any;
73
+ order: any[];
74
+ };
75
+ findAllFile({ where, folder, full, file_link, thumb, verify, width, height, parent_folder, attributes, limit, offset, tag, tags, group }?: {
70
76
  where?: {};
71
77
  folder?: boolean;
72
78
  full?: boolean;
73
79
  file_link?: boolean;
74
80
  thumb?: boolean;
81
+ verify?: boolean;
75
82
  width?: number;
76
83
  height?: number;
77
84
  parent_folder?: string;
@@ -82,6 +89,12 @@ export declare class FileUtil {
82
89
  tags?: TagFile;
83
90
  group?: any;
84
91
  }): Promise<any[]>;
92
+ countFileByFolder(slug: string, { where, parent_folder, tags, group }?: {
93
+ where?: {};
94
+ parent_folder?: string;
95
+ tags?: any[];
96
+ group?: any;
97
+ }): Promise<number>;
85
98
  findAndCountAllFileByFolder(slug: string, { where, file_link, parent_folder, limit, offset, tag, tags, group }?: {
86
99
  where?: {};
87
100
  file_link?: boolean;
package/utils/file.js CHANGED
@@ -14,7 +14,6 @@ const aws = require("aws-sdk");
14
14
  const jimp = require("jimp/dist");
15
15
  const mime = require("mime-types");
16
16
  const _ = require("lodash");
17
- const uuid_1 = require("uuid");
18
17
  const path = require("path");
19
18
  const fs = require("fs");
20
19
  const getBuffer = (image, { mimetype = "" } = {}) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
@@ -108,6 +107,7 @@ class FileUtil {
108
107
  }
109
108
  afterQueryFile(data = {}, { tag = {}, file_link = false } = {}) {
110
109
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
110
+ delete data['thumbnail'];
111
111
  data['custom'] = data['custom'] || {};
112
112
  data['tags'] = data['tags'] || [];
113
113
  if (data['filename'] == data['path']) {
@@ -276,12 +276,12 @@ class FileUtil {
276
276
  return null;
277
277
  where['$folder.parent_id$'] = query['id'];
278
278
  }
279
- where = this.beforeFindFile(where, { tags, group });
279
+ let option = this.beforeFindFile(where, { attributes: ['id', 'extension', 'filename', 'path', 'thumb'], tags, group });
280
280
  let result = yield file_1.FileModel.schema(this.ref, "_").findOne({
281
- raw: true, attributes: ['id', 'extension', 'filename', 'path', 'thumb'],
282
- where: Object.assign({ '$folder.slug$': slug }, where),
281
+ raw: true, attributes: option.attributes,
282
+ where: Object.assign({ '$folder.slug$': slug }, option.where),
283
283
  include: [{ as: 'folder', model: folder_1.FolderModel.schema(this.ref, "_"), attributes: [] }],
284
- order: [['sort', 'asc'], ['tags', 'desc']]
284
+ order: option.order
285
285
  });
286
286
  return this.findImageThumb(result, { width, height });
287
287
  }
@@ -299,7 +299,8 @@ class FileUtil {
299
299
  return this.findImageThumb(item, { width, height });
300
300
  });
301
301
  }
302
- beforeFindFile(where = {}, { tags = [], group = undefined } = {}) {
302
+ beforeFindFile(where = {}, { attributes = undefined, tags = [], group = undefined, verify = false } = {}) {
303
+ let order = [['sort', 'asc'], ['tags', 'desc']], thumbnail = false;
303
304
  if (this.option.organ_id) {
304
305
  where[sequelize_1.Op.and] = (where[sequelize_1.Op.and] || []).concat({ [sequelize_1.Op.or]: [{ organ_id: this.option.organ_id }, { organ_by: this.option.organ_id }] });
305
306
  }
@@ -310,9 +311,11 @@ class FileUtil {
310
311
  let op = tags.reduce((total, tag) => {
311
312
  let value = Object.keys(tag).reduce((total, key) => total.concat([`'${key}'`, `"${tag[key]}"`]), []).join(',');
312
313
  if (value) {
313
- total = total.concat((0, sequelize_1.literal)(`JSON_CONTAINS(tags,JSON_OBJECT(${value}))`));
314
- if (tag['slug'] == "thumbnail") {
315
- total = total.concat((0, sequelize_1.literal)(`tags IS NULL`));
314
+ if (tag['slug'] == "thumbnail" && !verify) {
315
+ thumbnail = true;
316
+ }
317
+ else {
318
+ total = total.concat((0, sequelize_1.literal)(`JSON_CONTAINS(tags,JSON_OBJECT(${value}))`));
316
319
  }
317
320
  }
318
321
  return total;
@@ -321,9 +324,19 @@ class FileUtil {
321
324
  where[sequelize_1.Op.and] = (where[sequelize_1.Op.and] || []).concat({ [sequelize_1.Op.or]: op });
322
325
  }
323
326
  }
324
- return where;
327
+ if (thumbnail) {
328
+ let include = [[(0, sequelize_1.literal)(`IF(JSON_CONTAINS(tags,JSON_OBJECT('slug',"thumbnail")),'yes','no')`), 'thumbnail']];
329
+ if (typeof attributes == "undefined") {
330
+ attributes = { include };
331
+ }
332
+ else if (attributes instanceof Array) {
333
+ attributes = attributes.concat(include);
334
+ }
335
+ order = [['thumbnail', 'desc'], ['sort', 'asc']];
336
+ }
337
+ return { where, attributes, order };
325
338
  }
326
- findAllFile({ where = {}, folder = false, full = false, file_link = false, thumb = false, width = 0, height = 0, parent_folder = "", attributes = undefined, limit = undefined, offset = undefined, tag = {}, tags = [], group = undefined } = {}) {
339
+ findAllFile({ where = {}, folder = false, full = false, file_link = false, thumb = false, verify = true, width = 0, height = 0, parent_folder = "", attributes = undefined, limit = undefined, offset = undefined, tag = {}, tags = [], group = undefined } = {}) {
327
340
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
328
341
  try {
329
342
  let include = [];
@@ -335,10 +348,10 @@ class FileUtil {
335
348
  return [];
336
349
  where['$folder.parent_id$'] = query['id'];
337
350
  }
338
- where = this.beforeFindFile(where, { tags, group });
339
351
  where['is_hidden'] = where['is_hidden'] || "no";
352
+ let option = this.beforeFindFile(where, { attributes, tags, group, verify });
340
353
  let result = yield file_1.FileModel.schema(this.ref, "_").findAll({
341
- attributes, raw: true, where, limit, offset, include, order: [['sort', 'asc'], ['tags', 'desc']]
354
+ attributes: option.attributes, raw: true, where: option.where, limit, offset, include, order: option.order
342
355
  });
343
356
  result.length && (yield this.getStorage());
344
357
  result = yield Promise.all(result.map((item) => tslib_1.__awaiter(this, void 0, void 0, function* () {
@@ -359,6 +372,33 @@ class FileUtil {
359
372
  }
360
373
  });
361
374
  }
375
+ countFileByFolder(slug, { where = {}, parent_folder = "", tags = [], group = null } = {}) {
376
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
377
+ let include_folder = [];
378
+ if (parent_folder) {
379
+ where['$`f->p`.slug$'] = parent_folder;
380
+ include_folder.push({
381
+ required: true, attributes: [],
382
+ model: folder_1.FolderModel.schema(this.ref, "_"),
383
+ association: new sequelize_1.BelongsTo(folder_1.FolderModel, folder_1.FolderModel, { as: "p", foreignKey: "parent_id", constraints: false })
384
+ });
385
+ }
386
+ where['$f.slug$'] = slug;
387
+ where['is_hidden'] = where['is_hidden'] || "no";
388
+ let option = this.beforeFindFile(where, { tags, group, verify: true });
389
+ return yield file_1.FileModel.schema(this.ref, "_").count({
390
+ where: option.where,
391
+ include: [
392
+ {
393
+ required: true, attributes: [],
394
+ model: folder_1.FolderModel.schema(this.ref, "_"),
395
+ association: new sequelize_1.BelongsTo(file_1.FileModel, folder_1.FolderModel, { as: "f", foreignKey: "folder_id", constraints: false }),
396
+ include: include_folder
397
+ }
398
+ ]
399
+ });
400
+ });
401
+ }
362
402
  findAndCountAllFileByFolder(slug, { where = {}, file_link = false, parent_folder = "", limit = undefined, offset = undefined, tag = {}, tags = [], group = null } = {}) {
363
403
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
364
404
  let where_folder = {};
@@ -372,9 +412,9 @@ class FileUtil {
372
412
  if (!folder)
373
413
  return { rows: [], count: 0 };
374
414
  where['folder_id'] = folder['id'];
375
- where = this.beforeFindFile(where, { tags, group });
376
415
  where['is_hidden'] = where['is_hidden'] || "no";
377
- let data = yield Promise.all([this.findAllFile({ where, full: true, file_link, limit, offset, tag, group }), file_1.FileModel.schema(this.ref, "_").count({ where })]);
416
+ let option = this.beforeFindFile(where, { tags, group, verify: true });
417
+ let data = yield Promise.all([this.findAllFile({ where, full: true, file_link, limit, offset, tag, group }), file_1.FileModel.schema(this.ref, "_").count({ where: option.where })]);
378
418
  return { rows: data[0], count: data[1] };
379
419
  });
380
420
  }
@@ -385,7 +425,7 @@ class FileUtil {
385
425
  }
386
426
  findOneFileByFolder(slug, { where = {}, full = false, file_link = false, parent_folder = "", tags = [], group = null } = {}) {
387
427
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
388
- return (yield this.findAllFile({ where: Object.assign({ '$folder.slug$': slug }, where), folder: true, full, file_link, parent_folder, limit: 1, tags, group }))[0] || null;
428
+ return (yield this.findAllFile({ where: Object.assign({ '$folder.slug$': slug }, where), folder: true, full, file_link, verify: false, parent_folder, limit: 1, tags, group }))[0] || null;
389
429
  });
390
430
  }
391
431
  findOneFileById(id, { where = {}, full = true, file_link = false, parent_folder = "", tags = [], group = null } = {}) {
@@ -569,7 +609,7 @@ class FileUtil {
569
609
  try {
570
610
  let result = yield Promise.all(files.map((file, key) => tslib_1.__awaiter(this, void 0, void 0, function* () {
571
611
  folder_id = reqs[key].folder ? reqs[key].folder : folder_id;
572
- let id = (0, uuid_1.v4)().replace(/-/gi, '').substring(0, 15);
612
+ let id = (0, helper_1.getFileId)();
573
613
  let organ_id = this.option.organ_id;
574
614
  let organ_by = this.option.parent_organ_id;
575
615
  let sort = (0, helper_1.getDateTime)().format(formatDateTime);
@@ -635,7 +675,7 @@ class FileUtil {
635
675
  }
636
676
  catch (err) {
637
677
  if (err.errors && err.errors[0].validatorKey == "not_unique") {
638
- results = results.map(item => (Object.assign(Object.assign({}, item), { id: (0, uuid_1.v4)().replace(/-/gi, '').substring(0, 15) })));
678
+ results = results.map(item => (Object.assign(Object.assign({}, item), { id: (0, helper_1.getFileId)() })));
639
679
  return yield this.insertFileUnique(results, { format, thumb, width, height });
640
680
  }
641
681
  return Promise.reject(errors_1.generalError.BAD_REQUEST);
@@ -678,8 +718,8 @@ class FileUtil {
678
718
  }
679
719
  remove({ where = {}, delete_object = false, error = true, tags = [], group = undefined } = {}) {
680
720
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
681
- where = this.beforeFindFile(where, { tags, group });
682
- let files = yield file_1.FileModel.schema(this.ref, "_").findAll({ where, attributes: ['id', 'path', 'thumb'], raw: true });
721
+ let option = this.beforeFindFile(where, { tags, group, verify: true });
722
+ let files = yield file_1.FileModel.schema(this.ref, "_").findAll({ where: option.where, attributes: ['id', 'path', 'thumb'], raw: true });
683
723
  if (files.length) {
684
724
  let paths = [], id = files.map(i => { paths = paths.concat(this.getFilePath(i)); return i['id']; });
685
725
  yield file_1.FileModel.schema(this.ref, "_").destroy({ where: { id } });
package/utils/helper.d.ts CHANGED
@@ -17,6 +17,7 @@ export declare const getENVIndex: (index: string, { prefix, force }?: {
17
17
  force?: boolean;
18
18
  }) => string;
19
19
  export declare const getSlug: (length?: number) => string;
20
+ export declare const getFileId: () => string;
20
21
  export declare const getDateMysql: (date?: any) => any;
21
22
  export declare const getTimestampMysql: (date?: any) => number;
22
23
  export declare const getDateTime: (time?: any, { utc }?: {
@@ -27,7 +28,12 @@ export declare const getValueFunctionFile: (key: any) => (value: any, { result,
27
28
  json?: {};
28
29
  fileUtil?: any;
29
30
  }) => Promise<void>;
30
- export declare const getValueFunctionLang: (key: any) => (value?: {}, { result, transform, spread, spread_all, raw, lang_code }?: {
31
+ export declare const getValueFunctionArray: (key: any) => (value: any, { result }: {
32
+ result?: {};
33
+ }) => void;
34
+ export declare const getValueFunctionLang: (key: any, { field_type }?: {
35
+ field_type?: string;
36
+ }) => (value?: {}, { result, transform, spread, spread_all, raw, lang_code }?: {
31
37
  result?: {};
32
38
  transform?: boolean;
33
39
  spread?: boolean;
package/utils/helper.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertCurrency = exports.xorMerge = exports.xorDecode = exports.xorEncode = exports.getInstanceNumber = exports.getDomain = exports.getParent = exports.replaceColon = exports.stripEmoji = exports.stripHtml = exports.slugifyField = exports.slugify = exports.convertToBigEndian = exports.expandTree = exports.buildTree = exports.treeToArray = exports.randomRef = exports.multiExecArray = exports.isBase64 = exports.isNumber = exports.removeAt = exports.removeSpace = exports.formatMobileNumber = exports.getMobileNumber = exports.removeHyphen = exports.signToken = exports.getTokenDataFromTokenBySecret = exports.getUUID32 = exports.getUUID = exports.sleep = exports.getValueByLang = exports.getValueFunctionLang = exports.getValueFunctionFile = exports.getDateTime = exports.getTimestampMysql = exports.getDateMysql = exports.getSlug = exports.getENVIndex = exports.getENV = exports.Joi_date = exports.getDaysBetweenDates = exports.getDateFromString = exports.getDateRangeFormat = void 0;
3
+ exports.convertCurrency = exports.xorMerge = exports.xorDecode = exports.xorEncode = exports.getInstanceNumber = exports.getDomain = exports.getParent = exports.replaceColon = exports.stripEmoji = exports.stripHtml = exports.slugifyField = exports.slugify = exports.convertToBigEndian = exports.expandTree = exports.buildTree = exports.treeToArray = exports.randomRef = exports.multiExecArray = exports.isBase64 = exports.isNumber = exports.removeAt = exports.removeSpace = exports.formatMobileNumber = exports.getMobileNumber = exports.removeHyphen = exports.signToken = exports.getTokenDataFromTokenBySecret = exports.getUUID32 = exports.getUUID = exports.sleep = exports.getValueByLang = exports.getValueFunctionLang = exports.getValueFunctionArray = exports.getValueFunctionFile = exports.getDateTime = exports.getTimestampMysql = exports.getDateMysql = exports.getFileId = exports.getSlug = exports.getENVIndex = exports.getENV = exports.Joi_date = exports.getDaysBetweenDates = exports.getDateFromString = exports.getDateRangeFormat = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const crypto = require("crypto");
6
6
  const dotenv = require("dotenv");
@@ -13,6 +13,7 @@ const date_1 = require("@joi/date");
13
13
  const numeral = require("numeral");
14
14
  const _ = require("lodash");
15
15
  const sha1 = require('js-sha1');
16
+ const uid = new short_unique_id_1.default();
16
17
  dotenv.config();
17
18
  const getDateRangeFormat = (dates = [], { format: { day = "D", month = "MMM", year = "Y" } = {} } = {}) => {
18
19
  dates = dates.map(i => (0, exports.getDateTime)(i));
@@ -65,9 +66,13 @@ const getENVIndex = (index, { prefix = "dev", force = false } = {}) => {
65
66
  };
66
67
  exports.getENVIndex = getENVIndex;
67
68
  const getSlug = (length = 8) => {
68
- return new short_unique_id_1.default().randomUUID(length);
69
+ return uid.rnd(length);
69
70
  };
70
71
  exports.getSlug = getSlug;
72
+ const getFileId = () => {
73
+ return uid.rnd(15);
74
+ };
75
+ exports.getFileId = getFileId;
71
76
  const getDateMysql = (date = undefined) => {
72
77
  try {
73
78
  return (0, exports.getDateTime)(date).format("YYYY-MM-DD HH:mm:ss");
@@ -101,7 +106,22 @@ const getValueFunctionFile = (key) => {
101
106
  });
102
107
  };
103
108
  exports.getValueFunctionFile = getValueFunctionFile;
104
- const getValueFunctionLang = (key) => {
109
+ const getValueFunctionArray = (key) => {
110
+ return (value, { result = {} }) => {
111
+ if (value[key]) {
112
+ try {
113
+ result[key] = JSON.parse(value[key]);
114
+ }
115
+ catch (err) { }
116
+ ;
117
+ }
118
+ if (!(result[key] instanceof Array)) {
119
+ result[key] = [];
120
+ }
121
+ };
122
+ };
123
+ exports.getValueFunctionArray = getValueFunctionArray;
124
+ const getValueFunctionLang = (key, { field_type = "" } = {}) => {
105
125
  return (value = {}, { result = {}, transform = true, spread = false, spread_all = false, raw = false, lang_code = "" } = {}) => {
106
126
  if (raw || typeof value[key] == "undefined")
107
127
  return;
@@ -125,6 +145,9 @@ const getValueFunctionLang = (key) => {
125
145
  return;
126
146
  }
127
147
  result[key] = bol ? (obj[lang_code] || obj['en']) : value[key];
148
+ if (field_type == "stream") {
149
+ (0, exports.getValueFunctionArray)(key)({ [key]: result[key] }, { result });
150
+ }
128
151
  };
129
152
  };
130
153
  exports.getValueFunctionLang = getValueFunctionLang;
package/utils/stream.d.ts CHANGED
@@ -76,13 +76,14 @@ export declare class StreamUtil {
76
76
  include?: any;
77
77
  include_only?: boolean;
78
78
  }): any;
79
- buildStream(slug: string, namespace: string, { query, builder, fetch, label, attribute, attributes, field_exclude, include, include_all }?: {
79
+ buildStream(slug: string, namespace: string, { query, builder, fetch, label, attribute, attributes, field_option, field_exclude, include, include_all }?: {
80
80
  query?: boolean;
81
81
  builder?: boolean;
82
82
  fetch?: boolean;
83
83
  label?: boolean;
84
84
  attribute?: boolean;
85
85
  attributes?: any;
86
+ field_option?: {};
86
87
  field_exclude?: any[];
87
88
  include?: {};
88
89
  include_all?: boolean;
@@ -92,10 +93,11 @@ export declare class StreamUtil {
92
93
  fetchFn: any;
93
94
  attributes: any;
94
95
  }>;
95
- getBuilder(slug: string, namespace: string, { query, index, builder, field_exclude }?: {
96
+ getBuilder(slug: string, namespace: string, { query, index, builder, field_option, field_exclude }?: {
96
97
  query?: boolean;
97
98
  index?: string;
98
99
  builder?: boolean;
100
+ field_option?: {};
99
101
  field_exclude?: any[];
100
102
  }): Promise<any>;
101
103
  getValue(slug: string, namespace: string, value: any, { query, transform, spread, spread_all, raw, lang_code }?: {
@@ -305,7 +307,7 @@ export declare class StreamUtil {
305
307
  stripUnknown?: boolean;
306
308
  builder?: boolean;
307
309
  }): Promise<Joi.ObjectSchema<any>>;
308
- validate(slug: string, namespace: string, input: any, { req, isNew, default_value, lang, stripUnknown, inputLang, inputLangSeparate, prefixMessage, builder, field_exclude }?: {
310
+ validate(slug: string, namespace: string, input: any, { req, isNew, default_value, lang, stripUnknown, inputLang, inputLangSeparate, prefixMessage, builder, field_option, field_exclude }?: {
309
311
  req?: Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
310
312
  isNew?: boolean;
311
313
  default_value?: {};
@@ -315,6 +317,7 @@ export declare class StreamUtil {
315
317
  inputLangSeparate?: boolean;
316
318
  prefixMessage?: string;
317
319
  builder?: boolean;
320
+ field_option?: {};
318
321
  field_exclude?: any[];
319
322
  }): Promise<any>;
320
323
  validateByField(streams: Array<any>, input: any, { req, isNew, default_value, lang, stripUnknown, inputLang, inputLangSeparate, prefixMessage }?: {
package/utils/stream.js CHANGED
@@ -235,13 +235,13 @@ class StreamUtil {
235
235
  }
236
236
  return data;
237
237
  }
238
- buildStream(slug, namespace, { query = true, builder = true, fetch = false, label = false, attribute = false, attributes = null, field_exclude = [], include = {}, include_all = false } = {}) {
238
+ buildStream(slug, namespace, { query = true, builder = true, fetch = false, label = false, attribute = false, attributes = null, field_option = {}, field_exclude = [], include = {}, include_all = false } = {}) {
239
239
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
240
240
  let build = this.builder[slug + "_" + namespace] || { stream: null, fields: null, fetchFn: [], attributes: null };
241
241
  if (!build['fields']) {
242
242
  let data = {};
243
243
  if (query)
244
- data = yield this.findField(slug, namespace, { field_only: false, convert_option: true, field_exclude });
244
+ data = yield this.findField(slug, namespace, { field_only: false, convert_option: true, field_option, field_exclude });
245
245
  build['fields'] = data['fields'] || [];
246
246
  build['stream'] = _.omit(data, ['fields']);
247
247
  }
@@ -255,7 +255,7 @@ class StreamUtil {
255
255
  delete attributes[field['field_slug']];
256
256
  }
257
257
  if (fetch) {
258
- if (field['is_lang'] == "yes") {
258
+ if (field['is_lang'] == "yes" && field['field_type'] != "stream") {
259
259
  label && fetchLabel.push(field);
260
260
  fetchFn.push((0, helper_2.getValueFunctionLang)(field['field_slug']));
261
261
  }
@@ -286,6 +286,15 @@ class StreamUtil {
286
286
  }
287
287
  }
288
288
  break;
289
+ case "stream":
290
+ if (include[field['field_slug']] || include_all) {
291
+ label && fetchLabel.push(field);
292
+ fetchFn.push((field['is_lang'] == "yes") ? (0, helper_2.getValueFunctionLang)(field['field_slug'], { field_type: field['field_type'] }) : (0, helper_2.getValueFunctionArray)(field['field_slug']));
293
+ }
294
+ else {
295
+ delete attributes[field['field_slug']];
296
+ }
297
+ break;
289
298
  }
290
299
  }
291
300
  }
@@ -303,9 +312,9 @@ class StreamUtil {
303
312
  return build;
304
313
  });
305
314
  }
306
- getBuilder(slug, namespace, { query = true, index = "", builder = true, field_exclude = [] } = {}) {
315
+ getBuilder(slug, namespace, { query = true, index = "", builder = true, field_option = {}, field_exclude = [] } = {}) {
307
316
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
308
- let result = yield this.buildStream(slug, namespace, { query, builder, field_exclude });
317
+ let result = yield this.buildStream(slug, namespace, { query, builder, field_option, field_exclude });
309
318
  return index ? result[index] : result;
310
319
  });
311
320
  }
@@ -404,6 +413,15 @@ class StreamUtil {
404
413
  else if (typeof default_value[item['field_slug']] !== 'undefined') {
405
414
  item['field_value'] = default_value[item['field_slug']];
406
415
  }
416
+ if (item['field_type'] == "stream" && item['field_value']) {
417
+ try {
418
+ item['field_value'] = JSON.parse(item['field_value']);
419
+ }
420
+ catch (err) { }
421
+ if (!(item['field_value'] instanceof Array)) {
422
+ item['field_value'] = [];
423
+ }
424
+ }
407
425
  if (item['instructions']) {
408
426
  (0, helper_2.getValueFunctionLang)('instructions')(item, { result: item, lang_code });
409
427
  }
@@ -468,8 +486,10 @@ class StreamUtil {
468
486
  }
469
487
  return Object.assign({ field_slug: i['lang_code'], field_name: `${convert_option ? (0, i18n_1.__)({ phrase: item['field_name'], locale: lang_code }) : item['field_name']} (${i['lang_code']})`, field_type: item['field_type'], field_name_raw: item['field_name'] ? item['field_name'] : "", is_required: item['is_required'] }, include);
470
488
  });
471
- fields.push(Object.assign(Object.assign({}, item), { field_data }));
472
- continue;
489
+ if (item['field_type'] != "stream") {
490
+ fields.push(Object.assign(Object.assign({}, item), { field_data }));
491
+ continue;
492
+ }
473
493
  }
474
494
  if (convert_option) {
475
495
  let obj_value = {};
@@ -661,6 +681,14 @@ class StreamUtil {
661
681
  field_data['range']['field_value'] = default_value[field_data['range']['field_target']];
662
682
  }
663
683
  }
684
+ else if (item['field_type'] == "stream") {
685
+ if (field_data['choose_stream']) {
686
+ let stream = yield stream_1.StreamModel.schema(this.ref, "_").findOne({ where: { id: field_data['choose_stream'] }, raw: true, attributes: ['stream_slug', 'stream_namespace'] });
687
+ if (stream) {
688
+ item['stream'] = yield this.findField(stream['stream_slug'], stream['stream_namespace'], { option, lang_code, field_only: true, convert_option: true });
689
+ }
690
+ }
691
+ }
664
692
  }
665
693
  fields.push(Object.assign(Object.assign({}, item), { field_data }));
666
694
  }
@@ -813,7 +841,7 @@ class StreamUtil {
813
841
  stream = stream || {};
814
842
  let id_stream = stream['id'], stream_prefix = stream['stream_prefix'];
815
843
  if (fields && fields.length) {
816
- fields = fields.filter(({ is_lang, field_type, field_data }) => field_type && (is_lang == "yes" || (field_type == "multiple" && field_data['self_table'] != "yes") || field_type == "image" || field_type == "file" || field_data['field_type'] == "encrypt"));
844
+ fields = fields.filter(({ is_lang, field_type, field_data }) => field_type && (is_lang == "yes" || (field_type == "multiple" && field_data['self_table'] != "yes") || field_type == "image" || field_type == "file" || field_data['field_type'] == "encrypt" || field_type == "stream"));
817
845
  }
818
846
  if (!Object.keys(raw_input).length) {
819
847
  raw_input = input;
@@ -893,6 +921,9 @@ class StreamUtil {
893
921
  else if (field_type == "multiple") {
894
922
  fields_post.push(fields[index]);
895
923
  }
924
+ else if (field_type == "stream" && input[field_slug]) {
925
+ data[field_slug] = JSON.stringify(input[field_slug]);
926
+ }
896
927
  })));
897
928
  }
898
929
  if (id) {
@@ -956,8 +987,8 @@ class StreamUtil {
956
987
  }
957
988
  let folder = yield fileUtil.createFolder(index, { parent_id: where_folder['parent_id'] });
958
989
  let where_file = { folder_id: folder['id'], is_hidden: "yes" };
959
- where_file = fileUtil.beforeFindFile(where_file, { tags, group });
960
- let query = yield file_1.FileModel.schema(ref, "_").findAll({ where: where_file, attributes: ['id', 'name'], raw: true });
990
+ let option_file = fileUtil.beforeFindFile(where_file, { tags, group, verify: true });
991
+ let query = yield file_1.FileModel.schema(ref, "_").findAll({ where: option_file.where, attributes: ['id', 'name'], raw: true });
961
992
  id_files = query.reduce((total, item) => Object.assign(total, { [item['name']]: item['id'] }), {});
962
993
  let input_files = [];
963
994
  yield Promise.all(fields.map(({ field_type, field_slug, field_data }) => tslib_1.__awaiter(this, void 0, void 0, function* () {
@@ -1666,6 +1697,12 @@ class StreamUtil {
1666
1697
  yield (0, db_1.addColumn)(`${this.ref}_${table}`, field_slug, Object.assign({ type: sequelize.STRING(20) }, opt));
1667
1698
  }
1668
1699
  break;
1700
+ case "stream":
1701
+ if (field_data['self_table'] == "yes") {
1702
+ opt['defaultValue'] = undefined;
1703
+ yield (0, db_1.addColumn)(`${this.ref}_${table}`, field_slug, Object.assign({ type: sequelize.TEXT('long') }, opt));
1704
+ }
1705
+ break;
1669
1706
  }
1670
1707
  }
1671
1708
  }
@@ -1826,6 +1863,9 @@ class StreamUtil {
1826
1863
  }
1827
1864
  field_data = _.pick(field_data, ['range']);
1828
1865
  break;
1866
+ case "stream":
1867
+ field_data = _.pick(field_data, ['choose_stream', 'self_table']);
1868
+ break;
1829
1869
  default:
1830
1870
  field_data = {};
1831
1871
  break;
@@ -1836,7 +1876,8 @@ class StreamUtil {
1836
1876
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
1837
1877
  let field_lang = [];
1838
1878
  let file = req ? ((req.file ? [req.file] : [].concat(req.files || [])).reduce((total, item) => Object.assign(total, { [item['fieldname']]: item }), {})) : {};
1839
- streams.forEach(({ field_type, field_slug, is_required, is_lang, field_data, data }) => {
1879
+ for (let val of streams) {
1880
+ let { field_type, field_slug, is_required, is_lang, field_data, data } = val;
1840
1881
  let field;
1841
1882
  field_data = field_data || {};
1842
1883
  is_required = (is_required == "yes" && (isNew || (!input[field_slug] && typeof input[field_slug] != "undefined")));
@@ -1969,6 +2010,18 @@ class StreamUtil {
1969
2010
  }
1970
2011
  field = field.regex(/^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$/).messages({ 'string.pattern.base': `${field_slug} invalid format` });
1971
2012
  break;
2013
+ case "stream":
2014
+ if (field_data['choose_stream']) {
2015
+ let stream = yield stream_1.StreamModel.schema(this.ref, "_").findOne({ where: { id: field_data['choose_stream'] }, raw: true, attributes: ['stream_slug', 'stream_namespace'] });
2016
+ if (stream) {
2017
+ let streams = yield this.findField(stream['stream_slug'], stream['stream_namespace'], { field_only: true, convert_option: true });
2018
+ let validator = yield this.getValidator(streams, { isNew: true, required: is_required, lang, stripUnknown: true });
2019
+ field = Joi.array().items(validator);
2020
+ }
2021
+ }
2022
+ field = field || Joi.array();
2023
+ field = is_required ? field.required().min(1) : field.allow(null);
2024
+ break;
1972
2025
  }
1973
2026
  field = field || Joi.any();
1974
2027
  if (is_required)
@@ -1976,12 +2029,12 @@ class StreamUtil {
1976
2029
  if (is_lang == "yes") {
1977
2030
  if (!lang.length) {
1978
2031
  field_lang.push({ field_slug, field });
1979
- return;
2032
+ continue;
1980
2033
  }
1981
2034
  field = Joi.object().keys(lang.reduce((total, i) => Object.assign(total, { [i['lang_code']]: field }), {}));
1982
2035
  }
1983
2036
  schema[field_slug] = field;
1984
- });
2037
+ }
1985
2038
  if (field_lang.length) {
1986
2039
  lang = yield this.languageUtil.getLangsLive();
1987
2040
  for (let item of field_lang) {
@@ -2003,9 +2056,9 @@ class StreamUtil {
2003
2056
  return yield this.getValidator(streams, { req, isNew, required, lang, stripUnknown });
2004
2057
  });
2005
2058
  }
2006
- validate(slug, namespace, input, { req = {}, isNew = false, default_value = {}, lang = [], stripUnknown = false, inputLang = false, inputLangSeparate = true, prefixMessage = "", builder = true, field_exclude = [] } = {}) {
2059
+ validate(slug, namespace, input, { req = {}, isNew = false, default_value = {}, lang = [], stripUnknown = false, inputLang = false, inputLangSeparate = true, prefixMessage = "", builder = true, field_option = {}, field_exclude = [] } = {}) {
2007
2060
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
2008
- let streams = yield this.getBuilder(slug, namespace, { index: "fields", builder, field_exclude });
2061
+ let streams = yield this.getBuilder(slug, namespace, { index: "fields", builder, field_option, field_exclude });
2009
2062
  return this.validateByField(streams, input, { req, isNew, default_value, lang, stripUnknown, inputLang, inputLangSeparate, prefixMessage });
2010
2063
  });
2011
2064
  }
@@ -104,8 +104,9 @@ const fileService = (setup, { userfiles = false, required = false, fileSize = 0,
104
104
  }
105
105
  let option = setup(validate);
106
106
  let upload = userfiles ? option.array("userfiles", maxCount) : option.any();
107
+ let schema = userfiles ? { tags: Joi.array().allow('', null).items(Joi.object().keys({ slug: Joi.string(), type: Joi.string() })) } : { tags: Joi.any() };
107
108
  return upload(req, res, (err) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
108
- return (0, exports.validateService)(Joi.object().keys({ tags: Joi.array().allow('', null).items(Joi.object().keys({ slug: Joi.string(), type: Joi.string() })) }).unknown(), { field_omit: [] })(req, res, () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
109
+ return (0, exports.validateService)(Joi.object().keys(schema).unknown(), { field_omit: [] })(req, res, () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
109
110
  try {
110
111
  let field = userfiles ? "userfiles" : undefined;
111
112
  if (err) {