shuttlepro-shared 1.2.7 → 1.2.9
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.
|
@@ -92,159 +92,80 @@ const {
|
|
|
92
92
|
deleteRedisData,
|
|
93
93
|
} = require("../../config/redis");
|
|
94
94
|
|
|
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 constructQuery = R.curry((baseQuery, additionalQuery) =>
|
|
113
|
-
R.mergeDeepRight(baseQuery, additionalQuery)
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
const createLabelRepository = (dependencies) => {
|
|
117
|
-
const { Label, redisConfig } = dependencies;
|
|
118
|
-
|
|
119
|
-
const generateCacheKey = R.pipe(
|
|
120
|
-
R.toPairs,
|
|
121
|
-
R.map(([key, value]) => `${key}:${JSON.stringify(value)}`),
|
|
122
|
-
R.join("|"),
|
|
123
|
-
R.concat("labels:query:")
|
|
124
|
-
);
|
|
95
|
+
const CACHE_KEYS = {
|
|
96
|
+
ALL_LABELS: "labels:all",
|
|
97
|
+
WORKSPACE_LABELS: (workspaceId) => `labels:workspace:${workspaceId}`,
|
|
98
|
+
LABEL_DETAILS: (labelId) => `labels:details:${labelId}`,
|
|
99
|
+
};
|
|
125
100
|
|
|
126
|
-
|
|
127
|
-
if (!forceFresh) {
|
|
128
|
-
const cachedData = await getRedisData(cacheKey);
|
|
129
|
-
if (cachedData) return cachedData;
|
|
130
|
-
}
|
|
101
|
+
const CACHE_EXPIRY = 60 * 60; // 1 hour
|
|
131
102
|
|
|
132
|
-
|
|
103
|
+
// Utility function for caching
|
|
104
|
+
const withCache = async (cacheKey, fetchFn, forceFresh = false) => {
|
|
105
|
+
if (!forceFresh) {
|
|
106
|
+
const cachedData = await getRedisData(cacheKey);
|
|
107
|
+
if (cachedData) return cachedData;
|
|
108
|
+
}
|
|
133
109
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
110
|
+
const data = await fetchFn();
|
|
111
|
+
if (data && data.length) {
|
|
112
|
+
await setRedisData(cacheKey, data, null, CACHE_EXPIRY);
|
|
113
|
+
}
|
|
137
114
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const validateLabel = R.curry((existingLabels, newLabel) => {
|
|
142
|
-
const isDuplicate = R.any(
|
|
143
|
-
(label) =>
|
|
144
|
-
label.title.toLowerCase() === newLabel.title.toLowerCase() &&
|
|
145
|
-
R.equals(label.workspaceId, newLabel.workspaceId)
|
|
146
|
-
)(existingLabels);
|
|
115
|
+
return data;
|
|
116
|
+
};
|
|
147
117
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
118
|
+
// Core functions
|
|
119
|
+
const createLabel = async (labelData) => {
|
|
120
|
+
const existingLabels = await Label.find();
|
|
121
|
+
const isDuplicate = existingLabels.some(
|
|
122
|
+
(label) =>
|
|
123
|
+
label.title.toLowerCase() === labelData.title.toLowerCase() &&
|
|
124
|
+
label.workspaceId === labelData.workspaceId
|
|
125
|
+
);
|
|
151
126
|
|
|
152
|
-
|
|
153
|
-
});
|
|
127
|
+
if (isDuplicate) throw new Error("Label with this title already exists");
|
|
154
128
|
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
validateLabel(await Label.find()),
|
|
159
|
-
Label.hydrate
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
return create(labelData);
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
const findLabels = R.curry(async (options = {}, query = {}) => {
|
|
166
|
-
const {
|
|
167
|
-
lean = true,
|
|
168
|
-
populate = [],
|
|
169
|
-
sort = { createdAt: -1 },
|
|
170
|
-
limit = 100,
|
|
171
|
-
} = options;
|
|
172
|
-
|
|
173
|
-
const executeQuery = R.pipe(
|
|
174
|
-
R.when(R.always(lean), R.map(R.prop("toObject"))),
|
|
175
|
-
(labels) => (populate.length ? Label.populate(labels, populate) : labels),
|
|
176
|
-
(labels) => R.take(limit, labels),
|
|
177
|
-
(labels) =>
|
|
178
|
-
R.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt), labels)
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
const cachedFind = withCache(
|
|
182
|
-
generateCacheKey(query),
|
|
183
|
-
() => Label.find(query).exec(),
|
|
184
|
-
false
|
|
185
|
-
);
|
|
186
|
-
|
|
187
|
-
return executeQuery(await cachedFind());
|
|
188
|
-
});
|
|
129
|
+
const newLabel = new Label(labelData);
|
|
130
|
+
return await newLabel.save();
|
|
131
|
+
};
|
|
189
132
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
(
|
|
194
|
-
|
|
195
|
-
|
|
133
|
+
const findLabels = async (query = {}, options = {}) => {
|
|
134
|
+
return await withCache(JSON.stringify(query), () =>
|
|
135
|
+
Label.find(query)
|
|
136
|
+
.sort({ createdAt: -1 })
|
|
137
|
+
.limit(options.limit || 100)
|
|
138
|
+
.exec()
|
|
139
|
+
);
|
|
140
|
+
};
|
|
196
141
|
|
|
197
|
-
|
|
198
|
-
|
|
142
|
+
const findAllLabels = async (query = {}) => {
|
|
143
|
+
return await withCache(JSON.stringify(query), () => Label.find(query).exec());
|
|
144
|
+
};
|
|
199
145
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
await setRedisData(
|
|
204
|
-
redisConfig.cache.keys.LABEL_DETAILS(labelId),
|
|
205
|
-
updatedLabel.toObject()
|
|
206
|
-
);
|
|
207
|
-
}),
|
|
208
|
-
(label) => label.save(),
|
|
209
|
-
(label) => {
|
|
210
|
-
const updatedFields = R.mergeDeepRight(label.toObject(), updateData);
|
|
211
|
-
return Label.hydrate(updatedFields);
|
|
212
|
-
},
|
|
213
|
-
() => Label.findById(labelId)
|
|
214
|
-
);
|
|
215
|
-
|
|
216
|
-
return update();
|
|
146
|
+
const updateLabel = async (labelId, updateData) => {
|
|
147
|
+
const updatedLabel = await Label.findByIdAndUpdate(labelId, updateData, {
|
|
148
|
+
new: true,
|
|
217
149
|
});
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}),
|
|
224
|
-
(label) => label.remove(),
|
|
225
|
-
() => Label.findById(labelId)
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
return performDelete();
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
const filterLabels = R.curry((filterFn, labels) =>
|
|
232
|
-
R.filter(filterFn, labels)
|
|
150
|
+
await setRedisData(
|
|
151
|
+
CACHE_KEYS.LABEL_DETAILS(labelId),
|
|
152
|
+
updatedLabel.toObject(),
|
|
153
|
+
null,
|
|
154
|
+
CACHE_EXPIRY
|
|
233
155
|
);
|
|
156
|
+
return updatedLabel;
|
|
157
|
+
};
|
|
234
158
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
findAllLabels,
|
|
239
|
-
updateLabel,
|
|
240
|
-
deleteLabel,
|
|
241
|
-
filterLabels,
|
|
242
|
-
};
|
|
159
|
+
const deleteLabel = async (labelId) => {
|
|
160
|
+
await deleteRedisData(CACHE_KEYS.LABEL_DETAILS(labelId));
|
|
161
|
+
return await Label.findByIdAndDelete(labelId);
|
|
243
162
|
};
|
|
244
163
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
164
|
+
module.exports = {
|
|
165
|
+
createLabel,
|
|
166
|
+
findLabels,
|
|
167
|
+
findAllLabels,
|
|
168
|
+
updateLabel,
|
|
169
|
+
deleteLabel,
|
|
248
170
|
};
|
|
249
171
|
|
|
250
|
-
module.exports = createLabelRepository(dependencies);
|