From 1b5a61f190addbc0d04f77a1d102bfde6b1fadd4 Mon Sep 17 00:00:00 2001 From: Julian Labeit Date: Mon, 6 Oct 2025 15:57:39 +0200 Subject: [PATCH 1/2] feat(ids): allow two different hashing functions --- src/generators/typescripts.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/generators/typescripts.ts b/src/generators/typescripts.ts index eb5522b..dce17da 100644 --- a/src/generators/typescripts.ts +++ b/src/generators/typescripts.ts @@ -28,7 +28,7 @@ export const generate = async (events: EventSchema[], serverSide: boolean): Prom const shouldParamsBeOptional = !Object.keys(event.schemaJson.properties ?? {}).length // eslint-disable-next-line max-len if (serverSide) { - return `${params}\n${formatDescription(event)}export const ${functionName} = async (userId: string, properties${shouldParamsBeOptional ? '?' : ''}: ${interfaceName}) => mixpanel?.track('${event.name}', { distinct_id: await sha256(userId), ...properties })` + return `${params}\n${formatDescription(event)}export const ${functionName} = async (userId: string, properties${shouldParamsBeOptional ? '?' : ''}: ${interfaceName}, isDriver = false) => mixpanel?.track('${event.name}', { distinct_id: await isDriver ? driverHash(userId) : dispatcherHash(userId), ...properties })` } // eslint-disable-next-line max-len return `${params}\n${formatDescription(event)}export const ${functionName} = (properties${shouldParamsBeOptional ? '?' : ''}: ${interfaceName}) => mixpanel.track('${event.name}', properties)` @@ -41,10 +41,16 @@ let mixpanel: Mixpanel.Mixpanel | undefined export const initMixpanel = (token: string) => { mixpanel = Mixpanel.init(token) } -const sha256 = async (str: string): Promise => { +const dispatcherHash = async (str: string): Promise => { const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(str)) return Array.prototype.map.call(new Uint8Array(buf), x => (('00' + x.toString(16)).slice(-2))).join('').slice(0, 16) } +const driverHash = async (str: string): Promise => { + const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(str)) + return Array.from(new Uint8Array(buf)) + .map(x => x.toString(16).padStart(2, "0")) + .join("") +} ${formattedEvents.join('\n\n')}` } return ` From e1780a8a39a3d808d2bd3db5715ea373f27f2fae Mon Sep 17 00:00:00 2001 From: Julian Labeit Date: Tue, 7 Oct 2025 15:02:32 +0200 Subject: [PATCH 2/2] fix(typescript): correct server side tracking --- src/generators/typescripts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generators/typescripts.ts b/src/generators/typescripts.ts index dce17da..57c5d01 100644 --- a/src/generators/typescripts.ts +++ b/src/generators/typescripts.ts @@ -28,7 +28,7 @@ export const generate = async (events: EventSchema[], serverSide: boolean): Prom const shouldParamsBeOptional = !Object.keys(event.schemaJson.properties ?? {}).length // eslint-disable-next-line max-len if (serverSide) { - return `${params}\n${formatDescription(event)}export const ${functionName} = async (userId: string, properties${shouldParamsBeOptional ? '?' : ''}: ${interfaceName}, isDriver = false) => mixpanel?.track('${event.name}', { distinct_id: await isDriver ? driverHash(userId) : dispatcherHash(userId), ...properties })` + return `${params}\n${formatDescription(event)}export const ${functionName} = async (userId: string, properties${shouldParamsBeOptional ? '?' : ''}: ${interfaceName}, isDriver = false) => mixpanel?.track('${event.name}', { distinct_id: isDriver ? await driverHash(userId) : await dispatcherHash(userId), ...properties })` } // eslint-disable-next-line max-len return `${params}\n${formatDescription(event)}export const ${functionName} = (properties${shouldParamsBeOptional ? '?' : ''}: ${interfaceName}) => mixpanel.track('${event.name}', properties)`