diff --git a/apps/api/src/controllers/event.controller.ts b/apps/api/src/controllers/event.controller.ts index 4d31c034..cb9f3597 100644 --- a/apps/api/src/controllers/event.controller.ts +++ b/apps/api/src/controllers/event.controller.ts @@ -5,7 +5,7 @@ import { getSalts } from '@openpanel/db'; import { getEventsGroupQueueShard } from '@openpanel/queue'; import type { PostEventPayload } from '@openpanel/sdk'; -import { generateId } from '@openpanel/common'; +import { generateId, slug } from '@openpanel/common'; import { getGeoLocation } from '@openpanel/geo'; import { getStringHeaders, getTimestamp } from './track.controller'; @@ -54,7 +54,7 @@ export async function postEvent( : `${projectId}:${generateId()}` : currentDeviceId; const jobId = [ - request.body.name, + slug(request.body.name), timestamp, projectId, currentDeviceId, diff --git a/apps/api/src/controllers/track.controller.ts b/apps/api/src/controllers/track.controller.ts index b3feb5ef..b5d00528 100644 --- a/apps/api/src/controllers/track.controller.ts +++ b/apps/api/src/controllers/track.controller.ts @@ -1,7 +1,7 @@ import type { FastifyReply, FastifyRequest } from 'fastify'; import { assocPath, pathOr, pick } from 'ramda'; -import { generateId } from '@openpanel/common'; +import { generateId, slug } from '@openpanel/common'; import { generateDeviceId, parseUserAgent } from '@openpanel/common/server'; import { getProfileById, getSalts, upsertProfile } from '@openpanel/db'; import { type GeoLocation, getGeoLocation } from '@openpanel/geo'; @@ -254,7 +254,13 @@ async function track({ ? `${projectId}:${payload.profileId}` : `${projectId}:${generateId()}` : currentDeviceId; - const jobId = [payload.name, timestamp, projectId, currentDeviceId, groupId] + const jobId = [ + slug(payload.name), + timestamp, + projectId, + currentDeviceId, + groupId, + ] .filter(Boolean) .join('-'); await getEventsGroupQueueShard(groupId).add({ diff --git a/packages/common/src/slug.test.ts b/packages/common/src/slug.test.ts new file mode 100644 index 00000000..49bf92e0 --- /dev/null +++ b/packages/common/src/slug.test.ts @@ -0,0 +1,10 @@ +import { describe, expect, it } from 'vitest'; +import { slug } from './slug'; + +describe('slug', () => { + it('should remove pipes from string', () => { + expect(slug('Hello || World, | Test å å ä ä')).toBe( + 'hello-world-test-a-a-a-a', + ); + }); +}); diff --git a/packages/common/src/slug.ts b/packages/common/src/slug.ts index f93bae73..dcb51481 100644 --- a/packages/common/src/slug.ts +++ b/packages/common/src/slug.ts @@ -3,12 +3,13 @@ import _slugify from 'slugify'; const slugify = (str: string) => { return _slugify( str - .replace('å', 'a') - .replace('ä', 'a') - .replace('ö', 'o') - .replace('Å', 'A') - .replace('Ä', 'A') - .replace('Ö', 'O'), + .replaceAll('å', 'a') + .replaceAll('ä', 'a') + .replaceAll('ö', 'o') + .replaceAll('Å', 'A') + .replaceAll('Ä', 'A') + .replaceAll('Ö', 'O') + .replace(/\|+/g, '-'), { lower: true, strict: true, trim: true }, ); };