fix: better validation of events + clean up (#267)
This commit is contained in:
@@ -3,6 +3,11 @@ import { differenceInDays, isSameDay, isSameMonth } from 'date-fns';
|
||||
export const DEFAULT_ASPECT_RATIO = 0.5625;
|
||||
export const NOT_SET_VALUE = '(not set)';
|
||||
|
||||
export const RESERVED_EVENT_NAMES = [
|
||||
'session_start',
|
||||
'session_end',
|
||||
] as const;
|
||||
|
||||
export const timeWindows = {
|
||||
'30min': {
|
||||
key: '30min',
|
||||
|
||||
@@ -8,6 +8,13 @@ export type ILogger = winston.Logger;
|
||||
const logLevel = process.env.LOG_LEVEL ?? 'info';
|
||||
const silent = process.env.LOG_SILENT === 'true';
|
||||
|
||||
// Add colors for custom levels (fatal, warn, trace) that aren't in default color schemes
|
||||
winston.addColors({
|
||||
fatal: 'red',
|
||||
warn: 'yellow',
|
||||
trace: 'gray',
|
||||
});
|
||||
|
||||
export function createLogger({ name }: { name: string }): ILogger {
|
||||
const service = [process.env.LOG_PREFIX, name, process.env.NODE_ENV ?? 'dev']
|
||||
.filter(Boolean)
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
"groupmq": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@openpanel/sdk": "workspace:*",
|
||||
"@openpanel/tsconfig": "workspace:*",
|
||||
"@types/node": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
|
||||
@@ -8,8 +8,8 @@ import type {
|
||||
} from '@openpanel/db';
|
||||
import { createLogger } from '@openpanel/logger';
|
||||
import { getRedisGroupQueue, getRedisQueue } from '@openpanel/redis';
|
||||
import type { TrackPayload } from '@openpanel/sdk';
|
||||
import { Queue as GroupQueue } from 'groupmq';
|
||||
import type { ITrackPayload } from '../../validation';
|
||||
|
||||
export const EVENTS_GROUP_QUEUES_SHARDS = Number.parseInt(
|
||||
process.env.EVENTS_GROUP_QUEUES_SHARDS || '1',
|
||||
@@ -32,7 +32,7 @@ export interface EventsQueuePayloadIncomingEvent {
|
||||
type: 'incomingEvent';
|
||||
payload: {
|
||||
projectId: string;
|
||||
event: TrackPayload & {
|
||||
event: ITrackPayload & {
|
||||
timestamp: string | number;
|
||||
isTimestampFromThePast: boolean;
|
||||
};
|
||||
|
||||
@@ -1,36 +1 @@
|
||||
export * from './src/index';
|
||||
|
||||
// Deprecated types for beta version of the SDKs
|
||||
// Still used in api/event.controller.ts and api/profile.controller.ts
|
||||
|
||||
export interface OpenpanelEventOptions {
|
||||
profileId?: string;
|
||||
}
|
||||
|
||||
export interface PostEventPayload {
|
||||
name: string;
|
||||
timestamp: string;
|
||||
profileId?: string;
|
||||
properties?: Record<string, unknown> & OpenpanelEventOptions;
|
||||
}
|
||||
|
||||
export interface UpdateProfilePayload {
|
||||
profileId: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
email?: string;
|
||||
avatar?: string;
|
||||
properties?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface IncrementProfilePayload {
|
||||
profileId: string;
|
||||
property: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export interface DecrementProfilePayload {
|
||||
profileId?: string;
|
||||
property: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@openpanel/tsconfig": "workspace:*",
|
||||
"@openpanel/validation": "workspace:*",
|
||||
"@types/node": "catalog:",
|
||||
"tsup": "^7.2.0",
|
||||
"typescript": "catalog:"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,20 @@
|
||||
import type {
|
||||
IAliasPayload as AliasPayload,
|
||||
IDecrementPayload as DecrementPayload,
|
||||
IIdentifyPayload as IdentifyPayload,
|
||||
IIncrementPayload as IncrementPayload,
|
||||
ITrackHandlerPayload as TrackHandlerPayload,
|
||||
ITrackPayload as TrackPayload,
|
||||
} from '@openpanel/validation';
|
||||
import { Api } from './api';
|
||||
|
||||
export type TrackHandlerPayload =
|
||||
| {
|
||||
type: 'track';
|
||||
payload: TrackPayload;
|
||||
}
|
||||
| {
|
||||
type: 'increment';
|
||||
payload: IncrementPayload;
|
||||
}
|
||||
| {
|
||||
type: 'decrement';
|
||||
payload: DecrementPayload;
|
||||
}
|
||||
| {
|
||||
type: 'alias';
|
||||
payload: AliasPayload;
|
||||
}
|
||||
| {
|
||||
type: 'identify';
|
||||
payload: IdentifyPayload;
|
||||
};
|
||||
|
||||
export type TrackPayload = {
|
||||
name: string;
|
||||
properties?: Record<string, unknown>;
|
||||
profileId?: string;
|
||||
export type {
|
||||
AliasPayload,
|
||||
DecrementPayload,
|
||||
IdentifyPayload,
|
||||
IncrementPayload,
|
||||
TrackHandlerPayload,
|
||||
TrackPayload,
|
||||
};
|
||||
|
||||
export type TrackProperties = {
|
||||
@@ -33,32 +22,6 @@ export type TrackProperties = {
|
||||
profileId?: string;
|
||||
};
|
||||
|
||||
export type IdentifyPayload = {
|
||||
profileId: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
email?: string;
|
||||
avatar?: string;
|
||||
properties?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type AliasPayload = {
|
||||
profileId: string;
|
||||
alias: string;
|
||||
};
|
||||
|
||||
export type IncrementPayload = {
|
||||
profileId: string;
|
||||
property: string;
|
||||
value?: number;
|
||||
};
|
||||
|
||||
export type DecrementPayload = {
|
||||
profileId: string;
|
||||
property: string;
|
||||
value?: number;
|
||||
};
|
||||
|
||||
export type OpenPanelOptions = {
|
||||
clientId: string;
|
||||
clientSecret?: string;
|
||||
|
||||
@@ -555,3 +555,4 @@ export const zCreateImport = z.object({
|
||||
export type ICreateImport = z.infer<typeof zCreateImport>;
|
||||
|
||||
export * from './types.insights';
|
||||
export * from './track.validation';
|
||||
|
||||
104
packages/validation/src/track.validation.ts
Normal file
104
packages/validation/src/track.validation.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { RESERVED_EVENT_NAMES } from '@openpanel/constants';
|
||||
|
||||
export const zTrackPayload = z
|
||||
.object({
|
||||
name: z.string().min(1),
|
||||
properties: z.record(z.unknown()).optional(),
|
||||
profileId: z.string().optional(),
|
||||
})
|
||||
.refine((data) => !RESERVED_EVENT_NAMES.includes(data.name as any), {
|
||||
message: `Event name cannot be one of the reserved names: ${RESERVED_EVENT_NAMES.join(', ')}`,
|
||||
path: ['name'],
|
||||
});
|
||||
|
||||
export const zIdentifyPayload = z.object({
|
||||
profileId: z.string().min(1),
|
||||
firstName: z.string().optional(),
|
||||
lastName: z.string().optional(),
|
||||
email: z.string().email().optional(),
|
||||
avatar: z.string().url().optional(),
|
||||
properties: z.record(z.unknown()).optional(),
|
||||
});
|
||||
|
||||
export const zIncrementPayload = z.object({
|
||||
profileId: z.string().min(1),
|
||||
property: z.string().min(1),
|
||||
value: z.number().positive().optional(),
|
||||
});
|
||||
|
||||
export const zDecrementPayload = z.object({
|
||||
profileId: z.string().min(1),
|
||||
property: z.string().min(1),
|
||||
value: z.number().positive().optional(),
|
||||
});
|
||||
|
||||
export const zAliasPayload = z.object({
|
||||
profileId: z.string().min(1),
|
||||
alias: z.string().min(1),
|
||||
});
|
||||
|
||||
export const zTrackHandlerPayload = z.discriminatedUnion('type', [
|
||||
z.object({
|
||||
type: z.literal('track'),
|
||||
payload: zTrackPayload,
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal('identify'),
|
||||
payload: zIdentifyPayload,
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal('increment'),
|
||||
payload: zIncrementPayload,
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal('decrement'),
|
||||
payload: zDecrementPayload,
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal('alias'),
|
||||
payload: zAliasPayload,
|
||||
}),
|
||||
]);
|
||||
|
||||
export type ITrackPayload = z.infer<typeof zTrackPayload>;
|
||||
export type IIdentifyPayload = z.infer<typeof zIdentifyPayload>;
|
||||
export type IIncrementPayload = z.infer<typeof zIncrementPayload>;
|
||||
export type IDecrementPayload = z.infer<typeof zDecrementPayload>;
|
||||
export type IAliasPayload = z.infer<typeof zAliasPayload>;
|
||||
export type ITrackHandlerPayload = z.infer<typeof zTrackHandlerPayload>;
|
||||
|
||||
// Deprecated types for beta version of the SDKs
|
||||
|
||||
export interface DeprecatedOpenpanelEventOptions {
|
||||
profileId?: string;
|
||||
}
|
||||
|
||||
export interface DeprecatedPostEventPayload {
|
||||
name: string;
|
||||
timestamp: string;
|
||||
profileId?: string;
|
||||
properties?: Record<string, unknown> & DeprecatedOpenpanelEventOptions;
|
||||
}
|
||||
|
||||
export interface DeprecatedUpdateProfilePayload {
|
||||
profileId: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
email?: string;
|
||||
avatar?: string;
|
||||
properties?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface DeprecatedIncrementProfilePayload {
|
||||
profileId: string;
|
||||
property: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export interface DeprecatedDecrementProfilePayload {
|
||||
profileId?: string;
|
||||
property: string;
|
||||
value: number;
|
||||
}
|
||||
Reference in New Issue
Block a user