shuttlepro-shared 1.2.8 → 1.2.10
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,90 +1,3 @@
|
|
|
1
|
-
// const { getRedisData, setRedisData } = require("../../config/redis");
|
|
2
|
-
// const Label = require("../../models/Label");
|
|
3
|
-
|
|
4
|
-
// const CACHE_KEY_ALL = "labels_all";
|
|
5
|
-
|
|
6
|
-
// const getCachedLabels = async () => {
|
|
7
|
-
// let labels = await getRedisData(CACHE_KEY_ALL);
|
|
8
|
-
// if (!labels) {
|
|
9
|
-
// labels = await Label.find().lean().exec();
|
|
10
|
-
// await setRedisData(CACHE_KEY_ALL, JSON.stringify(labels));
|
|
11
|
-
// } else {
|
|
12
|
-
// labels = JSON.parse(labels);
|
|
13
|
-
// }
|
|
14
|
-
// return labels;
|
|
15
|
-
// };
|
|
16
|
-
|
|
17
|
-
// const updateCachedLabels = async () => {
|
|
18
|
-
// const labels = await Label.find().lean().exec();
|
|
19
|
-
// await setRedisData(CACHE_KEY_ALL, JSON.stringify(labels));
|
|
20
|
-
// };
|
|
21
|
-
|
|
22
|
-
// const createLabel = async (data) => {
|
|
23
|
-
// const newLabel = new Label(data);
|
|
24
|
-
// const savedLabel = await newLabel.save();
|
|
25
|
-
// await updateCachedLabels();
|
|
26
|
-
// return savedLabel;
|
|
27
|
-
// };
|
|
28
|
-
|
|
29
|
-
// const findLabelById = async (id) => {
|
|
30
|
-
// const labels = await getCachedLabels();
|
|
31
|
-
// return labels.find((l) => l._id.toString() === id) || null;
|
|
32
|
-
// };
|
|
33
|
-
|
|
34
|
-
// const findLabel = async (filter) => {
|
|
35
|
-
// const labels = await getCachedLabels();
|
|
36
|
-
// return (
|
|
37
|
-
// labels.find((l) =>
|
|
38
|
-
// Object.entries(filter).every(([key, value]) => l[key] === value)
|
|
39
|
-
// ) || null
|
|
40
|
-
// );
|
|
41
|
-
// };
|
|
42
|
-
|
|
43
|
-
// const findAllLabels = async (filter = {}) => {
|
|
44
|
-
// const labels = await getCachedLabels();
|
|
45
|
-
// return labels.filter((l) =>
|
|
46
|
-
// Object.entries(filter).every(([key, value]) => l[key] === value)
|
|
47
|
-
// );
|
|
48
|
-
// };
|
|
49
|
-
|
|
50
|
-
// const updateLabelById = async (id, data) => {
|
|
51
|
-
// const updatedLabel = await Label.findByIdAndUpdate(id, data, {
|
|
52
|
-
// new: true,
|
|
53
|
-
// }).exec();
|
|
54
|
-
// if (updatedLabel) {
|
|
55
|
-
// await updateCachedLabels();
|
|
56
|
-
// }
|
|
57
|
-
// return updatedLabel;
|
|
58
|
-
// };
|
|
59
|
-
// const updateLabel = async (filter, data) => {
|
|
60
|
-
// const updatedLabel = await Label.findOneAndUpdate(filter, data, {
|
|
61
|
-
// new: true,
|
|
62
|
-
// }).exec();
|
|
63
|
-
// if (updatedLabel) {
|
|
64
|
-
// await updateCachedLabels();
|
|
65
|
-
// }
|
|
66
|
-
// return updatedLabel;
|
|
67
|
-
// };
|
|
68
|
-
|
|
69
|
-
// const deleteLabel = async (id) => {
|
|
70
|
-
// const deletedLabel = await Label.findByIdAndDelete(id).exec();
|
|
71
|
-
// if (deletedLabel) {
|
|
72
|
-
// await updateCachedLabels();
|
|
73
|
-
// }
|
|
74
|
-
// return deletedLabel;
|
|
75
|
-
// };
|
|
76
|
-
|
|
77
|
-
// module.exports = {
|
|
78
|
-
// createLabel,
|
|
79
|
-
// findLabelById,
|
|
80
|
-
// findLabel,
|
|
81
|
-
// findAllLabels,
|
|
82
|
-
// updateLabel,
|
|
83
|
-
// deleteLabel,
|
|
84
|
-
// updateLabelById,
|
|
85
|
-
// };
|
|
86
|
-
|
|
87
|
-
const R = require("ramda");
|
|
88
1
|
const Label = require("../../models/Label");
|
|
89
2
|
const {
|
|
90
3
|
setRedisData,
|
|
@@ -92,153 +5,91 @@ const {
|
|
|
92
5
|
deleteRedisData,
|
|
93
6
|
} = require("../../config/redis");
|
|
94
7
|
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
R.identity,
|
|
101
|
-
(workspaceId) => `labels:workspace:${workspaceId}`
|
|
102
|
-
),
|
|
103
|
-
LABEL_DETAILS: R.memoizeWith(
|
|
104
|
-
R.identity,
|
|
105
|
-
(labelId) => `labels:details:${labelId}`
|
|
106
|
-
),
|
|
107
|
-
},
|
|
108
|
-
expiry: 60 * 60,
|
|
109
|
-
},
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
const createLabelRepository = (dependencies) => {
|
|
113
|
-
const { Label, redisConfig } = dependencies;
|
|
114
|
-
|
|
115
|
-
const generateCacheKey = R.pipe(
|
|
116
|
-
R.toPairs,
|
|
117
|
-
R.map(([key, value]) => `${key}:${JSON.stringify(value)}`),
|
|
118
|
-
R.join("|"),
|
|
119
|
-
R.concat("labels:query:")
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
const withCache = R.curry(async (cacheKey, fetchFn, forceFresh = false) => {
|
|
123
|
-
if (!forceFresh) {
|
|
124
|
-
const cachedData = await getRedisData(cacheKey);
|
|
125
|
-
if (cachedData) return cachedData;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const data = await fetchFn();
|
|
129
|
-
|
|
130
|
-
if (data && data.length) {
|
|
131
|
-
await setRedisData(cacheKey, data, null, redisConfig.cache.expiry);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return data;
|
|
135
|
-
});
|
|
8
|
+
const CACHE_KEYS = {
|
|
9
|
+
ALL_LABELS: "labels:all",
|
|
10
|
+
WORKSPACE_LABELS: (workspaceId) => `labels:workspace:${workspaceId}`,
|
|
11
|
+
LABEL_DETAILS: (labelId) => `labels:details:${labelId}`,
|
|
12
|
+
};
|
|
136
13
|
|
|
137
|
-
|
|
138
|
-
const isDuplicate = R.any(
|
|
139
|
-
(label) =>
|
|
140
|
-
label.title.toLowerCase() === newLabel.title.toLowerCase() &&
|
|
141
|
-
R.equals(label.workspaceId, newLabel.workspaceId)
|
|
142
|
-
)(existingLabels);
|
|
14
|
+
const CACHE_EXPIRY = 60 * 60; // 1 hour
|
|
143
15
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
16
|
+
// Utility function for caching
|
|
17
|
+
const withCache = async (cacheKey, fetchFn, forceFresh = false) => {
|
|
18
|
+
if (!forceFresh) {
|
|
19
|
+
const cachedData = await getRedisData(cacheKey);
|
|
20
|
+
if (cachedData) return cachedData;
|
|
21
|
+
}
|
|
147
22
|
|
|
148
|
-
|
|
149
|
-
|
|
23
|
+
const data = await fetchFn();
|
|
24
|
+
if (data && data.length) {
|
|
25
|
+
await setRedisData(cacheKey, data, null, CACHE_EXPIRY);
|
|
26
|
+
}
|
|
150
27
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
(label) => label.save(),
|
|
154
|
-
validateLabel(await Label.find()),
|
|
155
|
-
Label.hydrate
|
|
156
|
-
);
|
|
28
|
+
return data;
|
|
29
|
+
};
|
|
157
30
|
|
|
158
|
-
|
|
159
|
-
|
|
31
|
+
// Core functions
|
|
32
|
+
const createLabel = async (labelData) => {
|
|
33
|
+
const existingLabels = await Label.find();
|
|
34
|
+
const isDuplicate = existingLabels.some(
|
|
35
|
+
(label) =>
|
|
36
|
+
label.title.toLowerCase() === labelData.title.toLowerCase() &&
|
|
37
|
+
label.workspaceId === labelData.workspaceId
|
|
38
|
+
);
|
|
160
39
|
|
|
161
|
-
|
|
162
|
-
const {
|
|
163
|
-
lean = true,
|
|
164
|
-
populate = [],
|
|
165
|
-
sort = { createdAt: -1 },
|
|
166
|
-
limit = 100,
|
|
167
|
-
} = options;
|
|
40
|
+
if (isDuplicate) throw new Error("Label with this title already exists");
|
|
168
41
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
(labels) => R.take(limit, labels),
|
|
173
|
-
(labels) =>
|
|
174
|
-
R.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt), labels)
|
|
175
|
-
);
|
|
42
|
+
const newLabel = new Label(labelData);
|
|
43
|
+
return await newLabel.save();
|
|
44
|
+
};
|
|
176
45
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
46
|
+
const findLabels = async (query = {}, options = {}) => {
|
|
47
|
+
return await withCache(JSON.stringify(query), () =>
|
|
48
|
+
Label.find(query)
|
|
49
|
+
.sort({ createdAt: -1 })
|
|
50
|
+
.limit(options.limit || 100)
|
|
51
|
+
.exec()
|
|
52
|
+
);
|
|
53
|
+
};
|
|
182
54
|
|
|
183
|
-
|
|
184
|
-
|
|
55
|
+
const findAllLabels = async (query = {}) => {
|
|
56
|
+
return await withCache(JSON.stringify(query), () => Label.find(query).exec());
|
|
57
|
+
};
|
|
185
58
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
);
|
|
192
|
-
});
|
|
59
|
+
const findLabelById = async (labelId) => {
|
|
60
|
+
return await withCache(CACHE_KEYS.LABEL_DETAILS(labelId), () =>
|
|
61
|
+
Label.findById(labelId).exec()
|
|
62
|
+
);
|
|
63
|
+
};
|
|
193
64
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
await setRedisData(
|
|
198
|
-
redisConfig.cache.keys.LABEL_DETAILS(labelId),
|
|
199
|
-
updatedLabel.toObject()
|
|
200
|
-
);
|
|
201
|
-
}),
|
|
202
|
-
(label) => label.save(),
|
|
203
|
-
(label) => {
|
|
204
|
-
const updatedFields = R.mergeDeepRight(label.toObject(), updateData);
|
|
205
|
-
return Label.hydrate(updatedFields);
|
|
206
|
-
},
|
|
207
|
-
() => Label.findById(labelId)
|
|
208
|
-
);
|
|
65
|
+
const findLabel = async (query = {}) => {
|
|
66
|
+
return await Label.findOne(query).exec();
|
|
67
|
+
};
|
|
209
68
|
|
|
210
|
-
|
|
69
|
+
const updateLabel = async (labelId, updateData) => {
|
|
70
|
+
const updatedLabel = await Label.findByIdAndUpdate(labelId, updateData, {
|
|
71
|
+
new: true,
|
|
211
72
|
});
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}),
|
|
218
|
-
(label) => label.remove(),
|
|
219
|
-
() => Label.findById(labelId)
|
|
220
|
-
);
|
|
221
|
-
|
|
222
|
-
return performDelete();
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
const filterLabels = R.curry((filterFn, labels) =>
|
|
226
|
-
R.filter(filterFn, labels)
|
|
73
|
+
await setRedisData(
|
|
74
|
+
CACHE_KEYS.LABEL_DETAILS(labelId),
|
|
75
|
+
updatedLabel.toObject(),
|
|
76
|
+
null,
|
|
77
|
+
CACHE_EXPIRY
|
|
227
78
|
);
|
|
228
|
-
|
|
229
|
-
return {
|
|
230
|
-
createLabel,
|
|
231
|
-
findLabels,
|
|
232
|
-
findAllLabels,
|
|
233
|
-
updateLabel,
|
|
234
|
-
deleteLabel,
|
|
235
|
-
filterLabels,
|
|
236
|
-
};
|
|
79
|
+
return updatedLabel;
|
|
237
80
|
};
|
|
238
81
|
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
82
|
+
const deleteLabel = async (labelId) => {
|
|
83
|
+
await deleteRedisData(CACHE_KEYS.LABEL_DETAILS(labelId));
|
|
84
|
+
return await Label.findByIdAndDelete(labelId);
|
|
242
85
|
};
|
|
243
86
|
|
|
244
|
-
module.exports =
|
|
87
|
+
module.exports = {
|
|
88
|
+
createLabel,
|
|
89
|
+
findLabels,
|
|
90
|
+
findAllLabels,
|
|
91
|
+
findLabelById,
|
|
92
|
+
findLabel,
|
|
93
|
+
updateLabel,
|
|
94
|
+
deleteLabel,
|
|
95
|
+
};
|