propro-utils 1.5.64 → 1.5.65

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.
@@ -102,7 +102,10 @@ async function createDefaultFolders(folderSchema, accountId) {
102
102
 
103
103
  const debugLog = (area, message, data = null) => {
104
104
  const timestamp = new Date().toISOString();
105
- console.log(`[${timestamp}] [${area}] ${message}`, data ? data : '');
105
+ console.log(
106
+ `[${timestamp}] [${area}] ${message}`,
107
+ data ? JSON.stringify(data, null, 2) : ''
108
+ );
106
109
  };
107
110
 
108
111
  const DEFAULT_THEME = {
@@ -113,142 +116,259 @@ const DEFAULT_THEME = {
113
116
  name: 'Default Theme',
114
117
  };
115
118
 
119
+ const timeoutPromise = (promise, timeout, name) => {
120
+ return Promise.race([
121
+ promise,
122
+ new Promise((_, reject) =>
123
+ setTimeout(
124
+ () =>
125
+ reject(new Error(`${name} operation timed out after ${timeout}ms`)),
126
+ timeout
127
+ )
128
+ ),
129
+ ]);
130
+ };
131
+
116
132
  const checkIfUserExists = async accountId => {
133
+ const startTime = Date.now();
117
134
  try {
135
+ if (!accountId) {
136
+ throw new Error('AccountId is required');
137
+ }
118
138
  debugLog('init', `Starting user check for accountId: ${accountId}`);
119
139
 
120
- // Parallel service initialization
121
- const [userSchema, userStyleSchema, folderSchema, Theme] =
122
- await Promise.all([
123
- ServiceManager.getService('UserSchema'),
124
- ServiceManager.getService('UserStyleSchema'),
125
- ServiceManager.getService('FolderSchema'),
126
- ServiceManager.getService('Theme'),
127
- ]);
128
-
129
- debugLog('services', 'All services initialized');
130
-
131
- // Find user and theme in parallel
132
- const [user, existingTheme] = await Promise.all([
133
- userSchema.findOne({ accountId }).populate('userGlobalStyles'),
134
- Theme.findOne({
135
- name: 'Default Theme',
136
- accountId,
137
- }),
138
- ]);
139
-
140
- debugLog('query', 'Initial queries complete', {
141
- userFound: !!user,
142
- themeFound: !!existingTheme,
143
- });
144
-
145
- // Create or use existing theme
146
- const defaultTheme =
147
- existingTheme ||
148
- (await Theme.create({
149
- ...DEFAULT_THEME,
150
- id: uuidv4(),
151
- accountId,
152
- }));
140
+ // Initialize services with timeout and individual error handling
141
+ let services;
142
+ try {
143
+ debugLog('services', 'Initializing services...');
144
+ services = await timeoutPromise(
145
+ Promise.all([
146
+ ServiceManager.getService('UserSchema').catch(e => {
147
+ throw new Error(`Failed to get UserSchema: ${e.message}`);
148
+ }),
149
+ ServiceManager.getService('UserStyleSchema').catch(e => {
150
+ throw new Error(`Failed to get UserStyleSchema: ${e.message}`);
151
+ }),
152
+ ServiceManager.getService('FolderSchema').catch(e => {
153
+ throw new Error(`Failed to get FolderSchema: ${e.message}`);
154
+ }),
155
+ ServiceManager.getService('Theme').catch(e => {
156
+ throw new Error(`Failed to get Theme: ${e.message}`);
157
+ }),
158
+ ]),
159
+ 5000,
160
+ 'Service initialization'
161
+ );
153
162
 
154
- debugLog('theme', 'Theme ready', { themeId: defaultTheme._id });
163
+ debugLog('services', 'Services initialized successfully', {
164
+ serviceCount: services.length,
165
+ initTime: Date.now() - startTime,
166
+ });
167
+ } catch (error) {
168
+ debugLog('error', 'Service initialization failed', {
169
+ error: error.message,
170
+ });
171
+ throw error;
172
+ }
155
173
 
156
- if (user) {
157
- debugLog('user', 'Existing user found, updating if needed');
174
+ const [userSchema, userStyleSchema, folderSchema, Theme] = services;
158
175
 
159
- const updates = [];
176
+ // Find user and theme with timeout
177
+ let user, existingTheme;
178
+ try {
179
+ debugLog('query', 'Starting user and theme queries');
180
+ [user, existingTheme] = await timeoutPromise(
181
+ Promise.all([
182
+ userSchema
183
+ .findOne({ accountId })
184
+ .populate('userGlobalStyles')
185
+ .exec()
186
+ .catch(e => {
187
+ throw new Error(`Failed to find user: ${e.message}`);
188
+ }),
189
+ Theme.findOne({
190
+ name: 'Default Theme',
191
+ accountId,
192
+ })
193
+ .exec()
194
+ .catch(e => {
195
+ throw new Error(`Failed to find theme: ${e.message}`);
196
+ }),
197
+ ]),
198
+ 5000,
199
+ 'Initial queries'
200
+ );
160
201
 
161
- // Collect necessary updates
162
- if (!user.theme) {
163
- user.theme = defaultTheme._id;
164
- updates.push('theme');
165
- }
202
+ debugLog('query', 'Queries completed', {
203
+ userFound: !!user,
204
+ themeFound: !!existingTheme,
205
+ queryTime: Date.now() - startTime,
206
+ });
207
+ } catch (error) {
208
+ debugLog('error', 'Query operations failed', { error: error.message });
209
+ throw error;
210
+ }
166
211
 
167
- if (!user.userGlobalStyles) {
168
- user.userGlobalStyles = await createUserGlobalStyles(
169
- userStyleSchema,
170
- accountId
212
+ // Create or use existing theme
213
+ let defaultTheme;
214
+ try {
215
+ if (!existingTheme) {
216
+ debugLog('theme', 'Creating new theme');
217
+ defaultTheme = await timeoutPromise(
218
+ Theme.create({
219
+ ...DEFAULT_THEME,
220
+ id: uuidv4(),
221
+ accountId,
222
+ }),
223
+ 5000,
224
+ 'Theme creation'
171
225
  );
172
- updates.push('userGlobalStyles');
173
- } else if (user.userGlobalStyles.styleShortcuts.length === 0) {
174
- user.userGlobalStyles.styleShortcuts = defaultUserGlobalStyleShortcuts;
175
- await user.userGlobalStyles.save();
226
+ debugLog('theme', 'New theme created', { themeId: defaultTheme._id });
227
+ } else {
228
+ defaultTheme = existingTheme;
229
+ debugLog('theme', 'Using existing theme', {
230
+ themeId: defaultTheme._id,
231
+ });
176
232
  }
233
+ } catch (error) {
234
+ debugLog('error', 'Theme operation failed', { error: error.message });
235
+ throw error;
236
+ }
177
237
 
178
- // Check folders only if needed
179
- const userFolders = await folderSchema.find(
180
- { user_id: user.id },
181
- { name: 1 }
182
- );
183
- const userFolderNames = new Set(userFolders.map(f => f.name));
184
- const foldersToCreate = defaultFolders.filter(
185
- f => !userFolderNames.has(f.name)
186
- );
238
+ if (user) {
239
+ debugLog('user', 'Processing existing user');
240
+ const updates = [];
241
+
242
+ try {
243
+ // Theme update if needed
244
+ if (!user.theme) {
245
+ debugLog('update', 'Adding theme to user');
246
+ user.theme = defaultTheme._id;
247
+ updates.push('theme');
248
+ }
249
+
250
+ // Global styles update if needed
251
+ if (!user.userGlobalStyles) {
252
+ debugLog('update', 'Creating user global styles');
253
+ user.userGlobalStyles = await timeoutPromise(
254
+ createUserGlobalStyles(userStyleSchema, accountId),
255
+ 5000,
256
+ 'Global styles creation'
257
+ );
258
+ updates.push('userGlobalStyles');
259
+ } else if (user.userGlobalStyles.styleShortcuts.length === 0) {
260
+ debugLog('update', 'Updating empty style shortcuts');
261
+ user.userGlobalStyles.styleShortcuts =
262
+ defaultUserGlobalStyleShortcuts;
263
+ await timeoutPromise(
264
+ user.userGlobalStyles.save(),
265
+ 5000,
266
+ 'Style shortcuts update'
267
+ );
268
+ }
187
269
 
188
- if (foldersToCreate.length > 0) {
189
- debugLog(
190
- 'folders',
191
- `Creating ${foldersToCreate.length} missing folders`
270
+ // Folder checks
271
+ debugLog('folders', 'Checking user folders');
272
+ const userFolders = await timeoutPromise(
273
+ folderSchema.find({ user_id: user.id }, { name: 1 }),
274
+ 5000,
275
+ 'Folder query'
192
276
  );
193
- await Promise.all(
194
- foldersToCreate.map(folder =>
195
- folderSchema.create({
196
- ...folder,
197
- user_id: user.id,
198
- })
199
- )
277
+
278
+ const userFolderNames = new Set(userFolders.map(f => f.name));
279
+ const foldersToCreate = defaultFolders.filter(
280
+ f => !userFolderNames.has(f.name)
200
281
  );
201
- }
202
282
 
203
- // Save user only if there were updates
204
- if (updates.length > 0) {
205
- debugLog('update', `Saving user updates: ${updates.join(', ')}`);
206
- await user.save();
283
+ if (foldersToCreate.length > 0) {
284
+ debugLog('folders', 'Creating missing folders', {
285
+ count: foldersToCreate.length,
286
+ });
287
+ await timeoutPromise(
288
+ Promise.all(
289
+ foldersToCreate.map(folder =>
290
+ folderSchema.create({
291
+ ...folder,
292
+ user_id: user.id,
293
+ })
294
+ )
295
+ ),
296
+ 5000,
297
+ 'Folder creation'
298
+ );
299
+ }
300
+
301
+ // Save user if there were updates
302
+ if (updates.length > 0) {
303
+ debugLog('update', 'Saving user updates', { updates });
304
+ await timeoutPromise(user.save(), 5000, 'User save');
305
+ }
306
+ } catch (error) {
307
+ debugLog('error', 'User update operations failed', {
308
+ error: error.message,
309
+ });
310
+ throw error;
207
311
  }
208
312
 
209
- debugLog('complete', 'Existing user processed successfully');
313
+ debugLog('complete', 'Existing user processed', {
314
+ userId: user.id,
315
+ totalTime: Date.now() - startTime,
316
+ });
210
317
  return user;
211
318
  }
212
319
 
213
- debugLog('create', 'Creating new user');
320
+ // Create new user
321
+ try {
322
+ debugLog('create', 'Creating new user');
323
+ const userGlobalStyles = await timeoutPromise(
324
+ createUserGlobalStyles(userStyleSchema, accountId),
325
+ 5000,
326
+ 'Global styles creation'
327
+ );
214
328
 
215
- // Create new user with all required relations
216
- const userGlobalStyles = await createUserGlobalStyles(
217
- userStyleSchema,
218
- accountId
219
- );
329
+ const newUserId = uuidv4();
220
330
 
221
- const [newUser, newFolders] = await Promise.all([
222
- userSchema.create({
223
- accountId,
224
- id: uuidv4(),
225
- verified: false,
226
- userGlobalStyles: userGlobalStyles._id,
227
- theme: defaultTheme._id,
228
- }),
229
- createDefaultFolders(folderSchema, uuidv4()), // Pass the new user ID
230
- ]);
231
-
232
- newUser.folders = newFolders.map(folder => folder._id);
233
- await newUser.save();
234
-
235
- debugLog('complete', 'New user created successfully', {
236
- userId: newUser.id,
237
- });
238
- return newUser;
331
+ const [newUser, newFolders] = await timeoutPromise(
332
+ Promise.all([
333
+ userSchema.create({
334
+ accountId,
335
+ id: newUserId,
336
+ verified: false,
337
+ userGlobalStyles: userGlobalStyles._id,
338
+ theme: defaultTheme._id,
339
+ }),
340
+ createDefaultFolders(folderSchema, newUserId),
341
+ ]),
342
+ 5000,
343
+ 'User and folders creation'
344
+ );
345
+
346
+ newUser.folders = newFolders.map(folder => folder._id);
347
+ await timeoutPromise(newUser.save(), 5000, 'New user save');
348
+
349
+ debugLog('complete', 'New user created', {
350
+ userId: newUser.id,
351
+ totalTime: Date.now() - startTime,
352
+ });
353
+ return newUser;
354
+ } catch (error) {
355
+ debugLog('error', 'User creation failed', { error: error.message });
356
+ throw error;
357
+ }
239
358
  } catch (error) {
359
+ const totalTime = Date.now() - startTime;
240
360
  debugLog('error', 'Operation failed', {
241
361
  error: error.message,
242
362
  stack: error.stack,
363
+ totalTime,
243
364
  });
244
365
 
245
- // Throw error with original cause and context
246
- throw new Error('Failed to get or create user', {
366
+ throw new Error(`Failed to get or create user: ${error.message}`, {
247
367
  cause: error,
248
- accountId,
249
368
  });
250
369
  }
251
370
  };
371
+
252
372
  module.exports = {
253
373
  getAccountProfile,
254
374
  checkIfUserExists,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "propro-utils",
3
- "version": "1.5.64",
3
+ "version": "1.5.65",
4
4
  "description": "Auth middleware for propro-auth",
5
5
  "main": "src/index.js",
6
6
  "scripts": {