@knovator/pagecreator-node 1.1.8 → 1.2.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.
Files changed (128) hide show
  1. package/package.json +3 -6
  2. package/src/constants/index.ts +30 -0
  3. package/src/controllers/PageController.ts +88 -0
  4. package/src/controllers/TabController.ts +47 -0
  5. package/src/controllers/UserController.ts +69 -0
  6. package/src/controllers/WidgetController.ts +420 -0
  7. package/src/index.ts +59 -0
  8. package/src/models/Item.ts +53 -0
  9. package/src/models/Page.ts +22 -0
  10. package/src/models/SrcSet.ts +16 -0
  11. package/src/models/Tab.ts +28 -0
  12. package/src/models/Widget.ts +65 -0
  13. package/src/models/{index.d.ts → index.ts} +13 -1
  14. package/src/plugins/softDelete.ts +84 -0
  15. package/src/routes/PageRoute.ts +30 -0
  16. package/src/routes/UserRoute.ts +32 -0
  17. package/src/routes/WidgetRoute.ts +77 -0
  18. package/src/services/dataService.ts +475 -0
  19. package/src/services/dbService.ts +102 -0
  20. package/src/types/{IRequest.d.ts → IRequest.ts} +4 -3
  21. package/src/types/{IResponse.d.ts → IResponse.ts} +4 -3
  22. package/src/types/{Router.d.ts → Router.ts} +2 -1
  23. package/src/types/common.ts +172 -0
  24. package/src/types/enums.ts +16 -0
  25. package/src/utils/defaults.ts +41 -0
  26. package/src/utils/helper.ts +285 -0
  27. package/src/utils/redis.ts +57 -0
  28. package/src/utils/responseHandlers.ts +60 -0
  29. package/src/utils/validate.ts +22 -0
  30. package/src/utils/validations/page.ts +52 -0
  31. package/src/utils/validations/tab.ts +26 -0
  32. package/src/utils/validations/user.ts +10 -0
  33. package/src/utils/validations/widget.ts +169 -0
  34. package/src/constants/index.d.ts +0 -20
  35. package/src/constants/index.js +0 -34
  36. package/src/constants/index.js.map +0 -1
  37. package/src/controllers/PageController.d.ts +0 -4
  38. package/src/controllers/PageController.js +0 -84
  39. package/src/controllers/PageController.js.map +0 -1
  40. package/src/controllers/TabController.d.ts +0 -4
  41. package/src/controllers/TabController.js +0 -46
  42. package/src/controllers/TabController.js.map +0 -1
  43. package/src/controllers/UserController.d.ts +0 -2
  44. package/src/controllers/UserController.js +0 -65
  45. package/src/controllers/UserController.js.map +0 -1
  46. package/src/controllers/WidgetController.d.ts +0 -10
  47. package/src/controllers/WidgetController.js +0 -329
  48. package/src/controllers/WidgetController.js.map +0 -1
  49. package/src/index.d.ts +0 -8
  50. package/src/index.js +0 -48
  51. package/src/index.js.map +0 -1
  52. package/src/models/Item.d.ts +0 -30
  53. package/src/models/Item.js +0 -50
  54. package/src/models/Item.js.map +0 -1
  55. package/src/models/Page.d.ts +0 -30
  56. package/src/models/Page.js +0 -19
  57. package/src/models/Page.js.map +0 -1
  58. package/src/models/SrcSet.d.ts +0 -30
  59. package/src/models/SrcSet.js +0 -17
  60. package/src/models/SrcSet.js.map +0 -1
  61. package/src/models/Tab.d.ts +0 -30
  62. package/src/models/Tab.js +0 -28
  63. package/src/models/Tab.js.map +0 -1
  64. package/src/models/Widget.d.ts +0 -30
  65. package/src/models/Widget.js +0 -58
  66. package/src/models/Widget.js.map +0 -1
  67. package/src/models/index.js +0 -19
  68. package/src/models/index.js.map +0 -1
  69. package/src/plugins/softDelete.d.ts +0 -7
  70. package/src/plugins/softDelete.js +0 -64
  71. package/src/plugins/softDelete.js.map +0 -1
  72. package/src/routes/PageRoute.d.ts +0 -3
  73. package/src/routes/PageRoute.js +0 -30
  74. package/src/routes/PageRoute.js.map +0 -1
  75. package/src/routes/UserRoute.d.ts +0 -3
  76. package/src/routes/UserRoute.js +0 -23
  77. package/src/routes/UserRoute.js.map +0 -1
  78. package/src/routes/WidgetRoute.d.ts +0 -3
  79. package/src/routes/WidgetRoute.js +0 -68
  80. package/src/routes/WidgetRoute.js.map +0 -1
  81. package/src/services/dataService.d.ts +0 -9
  82. package/src/services/dataService.js +0 -403
  83. package/src/services/dataService.js.map +0 -1
  84. package/src/services/dbService.d.ts +0 -16
  85. package/src/services/dbService.js +0 -88
  86. package/src/services/dbService.js.map +0 -1
  87. package/src/types/IRequest.js +0 -3
  88. package/src/types/IRequest.js.map +0 -1
  89. package/src/types/IResponse.js +0 -3
  90. package/src/types/IResponse.js.map +0 -1
  91. package/src/types/Router.js +0 -3
  92. package/src/types/Router.js.map +0 -1
  93. package/src/types/common.d.ts +0 -138
  94. package/src/types/common.js +0 -3
  95. package/src/types/common.js.map +0 -1
  96. package/src/types/enums.d.ts +0 -13
  97. package/src/types/enums.js +0 -20
  98. package/src/types/enums.js.map +0 -1
  99. package/src/types/index.js +0 -9
  100. package/src/types/index.js.map +0 -1
  101. package/src/utils/defaults.d.ts +0 -7
  102. package/src/utils/defaults.js +0 -41
  103. package/src/utils/defaults.js.map +0 -1
  104. package/src/utils/helper.d.ts +0 -7
  105. package/src/utils/helper.js +0 -225
  106. package/src/utils/helper.js.map +0 -1
  107. package/src/utils/redis.d.ts +0 -3
  108. package/src/utils/redis.js +0 -59
  109. package/src/utils/redis.js.map +0 -1
  110. package/src/utils/responseHandlers.d.ts +0 -6
  111. package/src/utils/responseHandlers.js +0 -57
  112. package/src/utils/responseHandlers.js.map +0 -1
  113. package/src/utils/validate.d.ts +0 -4
  114. package/src/utils/validate.js +0 -24
  115. package/src/utils/validate.js.map +0 -1
  116. package/src/utils/validations/page.d.ts +0 -7
  117. package/src/utils/validations/page.js +0 -51
  118. package/src/utils/validations/page.js.map +0 -1
  119. package/src/utils/validations/tab.d.ts +0 -6
  120. package/src/utils/validations/tab.js +0 -26
  121. package/src/utils/validations/tab.js.map +0 -1
  122. package/src/utils/validations/user.d.ts +0 -3
  123. package/src/utils/validations/user.js +0 -13
  124. package/src/utils/validations/user.js.map +0 -1
  125. package/src/utils/validations/widget.d.ts +0 -9
  126. package/src/utils/validations/widget.js +0 -151
  127. package/src/utils/validations/widget.js.map +0 -1
  128. /package/src/types/{index.d.ts → index.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knovator/pagecreator-node",
3
- "version": "1.1.8",
3
+ "version": "1.2.0",
4
4
  "type": "commonjs",
5
5
  "author": "knovator (https://knovator.com/)",
6
6
  "description": "PageCreator Node.js module",
@@ -29,14 +29,11 @@
29
29
  },
30
30
  "peerDependencies": {
31
31
  "mongoose": "*",
32
- "express": "*",
33
- "tslib": "2.4.1"
32
+ "express": "*"
34
33
  },
35
34
  "files": [
36
35
  "src",
37
36
  "package.json",
38
37
  "README.md"
39
- ],
40
- "main": "./src/index.js",
41
- "types": "./src/index.d.ts"
38
+ ]
42
39
  }
@@ -0,0 +1,30 @@
1
+ export const VALIDATION = {
2
+ WIDGET_EXISTS: 'Widget with same code is available!',
3
+ SLUG_EXISTS: 'Widget with same slug is available!',
4
+ };
5
+ export const RESPONSE_CODES = {
6
+ DEFAULT: 'SUCCESS',
7
+ ERROR: 'ERROR',
8
+ VALIDATION_FAILED: 'VALIDATION_FAILED'
9
+ };
10
+ export const REGEXS = {
11
+ OBJECTID_CAST_FAILED: /Cast to ObjectId failed/gm,
12
+ IS_AVAILABLE: /is available!/gm
13
+ };
14
+ export const MONGOOSE_FIND_QUERIES = [
15
+ 'count',
16
+ 'find',
17
+ 'findOne',
18
+ 'findOneAndDelete',
19
+ 'findOneAndRemove',
20
+ 'findOneAndUpdate',
21
+ 'update',
22
+ 'updateOne',
23
+ 'updateMany',
24
+ ];
25
+ export const success = 200;
26
+ export const create = 201;
27
+ export const internalServerError = 500;
28
+ export const validationError = 422;
29
+ export const notFoundError = 404;
30
+ export const messageRoutePrefix = 'msg';
@@ -0,0 +1,88 @@
1
+ import { Types } from 'mongoose';
2
+ import { create, remove, update, list , checkUnique } from '../services/dbService';
3
+ import {
4
+ successResponse,
5
+ createdDocumentResponse,
6
+ } from './../utils/responseHandlers';
7
+ import { IRequest, IResponse } from '../types';
8
+ import { defaults } from '../utils/defaults';
9
+ import { updateRedisPage } from '../services/dataService';
10
+ import { VALIDATION } from '../constants';
11
+
12
+ const catchAsync = (fn: any) => {
13
+ return defaults.catchAsync(fn, 'Page');
14
+ };
15
+ const getModals = (req: IRequest) => defaults.getModals(req);
16
+
17
+ export const createPage = catchAsync(async (req: IRequest, res: IResponse) => {
18
+ const { Page } = getModals(req);
19
+ const data = req.body;
20
+
21
+ await checkUnique({
22
+ Modal: Page,
23
+ uniqueField: 'code',
24
+ value: data.code,
25
+ errorMessage: VALIDATION.WIDGET_EXISTS
26
+ });
27
+
28
+ await checkUnique({
29
+ Modal: Page,
30
+ uniqueField: 'slug',
31
+ value: data.slug,
32
+ errorMessage: VALIDATION.SLUG_EXISTS
33
+ });
34
+ const page = await create(Page, data);
35
+ res.message = req?.i18n?.t('page.create');
36
+ return createdDocumentResponse(page, res);
37
+ });
38
+
39
+ export const updatePage = catchAsync(async (req: IRequest, res: IResponse) => {
40
+ const models = getModals(req);
41
+ const data = req.body;
42
+ const _id = req.params['id'];
43
+ const updatedPage = await update(models['Page'], { _id }, data);
44
+ res.message = req?.i18n?.t('page.update');
45
+ if (updatedPage) updateRedisPage(updatedPage.code, models); // update redis
46
+ return successResponse(updatedPage, res);
47
+ });
48
+
49
+ export const deletePage = catchAsync(async (req: IRequest, res: IResponse) => {
50
+ const { Page } = getModals(req);
51
+ const _id = new Types.ObjectId(req.params['id']);
52
+ const createdPage = await remove(Page, { _id });
53
+ res.message = req?.i18n?.t('page.delete');
54
+ return successResponse(createdPage, res);
55
+ });
56
+
57
+ export const getPages = catchAsync(async (req: IRequest, res: IResponse) => {
58
+ const { Page } = getModals(req);
59
+ const search = req.body.search || '';
60
+ const { page, limit, populate, sort } = req.body.options;
61
+ const customOptions = {
62
+ populate,
63
+ sort,
64
+ ...(page && limit ? { page, limit } : {}),
65
+ };
66
+ const query = {
67
+ isDeleted: false,
68
+ $or: [
69
+ {
70
+ name: {
71
+ $regex: search,
72
+ $options: 'i',
73
+ },
74
+ },
75
+ {
76
+ code: {
77
+ $regex: search,
78
+ $options: 'i',
79
+ },
80
+ },
81
+ ],
82
+ };
83
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
84
+ // @ts-ignore
85
+ const pages = await list(Page, query, customOptions);
86
+ res.message = req?.i18n?.t('page.getAll');
87
+ return successResponse(pages, res);
88
+ });
@@ -0,0 +1,47 @@
1
+ import { Types } from 'mongoose';
2
+ import { create, remove, update, getAll } from '../services/dbService';
3
+ import {
4
+ successResponse,
5
+ createdDocumentResponse,
6
+ } from './../utils/responseHandlers';
7
+
8
+ import { defaults } from '../utils/defaults';
9
+ import { IRequest, IResponse } from '../types';
10
+
11
+ const catchAsync = (fn: any) => {
12
+ return defaults.catchAsync(fn, 'Tab');
13
+ };
14
+ const getModals = (req: IRequest) => defaults.getModals(req);
15
+
16
+ export const createTab = catchAsync(async (req: IRequest, res: IResponse) => {
17
+ const { Tab } = getModals(req);
18
+ const data = req.body;
19
+ const tab = await create(Tab, data);
20
+ res.message = req?.i18n?.t('tab.create');
21
+ return createdDocumentResponse(tab, res);
22
+ });
23
+
24
+ export const updateTab = catchAsync(async (req: IRequest, res: IResponse) => {
25
+ const { Tab } = getModals(req);
26
+ const data = req.body;
27
+ const _id = req.params['tabId'];
28
+ const updatedTab = await update(Tab, { _id }, data);
29
+ res.message = req?.i18n?.t('tab.update');
30
+ return successResponse(updatedTab, res);
31
+ });
32
+
33
+ export const deleteTab = catchAsync(async (req: IRequest, res: IResponse) => {
34
+ const { Tab } = getModals(req);
35
+ const _id = new Types.ObjectId(req.params['tabId']);
36
+ const deletedTab = await remove(Tab, { _id });
37
+ res.message = req?.i18n?.t('tab.delete');
38
+ return successResponse(deletedTab, res);
39
+ });
40
+
41
+ export const getTabs = catchAsync(async (req: IRequest, res: IResponse) => {
42
+ const { Tab } = getModals(req);
43
+ const widgetId = new Types.ObjectId(req.params['widgetId']);
44
+ const tab = await getAll(Tab, { widgetId });
45
+ res.message = req?.i18n?.t('tab.getAll');
46
+ return successResponse(tab, res);
47
+ });
@@ -0,0 +1,69 @@
1
+ import { getRedisValue, setRedisValue } from '../utils/redis';
2
+ import { successResponse, recordNotFound } from './../utils/responseHandlers';
3
+ import { defaults } from '../utils/defaults';
4
+ import { IRequest, IResponse } from '../types';
5
+ import { getPageDataDB, getWidgetDataDB } from '../services/dataService';
6
+
7
+ const catchAsync = (fn: any) => {
8
+ return defaults.catchAsync(fn, 'User');
9
+ };
10
+
11
+ const getModals = (req: IRequest) => defaults.getModals(req);
12
+
13
+ // TO Do: Optimize the following
14
+ export const getWidgetData = catchAsync(
15
+ async (req: IRequest, res: IResponse) => {
16
+ const models = getModals(req);
17
+ const { fresh } = req.query;
18
+ const { code } = req.body;
19
+ let widgetData = await getRedisValue(`widgetData_${code}`);
20
+ if (widgetData && fresh !== 'true') {
21
+ return successResponse(widgetData, res);
22
+ }
23
+ widgetData = await getWidgetDataDB(code, models);
24
+
25
+ if (!widgetData) {
26
+ res.message = req?.i18n?.t('user.widgetNotFound');
27
+ return recordNotFound(res);
28
+ }
29
+
30
+ await setRedisValue(`widgetData_${code}`, widgetData);
31
+
32
+ return successResponse(widgetData, res);
33
+ }
34
+ );
35
+
36
+ // TO Do: Optimize the following
37
+ export const getPageData = catchAsync(async (req: IRequest, res: IResponse) => {
38
+ const models = getModals(req);
39
+ const { fresh } = req.query;
40
+ let code = req.body.code;
41
+ const slug = req.body.slug;
42
+ const { Page } = models;
43
+ if (slug) {
44
+ const page = await Page.findOne({ slug });
45
+ if (!page) {
46
+ res.message = req?.i18n?.t('user.pageNotFound');
47
+ return recordNotFound(res);
48
+ }
49
+ code = page.code;
50
+ }
51
+ let pageData = await getRedisValue(`pageData_${code}`);
52
+ if (pageData && fresh !== 'true') {
53
+ return successResponse(pageData, res);
54
+ }
55
+ try {
56
+ pageData = await getPageDataDB(code, models);
57
+ console.log(code);
58
+ } catch (error) {
59
+ console.log(error);
60
+ }
61
+
62
+ if (!pageData) {
63
+ res.message = req?.i18n?.t('user.pageNotFound');
64
+ return recordNotFound(res);
65
+ }
66
+ await setRedisValue(`pageData_${code}`, pageData);
67
+
68
+ return successResponse(pageData, res);
69
+ });
@@ -0,0 +1,420 @@
1
+ import { Models, Types } from 'mongoose';
2
+ import {
3
+ create,
4
+ remove,
5
+ update,
6
+ list,
7
+ bulkInsert,
8
+ deleteAll,
9
+ getOne,
10
+ checkUnique,
11
+ } from '../services/dbService';
12
+ import { VALIDATION } from '../constants';
13
+ import {
14
+ successResponse,
15
+ createdDocumentResponse,
16
+ } from './../utils/responseHandlers';
17
+
18
+ import { commonExcludedFields, defaults } from '../utils/defaults';
19
+ import { formatCollectionItems, getCollectionModal } from '../utils/helper';
20
+ import {
21
+ CollectionItem,
22
+ IRequest,
23
+ IResponse,
24
+ WidgetTypes,
25
+ TypesType,
26
+ ItemsType,
27
+ } from '../types';
28
+ import {
29
+ updateRedisWidget,
30
+ updateWidgetPagesData,
31
+ } from '../services/dataService';
32
+
33
+ const catchAsync = (fn: any) => {
34
+ return defaults.catchAsync(fn, 'Widget');
35
+ };
36
+
37
+ const getModals = (req: IRequest) => defaults.getModals(req);
38
+
39
+ const deleteItems = async (widgetId: string, models: Models) => {
40
+ const { Item } = models;
41
+ await deleteAll(Item, { widgetId: new Types.ObjectId(widgetId) });
42
+ };
43
+ const createItems = async (
44
+ itemsData: any[],
45
+ widgetId: string,
46
+ models: Models
47
+ ) => {
48
+ const { Item, SrcSet } = models;
49
+ itemsData = itemsData.map((item: any) => ({
50
+ ...item,
51
+ _id: new Types.ObjectId(),
52
+ widgetId,
53
+ }));
54
+ const srcSetItems = itemsData.reduce((acc: any[], item: any) => {
55
+ if (Array.isArray(item.srcset)) {
56
+ acc.push(
57
+ ...item.srcset.map((srcSetItem: any) => ({
58
+ ...srcSetItem,
59
+ itemId: item._id,
60
+ }))
61
+ );
62
+ delete item.srcset;
63
+ }
64
+ return acc;
65
+ }, []);
66
+ await bulkInsert(Item, itemsData);
67
+ await bulkInsert(SrcSet, srcSetItems);
68
+ };
69
+
70
+ export const createWidget = catchAsync(
71
+ async (req: IRequest, res: IResponse) => {
72
+ const models = getModals(req);
73
+ const data = req.body;
74
+ let items = [];
75
+
76
+ await checkUnique({
77
+ Modal: models['Widget'],
78
+ uniqueField: 'code',
79
+ value: data.code,
80
+ errorMessage: VALIDATION.WIDGET_EXISTS
81
+ });
82
+
83
+ if ('items' in data) {
84
+ items = JSON.parse(JSON.stringify(data.items));
85
+ delete data.items;
86
+ }
87
+ const widget = await create(models['Widget'], data);
88
+ if (items.length > 0) {
89
+ await createItems(items, widget._id, models);
90
+ }
91
+ res.message = req?.i18n?.t('widget.create');
92
+ return createdDocumentResponse(widget, res);
93
+ }
94
+ );
95
+
96
+ export const updateWidget = catchAsync(
97
+ async (req: IRequest, res: IResponse) => {
98
+ const models = getModals(req);
99
+ const data = req.body;
100
+ const _id = req.params['id'];
101
+ let items = [];
102
+ if ('items' in data) {
103
+ items = JSON.parse(JSON.stringify(data.items));
104
+ delete data.items;
105
+ }
106
+ const updatedWidget = await update(models['Widget'], { _id }, data);
107
+ if (items.length > 0 && updatedWidget) {
108
+ await deleteItems(_id, models);
109
+ await createItems(items, updatedWidget._id, models);
110
+ }
111
+ if (updatedWidget) {
112
+ updateRedisWidget(updatedWidget.code, models);
113
+ updateWidgetPagesData([updatedWidget.id], models);
114
+ }
115
+ res.message = req?.i18n?.t('widget.update');
116
+ return successResponse(updatedWidget, res);
117
+ }
118
+ );
119
+
120
+ export const deleteWidget = catchAsync(
121
+ async (req: IRequest, res: IResponse) => {
122
+ const models = getModals(req);
123
+ await deleteItems(req.params['id'], models);
124
+ const _id = new Types.ObjectId(req.params['id']);
125
+ const deletedWidget = await remove(models['Widget'], { _id });
126
+ if (deletedWidget) {
127
+ updateRedisWidget(deletedWidget.code, models);
128
+ updateWidgetPagesData([deletedWidget.id], models);
129
+ }
130
+ res.message = req?.i18n?.t('widget.delete');
131
+ return successResponse(deletedWidget, res);
132
+ }
133
+ );
134
+
135
+ export const getWidgets = catchAsync(async (req: IRequest, res: IResponse) => {
136
+ const { Widget } = getModals(req);
137
+ const search = req.body.search || '';
138
+ const { collectionItems } = req.body;
139
+ const { page, limit, sort } = req.body.options;
140
+ const all =
141
+ (typeof req.body.all !== 'undefined' && req.body.all === true) || false;
142
+ const isActive =
143
+ typeof req.body.isActive !== 'undefined'
144
+ ? req.body.isActive || false
145
+ : null;
146
+ const customOptions = {
147
+ pagination: !all,
148
+ sort,
149
+ select: 'name code isActive canDel',
150
+ ...(page && limit ? { page, limit } : {}),
151
+ };
152
+ const orOptions: any = [];
153
+ if (search) {
154
+ orOptions.push({ name: { $regex: search, $options: 'i' } });
155
+ orOptions.push({ code: { $regex: search, $options: 'i' } });
156
+ } else {
157
+ orOptions.push({});
158
+ }
159
+ if (Array.isArray(collectionItems) && collectionItems.length) {
160
+ orOptions.push({ _id: { $in: collectionItems } });
161
+ }
162
+ const query = {
163
+ isDeleted: false,
164
+ isActive: { $in: isActive === null ? [true, false] : [isActive] },
165
+ $or: orOptions,
166
+ };
167
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
168
+ // @ts-ignore
169
+ const notifications = await list(Widget, query, customOptions);
170
+ res.message = req?.i18n?.t('widget.getAll');
171
+ return successResponse(notifications, res);
172
+ });
173
+
174
+ export const getSingleWidget = catchAsync(
175
+ async (req: IRequest, res: IResponse) => {
176
+ const { Widget, Item } = getModals(req);
177
+ const _id = req.params['id'];
178
+ const widget = await (
179
+ await getOne(Widget, { _id, isDeleted: true })
180
+ ).toJSON();
181
+ widget['items'] = await Item.aggregate([
182
+ {
183
+ $match: {
184
+ widgetId: new Types.ObjectId(_id),
185
+ isDeleted: false,
186
+ },
187
+ },
188
+ {
189
+ $project: {
190
+ ...commonExcludedFields,
191
+ },
192
+ },
193
+ ...(defaults.languages && defaults.languages?.length > 0
194
+ ? defaults.languages.reduce((arr: any[], lng) => {
195
+ arr.push(
196
+ {
197
+ $lookup: {
198
+ from: 'file',
199
+ let: { imgsId: { $toObjectId: `$imgs.${lng.code}` } },
200
+ as: `imgs.${lng.code}`,
201
+ pipeline: [
202
+ {
203
+ $match: {
204
+ $expr: {
205
+ $eq: ['$_id', '$$imgsId'],
206
+ },
207
+ },
208
+ },
209
+ {
210
+ $project: {
211
+ ...commonExcludedFields,
212
+ width: 0,
213
+ module: 0,
214
+ height: 0,
215
+ },
216
+ },
217
+ ],
218
+ },
219
+ },
220
+ {
221
+ $unwind: {
222
+ path: `$imgs.${lng.code}`,
223
+ preserveNullAndEmptyArrays: true,
224
+ },
225
+ }
226
+ );
227
+ return arr;
228
+ }, [])
229
+ : [
230
+ {
231
+ $lookup: {
232
+ from: 'file',
233
+ let: { imgId: '$img' },
234
+ as: 'img',
235
+ pipeline: [
236
+ {
237
+ $match: {
238
+ $expr: {
239
+ $eq: ['$_id', '$$imgId'],
240
+ },
241
+ },
242
+ },
243
+ {
244
+ $project: {
245
+ ...commonExcludedFields,
246
+ width: 0,
247
+ module: 0,
248
+ height: 0,
249
+ },
250
+ },
251
+ ],
252
+ },
253
+ },
254
+ {
255
+ $unwind: {
256
+ path: '$img',
257
+ preserveNullAndEmptyArrays: true,
258
+ },
259
+ },
260
+ ]),
261
+ {
262
+ $lookup: {
263
+ from: 'srcsets',
264
+ let: { item: '$_id' },
265
+ as: 'srcset',
266
+ pipeline: [
267
+ {
268
+ $match: {
269
+ $expr: {
270
+ $eq: ['$itemId', '$$item'],
271
+ },
272
+ },
273
+ },
274
+ {
275
+ $project: {
276
+ ...commonExcludedFields,
277
+ _id: 0,
278
+ itemId: 0,
279
+ },
280
+ },
281
+ ],
282
+ },
283
+ },
284
+ ]);
285
+ res.message = req?.i18n?.t('widget.getOne');
286
+ return successResponse(widget, res);
287
+ }
288
+ );
289
+
290
+ export const partialUpdateWidget = catchAsync(
291
+ async (req: IRequest, res: IResponse) => {
292
+ const models = getModals(req);
293
+ const data = req.body;
294
+ const _id = req.params['id'];
295
+ const updatedWidget = await update(models['Widget'], { _id }, data);
296
+ if (updatedWidget) {
297
+ updateRedisWidget(updatedWidget.code, models);
298
+ updateWidgetPagesData([updatedWidget.id], models);
299
+ }
300
+ res.message = req?.i18n?.t('widget.partialUpdate');
301
+ return successResponse(updatedWidget, res);
302
+ }
303
+ );
304
+
305
+ export const getItemsTypes = catchAsync(
306
+ async (req: IRequest, res: IResponse) => {
307
+ const itemsTypes: TypesType[] = [
308
+ {
309
+ value: Object.keys(ItemsType)[0],
310
+ label: Object.values(ItemsType)[0],
311
+ },
312
+ ];
313
+ defaults.collections.forEach((item: CollectionItem) => {
314
+ itemsTypes.push({
315
+ value: item.collectionName,
316
+ label: item.title,
317
+ });
318
+ });
319
+ res.message = req?.i18n?.t('widget.getItemsTypes');
320
+ return successResponse(itemsTypes, res);
321
+ }
322
+ );
323
+
324
+ export const getWidgetTypes = catchAsync(
325
+ async (req: IRequest, res: IResponse) => {
326
+ const widgetTypes: any[] = Object.entries(WidgetTypes).map((e) => ({
327
+ label: e[1],
328
+ value: e[0],
329
+ }));
330
+ if (
331
+ Array.isArray(defaults.customWidgetTypes) &&
332
+ defaults.customWidgetTypes.length > 0
333
+ ) {
334
+ widgetTypes.push(...defaults.customWidgetTypes);
335
+ }
336
+ res.message = req?.i18n?.t('widget.getWidgetTypes');
337
+ return successResponse(widgetTypes, res);
338
+ }
339
+ );
340
+
341
+ export const getCollectionData = catchAsync(async (req: IRequest, res: IResponse) => {
342
+ const models = getModals(req);
343
+ const { search, collectionName, collectionItems } = req.body;
344
+ const collectionItem: CollectionItem | undefined = defaults.collections.find(
345
+ (collection) => collection.collectionName === collectionName
346
+ );
347
+ if (!collectionItem) {
348
+ throw new Error(`No collection is specified with ${collectionName}`);
349
+ }
350
+ let limit = collectionItem.searchLimit || 10;
351
+ if (Array.isArray(collectionItems))
352
+ limit = Math.max(collectionItems.length, limit);
353
+ // setting up mongoose model
354
+ const TempModel = getCollectionModal(collectionName, models);
355
+ // fetching data
356
+ let query: any = collectionItem.filters || {};
357
+ const orOptions: any = [];
358
+ let addFieldOptions: any = {};
359
+ if (
360
+ search &&
361
+ Array.isArray(collectionItem.searchColumns) &&
362
+ collectionItem.searchColumns.length
363
+ ) {
364
+ collectionItem.searchColumns.forEach((column) =>
365
+ orOptions.push({
366
+ [column]: {
367
+ $regex: search,
368
+ $options: 'i',
369
+ },
370
+ })
371
+ );
372
+ } else {
373
+ orOptions.push({});
374
+ }
375
+ if (Array.isArray(collectionItems) && collectionItems.length) {
376
+ addFieldOptions = {
377
+ __order: {
378
+ $indexOfArray: [
379
+ collectionItems,
380
+ {
381
+ $toString: '$_id',
382
+ },
383
+ ],
384
+ },
385
+ };
386
+ orOptions.push({ _id: { $in: formatCollectionItems(collectionItems) } });
387
+ }
388
+ if (orOptions.length > 0) {
389
+ query = {
390
+ ...query,
391
+ $or: orOptions,
392
+ };
393
+ }
394
+ const collectionData = await TempModel.aggregate([
395
+ ...(Array.isArray(collectionItem.aggregations)
396
+ ? collectionItem.aggregations
397
+ : []),
398
+ {
399
+ $match: query,
400
+ },
401
+ { $addFields: addFieldOptions },
402
+ {
403
+ $sort: {
404
+ __order: -1,
405
+ },
406
+ },
407
+ {
408
+ $limit: limit,
409
+ },
410
+ ]);
411
+ res.message = req?.i18n?.t('widget.getCollectionData');
412
+ return successResponse({ docs: collectionData }, res);
413
+ });
414
+
415
+ export const getLanguages = catchAsync(async (req: any, res: any) => {
416
+ return successResponse(
417
+ Array.isArray(defaults.languages) ? defaults.languages : [],
418
+ res
419
+ );
420
+ });