mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:17:11 -05:00 
			
		
		
		
	chore(server): user e2e: wait for user delete event (#7799)
* wait for user delete event * fix update event names * add test for hard deletion of user
This commit is contained in:
		
							parent
							
								
									ec8fb0be83
								
							
						
					
					
						commit
						11e7533a4d
					
				@ -96,7 +96,7 @@ describe('/asset', () => {
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await utils.waitForWebsocketEvent({ event: 'upload', assetId: locationAsset.id });
 | 
					    await utils.waitForWebsocketEvent({ event: 'assetUpload', id: locationAsset.id });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    user1Assets = await Promise.all([
 | 
					    user1Assets = await Promise.all([
 | 
				
			||||||
      utils.createAsset(user1.accessToken),
 | 
					      utils.createAsset(user1.accessToken),
 | 
				
			||||||
@ -693,7 +693,7 @@ describe('/asset', () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        expect(duplicate).toBe(false);
 | 
					        expect(duplicate).toBe(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await utils.waitForWebsocketEvent({ event: 'upload', assetId: id });
 | 
					        await utils.waitForWebsocketEvent({ event: 'assetUpload', id: id });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const asset = await utils.getAssetInfo(admin.accessToken, id);
 | 
					        const asset = await utils.getAssetInfo(admin.accessToken, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -795,7 +795,7 @@ describe('/asset', () => {
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await utils.waitForWebsocketEvent({ event: 'upload', assetId: response.id });
 | 
					        await utils.waitForWebsocketEvent({ event: 'assetUpload', id: response.id });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(response.duplicate).toBe(false);
 | 
					        expect(response.duplicate).toBe(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -822,8 +822,8 @@ describe('/asset', () => {
 | 
				
			|||||||
        .set('Authorization', `Bearer ${admin.accessToken}`);
 | 
					        .set('Authorization', `Bearer ${admin.accessToken}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      await utils.waitForWebsocketEvent({
 | 
					      await utils.waitForWebsocketEvent({
 | 
				
			||||||
        event: 'upload',
 | 
					        event: 'assetUpload',
 | 
				
			||||||
        assetId: locationAsset.id,
 | 
					        id: locationAsset.id,
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(status).toBe(200);
 | 
					      expect(status).toBe(200);
 | 
				
			||||||
 | 
				
			|||||||
@ -76,7 +76,7 @@ describe('/search', () => {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (const asset of assets) {
 | 
					    for (const asset of assets) {
 | 
				
			||||||
      await utils.waitForWebsocketEvent({ event: 'upload', assetId: asset.id });
 | 
					      await utils.waitForWebsocketEvent({ event: 'assetUpload', id: asset.id });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [
 | 
					    [
 | 
				
			||||||
@ -325,11 +325,9 @@ describe('/search', () => {
 | 
				
			|||||||
          .post('/search/metadata')
 | 
					          .post('/search/metadata')
 | 
				
			||||||
          .send(dto)
 | 
					          .send(dto)
 | 
				
			||||||
          .set('Authorization', `Bearer ${admin.accessToken}`);
 | 
					          .set('Authorization', `Bearer ${admin.accessToken}`);
 | 
				
			||||||
        console.dir({ status, body }, { depth: 10 });
 | 
					 | 
				
			||||||
        expect(status).toBe(200);
 | 
					        expect(status).toBe(200);
 | 
				
			||||||
        expect(body.assets).toBeDefined();
 | 
					        expect(body.assets).toBeDefined();
 | 
				
			||||||
        expect(Array.isArray(body.assets.items)).toBe(true);
 | 
					        expect(Array.isArray(body.assets.items)).toBe(true);
 | 
				
			||||||
        console.log({ assets: body.assets.items });
 | 
					 | 
				
			||||||
        for (const [i, asset] of assets.entries()) {
 | 
					        for (const [i, asset] of assets.entries()) {
 | 
				
			||||||
          expect(body.assets.items[i]).toEqual(expect.objectContaining({ id: asset.id }));
 | 
					          expect(body.assets.items[i]).toEqual(expect.objectContaining({ id: asset.id }));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,7 @@ describe('/trash', () => {
 | 
				
			|||||||
      const { status } = await request(app).post('/trash/empty').set('Authorization', `Bearer ${admin.accessToken}`);
 | 
					      const { status } = await request(app).post('/trash/empty').set('Authorization', `Bearer ${admin.accessToken}`);
 | 
				
			||||||
      expect(status).toBe(204);
 | 
					      expect(status).toBe(204);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      await utils.waitForWebsocketEvent({ event: 'delete', assetId });
 | 
					      await utils.waitForWebsocketEvent({ event: 'assetDelete', id: assetId });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const after = await getAllAssets({}, { headers: asBearerAuth(admin.accessToken) });
 | 
					      const after = await getAllAssets({}, { headers: asBearerAuth(admin.accessToken) });
 | 
				
			||||||
      expect(after.length).toBe(0);
 | 
					      expect(after.length).toBe(0);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,27 +1,37 @@
 | 
				
			|||||||
import { LoginResponseDto, deleteUser, getUserById } from '@immich/sdk';
 | 
					import { LoginResponseDto, deleteUser, getUserById } from '@immich/sdk';
 | 
				
			||||||
 | 
					import { Socket } from 'socket.io-client';
 | 
				
			||||||
import { createUserDto, userDto } from 'src/fixtures';
 | 
					import { createUserDto, userDto } from 'src/fixtures';
 | 
				
			||||||
import { errorDto } from 'src/responses';
 | 
					import { errorDto } from 'src/responses';
 | 
				
			||||||
import { app, asBearerAuth, utils } from 'src/utils';
 | 
					import { app, asBearerAuth, utils } from 'src/utils';
 | 
				
			||||||
import request from 'supertest';
 | 
					import request from 'supertest';
 | 
				
			||||||
import { beforeAll, describe, expect, it } from 'vitest';
 | 
					import { afterAll, beforeAll, describe, expect, it } from 'vitest';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('/user', () => {
 | 
				
			||||||
 | 
					  let websocket: Socket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('/server-info', () => {
 | 
					 | 
				
			||||||
  let admin: LoginResponseDto;
 | 
					  let admin: LoginResponseDto;
 | 
				
			||||||
  let deletedUser: LoginResponseDto;
 | 
					  let deletedUser: LoginResponseDto;
 | 
				
			||||||
  let userToDelete: LoginResponseDto;
 | 
					  let userToDelete: LoginResponseDto;
 | 
				
			||||||
 | 
					  let userToHardDelete: LoginResponseDto;
 | 
				
			||||||
  let nonAdmin: LoginResponseDto;
 | 
					  let nonAdmin: LoginResponseDto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  beforeAll(async () => {
 | 
					  beforeAll(async () => {
 | 
				
			||||||
    await utils.resetDatabase();
 | 
					    await utils.resetDatabase();
 | 
				
			||||||
    admin = await utils.adminSetup({ onboarding: false });
 | 
					    admin = await utils.adminSetup({ onboarding: false });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [deletedUser, nonAdmin, userToDelete] = await Promise.all([
 | 
					    [websocket, deletedUser, nonAdmin, userToDelete, userToHardDelete] = await Promise.all([
 | 
				
			||||||
 | 
					      utils.connectWebsocket(admin.accessToken),
 | 
				
			||||||
      utils.userSetup(admin.accessToken, createUserDto.user1),
 | 
					      utils.userSetup(admin.accessToken, createUserDto.user1),
 | 
				
			||||||
      utils.userSetup(admin.accessToken, createUserDto.user2),
 | 
					      utils.userSetup(admin.accessToken, createUserDto.user2),
 | 
				
			||||||
      utils.userSetup(admin.accessToken, createUserDto.user3),
 | 
					      utils.userSetup(admin.accessToken, createUserDto.user3),
 | 
				
			||||||
 | 
					      utils.userSetup(admin.accessToken, createUserDto.user4),
 | 
				
			||||||
    ]);
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await deleteUser({ id: deletedUser.userId }, { headers: asBearerAuth(admin.accessToken) });
 | 
					    await deleteUser({ id: deletedUser.userId, deleteUserDto: {} }, { headers: asBearerAuth(admin.accessToken) });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  afterAll(() => {
 | 
				
			||||||
 | 
					    utils.disconnectWebsocket(websocket);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe('GET /user', () => {
 | 
					  describe('GET /user', () => {
 | 
				
			||||||
@ -34,13 +44,14 @@ describe('/server-info', () => {
 | 
				
			|||||||
    it('should get users', async () => {
 | 
					    it('should get users', async () => {
 | 
				
			||||||
      const { status, body } = await request(app).get('/user').set('Authorization', `Bearer ${admin.accessToken}`);
 | 
					      const { status, body } = await request(app).get('/user').set('Authorization', `Bearer ${admin.accessToken}`);
 | 
				
			||||||
      expect(status).toEqual(200);
 | 
					      expect(status).toEqual(200);
 | 
				
			||||||
      expect(body).toHaveLength(4);
 | 
					      expect(body).toHaveLength(5);
 | 
				
			||||||
      expect(body).toEqual(
 | 
					      expect(body).toEqual(
 | 
				
			||||||
        expect.arrayContaining([
 | 
					        expect.arrayContaining([
 | 
				
			||||||
          expect.objectContaining({ email: 'admin@immich.cloud' }),
 | 
					          expect.objectContaining({ email: 'admin@immich.cloud' }),
 | 
				
			||||||
          expect.objectContaining({ email: 'user1@immich.cloud' }),
 | 
					          expect.objectContaining({ email: 'user1@immich.cloud' }),
 | 
				
			||||||
          expect.objectContaining({ email: 'user2@immich.cloud' }),
 | 
					          expect.objectContaining({ email: 'user2@immich.cloud' }),
 | 
				
			||||||
          expect.objectContaining({ email: 'user3@immich.cloud' }),
 | 
					          expect.objectContaining({ email: 'user3@immich.cloud' }),
 | 
				
			||||||
 | 
					          expect.objectContaining({ email: 'user4@immich.cloud' }),
 | 
				
			||||||
        ]),
 | 
					        ]),
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@ -51,12 +62,13 @@ describe('/server-info', () => {
 | 
				
			|||||||
        .query({ isAll: true })
 | 
					        .query({ isAll: true })
 | 
				
			||||||
        .set('Authorization', `Bearer ${admin.accessToken}`);
 | 
					        .set('Authorization', `Bearer ${admin.accessToken}`);
 | 
				
			||||||
      expect(status).toBe(200);
 | 
					      expect(status).toBe(200);
 | 
				
			||||||
      expect(body).toHaveLength(3);
 | 
					      expect(body).toHaveLength(4);
 | 
				
			||||||
      expect(body).toEqual(
 | 
					      expect(body).toEqual(
 | 
				
			||||||
        expect.arrayContaining([
 | 
					        expect.arrayContaining([
 | 
				
			||||||
          expect.objectContaining({ email: 'admin@immich.cloud' }),
 | 
					          expect.objectContaining({ email: 'admin@immich.cloud' }),
 | 
				
			||||||
          expect.objectContaining({ email: 'user2@immich.cloud' }),
 | 
					          expect.objectContaining({ email: 'user2@immich.cloud' }),
 | 
				
			||||||
          expect.objectContaining({ email: 'user3@immich.cloud' }),
 | 
					          expect.objectContaining({ email: 'user3@immich.cloud' }),
 | 
				
			||||||
 | 
					          expect.objectContaining({ email: 'user4@immich.cloud' }),
 | 
				
			||||||
        ]),
 | 
					        ]),
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@ -68,13 +80,14 @@ describe('/server-info', () => {
 | 
				
			|||||||
        .set('Authorization', `Bearer ${admin.accessToken}`);
 | 
					        .set('Authorization', `Bearer ${admin.accessToken}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(status).toBe(200);
 | 
					      expect(status).toBe(200);
 | 
				
			||||||
      expect(body).toHaveLength(4);
 | 
					      expect(body).toHaveLength(5);
 | 
				
			||||||
      expect(body).toEqual(
 | 
					      expect(body).toEqual(
 | 
				
			||||||
        expect.arrayContaining([
 | 
					        expect.arrayContaining([
 | 
				
			||||||
          expect.objectContaining({ email: 'admin@immich.cloud' }),
 | 
					          expect.objectContaining({ email: 'admin@immich.cloud' }),
 | 
				
			||||||
          expect.objectContaining({ email: 'user1@immich.cloud' }),
 | 
					          expect.objectContaining({ email: 'user1@immich.cloud' }),
 | 
				
			||||||
          expect.objectContaining({ email: 'user2@immich.cloud' }),
 | 
					          expect.objectContaining({ email: 'user2@immich.cloud' }),
 | 
				
			||||||
          expect.objectContaining({ email: 'user3@immich.cloud' }),
 | 
					          expect.objectContaining({ email: 'user3@immich.cloud' }),
 | 
				
			||||||
 | 
					          expect.objectContaining({ email: 'user4@immich.cloud' }),
 | 
				
			||||||
        ]),
 | 
					        ]),
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@ -138,13 +151,13 @@ describe('/server-info', () => {
 | 
				
			|||||||
        .post(`/user`)
 | 
					        .post(`/user`)
 | 
				
			||||||
        .send({
 | 
					        .send({
 | 
				
			||||||
          isAdmin: true,
 | 
					          isAdmin: true,
 | 
				
			||||||
          email: 'user4@immich.cloud',
 | 
					          email: 'user5@immich.cloud',
 | 
				
			||||||
          password: 'password123',
 | 
					          password: 'password123',
 | 
				
			||||||
          name: 'Immich',
 | 
					          name: 'Immich',
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .set('Authorization', `Bearer ${admin.accessToken}`);
 | 
					        .set('Authorization', `Bearer ${admin.accessToken}`);
 | 
				
			||||||
      expect(body).toMatchObject({
 | 
					      expect(body).toMatchObject({
 | 
				
			||||||
        email: 'user4@immich.cloud',
 | 
					        email: 'user5@immich.cloud',
 | 
				
			||||||
        isAdmin: false,
 | 
					        isAdmin: false,
 | 
				
			||||||
        shouldChangePassword: true,
 | 
					        shouldChangePassword: true,
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
@ -188,6 +201,22 @@ describe('/server-info', () => {
 | 
				
			|||||||
        deletedAt: expect.any(String),
 | 
					        deletedAt: expect.any(String),
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('should hard delete user', async () => {
 | 
				
			||||||
 | 
					      const { status, body } = await request(app)
 | 
				
			||||||
 | 
					        .delete(`/user/${userToHardDelete.userId}`)
 | 
				
			||||||
 | 
					        .send({ force: true })
 | 
				
			||||||
 | 
					        .set('Authorization', `Bearer ${admin.accessToken}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(status).toBe(200);
 | 
				
			||||||
 | 
					      expect(body).toMatchObject({
 | 
				
			||||||
 | 
					        id: userToHardDelete.userId,
 | 
				
			||||||
 | 
					        updatedAt: expect.any(String),
 | 
				
			||||||
 | 
					        deletedAt: expect.any(String),
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await utils.waitForWebsocketEvent({ event: 'userDelete', id: userToHardDelete.userId, timeout: 5000 });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe('PUT /user', () => {
 | 
					  describe('PUT /user', () => {
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,7 @@ export const createUserDto = {
 | 
				
			|||||||
  create(key: string) {
 | 
					  create(key: string) {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      email: `${key}@immich.cloud`,
 | 
					      email: `${key}@immich.cloud`,
 | 
				
			||||||
      name: `User ${key}`,
 | 
					      name: `Generated User ${key}`,
 | 
				
			||||||
      password: `password-${key}`,
 | 
					      password: `password-${key}`,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
@ -43,6 +43,11 @@ export const createUserDto = {
 | 
				
			|||||||
    name: 'User 3',
 | 
					    name: 'User 3',
 | 
				
			||||||
    password: 'password123',
 | 
					    password: 'password123',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  user4: {
 | 
				
			||||||
 | 
					    email: 'user4@immich.cloud',
 | 
				
			||||||
 | 
					    name: 'User 4',
 | 
				
			||||||
 | 
					    password: 'password123',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  userQuota: {
 | 
					  userQuota: {
 | 
				
			||||||
    email: 'user-quota@immich.cloud',
 | 
					    email: 'user-quota@immich.cloud',
 | 
				
			||||||
    name: 'User Quota',
 | 
					    name: 'User Quota',
 | 
				
			||||||
 | 
				
			|||||||
@ -36,8 +36,8 @@ import { makeRandomImage } from 'src/generators';
 | 
				
			|||||||
import request from 'supertest';
 | 
					import request from 'supertest';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CliResponse = { stdout: string; stderr: string; exitCode: number | null };
 | 
					type CliResponse = { stdout: string; stderr: string; exitCode: number | null };
 | 
				
			||||||
type EventType = 'upload' | 'delete';
 | 
					type EventType = 'assetUpload' | 'assetDelete' | 'userDelete';
 | 
				
			||||||
type WaitOptions = { event: EventType; assetId: string; timeout?: number };
 | 
					type WaitOptions = { event: EventType; id: string; timeout?: number };
 | 
				
			||||||
type AdminSetupOptions = { onboarding?: boolean };
 | 
					type AdminSetupOptions = { onboarding?: boolean };
 | 
				
			||||||
type AssetData = { bytes?: Buffer; filename: string };
 | 
					type AssetData = { bytes?: Buffer; filename: string };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,20 +78,21 @@ export const immichCli = async (args: string[]) => {
 | 
				
			|||||||
let client: pg.Client | null = null;
 | 
					let client: pg.Client | null = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const events: Record<EventType, Set<string>> = {
 | 
					const events: Record<EventType, Set<string>> = {
 | 
				
			||||||
  upload: new Set<string>(),
 | 
					  assetUpload: new Set<string>(),
 | 
				
			||||||
  delete: new Set<string>(),
 | 
					  assetDelete: new Set<string>(),
 | 
				
			||||||
 | 
					  userDelete: new Set<string>(),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const callbacks: Record<string, () => void> = {};
 | 
					const callbacks: Record<string, () => void> = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const execPromise = promisify(exec);
 | 
					const execPromise = promisify(exec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const onEvent = ({ event, assetId }: { event: EventType; assetId: string }) => {
 | 
					const onEvent = ({ event, id }: { event: EventType; id: string }) => {
 | 
				
			||||||
  events[event].add(assetId);
 | 
					  events[event].add(id);
 | 
				
			||||||
  const callback = callbacks[assetId];
 | 
					  const callback = callbacks[id];
 | 
				
			||||||
  if (callback) {
 | 
					  if (callback) {
 | 
				
			||||||
    callback();
 | 
					    callback();
 | 
				
			||||||
    delete callbacks[assetId];
 | 
					    delete callbacks[id];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -166,8 +167,9 @@ export const utils = {
 | 
				
			|||||||
    return new Promise<Socket>((resolve) => {
 | 
					    return new Promise<Socket>((resolve) => {
 | 
				
			||||||
      websocket
 | 
					      websocket
 | 
				
			||||||
        .on('connect', () => resolve(websocket))
 | 
					        .on('connect', () => resolve(websocket))
 | 
				
			||||||
        .on('on_upload_success', (data: AssetResponseDto) => onEvent({ event: 'upload', assetId: data.id }))
 | 
					        .on('on_upload_success', (data: AssetResponseDto) => onEvent({ event: 'assetUpload', id: data.id }))
 | 
				
			||||||
        .on('on_asset_delete', (assetId: string) => onEvent({ event: 'delete', assetId }))
 | 
					        .on('on_asset_delete', (assetId: string) => onEvent({ event: 'assetDelete', id: assetId }))
 | 
				
			||||||
 | 
					        .on('on_user_delete', (userId: string) => onEvent({ event: 'userDelete', id: userId }))
 | 
				
			||||||
        .connect();
 | 
					        .connect();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
@ -182,17 +184,17 @@ export const utils = {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  waitForWebsocketEvent: async ({ event, assetId, timeout: ms }: WaitOptions): Promise<void> => {
 | 
					  waitForWebsocketEvent: async ({ event, id, timeout: ms }: WaitOptions): Promise<void> => {
 | 
				
			||||||
    console.log(`Waiting for ${event} [${assetId}]`);
 | 
					    console.log(`Waiting for ${event} [${id}]`);
 | 
				
			||||||
    const set = events[event];
 | 
					    const set = events[event];
 | 
				
			||||||
    if (set.has(assetId)) {
 | 
					    if (set.has(id)) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return new Promise<void>((resolve, reject) => {
 | 
					    return new Promise<void>((resolve, reject) => {
 | 
				
			||||||
      const timeout = setTimeout(() => reject(new Error(`Timed out waiting for ${event} event`)), ms || 10_000);
 | 
					      const timeout = setTimeout(() => reject(new Error(`Timed out waiting for ${event} event`)), ms || 10_000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      callbacks[assetId] = () => {
 | 
					      callbacks[id] = () => {
 | 
				
			||||||
        clearTimeout(timeout);
 | 
					        clearTimeout(timeout);
 | 
				
			||||||
        resolve();
 | 
					        resolve();
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user