diff --git a/README.md b/README.md index c8fa9487..d32ca5ad 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,6 @@ -

- -

+# openpanel -# mixan - -Mixan is a simple analytics tool for logging events on web and react-native. My goal is to make a minimal mixpanel copy with the most basic features (for now). +Openpanel is a simple analytics tool for logging events on web and react-native. My goal is to make a minimal mixpanel copy with the most basic features (for now). - Easy to use - Fully responsive UI @@ -71,24 +67,24 @@ As of today (~~2023-12-12~~ 2024-01-16) I have more then ~~1.2~~ 2.8 million eve - [x] Create web sdk - [x] Screen view function should take in title, path and parse query string (especially utm tags) -## @mixan/sdk +## @openpanel/sdk For pushing events ### Install -- npm: `npm install @mixan/sdk` -- pnpm: `pnpm add @mixan/sdk` -- yarn: `yarn add @mixan/sdk` +- npm: `npm install @openpanel/sdk` +- pnpm: `pnpm add @openpanel/sdk` +- yarn: `yarn add @openpanel/sdk` ### Usage ```ts -import { MixanWeb } from '@mixan/web'; +import { OpenpanelWeb } from '@openpanel/web'; -// import { MixanNative } from '@mixan/sdk-native'; +// import { OpenpanelNative } from '@openpanel/sdk-native'; -const mixan = new MixanWeb({ +const openpanel = new OpenpanelWeb({ clientId: 'uuid', url: 'http://localhost:8080/api/sdk', batchInterval: 10000, @@ -96,7 +92,7 @@ const mixan = new MixanWeb({ trackIp: true, }); -// const mixan = new MixanNative({ +// const openpanel = new OpenpanelNative({ // clientId: 'uuid', // clientSecret: 'uuid', // url: 'http://localhost:8080/api/sdk', @@ -108,12 +104,12 @@ const mixan = new MixanWeb({ // Call this before you send any events // It will create a anonymous profile // This profile will be merged if you call `setUser` in a later stage -mixan.init(); +openpanel.init(); // tracks all outgoing links as a `link_out` event -mixan.trackOutgoingLinks(); +openpanel.trackOutgoingLinks(); -mixan.setUser({ +openpanel.setUser({ id: 'id', first_name: 'John', last_name: 'Doe', @@ -122,25 +118,25 @@ mixan.setUser({ }); // will upsert 'app_open' on user property and increment it -mixan.increment('app_open'); +openpanel.increment('app_open'); // will upsert 'app_open' on user property and increment it by 10 -mixan.increment('app_open', 10); +openpanel.increment('app_open', 10); // will upsert 'app_open' on user property and decrement it by 2 -mixan.decrement('app_open', 2); +openpanel.decrement('app_open', 2); // send a sign_in event -mixan.event('sign_in'); +openpanel.event('sign_in'); // send a sign_in event with properties -mixan.event('sign_in', { +openpanel.event('sign_in', { provider: 'gmail', }); // Screen view for web -mixan.screenView(); +openpanel.screenView(); // Screen view for native -mixan.screenView('Article', { +openpanel.screenView('Article', { id: '3', title: 'Nice article here', }); @@ -148,10 +144,10 @@ mixan.screenView('Article', { // Call this when a user is logged out. // This will just make sure you do not send // the associated profile id for the next events -mixan.clear(); +openpanel.clear(); ``` -## @mixan/dashboard +## @openpanel/dashboard A nextjs web app. Collects all events and your gui to analyze your data. diff --git a/apps/api/package.json b/apps/api/package.json index 3c226a19..348016a3 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/api", + "name": "@openpanel/api", "version": "0.0.1", "scripts": { "dev": "dotenv -e ../../.env -c -v WATCH=1 tsup", @@ -14,10 +14,10 @@ "@fastify/cors": "^9.0.0", "@fastify/websocket": "^8.3.1", "@logtail/pino": "^0.4.19", - "@mixan/common": "workspace:*", - "@mixan/db": "workspace:*", - "@mixan/queue": "workspace:*", - "@mixan/redis": "workspace:*", + "@openpanel/common": "workspace:*", + "@openpanel/db": "workspace:*", + "@openpanel/queue": "workspace:*", + "@openpanel/redis": "workspace:*", "fastify": "^4.25.2", "ico-to-png": "^0.2.1", "pino": "^8.17.2", @@ -28,10 +28,10 @@ "uuid": "^9.0.1" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/sdk": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/sdk": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@types/ramda": "^0.29.6", "@types/ua-parser-js": "^0.7.39", "@types/uuid": "^9.0.8", @@ -44,8 +44,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/apps/api/scripts/test-events.ts b/apps/api/scripts/test-events.ts index 4fa0a234..06f12faf 100644 --- a/apps/api/scripts/test-events.ts +++ b/apps/api/scripts/test-events.ts @@ -1,44 +1,44 @@ -import { omit, prop, uniqBy } from 'ramda'; +import { omit, prop, uniqBy } from "ramda"; -import { generateProfileId, getTime, toISOString } from '@mixan/common'; -import type { Event, IServiceCreateEventPayload } from '@mixan/db'; +import { generateProfileId, getTime, toISOString } from "@openpanel/common"; +import type { Event, IServiceCreateEventPayload } from "@openpanel/db"; import { createEvent as createClickhouseEvent, db, formatClickhouseDate, getSalts, -} from '@mixan/db'; +} from "@openpanel/db"; -import { parseIp } from '../src/utils/parseIp'; -import { parseUserAgent } from '../src/utils/parseUserAgent'; +import { parseIp } from "../src/utils/parseIp"; +import { parseUserAgent } from "../src/utils/parseUserAgent"; const clean = omit([ - 'ip', - 'os', - 'ua', - 'url', - 'hash', - 'host', - 'path', - 'device', - 'screen', - 'hostname', - 'language', - 'referrer', - 'timezone', + "ip", + "os", + "ua", + "url", + "hash", + "host", + "path", + "device", + "screen", + "hostname", + "language", + "referrer", + "timezone", ]); async function main() { const events = await db.event.findMany({ where: { - project_id: '4e2798cb-e255-4e9d-960d-c9ad095aabd7', - name: 'screen_view', + project_id: "4e2798cb-e255-4e9d-960d-c9ad095aabd7", + name: "screen_view", createdAt: { - gte: new Date('2024-01-01'), - lt: new Date('2024-02-04'), + gte: new Date("2024-01-01"), + lt: new Date("2024-02-04"), }, }, orderBy: { - createdAt: 'asc', + createdAt: "asc", }, }); @@ -50,7 +50,7 @@ async function main() { const properties = event.properties as Record; - if (properties.ua?.includes('bot')) { + if (properties.ua?.includes("bot")) { // console.log('IGNORE', event.id); continue; } @@ -67,20 +67,20 @@ async function main() { } } - console.log('Total users', Object.keys(grouped).length); + console.log("Total users", Object.keys(grouped).length); let uidx = -1; for (const profile_id of Object.keys(grouped)) { uidx++; console.log(`User index ${uidx}`); - const events = uniqBy(prop('createdAt'), grouped[profile_id] || []); + const events = uniqBy(prop("createdAt"), grouped[profile_id] || []); if (events) { let lastSessionStart = null; let screenViews = 0; let totalDuration = 0; - console.log('new user...'); + console.log("new user..."); let eidx = -1; for (const event of events) { eidx++; @@ -93,7 +93,7 @@ async function main() { const projectId = event.project_id; const path = properties.path!; const ip = properties.ip!; - const origin = 'https://mixan.kiddo.se'; + const origin = "https://openpanel.kiddo.se"; const ua = properties.ua!; const uaInfo = parseUserAgent(ua); const salts = await getSalts(); @@ -133,8 +133,8 @@ async function main() { ? nextEvent.createdAt.getTime() - event.createdAt.getTime() : 0, path, - referrer: properties?.referrer?.host ?? '', // TODO - referrerName: properties?.referrer?.host ?? '', // TODO + referrer: properties?.referrer?.host ?? "", // TODO + referrerName: properties?.referrer?.host ?? "", // TODO }; if (!prevEventAt) { @@ -173,8 +173,8 @@ async function main() { async function createEvent(event: IServiceCreateEventPayload) { console.log( `Create ${event.name} - ${event.path} - ${formatClickhouseDate( - event.createdAt - )} - ${event.duration / 1000} sec` + event.createdAt, + )} - ${event.duration / 1000} sec`, ); await createClickhouseEvent(event); } @@ -183,7 +183,7 @@ async function createSessionStart(event: IServiceCreateEventPayload) { const session: IServiceCreateEventPayload = { ...event, duration: 0, - name: 'session_start', + name: "session_start", createdAt: toISOString(getTime(event.createdAt) - 100), }; @@ -197,7 +197,7 @@ async function createSessionEnd( options: { screenViews: number; totalDuration: number; - } + }, ) { const properties: Record = {}; if (options.screenViews === 1) { @@ -213,7 +213,7 @@ async function createSessionEnd( ...sessionStart.properties, }, duration: options.totalDuration, - name: 'session_end', + name: "session_end", createdAt: toISOString(prevEventAt.getTime() + 10), }; diff --git a/apps/api/src/controllers/event.controller.ts b/apps/api/src/controllers/event.controller.ts index d1fc64fc..3b49567f 100644 --- a/apps/api/src/controllers/event.controller.ts +++ b/apps/api/src/controllers/event.controller.ts @@ -1,19 +1,19 @@ -import { logger, logInfo, noop } from '@/utils/logger'; -import { getClientIp, parseIp } from '@/utils/parseIp'; -import { getReferrerWithQuery, parseReferrer } from '@/utils/parseReferrer'; -import { isUserAgentSet, parseUserAgent } from '@/utils/parseUserAgent'; -import { isSameDomain, parsePath } from '@/utils/url'; -import type { FastifyReply, FastifyRequest } from 'fastify'; -import { omit } from 'ramda'; -import { v4 as uuid } from 'uuid'; +import { logger, logInfo, noop } from "@/utils/logger"; +import { getClientIp, parseIp } from "@/utils/parseIp"; +import { getReferrerWithQuery, parseReferrer } from "@/utils/parseReferrer"; +import { isUserAgentSet, parseUserAgent } from "@/utils/parseUserAgent"; +import { isSameDomain, parsePath } from "@/utils/url"; +import type { FastifyReply, FastifyRequest } from "fastify"; +import { omit } from "ramda"; +import { v4 as uuid } from "uuid"; -import { generateDeviceId, getTime, toISOString } from '@mixan/common'; -import type { IServiceCreateEventPayload } from '@mixan/db'; -import { createEvent, getEvents, getSalts } from '@mixan/db'; -import type { JobsOptions } from '@mixan/queue'; -import { eventsQueue } from '@mixan/queue'; -import { findJobByPrefix } from '@mixan/queue/src/utils'; -import type { PostEventPayload } from '@mixan/sdk'; +import { generateDeviceId, getTime, toISOString } from "@openpanel/common"; +import type { IServiceCreateEventPayload } from "@openpanel/db"; +import { createEvent, getEvents, getSalts } from "@openpanel/db"; +import type { JobsOptions } from "@openpanel/queue"; +import { eventsQueue } from "@openpanel/queue"; +import { findJobByPrefix } from "@openpanel/queue/src/utils"; +import type { PostEventPayload } from "@openpanel/sdk"; const SESSION_TIMEOUT = 1000 * 60 * 30; const SESSION_END_TIMEOUT = SESSION_TIMEOUT + 1000; @@ -55,7 +55,7 @@ export async function postEvent( request: FastifyRequest<{ Body: PostEventPayload; }>, - reply: FastifyReply + reply: FastifyReply, ) { const contextLogger = createContextLogger(request); let deviceId: string | null = null; @@ -65,23 +65,23 @@ export async function postEvent( // replace thing is just for older sdks when we didn't have `__` // remove when kiddokitchen app (24.09.02) is not used anymore return ( - ((properties[name] || properties[name.replace('__', '')]) as + ((properties[name] || properties[name.replace("__", "")]) as | string | null | undefined) ?? undefined ); }; - const profileId = body.profileId ?? ''; + const profileId = body.profileId ?? ""; const createdAt = new Date(body.timestamp); - const url = getProperty('__path'); + const url = getProperty("__path"); const { path, hash, query } = parsePath(url); - const referrer = isSameDomain(getProperty('__referrer'), url) + const referrer = isSameDomain(getProperty("__referrer"), url) ? null - : parseReferrer(getProperty('__referrer')); + : parseReferrer(getProperty("__referrer")); const utmReferrer = getReferrerWithQuery(query); const ip = getClientIp(request)!; const origin = request.headers.origin!; - const ua = request.headers['user-agent']!; + const ua = request.headers["user-agent"]!; const uaInfo = parseUserAgent(ua); const salts = await getSalts(); const currentDeviceId = generateDeviceId({ @@ -101,66 +101,66 @@ export async function postEvent( if (isServerEvent) { const [event] = await withTiming( - 'Get last event (server-event)', + "Get last event (server-event)", getEvents( - `SELECT * FROM events WHERE name = 'screen_view' AND profile_id = '${profileId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1` - ) + `SELECT * FROM events WHERE name = 'screen_view' AND profile_id = '${profileId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`, + ), ); - eventsQueue.add('event', { - type: 'createEvent', + eventsQueue.add("event", { + type: "createEvent", payload: { name: body.name, - deviceId: event?.deviceId || '', - sessionId: event?.sessionId || '', + deviceId: event?.deviceId || "", + sessionId: event?.sessionId || "", profileId, projectId, properties: Object.assign( {}, - omit(['__path', '__referrer'], properties), + omit(["__path", "__referrer"], properties), { hash, query, - } + }, ), createdAt, - country: event?.country ?? '', - city: event?.city ?? '', - region: event?.region ?? '', - continent: event?.continent ?? '', - os: event?.os ?? '', - osVersion: event?.osVersion ?? '', - browser: event?.browser ?? '', - browserVersion: event?.browserVersion ?? '', - device: event?.device ?? '', - brand: event?.brand ?? '', - model: event?.model ?? '', + country: event?.country ?? "", + city: event?.city ?? "", + region: event?.region ?? "", + continent: event?.continent ?? "", + os: event?.os ?? "", + osVersion: event?.osVersion ?? "", + browser: event?.browser ?? "", + browserVersion: event?.browserVersion ?? "", + device: event?.device ?? "", + brand: event?.brand ?? "", + model: event?.model ?? "", duration: 0, - path: event?.path ?? '', - referrer: event?.referrer ?? '', - referrerName: event?.referrerName ?? '', - referrerType: event?.referrerType ?? '', + path: event?.path ?? "", + referrer: event?.referrer ?? "", + referrerName: event?.referrerName ?? "", + referrerType: event?.referrerType ?? "", profile: undefined, meta: undefined, }, }); - return reply.status(200).send(''); + return reply.status(200).send(""); } const [geo, sessionEndJobCurrentDeviceId, sessionEndJobPreviousDeviceId] = await withTiming( - 'Get geo and jobs from queue', + "Get geo and jobs from queue", Promise.all([ parseIp(ip), findJobByPrefix( eventsQueue, - `sessionEnd:${projectId}:${currentDeviceId}:` + `sessionEnd:${projectId}:${currentDeviceId}:`, ), findJobByPrefix( eventsQueue, - `sessionEnd:${projectId}:${previousDeviceId}:` + `sessionEnd:${projectId}:${previousDeviceId}:`, ), - ]) + ]), ); const createSessionStart = @@ -178,9 +178,9 @@ export async function postEvent( deviceId = currentDeviceId; // Queue session end eventsQueue.add( - 'event', + "event", { - type: 'createSessionEnd', + type: "createSessionEnd", payload: { deviceId, }, @@ -188,27 +188,27 @@ export async function postEvent( { delay: SESSION_END_TIMEOUT, jobId: `sessionEnd:${projectId}:${deviceId}:${Date.now()}`, - } + }, ); } const [[sessionStartEvent], prevEventJob] = await withTiming( - 'Get session start event', + "Get session start event", Promise.all([ getEvents( - `SELECT * FROM events WHERE name = 'session_start' AND device_id = '${deviceId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1` + `SELECT * FROM events WHERE name = 'session_start' AND device_id = '${deviceId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`, ), findJobByPrefix(eventsQueue, `event:${projectId}:${deviceId}:`), - ]) + ]), ); - const payload: Omit = { + const payload: Omit = { name: body.name, deviceId, profileId, projectId, - sessionId: createSessionStart ? uuid() : sessionStartEvent?.sessionId ?? '', - properties: Object.assign({}, omit(['__path', '__referrer'], properties), { + sessionId: createSessionStart ? uuid() : sessionStartEvent?.sessionId ?? "", + properties: Object.assign({}, omit(["__path", "__referrer"], properties), { hash, query, }), @@ -227,27 +227,27 @@ export async function postEvent( duration: 0, path: path, referrer: referrer?.url, - referrerName: referrer?.name ?? utmReferrer?.name ?? '', - referrerType: referrer?.type ?? utmReferrer?.type ?? '', + referrerName: referrer?.name ?? utmReferrer?.name ?? "", + referrerType: referrer?.type ?? utmReferrer?.type ?? "", profile: undefined, meta: undefined, }; const isDelayed = prevEventJob ? await prevEventJob?.isDelayed() : false; - if (isDelayed && prevEventJob && prevEventJob.data.type === 'createEvent') { + if (isDelayed && prevEventJob && prevEventJob.data.type === "createEvent") { const prevEvent = prevEventJob.data.payload; const duration = getTime(payload.createdAt) - getTime(prevEvent.createdAt); - contextLogger.add('prevEvent', prevEvent); + contextLogger.add("prevEvent", prevEvent); // Set path from prev screen_view event if current event is not a screen_view - if (payload.name != 'screen_view') { + if (payload.name != "screen_view") { payload.path = prevEvent.path; } - if (payload.name === 'screen_view') { + if (payload.name === "screen_view") { if (duration < 0) { - contextLogger.send('duration is wrong', { + contextLogger.send("duration is wrong", { payload, duration, }); @@ -255,21 +255,21 @@ export async function postEvent( // Skip update duration if it's wrong // Seems like request is not in right order await withTiming( - 'Update previous job with duration', + "Update previous job with duration", prevEventJob.updateData({ - type: 'createEvent', + type: "createEvent", payload: { ...prevEvent, duration, }, - }) + }), ); } - await withTiming('Promote previous job', prevEventJob.promote()); + await withTiming("Promote previous job", prevEventJob.promote()); } - } else if (payload.name !== 'screen_view') { - contextLogger.send('no previous job', { + } else if (payload.name !== "screen_view") { + contextLogger.send("no previous job", { prevEventJob, payload, }); @@ -278,23 +278,23 @@ export async function postEvent( if (createSessionStart) { // We do not need to queue session_start await withTiming( - 'Create session start event', + "Create session start event", createEvent({ ...payload, - name: 'session_start', + name: "session_start", // @ts-expect-error createdAt: toISOString(getTime(payload.createdAt) - 100), - }) + }), ); } const options: JobsOptions = {}; - if (payload.name === 'screen_view') { + if (payload.name === "screen_view") { options.delay = SESSION_TIMEOUT; options.jobId = `event:${projectId}:${deviceId}:${Date.now()}`; } - contextLogger.send('event is queued', { + contextLogger.send("event is queued", { ip, origin, ua, @@ -312,14 +312,14 @@ export async function postEvent( // Queue current event eventsQueue .add( - 'event', + "event", { - type: 'createEvent', + type: "createEvent", payload, }, - options + options, ) - .catch(noop('Failed to queue event')); + .catch(noop("Failed to queue event")); reply.status(202).send(deviceId); } diff --git a/apps/api/src/controllers/live.controller.ts b/apps/api/src/controllers/live.controller.ts index 3949218b..08db054e 100644 --- a/apps/api/src/controllers/live.controller.ts +++ b/apps/api/src/controllers/live.controller.ts @@ -1,13 +1,13 @@ -import type { FastifyReply, FastifyRequest } from 'fastify'; -import type * as WebSocket from 'ws'; +import type { FastifyReply, FastifyRequest } from "fastify"; +import type * as WebSocket from "ws"; -import { getSafeJson } from '@mixan/common'; -import type { IServiceCreateEventPayload } from '@mixan/db'; -import { getEvents, getLiveVisitors } from '@mixan/db'; -import { redis, redisPub, redisSub } from '@mixan/redis'; +import { getSafeJson } from "@openpanel/common"; +import type { IServiceCreateEventPayload } from "@openpanel/db"; +import { getEvents, getLiveVisitors } from "@openpanel/db"; +import { redis, redisPub, redisSub } from "@openpanel/redis"; export function getLiveEventInfo(key: string) { - return key.split(':').slice(2) as [string, string]; + return key.split(":").slice(2) as [string, string]; } export async function test( @@ -16,20 +16,20 @@ export async function test( projectId: string; }; }>, - reply: FastifyReply + reply: FastifyReply, ) { const [event] = await getEvents( - `SELECT * FROM events WHERE project_id = '${req.params.projectId}' AND name = 'screen_view' LIMIT 1` + `SELECT * FROM events WHERE project_id = '${req.params.projectId}' AND name = 'screen_view' LIMIT 1`, ); if (!event) { - return reply.status(404).send('No event found'); + return reply.status(404).send("No event found"); } - redisPub.publish('event', JSON.stringify(event)); + redisPub.publish("event", JSON.stringify(event)); redis.set( `live:event:${event.projectId}:${Math.random() * 1000}`, - '', - 'EX', - 10 + "", + "EX", + 10, ); reply.status(202).send(event); } @@ -42,15 +42,15 @@ export function wsVisitors( Params: { projectId: string; }; - }> + }>, ) { const { params } = req; - redisSub.subscribe('event'); - redisSub.psubscribe('__key*:expired'); + redisSub.subscribe("event"); + redisSub.psubscribe("__key*:expired"); const message = (channel: string, message: string) => { - if (channel === 'event') { + if (channel === "event") { const event = getSafeJson(message); if (event?.projectId === params.projectId) { getLiveVisitors(params.projectId).then((count) => { @@ -68,14 +68,14 @@ export function wsVisitors( } }; - redisSub.on('message', message); - redisSub.on('pmessage', pmessage); + redisSub.on("message", message); + redisSub.on("pmessage", pmessage); - connection.socket.on('close', () => { - redisSub.unsubscribe('event'); - redisSub.punsubscribe('__key*:expired'); - redisSub.off('message', message); - redisSub.off('pmessage', pmessage); + connection.socket.on("close", () => { + redisSub.unsubscribe("event"); + redisSub.punsubscribe("__key*:expired"); + redisSub.off("message", message); + redisSub.off("pmessage", pmessage); }); } @@ -87,11 +87,11 @@ export function wsEvents( Params: { projectId: string; }; - }> + }>, ) { const { params } = req; - redisSub.subscribe('event'); + redisSub.subscribe("event"); const message = (channel: string, message: string) => { const event = getSafeJson(message); @@ -100,10 +100,10 @@ export function wsEvents( } }; - redisSub.on('message', message); + redisSub.on("message", message); - connection.socket.on('close', () => { - redisSub.unsubscribe('event'); - redisSub.off('message', message); + connection.socket.on("close", () => { + redisSub.unsubscribe("event"); + redisSub.off("message", message); }); } diff --git a/apps/api/src/controllers/misc.controller.ts b/apps/api/src/controllers/misc.controller.ts index e4e4a090..daa3ee7b 100644 --- a/apps/api/src/controllers/misc.controller.ts +++ b/apps/api/src/controllers/misc.controller.ts @@ -1,9 +1,9 @@ -import type { FastifyReply, FastifyRequest } from 'fastify'; -import icoToPng from 'ico-to-png'; -import sharp from 'sharp'; +import type { FastifyReply, FastifyRequest } from "fastify"; +import icoToPng from "ico-to-png"; +import sharp from "sharp"; -import { createHash } from '@mixan/common'; -import { redis } from '@mixan/redis'; +import { createHash } from "@openpanel/common"; +import { redis } from "@openpanel/redis"; interface GetFaviconParams { url: string; @@ -12,9 +12,9 @@ interface GetFaviconParams { async function getImageBuffer(url: string) { try { const res = await fetch(url); - const contentType = res.headers.get('content-type'); + const contentType = res.headers.get("content-type"); - if (!contentType?.includes('image')) { + if (!contentType?.includes("image")) { return null; } @@ -22,7 +22,7 @@ async function getImageBuffer(url: string) { return null; } - if (contentType === 'image/x-icon' || url.endsWith('.ico')) { + if (contentType === "image/x-icon" || url.endsWith(".ico")) { const arrayBuffer = await res.arrayBuffer(); const buffer = Buffer.from(arrayBuffer); return await icoToPng(buffer, 30); @@ -30,36 +30,36 @@ async function getImageBuffer(url: string) { return await sharp(await res.arrayBuffer()) .resize(30, 30, { - fit: 'cover', + fit: "cover", }) .png() .toBuffer(); } catch (e) { - console.log('Failed to get image from url', url); + console.log("Failed to get image from url", url); console.log(e); } } -const imageExtensions = ['svg', 'png', 'jpg', 'jpeg', 'gif', 'webp', 'ico']; +const imageExtensions = ["svg", "png", "jpg", "jpeg", "gif", "webp", "ico"]; export async function getFavicon( request: FastifyRequest<{ Querystring: GetFaviconParams; }>, - reply: FastifyReply + reply: FastifyReply, ) { function sendBuffer(buffer: Buffer, cacheKey?: string) { if (cacheKey) { - redis.set(`favicon:${cacheKey}`, buffer.toString('base64')); + redis.set(`favicon:${cacheKey}`, buffer.toString("base64")); } - reply.type('image/png'); - console.log('buffer', buffer.byteLength); + reply.type("image/png"); + console.log("buffer", buffer.byteLength); return reply.send(buffer); } if (!request.query.url) { - return reply.status(404).send('Not found'); + return reply.status(404).send("Not found"); } const url = decodeURIComponent(request.query.url); @@ -69,7 +69,7 @@ export async function getFavicon( const cacheKey = createHash(url, 32); const cache = await redis.get(`favicon:${cacheKey}`); if (cache) { - return sendBuffer(Buffer.from(cache, 'base64')); + return sendBuffer(Buffer.from(cache, "base64")); } const buffer = await getImageBuffer(url); if (buffer && buffer.byteLength > 0) { @@ -80,7 +80,7 @@ export async function getFavicon( const { hostname, origin } = new URL(url); const cache = await redis.get(`favicon:${hostname}`); if (cache) { - return sendBuffer(Buffer.from(cache, 'base64')); + return sendBuffer(Buffer.from(cache, "base64")); } // TRY FAVICON.ICO @@ -94,7 +94,7 @@ export async function getFavicon( function findFavicon(res: string) { const match = res.match( - /(\|\)/ + /(\|\)/, ); if (!match) { return null; @@ -112,16 +112,16 @@ export async function getFavicon( } } - return reply.status(404).send('Not found'); + return reply.status(404).send("Not found"); } export async function clearFavicons( request: FastifyRequest, - reply: FastifyReply + reply: FastifyReply, ) { - const keys = await redis.keys('favicon:*'); + const keys = await redis.keys("favicon:*"); for (const key of keys) { await redis.del(key); } - return reply.status(404).send('OK'); + return reply.status(404).send("OK"); } diff --git a/apps/api/src/controllers/profile.controller.ts b/apps/api/src/controllers/profile.controller.ts index e4edd42a..14befafb 100644 --- a/apps/api/src/controllers/profile.controller.ts +++ b/apps/api/src/controllers/profile.controller.ts @@ -1,21 +1,24 @@ -import { getClientIp, parseIp } from '@/utils/parseIp'; -import { isUserAgentSet, parseUserAgent } from '@/utils/parseUserAgent'; -import type { FastifyReply, FastifyRequest } from 'fastify'; -import { assocPath, pathOr } from 'ramda'; +import { getClientIp, parseIp } from "@/utils/parseIp"; +import { isUserAgentSet, parseUserAgent } from "@/utils/parseUserAgent"; +import type { FastifyReply, FastifyRequest } from "fastify"; +import { assocPath, pathOr } from "ramda"; -import { getProfileById, upsertProfile } from '@mixan/db'; -import type { IncrementProfilePayload, UpdateProfilePayload } from '@mixan/sdk'; +import { getProfileById, upsertProfile } from "@openpanel/db"; +import type { + IncrementProfilePayload, + UpdateProfilePayload, +} from "@openpanel/sdk"; export async function updateProfile( request: FastifyRequest<{ Body: UpdateProfilePayload; }>, - reply: FastifyReply + reply: FastifyReply, ) { const { profileId, properties, ...rest } = request.body; const projectId = request.projectId; const ip = getClientIp(request)!; - const ua = request.headers['user-agent']!; + const ua = request.headers["user-agent"]!; const uaInfo = parseUserAgent(ua); const geo = await parseIp(ip); @@ -37,29 +40,29 @@ export async function incrementProfileProperty( request: FastifyRequest<{ Body: IncrementProfilePayload; }>, - reply: FastifyReply + reply: FastifyReply, ) { const { profileId, property, value } = request.body; const projectId = request.projectId; const profile = await getProfileById(profileId); if (!profile) { - return reply.status(404).send('Not found'); + return reply.status(404).send("Not found"); } const parsed = parseInt( - pathOr('0', property.split('.'), profile.properties), - 10 + pathOr("0", property.split("."), profile.properties), + 10, ); if (isNaN(parsed)) { - return reply.status(400).send('Not number'); + return reply.status(400).send("Not number"); } profile.properties = assocPath( - property.split('.'), + property.split("."), parsed + value, - profile.properties + profile.properties, ); await upsertProfile({ @@ -75,29 +78,29 @@ export async function decrementProfileProperty( request: FastifyRequest<{ Body: IncrementProfilePayload; }>, - reply: FastifyReply + reply: FastifyReply, ) { const { profileId, property, value } = request.body; const projectId = request.projectId; const profile = await getProfileById(profileId); if (!profile) { - return reply.status(404).send('Not found'); + return reply.status(404).send("Not found"); } const parsed = parseInt( - pathOr('0', property.split('.'), profile.properties), - 10 + pathOr("0", property.split("."), profile.properties), + 10, ); if (isNaN(parsed)) { - return reply.status(400).send('Not number'); + return reply.status(400).send("Not number"); } profile.properties = assocPath( - property.split('.'), + property.split("."), parsed - value, - profile.properties + profile.properties, ); await upsertProfile({ diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 6197eeb0..3b53201b 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -1,43 +1,43 @@ -import cors from '@fastify/cors'; -import Fastify from 'fastify'; +import cors from "@fastify/cors"; +import Fastify from "fastify"; -import { redisPub } from '@mixan/redis'; +import { redisPub } from "@openpanel/redis"; -import eventRouter from './routes/event.router'; -import liveRouter from './routes/live.router'; -import miscRouter from './routes/misc.router'; -import profileRouter from './routes/profile.router'; -import { logger, logInfo } from './utils/logger'; +import eventRouter from "./routes/event.router"; +import liveRouter from "./routes/live.router"; +import miscRouter from "./routes/misc.router"; +import profileRouter from "./routes/profile.router"; +import { logger, logInfo } from "./utils/logger"; -declare module 'fastify' { +declare module "fastify" { interface FastifyRequest { projectId: string; } } -const port = parseInt(process.env.API_PORT || '3000', 10); +const port = parseInt(process.env.API_PORT || "3000", 10); const startServer = async () => { - logInfo('Starting server'); + logInfo("Starting server"); try { const fastify = Fastify({ logger: logger, }); fastify.register(cors, { - origin: '*', + origin: "*", }); - fastify.decorateRequest('projectId', ''); - fastify.register(eventRouter, { prefix: '/event' }); - fastify.register(profileRouter, { prefix: '/profile' }); - fastify.register(liveRouter, { prefix: '/live' }); - fastify.register(miscRouter, { prefix: '/misc' }); + fastify.decorateRequest("projectId", ""); + fastify.register(eventRouter, { prefix: "/event" }); + fastify.register(profileRouter, { prefix: "/profile" }); + fastify.register(liveRouter, { prefix: "/live" }); + fastify.register(miscRouter, { prefix: "/misc" }); fastify.setErrorHandler((error, request, reply) => { fastify.log.error(error); }); - fastify.get('/', (request, reply) => { - reply.send({ name: 'openpanel sdk api' }); + fastify.get("/", (request, reply) => { + reply.send({ name: "openpanel sdk api" }); }); // fastify.get('/health-check', async (request, reply) => { // try { @@ -47,8 +47,8 @@ const startServer = async () => { // reply.status(500).send() // } // }) - if (process.env.NODE_ENV === 'production') { - for (const signal of ['SIGINT', 'SIGTERM']) { + if (process.env.NODE_ENV === "production") { + for (const signal of ["SIGINT", "SIGTERM"]) { process.on(signal, (err) => { logger.fatal(err, `uncaught exception detected ${signal}`); fastify.close().then((err) => { @@ -59,12 +59,12 @@ const startServer = async () => { } await fastify.listen({ - host: process.env.NODE_ENV === 'production' ? '0.0.0.0' : 'localhost', + host: process.env.NODE_ENV === "production" ? "0.0.0.0" : "localhost", port, }); // Notify when keys expires - redisPub.config('SET', 'notify-keyspace-events', 'Ex'); + redisPub.config("SET", "notify-keyspace-events", "Ex"); } catch (e) { console.error(e); } diff --git a/apps/api/src/routes/event.router.ts b/apps/api/src/routes/event.router.ts index 0a476b5c..fffc39be 100644 --- a/apps/api/src/routes/event.router.ts +++ b/apps/api/src/routes/event.router.ts @@ -1,56 +1,56 @@ -import { isBot } from '@/bots'; -import * as controller from '@/controllers/event.controller'; -import { validateSdkRequest } from '@/utils/auth'; -import type { FastifyPluginCallback, FastifyRequest } from 'fastify'; +import { isBot } from "@/bots"; +import * as controller from "@/controllers/event.controller"; +import { validateSdkRequest } from "@/utils/auth"; +import type { FastifyPluginCallback, FastifyRequest } from "fastify"; -import { createBotEvent } from '@mixan/db'; -import type { PostEventPayload } from '@mixan/sdk'; +import { createBotEvent } from "@openpanel/db"; +import type { PostEventPayload } from "@openpanel/sdk"; const eventRouter: FastifyPluginCallback = (fastify, opts, done) => { fastify.addHook( - 'preHandler', + "preHandler", async ( req: FastifyRequest<{ Body: PostEventPayload; }>, - reply + reply, ) => { try { const projectId = await validateSdkRequest(req.headers); req.projectId = projectId; - const bot = req.headers['user-agent'] - ? isBot(req.headers['user-agent']) + const bot = req.headers["user-agent"] + ? isBot(req.headers["user-agent"]) : null; if (bot) { const path = (req.body?.properties?.__path || req.body?.properties?.path) as string | undefined; - req.log.warn({ ...req.headers, bot }, 'Bot detected (event)'); + req.log.warn({ ...req.headers, bot }, "Bot detected (event)"); await createBotEvent({ ...bot, projectId, - path: path ?? '', + path: path ?? "", createdAt: new Date(req.body?.timestamp), }); - reply.status(202).send('OK'); + reply.status(202).send("OK"); } } catch (e) { - req.log.error(e, 'Failed to create bot event'); + req.log.error(e, "Failed to create bot event"); reply.status(401).send(); return; } - } + }, ); fastify.route({ - method: 'POST', - url: '/', + method: "POST", + url: "/", handler: controller.postEvent, }); fastify.route({ - method: 'GET', - url: '/', + method: "GET", + url: "/", handler: controller.postEvent, }); done(); diff --git a/apps/api/src/utils/auth.ts b/apps/api/src/utils/auth.ts index 2a106720..825396d4 100644 --- a/apps/api/src/utils/auth.ts +++ b/apps/api/src/utils/auth.ts @@ -1,13 +1,13 @@ import type { RawRequestDefaultExpression } from 'fastify'; -import { verifyPassword } from '@mixan/common'; -import { db } from '@mixan/db'; +import { verifyPassword } from '@openpanel/common'; +import { db } from '@openpanel/db'; export async function validateSdkRequest( headers: RawRequestDefaultExpression['headers'] ): Promise { - const clientId = headers['mixan-client-id'] as string; - const clientSecret = headers['mixan-client-secret'] as string; + const clientId = headers['openpanel-client-id'] as string; + const clientSecret = headers['openpanel-client-secret'] as string; const origin = headers.origin; if (!clientId) { throw new Error('Misisng client id'); diff --git a/apps/api/src/utils/parseReferrer.ts b/apps/api/src/utils/parseReferrer.ts index 39c8d83d..0ff61a1b 100644 --- a/apps/api/src/utils/parseReferrer.ts +++ b/apps/api/src/utils/parseReferrer.ts @@ -1,41 +1,41 @@ -import { stripTrailingSlash } from '@mixan/common'; +import { stripTrailingSlash } from "@openpanel/common"; -import referrers from '../referrers'; +import referrers from "../referrers"; function getHostname(url: string | undefined) { if (!url) { - return ''; + return ""; } try { return new URL(url).hostname; } catch (e) { - return ''; + return ""; } } export function parseReferrer(url: string | undefined) { const hostname = getHostname(url); - const match = referrers[hostname] ?? referrers[hostname.replace('www.', '')]; + const match = referrers[hostname] ?? referrers[hostname.replace("www.", "")]; return { - name: match?.name ?? '', - type: match?.type ?? 'unknown', - url: stripTrailingSlash(url ?? ''), + name: match?.name ?? "", + type: match?.type ?? "unknown", + url: stripTrailingSlash(url ?? ""), }; } export function getReferrerWithQuery( - query: Record | undefined + query: Record | undefined, ) { if (!query) { return null; } - const source = query.utm_source ?? query.ref ?? query.utm_referrer ?? ''; + const source = query.utm_source ?? query.ref ?? query.utm_referrer ?? ""; const match = Object.values(referrers).find( - (referrer) => referrer.name.toLowerCase() === source?.toLowerCase() + (referrer) => referrer.name.toLowerCase() === source?.toLowerCase(), ); if (!match) { @@ -45,6 +45,6 @@ export function getReferrerWithQuery( return { name: match.name, type: match.type, - url: '', + url: "", }; } diff --git a/apps/api/tsconfig.json b/apps/api/tsconfig.json index 73b1bbe4..a291eef2 100644 --- a/apps/api/tsconfig.json +++ b/apps/api/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "baseUrl": ".", "paths": { diff --git a/apps/api/tsup.config.ts b/apps/api/tsup.config.ts index 9a320b05..12e0eb1b 100644 --- a/apps/api/tsup.config.ts +++ b/apps/api/tsup.config.ts @@ -4,7 +4,7 @@ import type { Options } from 'tsup'; const options: Options = { clean: true, entry: ['src/index.ts'], - noExternal: [/^@mixan\/.*$/u, /^@\/.*$/u], + noExternal: [/^@openpanel\/.*$/u, /^@\/.*$/u], sourcemap: true, splitting: false, }; diff --git a/apps/dashboard/next.config.mjs b/apps/dashboard/next.config.mjs index e5bcbe13..6c2cd5a9 100644 --- a/apps/dashboard/next.config.mjs +++ b/apps/dashboard/next.config.mjs @@ -7,7 +7,7 @@ await import('./src/env.mjs'); /** @type {import("next").NextConfig} */ const config = { reactStrictMode: true, - transpilePackages: ['@mixan/queue'], + transpilePackages: ['@openpanel/queue'], eslint: { ignoreDuringBuilds: true }, typescript: { ignoreBuildErrors: true }, experimental: { diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index 6781ebdd..2799069e 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/dashboard", + "name": "@openpanel/dashboard", "version": "0.1.0", "private": true, "scripts": { @@ -16,11 +16,11 @@ "@clerk/nextjs": "^4.29.7", "@clickhouse/client": "^0.2.9", "@hookform/resolvers": "^3.3.4", - "@mixan/common": "workspace:^", - "@mixan/constants": "workspace:^", - "@mixan/db": "workspace:^", - "@mixan/queue": "workspace:^", - "@mixan/validation": "workspace:^", + "@openpanel/common": "workspace:^", + "@openpanel/constants": "workspace:^", + "@openpanel/db": "workspace:^", + "@openpanel/queue": "workspace:^", + "@openpanel/validation": "workspace:^", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-aspect-ratio": "^1.0.3", @@ -93,9 +93,9 @@ "zod": "^3.22.4" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@types/bcrypt": "^5.0.2", "@types/lodash.debounce": "^4.0.9", "@types/lodash.throttle": "^4.1.9", @@ -121,10 +121,10 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base", - "@mixan/eslint-config/react", - "@mixan/eslint-config/nextjs" + "@openpanel/eslint-config/base", + "@openpanel/eslint-config/react", + "@openpanel/eslint-config/nextjs" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/[dashboardId]/list-reports.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/[dashboardId]/list-reports.tsx index a37d3032..13be6c69 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/[dashboardId]/list-reports.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/[dashboardId]/list-reports.tsx @@ -13,15 +13,14 @@ import { } from '@/components/ui/dropdown-menu'; import { useAppParams } from '@/hooks/useAppParams'; import { cn } from '@/utils/cn'; -import { ChevronRight, MoreHorizontal, PlusIcon, Trash } from 'lucide-react'; -import Link from 'next/link'; -import { useRouter } from 'next/navigation'; - import { getDefaultIntervalByDates, getDefaultIntervalByRange, -} from '@mixan/constants'; -import type { getReportsByDashboardId } from '@mixan/db'; +} from '@openpanel/constants'; +import type { getReportsByDashboardId } from '@openpanel/db'; +import { ChevronRight, MoreHorizontal, PlusIcon, Trash } from 'lucide-react'; +import Link from 'next/link'; +import { useRouter } from 'next/navigation'; import { OverviewReportRange } from '../../overview-sticky-header'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/[dashboardId]/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/[dashboardId]/page.tsx index d2a27ba2..5bf0b73a 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/[dashboardId]/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/[dashboardId]/page.tsx @@ -1,9 +1,8 @@ import PageLayout from '@/app/(app)/[organizationId]/[projectId]/page-layout'; import { getExists } from '@/server/pageExists'; +import { getDashboardById, getReportsByDashboardId } from '@openpanel/db'; import { notFound } from 'next/navigation'; -import { getDashboardById, getReportsByDashboardId } from '@mixan/db'; - import { ListReports } from './list-reports'; interface PageProps { diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/list-dashboards.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/list-dashboards.tsx index 73ab9ecb..c035e02e 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/list-dashboards.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/list-dashboards.tsx @@ -7,13 +7,12 @@ import { Button } from '@/components/ui/button'; import { ToastAction } from '@/components/ui/toast'; import { useAppParams } from '@/hooks/useAppParams'; import { pushModal } from '@/modals'; +import type { IServiceDashboards } from '@openpanel/db'; import { LayoutPanelTopIcon, Pencil, PlusIcon, Trash } from 'lucide-react'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; import { toast } from 'sonner'; -import type { IServiceDashboards } from '@mixan/db'; - interface ListDashboardsProps { dashboards: IServiceDashboards; } diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/page.tsx index 71275e46..e3025033 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/dashboards/page.tsx @@ -1,7 +1,6 @@ import PageLayout from '@/app/(app)/[organizationId]/[projectId]/page-layout'; import { getExists } from '@/server/pageExists'; - -import { getDashboardsByProjectId } from '@mixan/db'; +import { getDashboardsByProjectId } from '@openpanel/db'; import { HeaderDashboards } from './header-dashboards'; import { ListDashboards } from './list-dashboards'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-chart.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-chart.tsx index 59f9c5c4..445b21ee 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-chart.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-chart.tsx @@ -1,6 +1,5 @@ import { ChartSwitchShortcut } from '@/components/report/chart'; - -import type { IChartEvent } from '@mixan/validation'; +import type { IChartEvent } from '@openpanel/validation'; interface Props { projectId: string; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-details.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-details.tsx index 8d980e78..b06b4892 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-details.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-details.tsx @@ -13,10 +13,9 @@ import { useEventQueryFilters, useEventQueryNamesFilter, } from '@/hooks/useEventQueryFilters'; +import type { IServiceCreateEventPayload } from '@openpanel/db'; import { round } from 'mathjs'; -import type { IServiceCreateEventPayload } from '@mixan/db'; - interface Props { event: IServiceCreateEventPayload; open: boolean; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-edit.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-edit.tsx index 0180124e..28836790 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-edit.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-edit.tsx @@ -12,11 +12,10 @@ import { SheetTitle, } from '@/components/ui/sheet'; import { cn } from '@/utils/cn'; +import type { IServiceCreateEventPayload } from '@openpanel/db'; import { useRouter } from 'next/navigation'; import { toast } from 'sonner'; -import type { IServiceCreateEventPayload } from '@mixan/db'; - import { EventIconColors, EventIconMapper, diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-icon.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-icon.tsx index 8cf7a438..186f348c 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-icon.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-icon.tsx @@ -12,6 +12,7 @@ import { SheetTrigger, } from '@/components/ui/sheet'; import { cn } from '@/utils/cn'; +import type { EventMeta } from '@openpanel/db'; import type { VariantProps } from 'class-variance-authority'; import { cva } from 'class-variance-authority'; import type { LucideIcon } from 'lucide-react'; @@ -19,8 +20,6 @@ import * as Icons from 'lucide-react'; import { useRouter } from 'next/navigation'; import { toast } from 'sonner'; -import type { EventMeta } from '@mixan/db'; - const variants = cva('flex items-center justify-center shrink-0 rounded-full', { variants: { size: { diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-list-item.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-list-item.tsx index 36d7a835..272fa67e 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-list-item.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-list-item.tsx @@ -9,8 +9,7 @@ import { useEventQueryFilters } from '@/hooks/useEventQueryFilters'; import { useNumber } from '@/hooks/useNumerFormatter'; import { cn } from '@/utils/cn'; import { getProfileName } from '@/utils/getters'; - -import type { IServiceCreateEventPayload } from '@mixan/db'; +import type { IServiceCreateEventPayload } from '@openpanel/db'; import { EventDetails } from './event-details'; import { EventEdit } from './event-edit'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-list.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-list.tsx index bb9d28f4..2fff9d84 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-list.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-list.tsx @@ -8,11 +8,10 @@ import { Button } from '@/components/ui/button'; import { useAppParams } from '@/hooks/useAppParams'; import { useCursor } from '@/hooks/useCursor'; import { useEventQueryFilters } from '@/hooks/useEventQueryFilters'; +import type { IServiceCreateEventPayload } from '@openpanel/db'; import { isSameDay } from 'date-fns'; import { GanttChartIcon } from 'lucide-react'; -import type { IServiceCreateEventPayload } from '@mixan/db'; - import { EventListItem } from './event-list-item'; import EventListener from './event-listener'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-listener.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-listener.tsx index 09004ab8..6ea7627d 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-listener.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/event-listener.tsx @@ -8,14 +8,13 @@ import { } from '@/components/ui/tooltip'; import { useAppParams } from '@/hooks/useAppParams'; import { cn } from '@/utils/cn'; +import type { IServiceCreateEventPayload } from '@openpanel/db'; import { useQueryClient } from '@tanstack/react-query'; import dynamic from 'next/dynamic'; import { useRouter } from 'next/navigation'; import useWebSocket from 'react-use-websocket'; import { toast } from 'sonner'; -import type { IServiceCreateEventPayload } from '@mixan/db'; - const AnimatedNumbers = dynamic(() => import('react-animated-numbers'), { ssr: false, loading: () =>
0
, diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/page.tsx index 6e1802cd..69f19d6f 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/events/page.tsx @@ -6,10 +6,9 @@ import { eventQueryNamesFilter, } from '@/hooks/useEventQueryFilters'; import { getExists } from '@/server/pageExists'; +import { getEventList, getEventsCount } from '@openpanel/db'; import { parseAsInteger } from 'nuqs'; -import { getEventList, getEventsCount } from '@mixan/db'; - import { StickyBelowHeader } from '../layout-sticky-below-header'; import { EventChart } from './event-chart'; import { EventList } from './event-list'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-menu.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-menu.tsx index 6ba50d42..f0028c59 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-menu.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-menu.tsx @@ -4,6 +4,7 @@ import { useEffect } from 'react'; import { useAppParams } from '@/hooks/useAppParams'; import { cn } from '@/utils/cn'; import { useUser } from '@clerk/nextjs'; +import type { IServiceDashboards } from '@openpanel/db'; import { BuildingIcon, CogIcon, @@ -20,8 +21,6 @@ import type { LucideProps } from 'lucide-react'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; -import type { IServiceDashboards } from '@mixan/db'; - function LinkWithIcon({ href, icon: Icon, diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-organization-selector.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-organization-selector.tsx index 5461aaa8..8ce1c010 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-organization-selector.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-organization-selector.tsx @@ -2,11 +2,10 @@ import { Combobox } from '@/components/ui/combobox'; import { useAppParams } from '@/hooks/useAppParams'; +import type { IServiceOrganization } from '@openpanel/db'; import { Building } from 'lucide-react'; import { useRouter } from 'next/navigation'; -import type { IServiceOrganization } from '@mixan/db'; - interface LayoutOrganizationSelectorProps { organizations: IServiceOrganization[]; } diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-project-selector.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-project-selector.tsx index 8232925a..5b180cf1 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-project-selector.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-project-selector.tsx @@ -2,10 +2,9 @@ import { Combobox } from '@/components/ui/combobox'; import { useAppParams } from '@/hooks/useAppParams'; +import type { getProjectsByOrganizationSlug } from '@openpanel/db'; import { usePathname, useRouter } from 'next/navigation'; -import type { getProjectsByOrganizationSlug } from '@mixan/db'; - interface LayoutProjectSelectorProps { projects: Awaited>; } diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-sidebar.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-sidebar.tsx index cef271f4..71970307 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-sidebar.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout-sidebar.tsx @@ -4,13 +4,12 @@ import { useEffect, useState } from 'react'; import { Logo } from '@/components/Logo'; import { buttonVariants } from '@/components/ui/button'; import { cn } from '@/utils/cn'; +import type { IServiceDashboards, IServiceOrganization } from '@openpanel/db'; import { Rotate as Hamburger } from 'hamburger-react'; import { PlusIcon } from 'lucide-react'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; -import type { IServiceDashboards, IServiceOrganization } from '@mixan/db'; - import LayoutMenu from './layout-menu'; import LayoutOrganizationSelector from './layout-organization-selector'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout.tsx index a4fd55ef..e1667260 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/layout.tsx @@ -2,7 +2,7 @@ import { getCurrentOrganizations, getDashboardsByOrganization, getDashboardsByProjectId, -} from '@mixan/db'; +} from '@openpanel/db'; import { LayoutSidebar } from './layout-sidebar'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/page-layout.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/page-layout.tsx index c020f49c..a2959441 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/page-layout.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/page-layout.tsx @@ -1,4 +1,4 @@ -import { getProjectsByOrganizationSlug } from '@mixan/db'; +import { getProjectsByOrganizationSlug } from '@openpanel/db'; import LayoutProjectSelector from './layout-project-selector'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/page.tsx index 03a4ed2d..33bfc9fe 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/page.tsx @@ -10,8 +10,7 @@ import OverviewTopGeo from '@/components/overview/overview-top-geo'; import OverviewTopPages from '@/components/overview/overview-top-pages'; import OverviewTopSources from '@/components/overview/overview-top-sources'; import { getExists } from '@/server/pageExists'; - -import { db } from '@mixan/db'; +import { db } from '@openpanel/db'; import OverviewMetrics from '../../../../components/overview/overview-metrics'; import { CreateClient } from './create-client'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/[profileId]/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/[profileId]/page.tsx index 85dd4946..1bfe9b58 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/[profileId]/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/[profileId]/page.tsx @@ -12,17 +12,16 @@ import { import { getExists } from '@/server/pageExists'; import { cn } from '@/utils/cn'; import { getProfileName } from '@/utils/getters'; -import { notFound } from 'next/navigation'; -import { parseAsInteger, parseAsString } from 'nuqs'; - -import type { GetEventListOptions } from '@mixan/db'; +import type { GetEventListOptions } from '@openpanel/db'; import { getConversionEventNames, getEventList, getEventsCount, getProfileById, -} from '@mixan/db'; -import type { IChartEvent, IChartInput } from '@mixan/validation'; +} from '@openpanel/db'; +import type { IChartEvent, IChartInput } from '@openpanel/validation'; +import { notFound } from 'next/navigation'; +import { parseAsInteger, parseAsString } from 'nuqs'; import { EventList } from '../../events/event-list'; import { StickyBelowHeader } from '../../layout-sticky-below-header'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/page.tsx index 6886730a..55f19bba 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/page.tsx @@ -3,10 +3,9 @@ import { OverviewFiltersButtons } from '@/components/overview/filters/overview-f import { OverviewFiltersDrawer } from '@/components/overview/filters/overview-filters-drawer'; import { eventQueryFiltersParser } from '@/hooks/useEventQueryFilters'; import { getExists } from '@/server/pageExists'; +import { getProfileList, getProfileListCount } from '@openpanel/db'; import { parseAsInteger } from 'nuqs'; -import { getProfileList, getProfileListCount } from '@mixan/db'; - import { StickyBelowHeader } from '../layout-sticky-below-header'; import { ProfileList } from './profile-list'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/profile-list-item.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/profile-list-item.tsx index e1219885..028e8a04 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/profile-list-item.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/profile-list-item.tsx @@ -6,8 +6,7 @@ import { KeyValue, KeyValueSubtle } from '@/components/ui/key-value'; import { useAppParams } from '@/hooks/useAppParams'; import { useEventQueryFilters } from '@/hooks/useEventQueryFilters'; import { getProfileName } from '@/utils/getters'; - -import type { IServiceProfile } from '@mixan/db'; +import type { IServiceProfile } from '@openpanel/db'; type ProfileListItemProps = IServiceProfile; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/profile-list.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/profile-list.tsx index a0f29a1d..e783ab9d 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/profile-list.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/profiles/profile-list.tsx @@ -6,10 +6,9 @@ import { Pagination } from '@/components/Pagination'; import { Button } from '@/components/ui/button'; import { useCursor } from '@/hooks/useCursor'; import { useEventQueryFilters } from '@/hooks/useEventQueryFilters'; +import type { IServiceProfile } from '@openpanel/db'; import { UsersIcon } from 'lucide-react'; -import type { IServiceProfile } from '@mixan/db'; - import { ProfileListItem } from './profile-list-item'; interface ProfileListProps { diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/reports/[reportId]/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/reports/[reportId]/page.tsx index a24f7d6a..5eb5ef32 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/reports/[reportId]/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/reports/[reportId]/page.tsx @@ -1,10 +1,9 @@ import PageLayout from '@/app/(app)/[organizationId]/[projectId]/page-layout'; import { getExists } from '@/server/pageExists'; +import { getOrganizationBySlug, getReportById } from '@openpanel/db'; import { Pencil } from 'lucide-react'; import { notFound } from 'next/navigation'; -import { getOrganizationBySlug, getReportById } from '@mixan/db'; - import ReportEditor from '../report-editor'; interface PageProps { diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/reports/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/reports/page.tsx index 4a97bcc5..1558745f 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/reports/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/reports/page.tsx @@ -1,10 +1,9 @@ import PageLayout from '@/app/(app)/[organizationId]/[projectId]/page-layout'; import { getExists } from '@/server/pageExists'; +import { getOrganizationBySlug } from '@openpanel/db'; import { Pencil } from 'lucide-react'; import { notFound } from 'next/navigation'; -import { getOrganizationBySlug } from '@mixan/db'; - import ReportEditor from './report-editor'; interface PageProps { diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/reports/report-editor.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/reports/report-editor.tsx index 4b81c153..ad308f52 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/reports/report-editor.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/reports/report-editor.tsx @@ -22,11 +22,10 @@ import { Button } from '@/components/ui/button'; import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet'; import { useAppParams } from '@/hooks/useAppParams'; import { useDispatch, useSelector } from '@/redux'; +import type { IServiceReport } from '@openpanel/db'; import { endOfDay, startOfDay } from 'date-fns'; import { GanttChartSquareIcon } from 'lucide-react'; -import type { IServiceReport } from '@mixan/db'; - interface ReportEditorProps { report: IServiceReport | null; } diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/clients/list-clients.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/clients/list-clients.tsx index 36a35df4..3dea79e4 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/clients/list-clients.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/clients/list-clients.tsx @@ -6,10 +6,9 @@ import { DataTable } from '@/components/DataTable'; import { Button } from '@/components/ui/button'; import { useAppParams } from '@/hooks/useAppParams'; import { pushModal } from '@/modals'; +import type { getClientsByOrganizationId } from '@openpanel/db'; import { PlusIcon } from 'lucide-react'; -import type { getClientsByOrganizationId } from '@mixan/db'; - interface ListClientsProps { clients: Awaited>; } diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/clients/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/clients/page.tsx index 2cfc1321..7f66f77e 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/clients/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/clients/page.tsx @@ -1,7 +1,6 @@ import PageLayout from '@/app/(app)/[organizationId]/[projectId]/page-layout'; import { getExists } from '@/server/pageExists'; - -import { getClientsByOrganizationId } from '@mixan/db'; +import { getClientsByOrganizationId } from '@openpanel/db'; import ListClients from './list-clients'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/edit-organization.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/edit-organization.tsx index c972ba90..21090a8e 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/edit-organization.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/edit-organization.tsx @@ -4,13 +4,12 @@ import { api, handleError } from '@/app/_trpc/client'; import { InputWithLabel } from '@/components/forms/InputWithLabel'; import { Button } from '@/components/ui/button'; import { Widget, WidgetBody, WidgetHead } from '@/components/Widget'; +import type { getOrganizationBySlug } from '@openpanel/db'; import { useRouter } from 'next/navigation'; import { useForm } from 'react-hook-form'; import { toast } from 'sonner'; import { z } from 'zod'; -import type { getOrganizationBySlug } from '@mixan/db'; - const validator = z.object({ id: z.string().min(2), name: z.string().min(2), diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/invite-user.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/invite-user.tsx index c221d811..4c058e0e 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/invite-user.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/invite-user.tsx @@ -3,14 +3,13 @@ import { InputWithLabel } from '@/components/forms/InputWithLabel'; import { Button } from '@/components/ui/button'; import { useAppParams } from '@/hooks/useAppParams'; import { zodResolver } from '@hookform/resolvers/zod'; +import { zInviteUser } from '@openpanel/validation'; import { SendIcon } from 'lucide-react'; import { useRouter } from 'next/navigation'; import { useForm } from 'react-hook-form'; import { toast } from 'sonner'; import type { z } from 'zod'; -import { zInviteUser } from '@mixan/validation'; - type IForm = z.infer; export function InviteUser() { diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/invited-users.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/invited-users.tsx index 19a40c14..38835d4e 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/invited-users.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/invited-users.tsx @@ -9,8 +9,7 @@ import { TableRow, } from '@/components/ui/table'; import { Widget, WidgetBody, WidgetHead } from '@/components/Widget'; - -import type { IServiceInvites } from '@mixan/db'; +import type { IServiceInvites } from '@openpanel/db'; import { InviteUser } from './invite-user'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/page.tsx index b7c2f794..cbc8edbe 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/organization/page.tsx @@ -1,9 +1,8 @@ import PageLayout from '@/app/(app)/[organizationId]/[projectId]/page-layout'; import { clerkClient } from '@clerk/nextjs'; +import { getInvites, getOrganizationBySlug } from '@openpanel/db'; import { notFound } from 'next/navigation'; -import { getInvites, getOrganizationBySlug } from '@mixan/db'; - import EditOrganization from './edit-organization'; import InvitedUsers from './invited-users'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/profile/edit-profile.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/profile/edit-profile.tsx index c404eb46..6adeea31 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/profile/edit-profile.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/profile/edit-profile.tsx @@ -5,13 +5,12 @@ import { InputWithLabel } from '@/components/forms/InputWithLabel'; import { Button } from '@/components/ui/button'; import { Widget, WidgetBody, WidgetHead } from '@/components/Widget'; import { zodResolver } from '@hookform/resolvers/zod'; +import type { getUserById } from '@openpanel/db'; import { useRouter } from 'next/navigation'; import { useForm } from 'react-hook-form'; import { toast } from 'sonner'; import { z } from 'zod'; -import type { getUserById } from '@mixan/db'; - const validator = z.object({ firstName: z.string().min(2), lastName: z.string().min(2), diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/profile/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/profile/page.tsx index 4399831b..1fb4d25d 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/profile/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/profile/page.tsx @@ -1,8 +1,7 @@ import PageLayout from '@/app/(app)/[organizationId]/[projectId]/page-layout'; import { getExists } from '@/server/pageExists'; import { auth } from '@clerk/nextjs'; - -import { getUserById } from '@mixan/db'; +import { getUserById } from '@openpanel/db'; import EditProfile from './edit-profile'; import { Logout } from './logout'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/projects/list-projects.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/projects/list-projects.tsx index d64854d1..deb3a173 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/projects/list-projects.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/projects/list-projects.tsx @@ -6,10 +6,9 @@ import { columns } from '@/components/projects/table'; import { Button } from '@/components/ui/button'; import { useAppParams } from '@/hooks/useAppParams'; import { pushModal } from '@/modals'; +import type { getProjectsByOrganizationSlug } from '@openpanel/db'; import { PlusIcon } from 'lucide-react'; -import type { getProjectsByOrganizationSlug } from '@mixan/db'; - interface ListProjectsProps { projects: Awaited>; } diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/projects/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/projects/page.tsx index 421aea11..b6976bb4 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/projects/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/projects/page.tsx @@ -1,7 +1,6 @@ import PageLayout from '@/app/(app)/[organizationId]/[projectId]/page-layout'; import { getExists } from '@/server/pageExists'; - -import { getProjectsByOrganizationSlug } from '@mixan/db'; +import { getProjectsByOrganizationSlug } from '@openpanel/db'; import ListProjects from './list-projects'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/references/list-references.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/references/list-references.tsx index 383ccf07..d4270a29 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/references/list-references.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/references/list-references.tsx @@ -5,10 +5,9 @@ import { DataTable } from '@/components/DataTable'; import { columns } from '@/components/references/table'; import { Button } from '@/components/ui/button'; import { pushModal } from '@/modals'; +import type { IServiceReference } from '@openpanel/db'; import { PlusIcon } from 'lucide-react'; -import type { IServiceReference } from '@mixan/db'; - interface ListProjectsProps { data: IServiceReference[]; } diff --git a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/references/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/references/page.tsx index bdfbaaa4..ca5e8c01 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/references/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/[projectId]/settings/references/page.tsx @@ -1,7 +1,6 @@ import PageLayout from '@/app/(app)/[organizationId]/[projectId]/page-layout'; import { getExists } from '@/server/pageExists'; - -import { getReferences } from '@mixan/db'; +import { getReferences } from '@openpanel/db'; import ListReferences from './list-references'; diff --git a/apps/dashboard/src/app/(app)/[organizationId]/page.tsx b/apps/dashboard/src/app/(app)/[organizationId]/page.tsx index 79b31737..1b1b08ba 100644 --- a/apps/dashboard/src/app/(app)/[organizationId]/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationId]/page.tsx @@ -1,11 +1,10 @@ import { LogoSquare } from '@/components/Logo'; import { ProjectCard } from '@/components/projects/project-card'; -import { notFound, redirect } from 'next/navigation'; - import { getOrganizationBySlug, getProjectsByOrganizationSlug, -} from '@mixan/db'; +} from '@openpanel/db'; +import { notFound, redirect } from 'next/navigation'; import { CreateProject } from './create-project'; diff --git a/apps/dashboard/src/app/(app)/page.tsx b/apps/dashboard/src/app/(app)/page.tsx index 5a0adc47..86a03e2b 100644 --- a/apps/dashboard/src/app/(app)/page.tsx +++ b/apps/dashboard/src/app/(app)/page.tsx @@ -1,10 +1,9 @@ // import { CreateOrganization } from '@clerk/nextjs'; import { LogoSquare } from '@/components/Logo'; +import { getCurrentOrganizations } from '@openpanel/db'; import { redirect } from 'next/navigation'; -import { getCurrentOrganizations } from '@mixan/db'; - import { CreateOrganization } from './create-organization'; export default async function Page() { diff --git a/apps/dashboard/src/app/(public)/share/overview/[id]/page.tsx b/apps/dashboard/src/app/(public)/share/overview/[id]/page.tsx index 90072576..c875dc85 100644 --- a/apps/dashboard/src/app/(public)/share/overview/[id]/page.tsx +++ b/apps/dashboard/src/app/(public)/share/overview/[id]/page.tsx @@ -11,10 +11,9 @@ import OverviewTopEvents from '@/components/overview/overview-top-events'; import OverviewTopGeo from '@/components/overview/overview-top-geo'; import OverviewTopPages from '@/components/overview/overview-top-pages'; import OverviewTopSources from '@/components/overview/overview-top-sources'; +import { getOrganizationBySlug, getShareOverviewById } from '@openpanel/db'; import { notFound } from 'next/navigation'; -import { getOrganizationBySlug, getShareOverviewById } from '@mixan/db'; - interface PageProps { params: { id: string; diff --git a/apps/dashboard/src/components/clients/ClientActions.tsx b/apps/dashboard/src/components/clients/ClientActions.tsx index 06be845d..20c1f38e 100644 --- a/apps/dashboard/src/components/clients/ClientActions.tsx +++ b/apps/dashboard/src/components/clients/ClientActions.tsx @@ -3,12 +3,11 @@ import { api } from '@/app/_trpc/client'; import { pushModal, showConfirm } from '@/modals'; import { clipboard } from '@/utils/clipboard'; +import type { IServiceClientWithProject } from '@openpanel/db'; import { MoreHorizontal } from 'lucide-react'; import { useRouter } from 'next/navigation'; import { toast } from 'sonner'; -import type { IServiceClientWithProject } from '@mixan/db'; - import { Button } from '../ui/button'; import { DropdownMenu, diff --git a/apps/dashboard/src/components/clients/table.tsx b/apps/dashboard/src/components/clients/table.tsx index ed563b50..86d2ffce 100644 --- a/apps/dashboard/src/components/clients/table.tsx +++ b/apps/dashboard/src/components/clients/table.tsx @@ -1,8 +1,7 @@ import { formatDate } from '@/utils/date'; +import type { IServiceClientWithProject } from '@openpanel/db'; import type { ColumnDef } from '@tanstack/react-table'; -import type { IServiceClientWithProject } from '@mixan/db'; - import { ClientActions } from './ClientActions'; export const columns: ColumnDef[] = [ diff --git a/apps/dashboard/src/components/events/ListProperties.tsx b/apps/dashboard/src/components/events/ListProperties.tsx index c84cfe97..93aa80eb 100644 --- a/apps/dashboard/src/components/events/ListProperties.tsx +++ b/apps/dashboard/src/components/events/ListProperties.tsx @@ -1,4 +1,4 @@ -import { toDots } from '@mixan/common'; +import { toDots } from '@openpanel/common'; import { Table, TableBody, TableCell, TableRow } from '../ui/table'; diff --git a/apps/dashboard/src/components/overview/filters/overview-filters-drawer-content.tsx b/apps/dashboard/src/components/overview/filters/overview-filters-drawer-content.tsx index 1d78926c..9f2a8c80 100644 --- a/apps/dashboard/src/components/overview/filters/overview-filters-drawer-content.tsx +++ b/apps/dashboard/src/components/overview/filters/overview-filters-drawer-content.tsx @@ -11,14 +11,13 @@ import { import { useEventValues } from '@/hooks/useEventValues'; import { useProfileProperties } from '@/hooks/useProfileProperties'; import { useProfileValues } from '@/hooks/useProfileValues'; -import { XIcon } from 'lucide-react'; -import type { Options as NuqsOptions } from 'nuqs'; - import type { IChartEventFilter, IChartEventFilterOperator, IChartEventFilterValue, -} from '@mixan/validation'; +} from '@openpanel/validation'; +import { XIcon } from 'lucide-react'; +import type { Options as NuqsOptions } from 'nuqs'; export interface OverviewFiltersDrawerContentProps { projectId: string; diff --git a/apps/dashboard/src/components/overview/live-counter/index.tsx b/apps/dashboard/src/components/overview/live-counter/index.tsx index c5efb133..2eddb6af 100644 --- a/apps/dashboard/src/components/overview/live-counter/index.tsx +++ b/apps/dashboard/src/components/overview/live-counter/index.tsx @@ -1,4 +1,4 @@ -import { getLiveVisitors } from '@mixan/db'; +import { getLiveVisitors } from '@openpanel/db'; import type { LiveCounterProps } from './live-counter'; import LiveCounter from './live-counter'; diff --git a/apps/dashboard/src/components/overview/overview-latest-events/index.tsx b/apps/dashboard/src/components/overview/overview-latest-events/index.tsx index b29cea30..c3540a2e 100644 --- a/apps/dashboard/src/components/overview/overview-latest-events/index.tsx +++ b/apps/dashboard/src/components/overview/overview-latest-events/index.tsx @@ -1,4 +1,4 @@ -import { getConversionEventNames } from '@mixan/db'; +import { getConversionEventNames } from '@openpanel/db'; import type { OverviewLatestEventsProps } from './overview-latest-events'; import OverviewLatestEvents from './overview-latest-events'; diff --git a/apps/dashboard/src/components/overview/overview-live-histogram.tsx b/apps/dashboard/src/components/overview/overview-live-histogram.tsx index 16052a34..a436aac8 100644 --- a/apps/dashboard/src/components/overview/overview-live-histogram.tsx +++ b/apps/dashboard/src/components/overview/overview-live-histogram.tsx @@ -3,11 +3,10 @@ import { Fragment } from 'react'; import { api } from '@/app/_trpc/client'; import { cn } from '@/utils/cn'; +import type { IChartInput } from '@openpanel/validation'; import { ChevronsUpDownIcon } from 'lucide-react'; import AnimateHeight from 'react-animate-height'; -import type { IChartInput } from '@mixan/validation'; - import { redisSub } from '../../../../../packages/redis'; import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip'; import { useOverviewOptions } from './useOverviewOptions'; diff --git a/apps/dashboard/src/components/overview/overview-metrics.tsx b/apps/dashboard/src/components/overview/overview-metrics.tsx index 0b56868b..a1b7b5b5 100644 --- a/apps/dashboard/src/components/overview/overview-metrics.tsx +++ b/apps/dashboard/src/components/overview/overview-metrics.tsx @@ -6,8 +6,7 @@ import { ChartSwitch } from '@/components/report/chart'; import { Widget, WidgetBody } from '@/components/Widget'; import { useEventQueryFilters } from '@/hooks/useEventQueryFilters'; import { cn } from '@/utils/cn'; - -import type { IChartInput } from '@mixan/validation'; +import type { IChartInput } from '@openpanel/validation'; interface OverviewMetricsProps { projectId: string; diff --git a/apps/dashboard/src/components/overview/overview-share.tsx b/apps/dashboard/src/components/overview/overview-share.tsx index bbc46245..5d07e022 100644 --- a/apps/dashboard/src/components/overview/overview-share.tsx +++ b/apps/dashboard/src/components/overview/overview-share.tsx @@ -2,12 +2,11 @@ import { api } from '@/app/_trpc/client'; import { pushModal } from '@/modals'; +import type { ShareOverview } from '@openpanel/db'; import { EyeIcon, Globe2Icon, LockIcon } from 'lucide-react'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; -import type { ShareOverview } from '@mixan/db'; - import { Button } from '../ui/button'; import { DropdownMenu, diff --git a/apps/dashboard/src/components/overview/overview-top-events/index.tsx b/apps/dashboard/src/components/overview/overview-top-events/index.tsx index f54fa5eb..6c9601c1 100644 --- a/apps/dashboard/src/components/overview/overview-top-events/index.tsx +++ b/apps/dashboard/src/components/overview/overview-top-events/index.tsx @@ -1,4 +1,4 @@ -import { getConversionEventNames } from '@mixan/db'; +import { getConversionEventNames } from '@openpanel/db'; import type { OverviewTopEventsProps } from './overview-top-events'; import OverviewTopEvents from './overview-top-events'; diff --git a/apps/dashboard/src/components/overview/useOverviewOptions.ts b/apps/dashboard/src/components/overview/useOverviewOptions.ts index 48f38ba5..7a4000ad 100644 --- a/apps/dashboard/src/components/overview/useOverviewOptions.ts +++ b/apps/dashboard/src/components/overview/useOverviewOptions.ts @@ -1,3 +1,9 @@ +import { + getDefaultIntervalByDates, + getDefaultIntervalByRange, + timeRanges, +} from '@openpanel/constants'; +import { mapKeys } from '@openpanel/validation'; import { parseAsBoolean, parseAsInteger, @@ -6,13 +12,6 @@ import { useQueryState, } from 'nuqs'; -import { - getDefaultIntervalByDates, - getDefaultIntervalByRange, - timeRanges, -} from '@mixan/constants'; -import { mapKeys } from '@mixan/validation'; - const nuqsOptions = { history: 'push' } as const; export function useOverviewOptions() { diff --git a/apps/dashboard/src/components/overview/useOverviewWidget.tsx b/apps/dashboard/src/components/overview/useOverviewWidget.tsx index a516c471..2eefa355 100644 --- a/apps/dashboard/src/components/overview/useOverviewWidget.tsx +++ b/apps/dashboard/src/components/overview/useOverviewWidget.tsx @@ -1,8 +1,7 @@ +import { mapKeys } from '@openpanel/validation'; +import type { IChartInput } from '@openpanel/validation'; import { parseAsStringEnum, useQueryState } from 'nuqs'; -import { mapKeys } from '@mixan/validation'; -import type { IChartInput } from '@mixan/validation'; - export function useOverviewWidget( key: string, widgets: Record< diff --git a/apps/dashboard/src/components/profiles/ProfileAvatar.tsx b/apps/dashboard/src/components/profiles/ProfileAvatar.tsx index 62c69afb..e40417f5 100644 --- a/apps/dashboard/src/components/profiles/ProfileAvatar.tsx +++ b/apps/dashboard/src/components/profiles/ProfileAvatar.tsx @@ -1,12 +1,11 @@ 'use client'; import { cn } from '@/utils/cn'; +import type { IServiceProfile } from '@openpanel/db'; import { AvatarImage } from '@radix-ui/react-avatar'; import type { VariantProps } from 'class-variance-authority'; import { cva } from 'class-variance-authority'; -import type { IServiceProfile } from '@mixan/db'; - import { Avatar, AvatarFallback } from '../ui/avatar'; interface ProfileAvatarProps diff --git a/apps/dashboard/src/components/projects/ProjectActions.tsx b/apps/dashboard/src/components/projects/ProjectActions.tsx index e11ff397..6b58e124 100644 --- a/apps/dashboard/src/components/projects/ProjectActions.tsx +++ b/apps/dashboard/src/components/projects/ProjectActions.tsx @@ -3,12 +3,11 @@ import { api } from '@/app/_trpc/client'; import { pushModal, showConfirm } from '@/modals'; import { clipboard } from '@/utils/clipboard'; +import type { IServiceProject } from '@openpanel/db'; import { MoreHorizontal } from 'lucide-react'; import { useRouter } from 'next/navigation'; import { toast } from 'sonner'; -import type { IServiceProject } from '@mixan/db'; - import { Button } from '../ui/button'; import { DropdownMenu, diff --git a/apps/dashboard/src/components/projects/project-card.tsx b/apps/dashboard/src/components/projects/project-card.tsx index 7918eae6..c01c0d41 100644 --- a/apps/dashboard/src/components/projects/project-card.tsx +++ b/apps/dashboard/src/components/projects/project-card.tsx @@ -1,8 +1,8 @@ import { shortNumber } from '@/hooks/useNumerFormatter'; import Link from 'next/link'; -import type { IServiceProject } from '@mixan/db'; -import { chQuery } from '@mixan/db'; +import type { IServiceProject } from '@openpanel/db'; +import { chQuery } from '@openpanel/db'; import { ChartSSR } from '../chart-ssr'; diff --git a/apps/dashboard/src/components/projects/table.tsx b/apps/dashboard/src/components/projects/table.tsx index 0367b7a5..df97965f 100644 --- a/apps/dashboard/src/components/projects/table.tsx +++ b/apps/dashboard/src/components/projects/table.tsx @@ -1,9 +1,8 @@ import { formatDate } from '@/utils/date'; +import { IServiceProject } from '@openpanel/db'; +import type { Project as IProject } from '@openpanel/db'; import type { ColumnDef } from '@tanstack/react-table'; -import { IServiceProject } from '@mixan/db'; -import type { Project as IProject } from '@mixan/db'; - import { ProjectActions } from './ProjectActions'; export type Project = IProject; diff --git a/apps/dashboard/src/components/references/table.tsx b/apps/dashboard/src/components/references/table.tsx index ac0ac738..6fd734ea 100644 --- a/apps/dashboard/src/components/references/table.tsx +++ b/apps/dashboard/src/components/references/table.tsx @@ -1,8 +1,7 @@ import { formatDate, formatDateTime } from '@/utils/date'; +import type { IServiceReference } from '@openpanel/db'; import type { ColumnDef } from '@tanstack/react-table'; -import type { IServiceReference } from '@mixan/db'; - export const columns: ColumnDef[] = [ { accessorKey: 'title', diff --git a/apps/dashboard/src/components/report/ReportChartType.tsx b/apps/dashboard/src/components/report/ReportChartType.tsx index 51c492a0..58f1243d 100644 --- a/apps/dashboard/src/components/report/ReportChartType.tsx +++ b/apps/dashboard/src/components/report/ReportChartType.tsx @@ -1,9 +1,8 @@ import { useDispatch, useSelector } from '@/redux'; +import { chartTypes } from '@openpanel/constants'; +import { objectToZodEnums } from '@openpanel/validation'; import { LineChartIcon } from 'lucide-react'; -import { chartTypes } from '@mixan/constants'; -import { objectToZodEnums } from '@mixan/validation'; - import { Combobox } from '../ui/combobox'; import { changeChartType } from './reportSlice'; diff --git a/apps/dashboard/src/components/report/ReportInterval.tsx b/apps/dashboard/src/components/report/ReportInterval.tsx index d55330d0..9cc6e141 100644 --- a/apps/dashboard/src/components/report/ReportInterval.tsx +++ b/apps/dashboard/src/components/report/ReportInterval.tsx @@ -1,11 +1,10 @@ import { useDispatch, useSelector } from '@/redux'; -import { ClockIcon } from 'lucide-react'; - import { isHourIntervalEnabledByRange, isMinuteIntervalEnabledByRange, -} from '@mixan/constants'; -import type { IInterval } from '@mixan/validation'; +} from '@openpanel/constants'; +import type { IInterval } from '@openpanel/validation'; +import { ClockIcon } from 'lucide-react'; import { Combobox } from '../ui/combobox'; import { changeInterval } from './reportSlice'; diff --git a/apps/dashboard/src/components/report/ReportLineType.tsx b/apps/dashboard/src/components/report/ReportLineType.tsx index 272567ee..cada47fa 100644 --- a/apps/dashboard/src/components/report/ReportLineType.tsx +++ b/apps/dashboard/src/components/report/ReportLineType.tsx @@ -1,9 +1,8 @@ import { useDispatch, useSelector } from '@/redux'; +import { lineTypes } from '@openpanel/constants'; +import { objectToZodEnums } from '@openpanel/validation'; import { Tv2Icon } from 'lucide-react'; -import { lineTypes } from '@mixan/constants'; -import { objectToZodEnums } from '@mixan/validation'; - import { Combobox } from '../ui/combobox'; import { changeLineType } from './reportSlice'; diff --git a/apps/dashboard/src/components/report/ReportRange.tsx b/apps/dashboard/src/components/report/ReportRange.tsx index 4ea3bc77..d71f81c7 100644 --- a/apps/dashboard/src/components/report/ReportRange.tsx +++ b/apps/dashboard/src/components/report/ReportRange.tsx @@ -9,13 +9,12 @@ import { import { useBreakpoint } from '@/hooks/useBreakpoint'; import { useDispatch, useSelector } from '@/redux'; import { cn } from '@/utils/cn'; +import { timeRanges } from '@openpanel/constants'; +import type { IChartRange } from '@openpanel/validation'; import { endOfDay, format, startOfDay } from 'date-fns'; import { CalendarIcon, ChevronsUpDownIcon } from 'lucide-react'; import type { SelectRangeEventHandler } from 'react-day-picker'; -import { timeRanges } from '@mixan/constants'; -import type { IChartRange } from '@mixan/validation'; - import type { ExtendedComboboxProps } from '../ui/combobox'; import { ToggleGroup, ToggleGroupItem } from '../ui/toggle-group'; import { changeDates, changeEndDate, changeStartDate } from './reportSlice'; diff --git a/apps/dashboard/src/components/report/chart/Chart.tsx b/apps/dashboard/src/components/report/chart/Chart.tsx index ca56b70a..4b935fb3 100644 --- a/apps/dashboard/src/components/report/chart/Chart.tsx +++ b/apps/dashboard/src/components/report/chart/Chart.tsx @@ -1,8 +1,7 @@ 'use client'; import { api } from '@/app/_trpc/client'; - -import type { IChartInput } from '@mixan/validation'; +import type { IChartInput } from '@openpanel/validation'; import { ChartEmpty } from './ChartEmpty'; import { ReportAreaChart } from './ReportAreaChart'; diff --git a/apps/dashboard/src/components/report/chart/ChartProvider.tsx b/apps/dashboard/src/components/report/chart/ChartProvider.tsx index 38541245..d4554e77 100644 --- a/apps/dashboard/src/components/report/chart/ChartProvider.tsx +++ b/apps/dashboard/src/components/report/chart/ChartProvider.tsx @@ -10,8 +10,7 @@ import { useState, } from 'react'; import type { IChartSerie } from '@/server/api/routers/chart'; - -import type { IChartInput } from '@mixan/validation'; +import type { IChartInput } from '@openpanel/validation'; import { ChartLoading } from './ChartLoading'; import { MetricCardLoading } from './MetricCard'; diff --git a/apps/dashboard/src/components/report/chart/MetricCard.tsx b/apps/dashboard/src/components/report/chart/MetricCard.tsx index 9925db1e..e924aa67 100644 --- a/apps/dashboard/src/components/report/chart/MetricCard.tsx +++ b/apps/dashboard/src/components/report/chart/MetricCard.tsx @@ -4,11 +4,10 @@ import type { IChartData } from '@/app/_trpc/client'; import { ColorSquare } from '@/components/ColorSquare'; import { fancyMinutes, useNumber } from '@/hooks/useNumerFormatter'; import { theme } from '@/utils/theme'; +import type { IChartMetric } from '@openpanel/validation'; import AutoSizer from 'react-virtualized-auto-sizer'; import { Area, AreaChart } from 'recharts'; -import type { IChartMetric } from '@mixan/validation'; - import { getDiffIndicator, PreviousDiffIndicatorText, diff --git a/apps/dashboard/src/components/report/chart/ReportAreaChart.tsx b/apps/dashboard/src/components/report/chart/ReportAreaChart.tsx index 8d88b55a..f3f4bf23 100644 --- a/apps/dashboard/src/components/report/chart/ReportAreaChart.tsx +++ b/apps/dashboard/src/components/report/chart/ReportAreaChart.tsx @@ -5,6 +5,7 @@ import { useNumber } from '@/hooks/useNumerFormatter'; import { useRechartDataModel } from '@/hooks/useRechartDataModel'; import { useVisibleSeries } from '@/hooks/useVisibleSeries'; import { getChartColor } from '@/utils/theme'; +import type { IChartLineType, IInterval } from '@openpanel/validation'; import { Area, AreaChart, @@ -14,8 +15,6 @@ import { YAxis, } from 'recharts'; -import type { IChartLineType, IInterval } from '@mixan/validation'; - import { getYAxisWidth } from './chart-utils'; import { useChartContext } from './ChartProvider'; import { ReportChartTooltip } from './ReportChartTooltip'; diff --git a/apps/dashboard/src/components/report/chart/ReportBarChart.tsx b/apps/dashboard/src/components/report/chart/ReportBarChart.tsx index d0ed96d2..0187a337 100644 --- a/apps/dashboard/src/components/report/chart/ReportBarChart.tsx +++ b/apps/dashboard/src/components/report/chart/ReportBarChart.tsx @@ -6,8 +6,7 @@ import { Progress } from '@/components/ui/progress'; import { useNumber } from '@/hooks/useNumerFormatter'; import { cn } from '@/utils/cn'; import { getChartColor } from '@/utils/theme'; - -import { NOT_SET_VALUE } from '@mixan/constants'; +import { NOT_SET_VALUE } from '@openpanel/constants'; import { PreviousDiffIndicatorText } from '../PreviousDiffIndicator'; import { useChartContext } from './ChartProvider'; diff --git a/apps/dashboard/src/components/report/chart/ReportHistogramChart.tsx b/apps/dashboard/src/components/report/chart/ReportHistogramChart.tsx index 969b07e0..f8eddaec 100644 --- a/apps/dashboard/src/components/report/chart/ReportHistogramChart.tsx +++ b/apps/dashboard/src/components/report/chart/ReportHistogramChart.tsx @@ -5,10 +5,9 @@ import { useNumber } from '@/hooks/useNumerFormatter'; import { useRechartDataModel } from '@/hooks/useRechartDataModel'; import { useVisibleSeries } from '@/hooks/useVisibleSeries'; import { getChartColor, theme } from '@/utils/theme'; +import type { IInterval } from '@openpanel/validation'; import { Bar, BarChart, CartesianGrid, Tooltip, XAxis, YAxis } from 'recharts'; -import type { IInterval } from '@mixan/validation'; - import { getYAxisWidth } from './chart-utils'; import { useChartContext } from './ChartProvider'; import { ReportChartTooltip } from './ReportChartTooltip'; diff --git a/apps/dashboard/src/components/report/chart/ReportLineChart.tsx b/apps/dashboard/src/components/report/chart/ReportLineChart.tsx index aa1aea1d..581945a0 100644 --- a/apps/dashboard/src/components/report/chart/ReportLineChart.tsx +++ b/apps/dashboard/src/components/report/chart/ReportLineChart.tsx @@ -7,6 +7,8 @@ import { useNumber } from '@/hooks/useNumerFormatter'; import { useRechartDataModel } from '@/hooks/useRechartDataModel'; import { useVisibleSeries } from '@/hooks/useVisibleSeries'; import { getChartColor } from '@/utils/theme'; +import type { IServiceReference } from '@openpanel/db'; +import type { IChartLineType, IInterval } from '@openpanel/validation'; import { CartesianGrid, Line, @@ -17,9 +19,6 @@ import { YAxis, } from 'recharts'; -import type { IServiceReference } from '@mixan/db'; -import type { IChartLineType, IInterval } from '@mixan/validation'; - import { getYAxisWidth } from './chart-utils'; import { useChartContext } from './ChartProvider'; import { ReportChartTooltip } from './ReportChartTooltip'; diff --git a/apps/dashboard/src/components/report/chart/SerieIcon.tsx b/apps/dashboard/src/components/report/chart/SerieIcon.tsx index 68803599..26049ae0 100644 --- a/apps/dashboard/src/components/report/chart/SerieIcon.tsx +++ b/apps/dashboard/src/components/report/chart/SerieIcon.tsx @@ -1,4 +1,5 @@ import { useMemo } from 'react'; +import { NOT_SET_VALUE } from '@openpanel/constants'; import type { LucideIcon, LucideProps } from 'lucide-react'; import { ActivityIcon, @@ -14,8 +15,6 @@ import { TabletIcon, } from 'lucide-react'; -import { NOT_SET_VALUE } from '@mixan/constants'; - interface SerieIconProps extends LucideProps { name: string; } diff --git a/apps/dashboard/src/components/report/chart/index.tsx b/apps/dashboard/src/components/report/chart/index.tsx index bb5fbbab..a32f5f07 100644 --- a/apps/dashboard/src/components/report/chart/index.tsx +++ b/apps/dashboard/src/components/report/chart/index.tsx @@ -1,6 +1,6 @@ 'use client'; -import type { IChartInput } from '@mixan/validation'; +import type { IChartInput } from '@openpanel/validation'; import { Funnel } from '../funnel'; import { Chart } from './Chart'; diff --git a/apps/dashboard/src/components/report/funnel/index.tsx b/apps/dashboard/src/components/report/funnel/index.tsx index 0b6c9a21..f0ab77a1 100644 --- a/apps/dashboard/src/components/report/funnel/index.tsx +++ b/apps/dashboard/src/components/report/funnel/index.tsx @@ -2,8 +2,7 @@ import type { RouterOutputs } from '@/app/_trpc/client'; import { api } from '@/app/_trpc/client'; - -import type { IChartInput } from '@mixan/validation'; +import type { IChartInput } from '@openpanel/validation'; import { ChartEmpty } from '../chart/ChartEmpty'; import { withChartProivder } from '../chart/ChartProvider'; diff --git a/apps/dashboard/src/components/report/reportSlice.ts b/apps/dashboard/src/components/report/reportSlice.ts index e6e1dce0..b31f228c 100644 --- a/apps/dashboard/src/components/report/reportSlice.ts +++ b/apps/dashboard/src/components/report/reportSlice.ts @@ -1,15 +1,11 @@ import { start } from 'repl'; -import { createSlice } from '@reduxjs/toolkit'; -import type { PayloadAction } from '@reduxjs/toolkit'; -import { isSameDay, isSameMonth } from 'date-fns'; - import { alphabetIds, getDefaultIntervalByDates, getDefaultIntervalByRange, isHourIntervalEnabledByRange, isMinuteIntervalEnabledByRange, -} from '@mixan/constants'; +} from '@openpanel/constants'; import type { IChartBreakdown, IChartEvent, @@ -18,7 +14,10 @@ import type { IChartRange, IChartType, IInterval, -} from '@mixan/validation'; +} from '@openpanel/validation'; +import { createSlice } from '@reduxjs/toolkit'; +import type { PayloadAction } from '@reduxjs/toolkit'; +import { isSameDay, isSameMonth } from 'date-fns'; type InitialState = IChartInput & { dirty: boolean; diff --git a/apps/dashboard/src/components/report/sidebar/EventPropertiesCombobox.tsx b/apps/dashboard/src/components/report/sidebar/EventPropertiesCombobox.tsx index e25a2261..6e18e8bf 100644 --- a/apps/dashboard/src/components/report/sidebar/EventPropertiesCombobox.tsx +++ b/apps/dashboard/src/components/report/sidebar/EventPropertiesCombobox.tsx @@ -3,10 +3,9 @@ import { Combobox } from '@/components/ui/combobox'; import { useAppParams } from '@/hooks/useAppParams'; import { useDispatch } from '@/redux'; import { cn } from '@/utils/cn'; +import type { IChartEvent } from '@openpanel/validation'; import { DatabaseIcon } from 'lucide-react'; -import type { IChartEvent } from '@mixan/validation'; - import { changeEvent } from '../reportSlice'; interface EventPropertiesComboboxProps { diff --git a/apps/dashboard/src/components/report/sidebar/ReportBreakdowns.tsx b/apps/dashboard/src/components/report/sidebar/ReportBreakdowns.tsx index 18b39930..0f8b422a 100644 --- a/apps/dashboard/src/components/report/sidebar/ReportBreakdowns.tsx +++ b/apps/dashboard/src/components/report/sidebar/ReportBreakdowns.tsx @@ -5,10 +5,9 @@ import { ColorSquare } from '@/components/ColorSquare'; import { Combobox } from '@/components/ui/combobox'; import { useAppParams } from '@/hooks/useAppParams'; import { useDispatch, useSelector } from '@/redux'; +import type { IChartBreakdown } from '@openpanel/validation'; import { SplitIcon } from 'lucide-react'; -import type { IChartBreakdown } from '@mixan/validation'; - import { addBreakdown, changeBreakdown, removeBreakdown } from '../reportSlice'; import { ReportBreakdownMore } from './ReportBreakdownMore'; import type { ReportEventMoreProps } from './ReportEventMore'; diff --git a/apps/dashboard/src/components/report/sidebar/ReportEvents.tsx b/apps/dashboard/src/components/report/sidebar/ReportEvents.tsx index 1b21aa82..24b6fc52 100644 --- a/apps/dashboard/src/components/report/sidebar/ReportEvents.tsx +++ b/apps/dashboard/src/components/report/sidebar/ReportEvents.tsx @@ -9,10 +9,9 @@ import { useAppParams } from '@/hooks/useAppParams'; import { useDebounceFn } from '@/hooks/useDebounceFn'; import { useEventNames } from '@/hooks/useEventNames'; import { useDispatch, useSelector } from '@/redux'; +import type { IChartEvent } from '@openpanel/validation'; import { GanttChart, GanttChartIcon, Users } from 'lucide-react'; -import type { IChartEvent } from '@mixan/validation'; - import { addEvent, changeEvent, diff --git a/apps/dashboard/src/components/report/sidebar/filters/FilterItem.tsx b/apps/dashboard/src/components/report/sidebar/filters/FilterItem.tsx index ac621b84..a5294c4e 100644 --- a/apps/dashboard/src/components/report/sidebar/filters/FilterItem.tsx +++ b/apps/dashboard/src/components/report/sidebar/filters/FilterItem.tsx @@ -7,15 +7,14 @@ import { RenderDots } from '@/components/ui/RenderDots'; import { useAppParams } from '@/hooks/useAppParams'; import { useMappings } from '@/hooks/useMappings'; import { useDispatch } from '@/redux'; -import { SlidersHorizontal, Trash } from 'lucide-react'; - -import { operators } from '@mixan/constants'; +import { operators } from '@openpanel/constants'; import type { IChartEvent, IChartEventFilterOperator, IChartEventFilterValue, -} from '@mixan/validation'; -import { mapKeys } from '@mixan/validation'; +} from '@openpanel/validation'; +import { mapKeys } from '@openpanel/validation'; +import { SlidersHorizontal, Trash } from 'lucide-react'; import { changeEvent } from '../../reportSlice'; diff --git a/apps/dashboard/src/components/report/sidebar/filters/FiltersCombobox.tsx b/apps/dashboard/src/components/report/sidebar/filters/FiltersCombobox.tsx index b51bdee3..d29c381a 100644 --- a/apps/dashboard/src/components/report/sidebar/filters/FiltersCombobox.tsx +++ b/apps/dashboard/src/components/report/sidebar/filters/FiltersCombobox.tsx @@ -2,10 +2,9 @@ import { api } from '@/app/_trpc/client'; import { Combobox } from '@/components/ui/combobox'; import { useAppParams } from '@/hooks/useAppParams'; import { useDispatch } from '@/redux'; +import type { IChartEvent } from '@openpanel/validation'; import { FilterIcon } from 'lucide-react'; -import type { IChartEvent } from '@mixan/validation'; - import { changeEvent } from '../../reportSlice'; interface FiltersComboboxProps { diff --git a/apps/dashboard/src/components/report/sidebar/filters/FiltersList.tsx b/apps/dashboard/src/components/report/sidebar/filters/FiltersList.tsx index cc9dc981..58b73591 100644 --- a/apps/dashboard/src/components/report/sidebar/filters/FiltersList.tsx +++ b/apps/dashboard/src/components/report/sidebar/filters/FiltersList.tsx @@ -1,4 +1,4 @@ -import type { IChartEvent } from '@mixan/validation'; +import type { IChartEvent } from '@openpanel/validation'; import { FilterItem } from './FilterItem'; diff --git a/apps/dashboard/src/hooks/useFormatDateInterval.ts b/apps/dashboard/src/hooks/useFormatDateInterval.ts index 2c0779bf..d00f9fec 100644 --- a/apps/dashboard/src/hooks/useFormatDateInterval.ts +++ b/apps/dashboard/src/hooks/useFormatDateInterval.ts @@ -1,4 +1,4 @@ -import type { IInterval } from '@mixan/validation'; +import type { IInterval } from '@openpanel/validation'; export function formatDateInterval(interval: IInterval, date: Date): string { if (interval === 'hour' || interval === 'minute') { diff --git a/apps/dashboard/src/modals/AddReference.tsx b/apps/dashboard/src/modals/AddReference.tsx index 44ead4a0..2ab88741 100644 --- a/apps/dashboard/src/modals/AddReference.tsx +++ b/apps/dashboard/src/modals/AddReference.tsx @@ -7,13 +7,12 @@ import { Button } from '@/components/ui/button'; import { Calendar } from '@/components/ui/calendar'; import { useAppParams } from '@/hooks/useAppParams'; import { zodResolver } from '@hookform/resolvers/zod'; +import { zCreateReference } from '@openpanel/validation'; import { useRouter } from 'next/navigation'; import { Controller, useForm } from 'react-hook-form'; import { toast } from 'sonner'; import type { z } from 'zod'; -import { zCreateReference } from '@mixan/validation'; - import { popModal } from '.'; import { ModalContent, ModalHeader } from './Modal/Container'; diff --git a/apps/dashboard/src/modals/EditClient.tsx b/apps/dashboard/src/modals/EditClient.tsx index fb38490f..9c83eafb 100644 --- a/apps/dashboard/src/modals/EditClient.tsx +++ b/apps/dashboard/src/modals/EditClient.tsx @@ -5,13 +5,12 @@ import { ButtonContainer } from '@/components/ButtonContainer'; import { InputWithLabel } from '@/components/forms/InputWithLabel'; import { Button } from '@/components/ui/button'; import { zodResolver } from '@hookform/resolvers/zod'; +import type { IServiceClient } from '@openpanel/db'; import { useRouter } from 'next/navigation'; import { useForm } from 'react-hook-form'; import { toast } from 'sonner'; import { z } from 'zod'; -import type { IServiceClient } from '@mixan/db'; - import { popModal } from '.'; import { ModalContent, ModalHeader } from './Modal/Container'; diff --git a/apps/dashboard/src/modals/EditDashboard.tsx b/apps/dashboard/src/modals/EditDashboard.tsx index 6e717b1a..5028e52d 100644 --- a/apps/dashboard/src/modals/EditDashboard.tsx +++ b/apps/dashboard/src/modals/EditDashboard.tsx @@ -5,13 +5,12 @@ import { ButtonContainer } from '@/components/ButtonContainer'; import { InputWithLabel } from '@/components/forms/InputWithLabel'; import { Button } from '@/components/ui/button'; import { zodResolver } from '@hookform/resolvers/zod'; +import type { IServiceDashboard } from '@openpanel/db'; import { useRouter } from 'next/navigation'; import { useForm } from 'react-hook-form'; import { toast } from 'sonner'; import { z } from 'zod'; -import type { IServiceDashboard } from '@mixan/db'; - import { popModal } from '.'; import { ModalContent, ModalHeader } from './Modal/Container'; diff --git a/apps/dashboard/src/modals/EditProject.tsx b/apps/dashboard/src/modals/EditProject.tsx index 50edb250..2a43bcab 100644 --- a/apps/dashboard/src/modals/EditProject.tsx +++ b/apps/dashboard/src/modals/EditProject.tsx @@ -5,13 +5,12 @@ import { ButtonContainer } from '@/components/ButtonContainer'; import { InputWithLabel } from '@/components/forms/InputWithLabel'; import { Button } from '@/components/ui/button'; import { zodResolver } from '@hookform/resolvers/zod'; +import type { IServiceProject } from '@openpanel/db'; import { useRouter } from 'next/navigation'; import { useForm } from 'react-hook-form'; import { toast } from 'sonner'; import { z } from 'zod'; -import type { IServiceProject } from '@mixan/db'; - import { popModal } from '.'; import { ModalContent, ModalHeader } from './Modal/Container'; diff --git a/apps/dashboard/src/modals/SaveReport.tsx b/apps/dashboard/src/modals/SaveReport.tsx index 68d6cca0..9f2b8090 100644 --- a/apps/dashboard/src/modals/SaveReport.tsx +++ b/apps/dashboard/src/modals/SaveReport.tsx @@ -8,13 +8,12 @@ import { Combobox } from '@/components/ui/combobox'; import { Label } from '@/components/ui/label'; import { useAppParams } from '@/hooks/useAppParams'; import { zodResolver } from '@hookform/resolvers/zod'; +import type { IChartInput } from '@openpanel/validation'; import { useRouter, useSearchParams } from 'next/navigation'; import { Controller, useForm } from 'react-hook-form'; import { toast } from 'sonner'; import { z } from 'zod'; -import type { IChartInput } from '@mixan/validation'; - import { popModal } from '.'; import { ModalContent, ModalHeader } from './Modal/Container'; diff --git a/apps/dashboard/src/modals/ShareOverviewModal.tsx b/apps/dashboard/src/modals/ShareOverviewModal.tsx index 85f8629b..8631aa5f 100644 --- a/apps/dashboard/src/modals/ShareOverviewModal.tsx +++ b/apps/dashboard/src/modals/ShareOverviewModal.tsx @@ -7,13 +7,12 @@ import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { useAppParams } from '@/hooks/useAppParams'; import { zodResolver } from '@hookform/resolvers/zod'; +import { zShareOverview } from '@openpanel/validation'; import { useRouter } from 'next/navigation'; import { Controller, useForm } from 'react-hook-form'; import { toast } from 'sonner'; import type { z } from 'zod'; -import { zShareOverview } from '@mixan/validation'; - import { popModal } from '.'; import { ModalContent, ModalHeader } from './Modal/Container'; diff --git a/apps/dashboard/src/server/api/routers/chart.helpers.ts b/apps/dashboard/src/server/api/routers/chart.helpers.ts index 933b3103..4fe96cf3 100644 --- a/apps/dashboard/src/server/api/routers/chart.helpers.ts +++ b/apps/dashboard/src/server/api/routers/chart.helpers.ts @@ -1,17 +1,16 @@ import { getDaysOldDate } from '@/utils/date'; import { round } from '@/utils/math'; -import * as mathjs from 'mathjs'; -import { sort } from 'ramda'; - -import { alphabetIds, NOT_SET_VALUE } from '@mixan/constants'; -import { chQuery, convertClickhouseDateToJs, getChartSql } from '@mixan/db'; +import { alphabetIds, NOT_SET_VALUE } from '@openpanel/constants'; +import { chQuery, convertClickhouseDateToJs, getChartSql } from '@openpanel/db'; import type { IChartEvent, IChartInput, IChartRange, IGetChartDataInput, IInterval, -} from '@mixan/validation'; +} from '@openpanel/validation'; +import * as mathjs from 'mathjs'; +import { sort } from 'ramda'; export type GetChartDataResult = Awaited>; export interface ResultItem { diff --git a/apps/dashboard/src/server/api/routers/chart.ts b/apps/dashboard/src/server/api/routers/chart.ts index d0d23fa8..b187493f 100644 --- a/apps/dashboard/src/server/api/routers/chart.ts +++ b/apps/dashboard/src/server/api/routers/chart.ts @@ -4,17 +4,16 @@ import { publicProcedure, } from '@/server/api/trpc'; import { average, max, min, round, sum } from '@/utils/math'; -import { flatten, map, pipe, prop, repeat, reverse, sort, uniq } from 'ramda'; -import { z } from 'zod'; - import { chQuery, createSqlBuilder, formatClickhouseDate, getEventFiltersWhereClause, -} from '@mixan/db'; -import { zChartInput } from '@mixan/validation'; -import type { IChartEvent, IChartInput } from '@mixan/validation'; +} from '@openpanel/db'; +import { zChartInput } from '@openpanel/validation'; +import type { IChartEvent, IChartInput } from '@openpanel/validation'; +import { flatten, map, pipe, prop, repeat, reverse, sort, uniq } from 'ramda'; +import { z } from 'zod'; import { getChartData, diff --git a/apps/dashboard/src/server/api/routers/client.ts b/apps/dashboard/src/server/api/routers/client.ts index 3fda7d76..17698c57 100644 --- a/apps/dashboard/src/server/api/routers/client.ts +++ b/apps/dashboard/src/server/api/routers/client.ts @@ -1,10 +1,9 @@ import { randomUUID } from 'crypto'; import { createTRPCRouter, protectedProcedure } from '@/server/api/trpc'; import { db } from '@/server/db'; +import { hashPassword } from '@openpanel/common'; import { z } from 'zod'; -import { hashPassword } from '@mixan/common'; - export const clientRouter = createTRPCRouter({ list: protectedProcedure .input( diff --git a/apps/dashboard/src/server/api/routers/dashboard.ts b/apps/dashboard/src/server/api/routers/dashboard.ts index f29bf62e..f093024f 100644 --- a/apps/dashboard/src/server/api/routers/dashboard.ts +++ b/apps/dashboard/src/server/api/routers/dashboard.ts @@ -1,10 +1,9 @@ import { createTRPCRouter, protectedProcedure } from '@/server/api/trpc'; import { db, getId } from '@/server/db'; +import type { Prisma } from '@openpanel/db'; import { PrismaError } from 'prisma-error-enum'; import { z } from 'zod'; -import type { Prisma } from '@mixan/db'; - export const dashboardRouter = createTRPCRouter({ get: protectedProcedure .input(z.object({ id: z.string() })) diff --git a/apps/dashboard/src/server/api/routers/event.ts b/apps/dashboard/src/server/api/routers/event.ts index a93c0d16..fd027d7f 100644 --- a/apps/dashboard/src/server/api/routers/event.ts +++ b/apps/dashboard/src/server/api/routers/event.ts @@ -1,8 +1,7 @@ import { createTRPCRouter, protectedProcedure } from '@/server/api/trpc'; +import { db } from '@openpanel/db'; import { z } from 'zod'; -import { db } from '@mixan/db'; - export const eventRouter = createTRPCRouter({ updateEventMeta: protectedProcedure .input( diff --git a/apps/dashboard/src/server/api/routers/onboarding.ts b/apps/dashboard/src/server/api/routers/onboarding.ts index 1e0235a0..cf60c687 100644 --- a/apps/dashboard/src/server/api/routers/onboarding.ts +++ b/apps/dashboard/src/server/api/routers/onboarding.ts @@ -1,9 +1,8 @@ import { createTRPCRouter, protectedProcedure } from '@/server/api/trpc'; import { clerkClient } from '@clerk/nextjs'; +import { db } from '@openpanel/db'; import { z } from 'zod'; -import { db } from '@mixan/db'; - export const onboardingRouter = createTRPCRouter({ organziation: protectedProcedure .input( diff --git a/apps/dashboard/src/server/api/routers/organization.ts b/apps/dashboard/src/server/api/routers/organization.ts index a0d7f4bd..eaae290c 100644 --- a/apps/dashboard/src/server/api/routers/organization.ts +++ b/apps/dashboard/src/server/api/routers/organization.ts @@ -1,10 +1,9 @@ import { createTRPCRouter, protectedProcedure } from '@/server/api/trpc'; import { clerkClient } from '@clerk/nextjs'; +import { getOrganizationBySlug } from '@openpanel/db'; +import { zInviteUser } from '@openpanel/validation'; import { z } from 'zod'; -import { getOrganizationBySlug } from '@mixan/db'; -import { zInviteUser } from '@mixan/validation'; - export const organizationRouter = createTRPCRouter({ list: protectedProcedure.query(() => { return clerkClient.organizations.getOrganizationList(); diff --git a/apps/dashboard/src/server/api/routers/profile.ts b/apps/dashboard/src/server/api/routers/profile.ts index 471ae559..b139cb02 100644 --- a/apps/dashboard/src/server/api/routers/profile.ts +++ b/apps/dashboard/src/server/api/routers/profile.ts @@ -4,11 +4,10 @@ import { publicProcedure, } from '@/server/api/trpc'; import { db } from '@/server/db'; +import { chQuery, createSqlBuilder } from '@openpanel/db'; import { flatten, map, pipe, prop, sort, uniq } from 'ramda'; import { z } from 'zod'; -import { chQuery, createSqlBuilder } from '@mixan/db'; - export const profileRouter = createTRPCRouter({ list: protectedProcedure .input( diff --git a/apps/dashboard/src/server/api/routers/reference.ts b/apps/dashboard/src/server/api/routers/reference.ts index 4caab84c..70d8c467 100644 --- a/apps/dashboard/src/server/api/routers/reference.ts +++ b/apps/dashboard/src/server/api/routers/reference.ts @@ -1,9 +1,8 @@ import { createTRPCRouter, protectedProcedure } from '@/server/api/trpc'; +import { db, getReferences } from '@openpanel/db'; +import { zCreateReference, zRange } from '@openpanel/validation'; import { z } from 'zod'; -import { db, getReferences } from '@mixan/db'; -import { zCreateReference, zRange } from '@mixan/validation'; - import { getChartStartEndDate } from './chart.helpers'; export const referenceRouter = createTRPCRouter({ diff --git a/apps/dashboard/src/server/api/routers/report.ts b/apps/dashboard/src/server/api/routers/report.ts index 49141844..240aae2d 100644 --- a/apps/dashboard/src/server/api/routers/report.ts +++ b/apps/dashboard/src/server/api/routers/report.ts @@ -1,10 +1,9 @@ import { createTRPCRouter, protectedProcedure } from '@/server/api/trpc'; import { db } from '@/server/db'; +import { transformReport } from '@openpanel/db'; +import { zChartInput } from '@openpanel/validation'; import { z } from 'zod'; -import { transformReport } from '@mixan/db'; -import { zChartInput } from '@mixan/validation'; - export const reportRouter = createTRPCRouter({ get: protectedProcedure .input( diff --git a/apps/dashboard/src/server/api/routers/share.ts b/apps/dashboard/src/server/api/routers/share.ts index 4a71b011..758b408f 100644 --- a/apps/dashboard/src/server/api/routers/share.ts +++ b/apps/dashboard/src/server/api/routers/share.ts @@ -1,9 +1,8 @@ import { createTRPCRouter, protectedProcedure } from '@/server/api/trpc'; import { db } from '@/server/db'; +import { zShareOverview } from '@openpanel/validation'; import ShortUniqueId from 'short-unique-id'; -import { zShareOverview } from '@mixan/validation'; - const uid = new ShortUniqueId({ length: 6 }); export const shareRouter = createTRPCRouter({ diff --git a/apps/dashboard/src/server/api/routers/user.ts b/apps/dashboard/src/server/api/routers/user.ts index ae20ed35..e1a71699 100644 --- a/apps/dashboard/src/server/api/routers/user.ts +++ b/apps/dashboard/src/server/api/routers/user.ts @@ -1,9 +1,8 @@ import { createTRPCRouter, protectedProcedure } from '@/server/api/trpc'; import { clerkClient } from '@clerk/nextjs'; +import { transformUser } from '@openpanel/db'; import { z } from 'zod'; -import { transformUser } from '@mixan/db'; - export const userRouter = createTRPCRouter({ update: protectedProcedure .input( diff --git a/apps/dashboard/src/server/db.ts b/apps/dashboard/src/server/db.ts index e3216689..52cfb321 100644 --- a/apps/dashboard/src/server/db.ts +++ b/apps/dashboard/src/server/db.ts @@ -1,8 +1,7 @@ import { slug } from '@/utils/slug'; +import { db } from '@openpanel/db'; -import { db } from '@mixan/db'; - -export { db } from '@mixan/db'; +export { db } from '@openpanel/db'; export async function getId(tableName: 'project' | 'dashboard', name: string) { const newId = slug(name); diff --git a/apps/dashboard/src/server/pageExists.tsx b/apps/dashboard/src/server/pageExists.tsx index 2d14cf5c..7e262276 100644 --- a/apps/dashboard/src/server/pageExists.tsx +++ b/apps/dashboard/src/server/pageExists.tsx @@ -1,7 +1,6 @@ +import { getOrganizationBySlug, getProjectById } from '@openpanel/db'; import { notFound } from 'next/navigation'; -import { getOrganizationBySlug, getProjectById } from '@mixan/db'; - export async function getExists(organizationSlug: string, projectId?: string) { const promises: Promise[] = [getOrganizationBySlug(organizationSlug)]; diff --git a/apps/dashboard/src/utils/getters.ts b/apps/dashboard/src/utils/getters.ts index c8b9e3b6..1257b551 100644 --- a/apps/dashboard/src/utils/getters.ts +++ b/apps/dashboard/src/utils/getters.ts @@ -1,4 +1,4 @@ -import type { IServiceProfile } from '@mixan/db'; +import type { IServiceProfile } from '@openpanel/db'; export function getProfileName(profile: IServiceProfile | undefined | null) { if (!profile) return 'No profile'; diff --git a/apps/dashboard/tsconfig.json b/apps/dashboard/tsconfig.json index 9d21e044..d17f2ec2 100644 --- a/apps/dashboard/tsconfig.json +++ b/apps/dashboard/tsconfig.json @@ -1,11 +1,9 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "baseUrl": ".", "paths": { - "@/*": [ - "./src/*" - ] + "@/*": ["./src/*"] }, "plugins": [ { @@ -15,11 +13,6 @@ "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json", "strictNullChecks": true }, - "include": [ - ".", - ".next/types/**/*.ts" - ], - "exclude": [ - "node_modules" - ] + "include": [".", ".next/types/**/*.ts"], + "exclude": ["node_modules"] } diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs index 23f7d2c8..50072116 100644 --- a/apps/docs/next.config.mjs +++ b/apps/docs/next.config.mjs @@ -3,7 +3,7 @@ import nextra from 'nextra'; /** @type {import("next").NextConfig} */ const config = { reactStrictMode: true, - transpilePackages: ['@mixan/queue'], + transpilePackages: ['@openpanel/queue'], eslint: { ignoreDuringBuilds: true }, typescript: { ignoreBuildErrors: true }, experimental: { diff --git a/apps/docs/package.json b/apps/docs/package.json index 1cd8db07..5459f19b 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/docs", + "name": "@openpanel/docs", "version": "0.1.0", "private": true, "scripts": { @@ -19,9 +19,9 @@ "react-dom": "18.2.0" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@types/node": "^18.16.0", "@types/react": "^18.2.20", "@types/react-dom": "^18.2.7", @@ -37,10 +37,10 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base", - "@mixan/eslint-config/react", - "@mixan/eslint-config/nextjs" + "@openpanel/eslint-config/base", + "@openpanel/eslint-config/react", + "@openpanel/eslint-config/nextjs" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json index 9d21e044..f25ad65e 100644 --- a/apps/docs/tsconfig.json +++ b/apps/docs/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "baseUrl": ".", "paths": { diff --git a/apps/public/next.config.mjs b/apps/public/next.config.mjs index e5bcbe13..6c2cd5a9 100644 --- a/apps/public/next.config.mjs +++ b/apps/public/next.config.mjs @@ -7,7 +7,7 @@ await import('./src/env.mjs'); /** @type {import("next").NextConfig} */ const config = { reactStrictMode: true, - transpilePackages: ['@mixan/queue'], + transpilePackages: ['@openpanel/queue'], eslint: { ignoreDuringBuilds: true }, typescript: { ignoreBuildErrors: true }, experimental: { diff --git a/apps/public/package.json b/apps/public/package.json index 64d6a733..ee88b426 100644 --- a/apps/public/package.json +++ b/apps/public/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/public", + "name": "@openpanel/public", "version": "0.1.0", "private": true, "scripts": { @@ -12,7 +12,7 @@ "with-env": "dotenv -e ../../.env -c --" }, "dependencies": { - "@mixan/db": "workspace:*", + "@openpanel/db": "workspace:*", "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-aspect-ratio": "^1.0.3", "@radix-ui/react-avatar": "^1.0.4", @@ -42,9 +42,9 @@ "zod": "^3.22.4" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@tailwindcss/typography": "^0.5.10", "@types/node": "^18.16.0", "@types/react": "^18.2.20", @@ -66,10 +66,10 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base", - "@mixan/eslint-config/react", - "@mixan/eslint-config/nextjs" + "@openpanel/eslint-config/base", + "@openpanel/eslint-config/react", + "@openpanel/eslint-config/nextjs" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/apps/public/public/op.js b/apps/public/public/op.js index 92c1b0af..fb92b806 100644 --- a/apps/public/public/op.js +++ b/apps/public/public/op.js @@ -1,2 +1,2 @@ -"use strict";(()=>{function w(s){return Promise.all(Object.entries(s).map(async([t,e])=>[t,await e??""])).then(t=>Object.fromEntries(t))}function P(s){let t={"Content-Type":"application/json"};return{headers:t,async fetch(e,i,n){let o=`${s}${e}`,u,m=await w(t);return new Promise(c=>{let h=r=>{clearTimeout(u),fetch(o,{headers:m,method:"POST",body:JSON.stringify(i??{}),keepalive:!0,...n??{}}).then(async a=>{if(a.status!==200&&a.status!==202)return f(r,c);let g=await a.text();if(!g)return c(null);c(g)}).catch(()=>f(r,c))};function f(r,a){if(r>1)return a(null);u=setTimeout(()=>{h(r+1)},Math.pow(2,r)*500)}h(0)})}}}var l=class{options;api;state={properties:{}};constructor(t){this.options=t,this.api=P(t.url),this.api.headers["mixan-client-id"]=t.clientId,this.options.clientSecret&&(this.api.headers["mixan-client-secret"]=this.options.clientSecret)}init(t){this.state.properties=t??{}}setUser(t){this.api.fetch("/profile",{profileId:this.getProfileId(),...t,properties:{...this.state.properties,...t.properties}})}increment(t,e){this.api.fetch("/profile/increment",{property:t,value:e,profileId:this.getProfileId()})}decrement(t,e){this.api.fetch("/profile/decrement",{property:t,value:e,profileId:this.getProfileId()})}event(t,e){this.api.fetch("/event",{name:t,properties:{...this.state.properties,...e??{}},timestamp:this.timestamp(),profileId:this.getProfileId()}).then(i=>{this.options.setProfileId&&i&&this.options.setProfileId(i)})}setGlobalProperties(t){this.state.properties={...this.state.properties,...t}}clear(){this.state.profileId=void 0,this.options.removeProfileId&&this.options.removeProfileId()}timestamp(){return new Date().toISOString()}getProfileId(){if(this.state.profileId)return this.state.profileId;this.options.getProfileId&&(this.state.profileId=this.options.getProfileId()||void 0)}};var d=class extends l{lastPath="";constructor(t){super(t),this.isServer()||(this.setGlobalProperties({referrer:document.referrer}),this.options.trackOutgoingLinks&&this.trackOutgoingLinks(),this.options.trackScreenViews&&this.trackScreenViews())}isServer(){return typeof document>"u"}trackOutgoingLinks(){this.isServer()||document.addEventListener("click",t=>{let e=t.target,i=e.closest("a");if(i&&e){let n=i.getAttribute("href");n?.startsWith("http")&&super.event("link_out",{href:n,text:i.innerText||i.getAttribute("title")||e.getAttribute("alt")||e.getAttribute("title")})}})}trackScreenViews(){if(this.isServer())return;let t=history.pushState;history.pushState=function(...n){let o=t.apply(this,n);return window.dispatchEvent(new Event("pushstate")),window.dispatchEvent(new Event("locationchange")),o};let e=history.replaceState;history.replaceState=function(...n){let o=e.apply(this,n);return window.dispatchEvent(new Event("replacestate")),window.dispatchEvent(new Event("locationchange")),o},window.addEventListener("popstate",()=>window.dispatchEvent(new Event("locationchange"))),this.options.hash?window.addEventListener("hashchange",()=>this.screenView()):window.addEventListener("locationchange",()=>this.screenView()),this.screenView()}screenView(t){if(this.isServer())return;let e=window.location.href;this.lastPath!==e&&(this.lastPath=e,super.event("screen_view",{...t??{},path:e,title:document.title}))}};var p=document.currentScript;p&&(window.openpanel=new d({url:p?.getAttribute("data-url"),clientId:p?.getAttribute("data-client-id"),trackOutgoingLinks:!!p?.getAttribute("data-track-outgoing-links"),trackScreenViews:!!p?.getAttribute("data-track-screen-views")}));})(); +"use strict";(()=>{function w(s){return Promise.all(Object.entries(s).map(async([t,e])=>[t,await e??""])).then(t=>Object.fromEntries(t))}function P(s){let t={"Content-Type":"application/json"};return{headers:t,async fetch(e,i,n){let o=`${s}${e}`,u,m=await w(t);return new Promise(c=>{let h=r=>{clearTimeout(u),fetch(o,{headers:m,method:"POST",body:JSON.stringify(i??{}),keepalive:!0,...n??{}}).then(async a=>{if(a.status!==200&&a.status!==202)return f(r,c);let g=await a.text();if(!g)return c(null);c(g)}).catch(()=>f(r,c))};function f(r,a){if(r>1)return a(null);u=setTimeout(()=>{h(r+1)},Math.pow(2,r)*500)}h(0)})}}}var l=class{options;api;state={properties:{}};constructor(t){this.options=t,this.api=P(t.url),this.api.headers["openpanel-client-id"]=t.clientId,this.options.clientSecret&&(this.api.headers["openpanel-client-secret"]=this.options.clientSecret)}init(t){this.state.properties=t??{}}setUser(t){this.api.fetch("/profile",{profileId:this.getProfileId(),...t,properties:{...this.state.properties,...t.properties}})}increment(t,e){this.api.fetch("/profile/increment",{property:t,value:e,profileId:this.getProfileId()})}decrement(t,e){this.api.fetch("/profile/decrement",{property:t,value:e,profileId:this.getProfileId()})}event(t,e){this.api.fetch("/event",{name:t,properties:{...this.state.properties,...e??{}},timestamp:this.timestamp(),profileId:this.getProfileId()}).then(i=>{this.options.setProfileId&&i&&this.options.setProfileId(i)})}setGlobalProperties(t){this.state.properties={...this.state.properties,...t}}clear(){this.state.profileId=void 0,this.options.removeProfileId&&this.options.removeProfileId()}timestamp(){return new Date().toISOString()}getProfileId(){if(this.state.profileId)return this.state.profileId;this.options.getProfileId&&(this.state.profileId=this.options.getProfileId()||void 0)}};var d=class extends l{lastPath="";constructor(t){super(t),this.isServer()||(this.setGlobalProperties({referrer:document.referrer}),this.options.trackOutgoingLinks&&this.trackOutgoingLinks(),this.options.trackScreenViews&&this.trackScreenViews())}isServer(){return typeof document>"u"}trackOutgoingLinks(){this.isServer()||document.addEventListener("click",t=>{let e=t.target,i=e.closest("a");if(i&&e){let n=i.getAttribute("href");n?.startsWith("http")&&super.event("link_out",{href:n,text:i.innerText||i.getAttribute("title")||e.getAttribute("alt")||e.getAttribute("title")})}})}trackScreenViews(){if(this.isServer())return;let t=history.pushState;history.pushState=function(...n){let o=t.apply(this,n);return window.dispatchEvent(new Event("pushstate")),window.dispatchEvent(new Event("locationchange")),o};let e=history.replaceState;history.replaceState=function(...n){let o=e.apply(this,n);return window.dispatchEvent(new Event("replacestate")),window.dispatchEvent(new Event("locationchange")),o},window.addEventListener("popstate",()=>window.dispatchEvent(new Event("locationchange"))),this.options.hash?window.addEventListener("hashchange",()=>this.screenView()):window.addEventListener("locationchange",()=>this.screenView()),this.screenView()}screenView(t){if(this.isServer())return;let e=window.location.href;this.lastPath!==e&&(this.lastPath=e,super.event("screen_view",{...t??{},path:e,title:document.title}))}};var p=document.currentScript;p&&(window.openpanel=new d({url:p?.getAttribute("data-url"),clientId:p?.getAttribute("data-client-id"),trackOutgoingLinks:!!p?.getAttribute("data-track-outgoing-links"),trackScreenViews:!!p?.getAttribute("data-track-screen-views")}));})(); //# sourceMappingURL=cdn.global.js.map \ No newline at end of file diff --git a/apps/public/src/app/api/waitlist/route.ts b/apps/public/src/app/api/waitlist/route.ts index 26352e46..06fb0548 100644 --- a/apps/public/src/app/api/waitlist/route.ts +++ b/apps/public/src/app/api/waitlist/route.ts @@ -1,7 +1,7 @@ import * as EmailValidator from 'email-validator'; import { NextResponse } from 'next/server'; -import { db } from '@mixan/db'; +import { db } from '@openpanel/db'; export const dynamic = 'force-dynamic'; diff --git a/apps/public/src/app/page.tsx b/apps/public/src/app/page.tsx index cd5dbf4e..a5d2faf9 100644 --- a/apps/public/src/app/page.tsx +++ b/apps/public/src/app/page.tsx @@ -1,4 +1,4 @@ -import { db } from '@mixan/db'; +import { db } from '@openpanel/db'; import { PreviewCarousel } from './carousel'; import { Heading2, Lead2, Paragraph } from './copy'; diff --git a/apps/public/tsconfig.json b/apps/public/tsconfig.json index 9d21e044..5df87e7a 100644 --- a/apps/public/tsconfig.json +++ b/apps/public/tsconfig.json @@ -1,25 +1,18 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "baseUrl": ".", "paths": { - "@/*": [ - "./src/*" - ] + "@/*": ["./src/*"], }, "plugins": [ { - "name": "next" - } + "name": "next", + }, ], "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json", - "strictNullChecks": true + "strictNullChecks": true, }, - "include": [ - ".", - ".next/types/**/*.ts" - ], - "exclude": [ - "node_modules" - ] + "include": [".", ".next/types/**/*.ts"], + "exclude": ["node_modules"], } diff --git a/apps/test/next.config.mjs b/apps/test/next.config.mjs index 4b9938c8..d3309c59 100644 --- a/apps/test/next.config.mjs +++ b/apps/test/next.config.mjs @@ -6,7 +6,7 @@ /** @type {import("next").NextConfig} */ const config = { reactStrictMode: false, - transpilePackages: ['@mixan/sdk', '@mixan/web', '@mixan/nextjs'], + transpilePackages: ['@openpanel/sdk', '@openpanel/web', '@openpanel/nextjs'], eslint: { ignoreDuringBuilds: true }, typescript: { ignoreBuildErrors: true }, /** diff --git a/apps/test/package.json b/apps/test/package.json index cf7e9246..68f85cae 100644 --- a/apps/test/package.json +++ b/apps/test/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/test", + "name": "@openpanel/test", "version": "0.1.0", "private": true, "scripts": { @@ -12,17 +12,17 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@mixan-test/nextjs": "workspace:@mixan/nextjs@*", - "@mixan-test/sdk": "workspace:@mixan/sdk@*", - "@mixan-test/web": "workspace:@mixan/web@*", + "@openpanel-test/nextjs": "workspace:@openpanel/nextjs@*", + "@openpanel-test/sdk": "workspace:@openpanel/sdk@*", + "@openpanel-test/web": "workspace:@openpanel/web@*", "next": "~14.1.0", "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@types/react": "^18.2.20", "@types/react-dom": "^18.2.7", "@types/react-syntax-highlighter": "^15.5.9", @@ -42,10 +42,10 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base", - "@mixan/eslint-config/nextjs", - "@mixan/eslint-config/react" + "@openpanel/eslint-config/base", + "@openpanel/eslint-config/nextjs", + "@openpanel/eslint-config/react" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/apps/test/public/op.js b/apps/test/public/op.js index 8d8698d6..897c8bd1 100644 --- a/apps/test/public/op.js +++ b/apps/test/public/op.js @@ -1,2 +1,2 @@ -"use strict";(()=>{function v(r){return Promise.all(Object.entries(r).map(async([t,e])=>[t,await e??""])).then(t=>Object.fromEntries(t))}function m(r){let t={"Content-Type":"application/json"};return{headers:t,async fetch(e,i,n){let s=`${r}${e}`,c,l=await v(t);return new Promise(o=>{let h=a=>{clearTimeout(c),fetch(s,{headers:l,method:"POST",body:JSON.stringify(i??{}),keepalive:!0,...n??{}}).then(async p=>{if(p.status!==200&&p.status!==202)return f(a,o);let g=await p.text();if(!g)return o(null);o(g)}).catch(()=>f(a,o))};function f(a,p){if(a>1)return p(null);c=setTimeout(()=>{h(a+1)},Math.pow(2,a)*500)}h(0)})}}}var d=class{options;api;state={properties:{}};constructor(t){this.options=t,this.api=m(t.url),this.api.headers["mixan-client-id"]=t.clientId,this.options.clientSecret&&(this.api.headers["mixan-client-secret"]=this.options.clientSecret)}init(t){this.state.properties=t??{}}setProfileId(t){this.state.profileId=t}setProfile(t){this.setProfileId(t.profileId),this.api.fetch("/profile",{...t,properties:{...this.state.properties,...t.properties}})}increment(t,e,i){let n=i?.profileId??this.state.profileId;if(!n)return console.log("No profile id");this.api.fetch("/profile/increment",{profileId:n,property:t,value:e})}decrement(t,e,i){let n=i?.profileId??this.state.profileId;if(!n)return console.log("No profile id");this.api.fetch("/profile/decrement",{profileId:n,property:t,value:e})}event(t,e){let i=e?.profileId??this.state.profileId;delete e?.profileId,this.api.fetch("/event",{name:t,properties:{...this.state.properties,...e??{}},timestamp:this.timestamp(),deviceId:this.getDeviceId(),profileId:i}).then(n=>{this.options.setDeviceId&&n&&this.options.setDeviceId(n)})}setGlobalProperties(t){this.state.properties={...this.state.properties,...t}}clear(){this.state.properties={},this.state.deviceId=void 0,this.options.removeDeviceId&&this.options.removeDeviceId()}timestamp(){return new Date().toISOString()}getDeviceId(){if(this.state.deviceId)return this.state.deviceId;this.options.getDeviceId&&(this.state.deviceId=this.options.getDeviceId()||void 0)}};function b(r){return r.replace(/([-_][a-z])/gi,t=>t.toUpperCase().replace("-","").replace("_",""))}var u=class extends d{lastPath="";constructor(t){super(t),this.isServer()||(this.setGlobalProperties({referrer:document.referrer}),this.options.trackOutgoingLinks&&this.trackOutgoingLinks(),this.options.trackScreenViews&&this.trackScreenViews(),this.options.trackAttributes&&this.trackAttributes())}isServer(){return typeof document>"u"}trackOutgoingLinks(){this.isServer()||document.addEventListener("click",t=>{let e=t.target,i=e.closest("a");if(i&&e){let n=i.getAttribute("href");n?.startsWith("http")&&super.event("link_out",{href:n,text:i.innerText||i.getAttribute("title")||e.getAttribute("alt")||e.getAttribute("title")})}})}trackScreenViews(){if(this.isServer())return;let t=history.pushState;history.pushState=function(...n){let s=t.apply(this,n);return window.dispatchEvent(new Event("pushstate")),window.dispatchEvent(new Event("locationchange")),s};let e=history.replaceState;history.replaceState=function(...n){let s=e.apply(this,n);return window.dispatchEvent(new Event("replacestate")),window.dispatchEvent(new Event("locationchange")),s},window.addEventListener("popstate",()=>window.dispatchEvent(new Event("locationchange"))),this.options.hash?window.addEventListener("hashchange",()=>this.screenView()):window.addEventListener("locationchange",()=>this.screenView()),setTimeout(()=>{this.screenView()},50)}trackAttributes(){this.isServer()||document.addEventListener("click",t=>{let e=t.target,i=e.closest("button"),n=e.closest("button"),s=i?.getAttribute("data-event")?i:n?.getAttribute("data-event")?n:null;if(s){let c={};for(let o of s.attributes)o.name.startsWith("data-")&&o.name!=="data-event"&&(c[b(o.name.replace(/^data-/,""))]=o.value);let l=s.getAttribute("data-event");l&&super.event(l,c)}})}screenView(t){if(this.isServer())return;let e=window.location.href;this.lastPath!==e&&(this.lastPath=e,super.event("screen_view",{...t??{},path:e,title:document.title}))}};(r=>{if(r.op&&"q"in r.op){let t=r.op.q||[],e=new u(t.shift()[1]);t.forEach(i=>{i[0]in e&&e[i[0]](...i.slice(1))}),r.op=(i,...n)=>{let s=e[i].bind(e);typeof s=="function"&&s(...n)}}})(window);})(); +"use strict";(()=>{function v(r){return Promise.all(Object.entries(r).map(async([t,e])=>[t,await e??""])).then(t=>Object.fromEntries(t))}function m(r){let t={"Content-Type":"application/json"};return{headers:t,async fetch(e,i,n){let s=`${r}${e}`,c,l=await v(t);return new Promise(o=>{let h=a=>{clearTimeout(c),fetch(s,{headers:l,method:"POST",body:JSON.stringify(i??{}),keepalive:!0,...n??{}}).then(async p=>{if(p.status!==200&&p.status!==202)return f(a,o);let g=await p.text();if(!g)return o(null);o(g)}).catch(()=>f(a,o))};function f(a,p){if(a>1)return p(null);c=setTimeout(()=>{h(a+1)},Math.pow(2,a)*500)}h(0)})}}}var d=class{options;api;state={properties:{}};constructor(t){this.options=t,this.api=m(t.url),this.api.headers["openpanel-client-id"]=t.clientId,this.options.clientSecret&&(this.api.headers["openpanel-client-secret"]=this.options.clientSecret)}init(t){this.state.properties=t??{}}setProfileId(t){this.state.profileId=t}setProfile(t){this.setProfileId(t.profileId),this.api.fetch("/profile",{...t,properties:{...this.state.properties,...t.properties}})}increment(t,e,i){let n=i?.profileId??this.state.profileId;if(!n)return console.log("No profile id");this.api.fetch("/profile/increment",{profileId:n,property:t,value:e})}decrement(t,e,i){let n=i?.profileId??this.state.profileId;if(!n)return console.log("No profile id");this.api.fetch("/profile/decrement",{profileId:n,property:t,value:e})}event(t,e){let i=e?.profileId??this.state.profileId;delete e?.profileId,this.api.fetch("/event",{name:t,properties:{...this.state.properties,...e??{}},timestamp:this.timestamp(),deviceId:this.getDeviceId(),profileId:i}).then(n=>{this.options.setDeviceId&&n&&this.options.setDeviceId(n)})}setGlobalProperties(t){this.state.properties={...this.state.properties,...t}}clear(){this.state.properties={},this.state.deviceId=void 0,this.options.removeDeviceId&&this.options.removeDeviceId()}timestamp(){return new Date().toISOString()}getDeviceId(){if(this.state.deviceId)return this.state.deviceId;this.options.getDeviceId&&(this.state.deviceId=this.options.getDeviceId()||void 0)}};function b(r){return r.replace(/([-_][a-z])/gi,t=>t.toUpperCase().replace("-","").replace("_",""))}var u=class extends d{lastPath="";constructor(t){super(t),this.isServer()||(this.setGlobalProperties({referrer:document.referrer}),this.options.trackOutgoingLinks&&this.trackOutgoingLinks(),this.options.trackScreenViews&&this.trackScreenViews(),this.options.trackAttributes&&this.trackAttributes())}isServer(){return typeof document>"u"}trackOutgoingLinks(){this.isServer()||document.addEventListener("click",t=>{let e=t.target,i=e.closest("a");if(i&&e){let n=i.getAttribute("href");n?.startsWith("http")&&super.event("link_out",{href:n,text:i.innerText||i.getAttribute("title")||e.getAttribute("alt")||e.getAttribute("title")})}})}trackScreenViews(){if(this.isServer())return;let t=history.pushState;history.pushState=function(...n){let s=t.apply(this,n);return window.dispatchEvent(new Event("pushstate")),window.dispatchEvent(new Event("locationchange")),s};let e=history.replaceState;history.replaceState=function(...n){let s=e.apply(this,n);return window.dispatchEvent(new Event("replacestate")),window.dispatchEvent(new Event("locationchange")),s},window.addEventListener("popstate",()=>window.dispatchEvent(new Event("locationchange"))),this.options.hash?window.addEventListener("hashchange",()=>this.screenView()):window.addEventListener("locationchange",()=>this.screenView()),setTimeout(()=>{this.screenView()},50)}trackAttributes(){this.isServer()||document.addEventListener("click",t=>{let e=t.target,i=e.closest("button"),n=e.closest("button"),s=i?.getAttribute("data-event")?i:n?.getAttribute("data-event")?n:null;if(s){let c={};for(let o of s.attributes)o.name.startsWith("data-")&&o.name!=="data-event"&&(c[b(o.name.replace(/^data-/,""))]=o.value);let l=s.getAttribute("data-event");l&&super.event(l,c)}})}screenView(t){if(this.isServer())return;let e=window.location.href;this.lastPath!==e&&(this.lastPath=e,super.event("screen_view",{...t??{},path:e,title:document.title}))}};(r=>{if(r.op&&"q"in r.op){let t=r.op.q||[],e=new u(t.shift()[1]);t.forEach(i=>{i[0]in e&&e[i[0]](...i.slice(1))}),r.op=(i,...n)=>{let s=e[i].bind(e);typeof s=="function"&&s(...n)}}})(window);})(); //# sourceMappingURL=cdn.global.js.map \ No newline at end of file diff --git a/apps/test/public/op.js.map b/apps/test/public/op.js.map index 82f6866b..cffe941b 100644 --- a/apps/test/public/op.js.map +++ b/apps/test/public/op.js.map @@ -1 +1,51 @@ -{"version":3,"sources":["../../sdk/index.ts","../index.ts","../cdn.ts"],"sourcesContent":["import type { PostEventPayload } from '@mixan/types';\n\nexport interface MixanOptions {\n url: string;\n clientId: string;\n clientSecret?: string;\n verbose?: boolean;\n setProfileId?: (profileId: string) => void;\n getProfileId?: () => string | null | undefined;\n removeProfileId?: () => void;\n}\n\nexport interface MixanState {\n profileId?: string;\n properties: Record;\n}\n\nfunction createApi(_url: string, clientId: string, clientSecret?: string) {\n return function post(\n path: string,\n data: ReqBody,\n options?: RequestInit\n ): Promise {\n const url = `${_url}${path}`;\n let timer: ReturnType;\n const headers: Record = {\n 'mixan-client-id': clientId,\n 'Content-Type': 'application/json',\n };\n if (clientSecret) {\n headers['mixan-client-secret'] = clientSecret;\n }\n return new Promise((resolve) => {\n const wrappedFetch = (attempt: number) => {\n clearTimeout(timer);\n fetch(url, {\n headers,\n method: 'POST',\n body: JSON.stringify(data ?? {}),\n keepalive: true,\n ...(options ?? {}),\n })\n .then(async (res) => {\n if (res.status !== 200) {\n return retry(attempt, resolve);\n }\n\n const response = await res.json();\n\n if (!response) {\n return resolve(null);\n }\n\n resolve(response as ResBody);\n })\n .catch(() => {\n return retry(attempt, resolve);\n });\n };\n\n function retry(\n attempt: number,\n resolve: (value: ResBody | null) => void\n ) {\n if (attempt > 1) {\n return resolve(null);\n }\n\n timer = setTimeout(\n () => {\n wrappedFetch(attempt + 1);\n },\n Math.pow(2, attempt) * 500\n );\n }\n\n wrappedFetch(0);\n });\n };\n}\n\nexport class Mixan {\n public options: Options;\n private api: ReturnType;\n private state: MixanState = {\n properties: {},\n };\n\n constructor(options: Options) {\n this.options = options;\n this.api = createApi(options.url, options.clientId, options.clientSecret);\n }\n\n // Public\n\n public init(properties?: Record) {\n this.state.properties = properties ?? {};\n }\n\n // public setUser(payload: Omit) {\n // this.batcher.add({\n // type: 'update_profile',\n // payload: {\n // ...payload,\n // properties: payload.properties ?? {},\n // profileId: this.state.profileId,\n // },\n // });\n // }\n\n // public increment(name: string, value: number) {\n // this.batcher.add({\n // type: 'increment',\n // payload: {\n // name,\n // value,\n // profileId: this.state.profileId,\n // },\n // });\n // }\n\n // public decrement(name: string, value: number) {\n // this.batcher.add({\n // type: 'decrement',\n // payload: {\n // name,\n // value,\n // profileId: this.state.profileId,\n // },\n // });\n // }\n\n private getProfileId() {\n if (this.state.profileId) {\n return this.state.profileId;\n } else if (this.options.getProfileId) {\n this.state.profileId = this.options.getProfileId() || undefined;\n }\n }\n\n public async event(name: string, properties?: Record) {\n const profileId = await this.api('/event', {\n name,\n properties: {\n ...this.state.properties,\n ...(properties ?? {}),\n },\n timestamp: this.timestamp(),\n profileId: this.getProfileId(),\n });\n\n if (this.options.setProfileId && profileId) {\n this.options.setProfileId(profileId);\n }\n }\n\n public setGlobalProperties(properties: Record) {\n this.state.properties = {\n ...this.state.properties,\n ...properties,\n };\n }\n\n public clear() {\n this.state.profileId = undefined;\n if (this.options.removeProfileId) {\n this.options.removeProfileId();\n }\n }\n\n public setUserProperty(name: string, value: unknown, update = true) {\n // this.batcher.add({\n // type: 'set_profile_property',\n // payload: {\n // name,\n // value,\n // update,\n // profileId: this.state.profileId,\n // },\n // });\n }\n\n // Private\n\n private timestamp() {\n return new Date().toISOString();\n }\n}\n","import type { MixanOptions } from '@mixan/sdk';\nimport { Mixan } from '@mixan/sdk';\n\ntype MixanWebOptions = MixanOptions & {\n trackOutgoingLinks?: boolean;\n trackScreenViews?: boolean;\n hash?: boolean;\n};\n\nexport class MixanWeb extends Mixan {\n constructor(options: MixanWebOptions) {\n super(options);\n\n if (this.options.trackOutgoingLinks) {\n this.trackOutgoingLinks();\n }\n\n if (this.options.trackScreenViews) {\n this.trackScreenViews();\n }\n }\n\n private isServer() {\n return typeof document === 'undefined';\n }\n\n private getTimezone() {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch (e) {\n return undefined;\n }\n }\n\n public trackOutgoingLinks() {\n if (this.isServer()) {\n return;\n }\n\n document.addEventListener('click', (event) => {\n const target = event.target as HTMLElement;\n if (target.tagName === 'A') {\n const href = target.getAttribute('href');\n if (href?.startsWith('http')) {\n super.event('link_out', {\n href,\n text: target.innerText,\n });\n }\n }\n });\n }\n\n public trackScreenViews() {\n if (this.isServer()) {\n return;\n }\n\n const oldPushState = history.pushState;\n history.pushState = function pushState(...args) {\n const ret = oldPushState.apply(this, args);\n window.dispatchEvent(new Event('pushstate'));\n window.dispatchEvent(new Event('locationchange'));\n return ret;\n };\n\n const oldReplaceState = history.replaceState;\n history.replaceState = function replaceState(...args) {\n const ret = oldReplaceState.apply(this, args);\n window.dispatchEvent(new Event('replacestate'));\n window.dispatchEvent(new Event('locationchange'));\n return ret;\n };\n\n window.addEventListener('popstate', () =>\n window.dispatchEvent(new Event('locationchange'))\n );\n\n if (this.options.hash) {\n window.addEventListener('hashchange', () => this.screenView());\n } else {\n window.addEventListener('locationchange', () => this.screenView());\n }\n }\n\n public screenView(properties?: Record): void {\n if (this.isServer()) {\n return;\n }\n\n super.event('screen_view', {\n ...(properties ?? {}),\n path: window.location.href,\n title: document.title,\n referrer: document.referrer,\n });\n }\n}\n","// @ts-nocheck\n\nimport { MixanWeb as Openpanel } from './index';\n\nconst el = document.currentScript;\nif (el) {\n window.openpanel = new Openpanel({\n url: el?.getAttribute('data-url'),\n clientId: el?.getAttribute('data-client-id'),\n clientSecret: el?.getAttribute('data-client-secret'),\n trackOutgoingLinks: !!el?.getAttribute('data-track-outgoing-links'),\n trackScreenViews: !!el?.getAttribute('data-track-screen-views'),\n });\n}\n"],"mappings":"mBAiBA,SAASA,EAAUC,EAAcC,EAAkBC,EAAuB,CACxE,OAAO,SACLC,EACAC,EACAC,EACyB,CACzB,IAAMC,EAAM,GAAGN,CAAI,GAAGG,CAAI,GACtBI,EACEC,EAAkC,CACtC,kBAAmBP,EACnB,eAAgB,kBAClB,EACA,OAAIC,IACFM,EAAQ,qBAAqB,EAAIN,GAE5B,IAAI,QAASO,GAAY,CAC9B,IAAMC,EAAgBC,GAAoB,CACxC,aAAaJ,CAAK,EAClB,MAAMD,EAAK,CACT,QAAAE,EACA,OAAQ,OACR,KAAM,KAAK,UAAUJ,GAAQ,CAAC,CAAC,EAC/B,UAAW,GACX,GAAIC,GAAW,CAAC,CAClB,CAAC,EACE,KAAK,MAAOO,GAAQ,CACnB,GAAIA,EAAI,SAAW,IACjB,OAAOC,EAAMF,EAASF,CAAO,EAG/B,IAAMK,EAAW,MAAMF,EAAI,KAAK,EAEhC,GAAI,CAACE,EACH,OAAOL,EAAQ,IAAI,EAGrBA,EAAQK,CAAmB,CAC7B,CAAC,EACA,MAAM,IACED,EAAMF,EAASF,CAAO,CAC9B,CACL,EAEA,SAASI,EACPF,EACAF,EACA,CACA,GAAIE,EAAU,EACZ,OAAOF,EAAQ,IAAI,EAGrBF,EAAQ,WACN,IAAM,CACJG,EAAaC,EAAU,CAAC,CAC1B,EACA,KAAK,IAAI,EAAGA,CAAO,EAAI,GACzB,CACF,CAEAD,EAAa,CAAC,CAChB,CAAC,CACH,CACF,CAEO,IAAMK,EAAN,KAAyD,CACvD,QACC,IACA,MAAoB,CAC1B,WAAY,CAAC,CACf,EAEA,YAAYV,EAAkB,CAC5B,KAAK,QAAUA,EACf,KAAK,IAAMN,EAAUM,EAAQ,IAAKA,EAAQ,SAAUA,EAAQ,YAAY,CAC1E,CAIO,KAAKW,EAAsC,CAChD,KAAK,MAAM,WAAaA,GAAc,CAAC,CACzC,CAmCQ,cAAe,CACrB,GAAI,KAAK,MAAM,UACb,OAAO,KAAK,MAAM,UACT,KAAK,QAAQ,eACtB,KAAK,MAAM,UAAY,KAAK,QAAQ,aAAa,GAAK,OAE1D,CAEA,MAAa,MAAMC,EAAcD,EAAsC,CACrE,IAAME,EAAY,MAAM,KAAK,IAA8B,SAAU,CACnE,KAAAD,EACA,WAAY,CACV,GAAG,KAAK,MAAM,WACd,GAAID,GAAc,CAAC,CACrB,EACA,UAAW,KAAK,UAAU,EAC1B,UAAW,KAAK,aAAa,CAC/B,CAAC,EAEG,KAAK,QAAQ,cAAgBE,GAC/B,KAAK,QAAQ,aAAaA,CAAS,CAEvC,CAEO,oBAAoBF,EAAqC,CAC9D,KAAK,MAAM,WAAa,CACtB,GAAG,KAAK,MAAM,WACd,GAAGA,CACL,CACF,CAEO,OAAQ,CACb,KAAK,MAAM,UAAY,OACnB,KAAK,QAAQ,iBACf,KAAK,QAAQ,gBAAgB,CAEjC,CAEO,gBAAgBC,EAAcE,EAAgBC,EAAS,GAAM,CAUpE,CAIQ,WAAY,CAClB,OAAO,IAAI,KAAK,EAAE,YAAY,CAChC,CACF,EClLO,IAAMC,EAAN,cAAuBC,CAAuB,CACnD,YAAYC,EAA0B,CACpC,MAAMA,CAAO,EAET,KAAK,QAAQ,oBACf,KAAK,mBAAmB,EAGtB,KAAK,QAAQ,kBACf,KAAK,iBAAiB,CAE1B,CAEQ,UAAW,CACjB,OAAO,OAAO,SAAa,GAC7B,CAEQ,aAAc,CACpB,GAAI,CACF,OAAO,KAAK,eAAe,EAAE,gBAAgB,EAAE,QACjD,MAAY,CACV,MACF,CACF,CAEO,oBAAqB,CACtB,KAAK,SAAS,GAIlB,SAAS,iBAAiB,QAAUC,GAAU,CAC5C,IAAMC,EAASD,EAAM,OACrB,GAAIC,EAAO,UAAY,IAAK,CAC1B,IAAMC,EAAOD,EAAO,aAAa,MAAM,EACnCC,GAAM,WAAW,MAAM,GACzB,MAAM,MAAM,WAAY,CACtB,KAAAA,EACA,KAAMD,EAAO,SACf,CAAC,CAEL,CACF,CAAC,CACH,CAEO,kBAAmB,CACxB,GAAI,KAAK,SAAS,EAChB,OAGF,IAAME,EAAe,QAAQ,UAC7B,QAAQ,UAAY,YAAsBC,EAAM,CAC9C,IAAMC,EAAMF,EAAa,MAAM,KAAMC,CAAI,EACzC,cAAO,cAAc,IAAI,MAAM,WAAW,CAAC,EAC3C,OAAO,cAAc,IAAI,MAAM,gBAAgB,CAAC,EACzCC,CACT,EAEA,IAAMC,EAAkB,QAAQ,aAChC,QAAQ,aAAe,YAAyBF,EAAM,CACpD,IAAMC,EAAMC,EAAgB,MAAM,KAAMF,CAAI,EAC5C,cAAO,cAAc,IAAI,MAAM,cAAc,CAAC,EAC9C,OAAO,cAAc,IAAI,MAAM,gBAAgB,CAAC,EACzCC,CACT,EAEA,OAAO,iBAAiB,WAAY,IAClC,OAAO,cAAc,IAAI,MAAM,gBAAgB,CAAC,CAClD,EAEI,KAAK,QAAQ,KACf,OAAO,iBAAiB,aAAc,IAAM,KAAK,WAAW,CAAC,EAE7D,OAAO,iBAAiB,iBAAkB,IAAM,KAAK,WAAW,CAAC,CAErE,CAEO,WAAWE,EAA4C,CACxD,KAAK,SAAS,GAIlB,MAAM,MAAM,cAAe,CACzB,GAAIA,GAAc,CAAC,EACnB,KAAM,OAAO,SAAS,KACtB,MAAO,SAAS,MAChB,SAAU,SAAS,QACrB,CAAC,CACH,CACF,EC7FA,IAAMC,EAAK,SAAS,cAChBA,IACF,OAAO,UAAY,IAAIC,EAAU,CAC/B,IAAKD,GAAI,aAAa,UAAU,EAChC,SAAUA,GAAI,aAAa,gBAAgB,EAC3C,aAAcA,GAAI,aAAa,oBAAoB,EACnD,mBAAoB,CAAC,CAACA,GAAI,aAAa,2BAA2B,EAClE,iBAAkB,CAAC,CAACA,GAAI,aAAa,yBAAyB,CAChE,CAAC","names":["createApi","_url","clientId","clientSecret","path","data","options","url","timer","headers","resolve","wrappedFetch","attempt","res","retry","response","Mixan","properties","name","profileId","value","update","MixanWeb","Mixan","options","event","target","href","oldPushState","args","ret","oldReplaceState","properties","el","MixanWeb"]} \ No newline at end of file +{ + "version": 3, + "sources": [ + "../../sdk/index.ts", + "../index.ts", + "../cdn.ts" + ], + "sourcesContent": [ + "import type { PostEventPayload } from '@openpanel/types';\n\nexport interface OpenpanelOptions {\n url: string;\n clientId: string;\n clientSecret?: string;\n verbose?: boolean;\n setProfileId?: (profileId: string) => void;\n getProfileId?: () => string | null | undefined;\n removeProfileId?: () => void;\n}\n\nexport interface OpenpanelState {\n profileId?: string;\n properties: Record;\n}\n\nfunction createApi(_url: string, clientId: string, clientSecret?: string) {\n return function post(\n path: string,\n data: ReqBody,\n options?: RequestInit\n ): Promise {\n const url = `${_url}${path}`;\n let timer: ReturnType;\n const headers: Record = {\n 'openpanel-client-id': clientId,\n 'Content-Type': 'application/json',\n };\n if (clientSecret) {\n headers['openpanel-client-secret'] = clientSecret;\n }\n return new Promise((resolve) => {\n const wrappedFetch = (attempt: number) => {\n clearTimeout(timer);\n fetch(url, {\n headers,\n method: 'POST',\n body: JSON.stringify(data ?? {}),\n keepalive: true,\n ...(options ?? {}),\n })\n .then(async (res) => {\n if (res.status !== 200) {\n return retry(attempt, resolve);\n }\n\n const response = await res.json();\n\n if (!response) {\n return resolve(null);\n }\n\n resolve(response as ResBody);\n })\n .catch(() => {\n return retry(attempt, resolve);\n });\n };\n\n function retry(\n attempt: number,\n resolve: (value: ResBody | null) => void\n ) {\n if (attempt > 1) {\n return resolve(null);\n }\n\n timer = setTimeout(\n () => {\n wrappedFetch(attempt + 1);\n },\n Math.pow(2, attempt) * 500\n );\n }\n\n wrappedFetch(0);\n });\n };\n}\n\nexport class Openpanel {\n public options: Options;\n private api: ReturnType;\n private state: OpenpanelState = {\n properties: {},\n };\n\n constructor(options: Options) {\n this.options = options;\n this.api = createApi(options.url, options.clientId, options.clientSecret);\n }\n\n // Public\n\n public init(properties?: Record) {\n this.state.properties = properties ?? {};\n }\n\n // public setUser(payload: Omit) {\n // this.batcher.add({\n // type: 'update_profile',\n // payload: {\n // ...payload,\n // properties: payload.properties ?? {},\n // profileId: this.state.profileId,\n // },\n // });\n // }\n\n // public increment(name: string, value: number) {\n // this.batcher.add({\n // type: 'increment',\n // payload: {\n // name,\n // value,\n // profileId: this.state.profileId,\n // },\n // });\n // }\n\n // public decrement(name: string, value: number) {\n // this.batcher.add({\n // type: 'decrement',\n // payload: {\n // name,\n // value,\n // profileId: this.state.profileId,\n // },\n // });\n // }\n\n private getProfileId() {\n if (this.state.profileId) {\n return this.state.profileId;\n } else if (this.options.getProfileId) {\n this.state.profileId = this.options.getProfileId() || undefined;\n }\n }\n\n public async event(name: string, properties?: Record) {\n const profileId = await this.api('/event', {\n name,\n properties: {\n ...this.state.properties,\n ...(properties ?? {}),\n },\n timestamp: this.timestamp(),\n profileId: this.getProfileId(),\n });\n\n if (this.options.setProfileId && profileId) {\n this.options.setProfileId(profileId);\n }\n }\n\n public setGlobalProperties(properties: Record) {\n this.state.properties = {\n ...this.state.properties,\n ...properties,\n };\n }\n\n public clear() {\n this.state.profileId = undefined;\n if (this.options.removeProfileId) {\n this.options.removeProfileId();\n }\n }\n\n public setUserProperty(name: string, value: unknown, update = true) {\n // this.batcher.add({\n // type: 'set_profile_property',\n // payload: {\n // name,\n // value,\n // update,\n // profileId: this.state.profileId,\n // },\n // });\n }\n\n // Private\n\n private timestamp() {\n return new Date().toISOString();\n }\n}\n", + "import type { OpenpanelOptions } from '@openpanel/sdk';\nimport { Openpanel } from '@openpanel/sdk';\n\ntype OpenpanelWebOptions = OpenpanelOptions & {\n trackOutgoingLinks?: boolean;\n trackScreenViews?: boolean;\n hash?: boolean;\n};\n\nexport class OpenpanelWeb extends Openpanel {\n constructor(options: OpenpanelWebOptions) {\n super(options);\n\n if (this.options.trackOutgoingLinks) {\n this.trackOutgoingLinks();\n }\n\n if (this.options.trackScreenViews) {\n this.trackScreenViews();\n }\n }\n\n private isServer() {\n return typeof document === 'undefined';\n }\n\n private getTimezone() {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch (e) {\n return undefined;\n }\n }\n\n public trackOutgoingLinks() {\n if (this.isServer()) {\n return;\n }\n\n document.addEventListener('click', (event) => {\n const target = event.target as HTMLElement;\n if (target.tagName === 'A') {\n const href = target.getAttribute('href');\n if (href?.startsWith('http')) {\n super.event('link_out', {\n href,\n text: target.innerText,\n });\n }\n }\n });\n }\n\n public trackScreenViews() {\n if (this.isServer()) {\n return;\n }\n\n const oldPushState = history.pushState;\n history.pushState = function pushState(...args) {\n const ret = oldPushState.apply(this, args);\n window.dispatchEvent(new Event('pushstate'));\n window.dispatchEvent(new Event('locationchange'));\n return ret;\n };\n\n const oldReplaceState = history.replaceState;\n history.replaceState = function replaceState(...args) {\n const ret = oldReplaceState.apply(this, args);\n window.dispatchEvent(new Event('replacestate'));\n window.dispatchEvent(new Event('locationchange'));\n return ret;\n };\n\n window.addEventListener('popstate', () =>\n window.dispatchEvent(new Event('locationchange'))\n );\n\n if (this.options.hash) {\n window.addEventListener('hashchange', () => this.screenView());\n } else {\n window.addEventListener('locationchange', () => this.screenView());\n }\n }\n\n public screenView(properties?: Record): void {\n if (this.isServer()) {\n return;\n }\n\n super.event('screen_view', {\n ...(properties ?? {}),\n path: window.location.href,\n title: document.title,\n referrer: document.referrer,\n });\n }\n}\n", + "// @ts-nocheck\n\nimport { OpenpanelWeb as Openpanel } from './index';\n\nconst el = document.currentScript;\nif (el) {\n window.openpanel = new Openpanel({\n url: el?.getAttribute('data-url'),\n clientId: el?.getAttribute('data-client-id'),\n clientSecret: el?.getAttribute('data-client-secret'),\n trackOutgoingLinks: !!el?.getAttribute('data-track-outgoing-links'),\n trackScreenViews: !!el?.getAttribute('data-track-screen-views'),\n });\n}\n" + ], + "mappings": "mBAiBA,SAASA,EAAUC,EAAcC,EAAkBC,EAAuB,CACxE,OAAO,SACLC,EACAC,EACAC,EACyB,CACzB,IAAMC,EAAM,GAAGN,CAAI,GAAGG,CAAI,GACtBI,EACEC,EAAkC,CACtC,kBAAmBP,EACnB,eAAgB,kBAClB,EACA,OAAIC,IACFM,EAAQ,qBAAqB,EAAIN,GAE5B,IAAI,QAASO,GAAY,CAC9B,IAAMC,EAAgBC,GAAoB,CACxC,aAAaJ,CAAK,EAClB,MAAMD,EAAK,CACT,QAAAE,EACA,OAAQ,OACR,KAAM,KAAK,UAAUJ,GAAQ,CAAC,CAAC,EAC/B,UAAW,GACX,GAAIC,GAAW,CAAC,CAClB,CAAC,EACE,KAAK,MAAOO,GAAQ,CACnB,GAAIA,EAAI,SAAW,IACjB,OAAOC,EAAMF,EAASF,CAAO,EAG/B,IAAMK,EAAW,MAAMF,EAAI,KAAK,EAEhC,GAAI,CAACE,EACH,OAAOL,EAAQ,IAAI,EAGrBA,EAAQK,CAAmB,CAC7B,CAAC,EACA,MAAM,IACED,EAAMF,EAASF,CAAO,CAC9B,CACL,EAEA,SAASI,EACPF,EACAF,EACA,CACA,GAAIE,EAAU,EACZ,OAAOF,EAAQ,IAAI,EAGrBF,EAAQ,WACN,IAAM,CACJG,EAAaC,EAAU,CAAC,CAC1B,EACA,KAAK,IAAI,EAAGA,CAAO,EAAI,GACzB,CACF,CAEAD,EAAa,CAAC,CAChB,CAAC,CACH,CACF,CAEO,IAAMK,EAAN,KAAyD,CACvD,QACC,IACA,MAAoB,CAC1B,WAAY,CAAC,CACf,EAEA,YAAYV,EAAkB,CAC5B,KAAK,QAAUA,EACf,KAAK,IAAMN,EAAUM,EAAQ,IAAKA,EAAQ,SAAUA,EAAQ,YAAY,CAC1E,CAIO,KAAKW,EAAsC,CAChD,KAAK,MAAM,WAAaA,GAAc,CAAC,CACzC,CAmCQ,cAAe,CACrB,GAAI,KAAK,MAAM,UACb,OAAO,KAAK,MAAM,UACT,KAAK,QAAQ,eACtB,KAAK,MAAM,UAAY,KAAK,QAAQ,aAAa,GAAK,OAE1D,CAEA,MAAa,MAAMC,EAAcD,EAAsC,CACrE,IAAME,EAAY,MAAM,KAAK,IAA8B,SAAU,CACnE,KAAAD,EACA,WAAY,CACV,GAAG,KAAK,MAAM,WACd,GAAID,GAAc,CAAC,CACrB,EACA,UAAW,KAAK,UAAU,EAC1B,UAAW,KAAK,aAAa,CAC/B,CAAC,EAEG,KAAK,QAAQ,cAAgBE,GAC/B,KAAK,QAAQ,aAAaA,CAAS,CAEvC,CAEO,oBAAoBF,EAAqC,CAC9D,KAAK,MAAM,WAAa,CACtB,GAAG,KAAK,MAAM,WACd,GAAGA,CACL,CACF,CAEO,OAAQ,CACb,KAAK,MAAM,UAAY,OACnB,KAAK,QAAQ,iBACf,KAAK,QAAQ,gBAAgB,CAEjC,CAEO,gBAAgBC,EAAcE,EAAgBC,EAAS,GAAM,CAUpE,CAIQ,WAAY,CAClB,OAAO,IAAI,KAAK,EAAE,YAAY,CAChC,CACF,EClLO,IAAMC,EAAN,cAAuBC,CAAuB,CACnD,YAAYC,EAA0B,CACpC,MAAMA,CAAO,EAET,KAAK,QAAQ,oBACf,KAAK,mBAAmB,EAGtB,KAAK,QAAQ,kBACf,KAAK,iBAAiB,CAE1B,CAEQ,UAAW,CACjB,OAAO,OAAO,SAAa,GAC7B,CAEQ,aAAc,CACpB,GAAI,CACF,OAAO,KAAK,eAAe,EAAE,gBAAgB,EAAE,QACjD,MAAY,CACV,MACF,CACF,CAEO,oBAAqB,CACtB,KAAK,SAAS,GAIlB,SAAS,iBAAiB,QAAUC,GAAU,CAC5C,IAAMC,EAASD,EAAM,OACrB,GAAIC,EAAO,UAAY,IAAK,CAC1B,IAAMC,EAAOD,EAAO,aAAa,MAAM,EACnCC,GAAM,WAAW,MAAM,GACzB,MAAM,MAAM,WAAY,CACtB,KAAAA,EACA,KAAMD,EAAO,SACf,CAAC,CAEL,CACF,CAAC,CACH,CAEO,kBAAmB,CACxB,GAAI,KAAK,SAAS,EAChB,OAGF,IAAME,EAAe,QAAQ,UAC7B,QAAQ,UAAY,YAAsBC,EAAM,CAC9C,IAAMC,EAAMF,EAAa,MAAM,KAAMC,CAAI,EACzC,cAAO,cAAc,IAAI,MAAM,WAAW,CAAC,EAC3C,OAAO,cAAc,IAAI,MAAM,gBAAgB,CAAC,EACzCC,CACT,EAEA,IAAMC,EAAkB,QAAQ,aAChC,QAAQ,aAAe,YAAyBF,EAAM,CACpD,IAAMC,EAAMC,EAAgB,MAAM,KAAMF,CAAI,EAC5C,cAAO,cAAc,IAAI,MAAM,cAAc,CAAC,EAC9C,OAAO,cAAc,IAAI,MAAM,gBAAgB,CAAC,EACzCC,CACT,EAEA,OAAO,iBAAiB,WAAY,IAClC,OAAO,cAAc,IAAI,MAAM,gBAAgB,CAAC,CAClD,EAEI,KAAK,QAAQ,KACf,OAAO,iBAAiB,aAAc,IAAM,KAAK,WAAW,CAAC,EAE7D,OAAO,iBAAiB,iBAAkB,IAAM,KAAK,WAAW,CAAC,CAErE,CAEO,WAAWE,EAA4C,CACxD,KAAK,SAAS,GAIlB,MAAM,MAAM,cAAe,CACzB,GAAIA,GAAc,CAAC,EACnB,KAAM,OAAO,SAAS,KACtB,MAAO,SAAS,MAChB,SAAU,SAAS,QACrB,CAAC,CACH,CACF,EC7FA,IAAMC,EAAK,SAAS,cAChBA,IACF,OAAO,UAAY,IAAIC,EAAU,CAC/B,IAAKD,GAAI,aAAa,UAAU,EAChC,SAAUA,GAAI,aAAa,gBAAgB,EAC3C,aAAcA,GAAI,aAAa,oBAAoB,EACnD,mBAAoB,CAAC,CAACA,GAAI,aAAa,2BAA2B,EAClE,iBAAkB,CAAC,CAACA,GAAI,aAAa,yBAAyB,CAChE,CAAC", + "names": [ + "createApi", + "_url", + "clientId", + "clientSecret", + "path", + "data", + "options", + "url", + "timer", + "headers", + "resolve", + "wrappedFetch", + "attempt", + "res", + "retry", + "response", + "Openpanel", + "properties", + "name", + "profileId", + "value", + "update", + "OpenpanelWeb", + "Openpanel", + "options", + "event", + "target", + "href", + "oldPushState", + "args", + "ret", + "oldReplaceState", + "properties", + "el", + "OpenpanelWeb" + ] +} diff --git a/apps/test/src/analytics.ts b/apps/test/src/analytics.ts index 910620b9..daa3ee7b 100644 --- a/apps/test/src/analytics.ts +++ b/apps/test/src/analytics.ts @@ -1,14 +1,127 @@ -// import { MixanWeb } from '@mixan-test/web'; +import type { FastifyReply, FastifyRequest } from "fastify"; +import icoToPng from "ico-to-png"; +import sharp from "sharp"; -// export const mixan = new MixanWeb({ -// verbose: true, -// url: 'http://localhost:3000/api/sdk', -// clientId: '568b4ed1-5d00-4f27-88a7-b8959e6674bd', -// clientSecret: '1e362905-d352-44c4-9263-e037a2ad52fb', -// trackIp: true, -// }); +import { createHash } from "@openpanel/common"; +import { redis } from "@openpanel/redis"; -// mixan.init({ -// appVersion: '1.0.0', -// }); -// mixan.trackOutgoingLinks(); +interface GetFaviconParams { + url: string; +} + +async function getImageBuffer(url: string) { + try { + const res = await fetch(url); + const contentType = res.headers.get("content-type"); + + if (!contentType?.includes("image")) { + return null; + } + + if (!res.ok) { + return null; + } + + if (contentType === "image/x-icon" || url.endsWith(".ico")) { + const arrayBuffer = await res.arrayBuffer(); + const buffer = Buffer.from(arrayBuffer); + return await icoToPng(buffer, 30); + } + + return await sharp(await res.arrayBuffer()) + .resize(30, 30, { + fit: "cover", + }) + .png() + .toBuffer(); + } catch (e) { + console.log("Failed to get image from url", url); + console.log(e); + } +} + +const imageExtensions = ["svg", "png", "jpg", "jpeg", "gif", "webp", "ico"]; + +export async function getFavicon( + request: FastifyRequest<{ + Querystring: GetFaviconParams; + }>, + reply: FastifyReply, +) { + function sendBuffer(buffer: Buffer, cacheKey?: string) { + if (cacheKey) { + redis.set(`favicon:${cacheKey}`, buffer.toString("base64")); + } + reply.type("image/png"); + console.log("buffer", buffer.byteLength); + + return reply.send(buffer); + } + + if (!request.query.url) { + return reply.status(404).send("Not found"); + } + + const url = decodeURIComponent(request.query.url); + + // DIRECT IMAGE + if (imageExtensions.find((ext) => url.endsWith(ext))) { + const cacheKey = createHash(url, 32); + const cache = await redis.get(`favicon:${cacheKey}`); + if (cache) { + return sendBuffer(Buffer.from(cache, "base64")); + } + const buffer = await getImageBuffer(url); + if (buffer && buffer.byteLength > 0) { + return sendBuffer(buffer, cacheKey); + } + } + + const { hostname, origin } = new URL(url); + const cache = await redis.get(`favicon:${hostname}`); + if (cache) { + return sendBuffer(Buffer.from(cache, "base64")); + } + + // TRY FAVICON.ICO + const buffer = await getImageBuffer(`${origin}/favicon.ico`); + if (buffer && buffer.byteLength > 0) { + return sendBuffer(buffer, hostname); + } + + // PARSE HTML + const res = await fetch(url).then((res) => res.text()); + + function findFavicon(res: string) { + const match = res.match( + /(\|\)/, + ); + if (!match) { + return null; + } + + return match[0].match(/href="(.+?)"/)?.[1] ?? null; + } + + const favicon = findFavicon(res); + if (favicon) { + const buffer = await getImageBuffer(favicon); + + if (buffer && buffer.byteLength > 0) { + return sendBuffer(buffer, hostname); + } + } + + return reply.status(404).send("Not found"); +} + +export async function clearFavicons( + request: FastifyRequest, + reply: FastifyReply, +) { + const keys = await redis.keys("favicon:*"); + for (const key of keys) { + await redis.del(key); + } + return reply.status(404).send("OK"); +} diff --git a/apps/test/src/app/app-dir/page.tsx b/apps/test/src/app/app-dir/page.tsx index 45836297..14befafb 100644 --- a/apps/test/src/app/app-dir/page.tsx +++ b/apps/test/src/app/app-dir/page.tsx @@ -1,59 +1,113 @@ -import { - OpenpanelProvider, - SetProfileId, - trackEvent, -} from '@mixan-test/nextjs'; -import { Mixan as Openpanel } from '@mixan-test/sdk'; +import { getClientIp, parseIp } from "@/utils/parseIp"; +import { isUserAgentSet, parseUserAgent } from "@/utils/parseUserAgent"; +import type { FastifyReply, FastifyRequest } from "fastify"; +import { assocPath, pathOr } from "ramda"; -const opServer = new Openpanel({ - clientId: '4c9a28cb-73c3-429f-beaf-4b3fe91352ea', - clientSecret: '2701ada9-fcbf-414a-ac94-9511949ee44d', - url: 'https://api.openpanel.dev', -}); +import { getProfileById, upsertProfile } from "@openpanel/db"; +import type { + IncrementProfilePayload, + UpdateProfilePayload, +} from "@openpanel/sdk"; -export default function Page() { - // Track event in server actions - async function create() { - 'use server'; - opServer.event('some-event', { - profileId: '1234', - }); +export async function updateProfile( + request: FastifyRequest<{ + Body: UpdateProfilePayload; + }>, + reply: FastifyReply, +) { + const { profileId, properties, ...rest } = request.body; + const projectId = request.projectId; + const ip = getClientIp(request)!; + const ua = request.headers["user-agent"]!; + const uaInfo = parseUserAgent(ua); + const geo = await parseIp(ip); + + await upsertProfile({ + id: profileId, + projectId, + properties: { + ...(properties ?? {}), + ...(ip ? geo : {}), + ...(isUserAgentSet(ua) ? uaInfo : {}), + }, + ...rest, + }); + + reply.status(202).send(profileId); +} + +export async function incrementProfileProperty( + request: FastifyRequest<{ + Body: IncrementProfilePayload; + }>, + reply: FastifyReply, +) { + const { profileId, property, value } = request.body; + const projectId = request.projectId; + + const profile = await getProfileById(profileId); + if (!profile) { + return reply.status(404).send("Not found"); } - return ( -
- {/* In layout.tsx (app dir) or _app.tsx (pages) */} - - - {/* Provide user id in React Server Components */} - - - - - -
+ const parsed = parseInt( + pathOr("0", property.split("."), profile.properties), + 10, ); + + if (isNaN(parsed)) { + return reply.status(400).send("Not number"); + } + + profile.properties = assocPath( + property.split("."), + parsed + value, + profile.properties, + ); + + await upsertProfile({ + id: profile.id, + projectId, + properties: profile.properties, + }); + + reply.status(202).send(profile.id); +} + +export async function decrementProfileProperty( + request: FastifyRequest<{ + Body: IncrementProfilePayload; + }>, + reply: FastifyReply, +) { + const { profileId, property, value } = request.body; + const projectId = request.projectId; + + const profile = await getProfileById(profileId); + if (!profile) { + return reply.status(404).send("Not found"); + } + + const parsed = parseInt( + pathOr("0", property.split("."), profile.properties), + 10, + ); + + if (isNaN(parsed)) { + return reply.status(400).send("Not number"); + } + + profile.properties = assocPath( + property.split("."), + parsed - value, + profile.properties, + ); + + await upsertProfile({ + id: profile.id, + projectId, + properties: profile.properties, + }); + + reply.status(202).send(profile.id); } diff --git a/apps/test/src/app/layout.tsx b/apps/test/src/app/layout.tsx index 2a1915d1..f15c9cd8 100644 --- a/apps/test/src/app/layout.tsx +++ b/apps/test/src/app/layout.tsx @@ -1,4 +1,4 @@ -import { OpenpanelProvider } from '@mixan-test/nextjs'; +import { OpenpanelProvider } from '@openpanel-test/nextjs'; export default function Layout({ children }: { children: React.ReactNode }) { return ( diff --git a/apps/test/src/pages/_app.tsx b/apps/test/src/pages/_app.tsx index 61c6ad43..348016a3 100644 --- a/apps/test/src/pages/_app.tsx +++ b/apps/test/src/pages/_app.tsx @@ -1,15 +1,51 @@ -import { OpenpanelProvider } from '@mixan-test/nextjs'; -import type { AppProps } from 'next/app'; - -export default function MyApp({ Component, pageProps }: AppProps) { - return ( - <> - - - - ); +{ + "name": "@openpanel/api", + "version": "0.0.1", + "scripts": { + "dev": "dotenv -e ../../.env -c -v WATCH=1 tsup", + "testing": "API_PORT=3333 pnpm dev", + "start": "node dist/index.js", + "build": "rm -rf dist && tsup", + "lint": "eslint .", + "format": "prettier --check \"**/*.{mjs,ts,md,json}\"", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@fastify/cors": "^9.0.0", + "@fastify/websocket": "^8.3.1", + "@logtail/pino": "^0.4.19", + "@openpanel/common": "workspace:*", + "@openpanel/db": "workspace:*", + "@openpanel/queue": "workspace:*", + "@openpanel/redis": "workspace:*", + "fastify": "^4.25.2", + "ico-to-png": "^0.2.1", + "pino": "^8.17.2", + "pino-pretty": "^10.3.1", + "ramda": "^0.29.1", + "sharp": "^0.33.2", + "ua-parser-js": "^1.0.37", + "uuid": "^9.0.1" + }, + "devDependencies": { + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/sdk": "workspace:*", + "@openpanel/tsconfig": "workspace:*", + "@types/ramda": "^0.29.6", + "@types/ua-parser-js": "^0.7.39", + "@types/uuid": "^9.0.8", + "@types/ws": "^8.5.10", + "eslint": "^8.48.0", + "prettier": "^3.0.3", + "tsup": "^7.2.0", + "typescript": "^5.2.2" + }, + "eslintConfig": { + "root": true, + "extends": [ + "@openpanel/eslint-config/base" + ] + }, + "prettier": "@openpanel/prettier-config" } diff --git a/apps/test/src/pages/test.tsx b/apps/test/src/pages/test.tsx index 1cdd3918..d93d4241 100644 --- a/apps/test/src/pages/test.tsx +++ b/apps/test/src/pages/test.tsx @@ -5,7 +5,7 @@ import { increment, setProfile, trackEvent, -} from '@mixan-test/nextjs'; +} from '@openpanel-test/nextjs'; import Link from 'next/link'; export default function Test() { diff --git a/apps/test/tsconfig.json b/apps/test/tsconfig.json index 9d21e044..f25ad65e 100644 --- a/apps/test/tsconfig.json +++ b/apps/test/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "baseUrl": ".", "paths": { diff --git a/apps/worker/package.json b/apps/worker/package.json index 935d9ef5..f56f9d04 100644 --- a/apps/worker/package.json +++ b/apps/worker/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/worker", + "name": "@openpanel/worker", "version": "0.0.1", "scripts": { "dev": "dotenv -e ../../.env -c -v WATCH=1 tsup", @@ -13,18 +13,18 @@ "dependencies": { "@bull-board/api": "^5.13.0", "@bull-board/express": "^5.13.0", - "@mixan/db": "workspace:*", - "@mixan/queue": "workspace:*", - "@mixan/common": "workspace:*", - "@mixan/redis": "workspace:*", + "@openpanel/db": "workspace:*", + "@openpanel/queue": "workspace:*", + "@openpanel/common": "workspace:*", + "@openpanel/redis": "workspace:*", "bullmq": "^5.1.1", "express": "^4.18.2", "ramda": "^0.29.1" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@types/express": "^4.17.21", "@types/ramda": "^0.29.6", "eslint": "^8.48.0", @@ -35,8 +35,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/apps/worker/src/index.ts b/apps/worker/src/index.ts index a43b4862..422a5588 100644 --- a/apps/worker/src/index.ts +++ b/apps/worker/src/index.ts @@ -5,8 +5,8 @@ import type { WorkerOptions } from 'bullmq'; import { Worker } from 'bullmq'; import express from 'express'; -import { connection, eventsQueue } from '@mixan/queue'; -import { cronQueue } from '@mixan/queue/src/queues'; +import { connection, eventsQueue } from '@openpanel/queue'; +import { cronQueue } from '@openpanel/queue/src/queues'; import { cronJob } from './jobs/cron'; import { eventsJob } from './jobs/events'; diff --git a/apps/worker/src/jobs/cron.salt.ts b/apps/worker/src/jobs/cron.salt.ts index 403bf64b..9792040e 100644 --- a/apps/worker/src/jobs/cron.salt.ts +++ b/apps/worker/src/jobs/cron.salt.ts @@ -1,5 +1,5 @@ -import { generateSalt } from '@mixan/common'; -import { db, getCurrentSalt } from '@mixan/db'; +import { generateSalt } from '@openpanel/common'; +import { db, getCurrentSalt } from '@openpanel/db'; export async function salt() { const oldSalt = await getCurrentSalt(); diff --git a/apps/worker/src/jobs/cron.ts b/apps/worker/src/jobs/cron.ts index 7dfa16f8..87e5d588 100644 --- a/apps/worker/src/jobs/cron.ts +++ b/apps/worker/src/jobs/cron.ts @@ -1,6 +1,6 @@ import type { Job } from 'bullmq'; -import type { CronQueuePayload } from '@mixan/queue/src/queues'; +import type { CronQueuePayload } from '@openpanel/queue/src/queues'; import { salt } from './cron.salt'; diff --git a/apps/worker/src/jobs/events.create-session-end.ts b/apps/worker/src/jobs/events.create-session-end.ts index 982c7012..ee7b2a22 100644 --- a/apps/worker/src/jobs/events.create-session-end.ts +++ b/apps/worker/src/jobs/events.create-session-end.ts @@ -1,8 +1,8 @@ import type { Job } from 'bullmq'; -import { getTime } from '@mixan/common'; -import { createEvent, getEvents } from '@mixan/db'; -import type { EventsQueuePayloadCreateSessionEnd } from '@mixan/queue/src/queues'; +import { getTime } from '@openpanel/common'; +import { createEvent, getEvents } from '@openpanel/db'; +import type { EventsQueuePayloadCreateSessionEnd } from '@openpanel/queue/src/queues'; export async function createSessionEnd( job: Job diff --git a/apps/worker/src/jobs/events.ts b/apps/worker/src/jobs/events.ts index c8811d1b..08998f83 100644 --- a/apps/worker/src/jobs/events.ts +++ b/apps/worker/src/jobs/events.ts @@ -1,10 +1,10 @@ import type { Job } from 'bullmq'; -import { createEvent } from '@mixan/db'; +import { createEvent } from '@openpanel/db'; import type { EventsQueuePayload, EventsQueuePayloadCreateSessionEnd, -} from '@mixan/queue/src/queues'; +} from '@openpanel/queue/src/queues'; import { createSessionEnd } from './events.create-session-end'; diff --git a/apps/worker/tsconfig.json b/apps/worker/tsconfig.json index 73b1bbe4..5df87e7a 100644 --- a/apps/worker/tsconfig.json +++ b/apps/worker/tsconfig.json @@ -1,12 +1,18 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "baseUrl": ".", "paths": { - "@/*": ["./src/*"] + "@/*": ["./src/*"], }, - "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" + "plugins": [ + { + "name": "next", + }, + ], + "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json", + "strictNullChecks": true, }, - "include": ["."], - "exclude": ["node_modules"] + "include": [".", ".next/types/**/*.ts"], + "exclude": ["node_modules"], } diff --git a/apps/worker/tsup.config.ts b/apps/worker/tsup.config.ts index 8085bff4..995a74bd 100644 --- a/apps/worker/tsup.config.ts +++ b/apps/worker/tsup.config.ts @@ -4,7 +4,7 @@ import type { Options } from 'tsup'; const options: Options = { clean: true, entry: ['src/index.ts'], - noExternal: [/^@mixan\/.*$/u, /^@\/.*$/u], + noExternal: [/^@openpanel\/.*$/u, /^@\/.*$/u], sourcemap: true, splitting: false, }; diff --git a/docker/Dockerfile-composed b/docker/Dockerfile-composed index 713202a1..149409d5 100644 --- a/docker/Dockerfile-composed +++ b/docker/Dockerfile-composed @@ -6,7 +6,7 @@ FROM --platform=linux/amd64 node:20-slim AS base -ARG DATABASE_URL="postgresql://local@host.docker.internal:5432/mixan?schema=public" +ARG DATABASE_URL="postgresql://local@host.docker.internal:5432/openpanel?schema=public" ENV DATABASE_URL=$DATABASE_URL ARG NEXTAUTH_SECRET="secret_sauce" diff --git a/docker/Dockerfile-web b/docker/Dockerfile-web index 9bc83e58..b4f59593 100644 --- a/docker/Dockerfile-web +++ b/docker/Dockerfile-web @@ -2,7 +2,7 @@ FROM --platform=linux/amd64 node:20-slim AS base -ARG DATABASE_URL="postgresql://local@host.docker.internal:5432/mixan?schema=public" +ARG DATABASE_URL="postgresql://local@host.docker.internal:5432/openpanel?schema=public" ENV DATABASE_URL=$DATABASE_URL ARG NEXTAUTH_SECRET="secret_sauce" diff --git a/docker/Dockerfile-worker b/docker/Dockerfile-worker index 437b5519..de6da350 100644 --- a/docker/Dockerfile-worker +++ b/docker/Dockerfile-worker @@ -2,7 +2,7 @@ FROM --platform=linux/amd64 node:20-slim AS base -ARG DATABASE_URL="postgresql://local@host.docker.internal:5432/mixan?schema=public" +ARG DATABASE_URL="postgresql://local@host.docker.internal:5432/openpanel?schema=public" ENV DATABASE_URL=$DATABASE_URL ARG REDIS_URL="redis://127.0.0.1:6379" diff --git a/docker/build-composed b/docker/build-composed index 9626e5e8..cb872e52 100755 --- a/docker/build-composed +++ b/docker/build-composed @@ -1,10 +1,10 @@ #!/bin/bash docker build \ - --build-arg DATABASE_URL="postgresql://local@host.docker.internal:5432/mixan?schema=public" \ + --build-arg DATABASE_URL="postgresql://local@host.docker.internal:5432/openpanel?schema=public" \ --build-arg NEXTAUTH_SECRET="secret_sauce" \ --build-arg REDIS_URL="redis://127.0.0.1:6379" \ - -t mixan/composed:latest \ - -t mixan/composed:1.0 \ + -t openpanel/composed:latest \ + -t openpanel/composed:1.0 \ -f docker/Dockerfile-composed \ . \ No newline at end of file diff --git a/images/bar.png b/images/bar.png deleted file mode 100644 index 9d371cd8..00000000 Binary files a/images/bar.png and /dev/null differ diff --git a/images/dashboard.png b/images/dashboard.png deleted file mode 100644 index a46b917b..00000000 Binary files a/images/dashboard.png and /dev/null differ diff --git a/images/line.png b/images/line.png deleted file mode 100644 index 5bf35a35..00000000 Binary files a/images/line.png and /dev/null differ diff --git a/images/mixan.svg b/images/mixan.svg deleted file mode 100644 index 031d4e9c..00000000 --- a/images/mixan.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/images/settings.png b/images/settings.png deleted file mode 100644 index b0d6ba18..00000000 Binary files a/images/settings.png and /dev/null differ diff --git a/package.json b/package.json index 76c71b47..99ff28f7 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/root", + "name": "@openpanel/root", "version": "1.0.0", "private": true, "license": "MIT", @@ -20,11 +20,11 @@ "typecheck": "pnpm -r typecheck" }, "dependencies": { - "@mixan/prettier-config": "^0.1.0", + "@openpanel/prettier-config": "^0.1.0", "dotenv-cli": "^7.3.0", "prettier": "^3.0.3", "semver": "^7.5.4", "typescript": "^5.2.2" }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/packages/common/package.json b/packages/common/package.json index 97e8c3ad..410e031c 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/common", + "name": "@openpanel/common", "version": "0.0.1", "main": "index.ts", "scripts": { @@ -12,9 +12,9 @@ "unique-names-generator": "^4.7.1" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@types/node": "^18.16.0", "@types/ramda": "^0.29.6", "eslint": "^8.48.0", @@ -25,8 +25,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/packages/common/tsconfig.json b/packages/common/tsconfig.json index 73b1bbe4..a291eef2 100644 --- a/packages/common/tsconfig.json +++ b/packages/common/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "baseUrl": ".", "paths": { diff --git a/packages/constants/package.json b/packages/constants/package.json index 46c506a5..35f91619 100644 --- a/packages/constants/package.json +++ b/packages/constants/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/constants", + "name": "@openpanel/constants", "version": "0.0.1", "main": "index.ts", "scripts": { @@ -8,9 +8,9 @@ "typecheck": "tsc --noEmit" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "date-fns": "^3.3.1", "eslint": "^8.48.0", "prettier": "^3.0.3", @@ -20,8 +20,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/packages/constants/tsconfig.json b/packages/constants/tsconfig.json index 73b1bbe4..a291eef2 100644 --- a/packages/constants/tsconfig.json +++ b/packages/constants/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "baseUrl": ".", "paths": { diff --git a/packages/db/package.json b/packages/db/package.json index 6e45d10f..7ea06e8f 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/db", + "name": "@openpanel/db", "version": "0.0.1", "main": "index.ts", "scripts": { @@ -14,18 +14,18 @@ "dependencies": { "@clerk/nextjs": "^4.29.7", "@clickhouse/client": "^0.2.9", - "@mixan/common": "workspace:*", - "@mixan/constants": "workspace:*", - "@mixan/redis": "workspace:*", - "@mixan/validation": "workspace:*", + "@openpanel/common": "workspace:*", + "@openpanel/constants": "workspace:*", + "@openpanel/redis": "workspace:*", + "@openpanel/validation": "workspace:*", "@prisma/client": "^5.1.1", "ramda": "^0.29.1", "uuid": "^9.0.1" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@types/node": "^18.16.0", "@types/ramda": "^0.29.6", "@types/uuid": "^9.0.8", @@ -37,8 +37,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/packages/db/scripts/insert.ts b/packages/db/scripts/insert.ts index e0940c87..5f270b23 100644 --- a/packages/db/scripts/insert.ts +++ b/packages/db/scripts/insert.ts @@ -40,8 +40,8 @@ async function push(event: Event) { 'Content-Type': 'application/json', 'User-Agent': event.properties.ua, 'X-Forwarded-For': event.properties.ip, - 'mixan-client-id': 'c8b4962e-bc3d-4b23-8ea4-505c8fbdf09e', - origin: 'https://mixan.kiddo.se', + 'openpanel-client-id': 'c8b4962e-bc3d-4b23-8ea4-505c8fbdf09e', + origin: 'https://openpanel.kiddo.se', }, }).catch(() => {}); } @@ -93,7 +93,7 @@ async function main() { const projectId = event.project_id; const path = event.properties.path as string; const ip = event.properties.ip as string; - const origin = 'https://mixan.kiddo.se'; + const origin = 'https://openpanel.kiddo.se'; const ua = event.properties.ua as string; const uaInfo = parseUserAgent(ua); const salts = await getSalts(); diff --git a/packages/db/src/services/chart.service.ts b/packages/db/src/services/chart.service.ts index b4009f64..2ea800e7 100644 --- a/packages/db/src/services/chart.service.ts +++ b/packages/db/src/services/chart.service.ts @@ -1,4 +1,4 @@ -import type { IChartEventFilter, IGetChartDataInput } from '@mixan/validation'; +import type { IChartEventFilter, IGetChartDataInput } from '@openpanel/validation'; import { formatClickhouseDate } from '../clickhouse-client'; import type { SqlBuilderObject } from '../sql-builder'; diff --git a/packages/db/src/services/event.service.ts b/packages/db/src/services/event.service.ts index 912c7e35..3d9be664 100644 --- a/packages/db/src/services/event.service.ts +++ b/packages/db/src/services/event.service.ts @@ -1,22 +1,22 @@ -import { omit, uniq } from 'ramda'; -import { v4 as uuid } from 'uuid'; +import { omit, uniq } from "ramda"; +import { v4 as uuid } from "uuid"; -import { randomSplitName, toDots } from '@mixan/common'; -import { redis, redisPub } from '@mixan/redis'; -import type { IChartEventFilter } from '@mixan/validation'; +import { randomSplitName, toDots } from "@openpanel/common"; +import { redis, redisPub } from "@openpanel/redis"; +import type { IChartEventFilter } from "@openpanel/validation"; import { ch, chQuery, convertClickhouseDateToJs, formatClickhouseDate, -} from '../clickhouse-client'; -import type { EventMeta, Prisma } from '../prisma-client'; -import { db } from '../prisma-client'; -import { createSqlBuilder } from '../sql-builder'; -import { getEventFiltersWhereClause } from './chart.service'; -import { getProfileById, getProfiles, upsertProfile } from './profile.service'; -import type { IServiceProfile } from './profile.service'; +} from "../clickhouse-client"; +import type { EventMeta, Prisma } from "../prisma-client"; +import { db } from "../prisma-client"; +import { createSqlBuilder } from "../sql-builder"; +import { getEventFiltersWhereClause } from "./chart.service"; +import { getProfileById, getProfiles, upsertProfile } from "./profile.service"; +import type { IServiceProfile } from "./profile.service"; export interface IClickhouseEvent { id: string; @@ -49,7 +49,7 @@ export interface IClickhouseEvent { } export function transformEvent( - event: IClickhouseEvent + event: IClickhouseEvent, ): IServiceCreateEventPayload { return { id: event.id, @@ -124,7 +124,7 @@ export async function getLiveVisitors(projectId: string) { export async function getEvents( sql: string, - options: GetEventsOptions = {} + options: GetEventsOptions = {}, ): Promise { const events = await chQuery(sql); if (options.profile) { @@ -155,17 +155,17 @@ export async function getEvents( } export async function createEvent( - payload: Omit + payload: Omit, ) { if (!payload.profileId) { payload.profileId = payload.deviceId; } console.log( - `create event ${payload.name} for deviceId: ${payload.deviceId} profileId ${payload.profileId}` + `create event ${payload.name} for deviceId: ${payload.deviceId} profileId ${payload.profileId}`, ); const exists = await getProfileById(payload.profileId); - if (!exists && payload.profileId !== '') { + if (!exists && payload.profileId !== "") { const { firstName, lastName } = randomSplitName(); await upsertProfile({ id: payload.profileId, @@ -198,40 +198,40 @@ export async function createEvent( profile_id: payload.profileId, project_id: payload.projectId, session_id: payload.sessionId, - properties: toDots(omit(['_path'], payload.properties)), - path: payload.path ?? '', + properties: toDots(omit(["_path"], payload.properties)), + path: payload.path ?? "", created_at: formatClickhouseDate(payload.createdAt), - country: payload.country ?? '', - city: payload.city ?? '', - region: payload.region ?? '', - os: payload.os ?? '', - os_version: payload.osVersion ?? '', - browser: payload.browser ?? '', - browser_version: payload.browserVersion ?? '', - device: payload.device ?? '', - brand: payload.brand ?? '', - model: payload.model ?? '', + country: payload.country ?? "", + city: payload.city ?? "", + region: payload.region ?? "", + os: payload.os ?? "", + os_version: payload.osVersion ?? "", + browser: payload.browser ?? "", + browser_version: payload.browserVersion ?? "", + device: payload.device ?? "", + brand: payload.brand ?? "", + model: payload.model ?? "", duration: payload.duration, - referrer: payload.referrer ?? '', - referrer_name: payload.referrerName ?? '', - referrer_type: payload.referrerType ?? '', + referrer: payload.referrer ?? "", + referrer_name: payload.referrerName ?? "", + referrer_type: payload.referrerType ?? "", }; const res = await ch.insert({ - table: 'events', + table: "events", values: [event], - format: 'JSONEachRow', + format: "JSONEachRow", clickhouse_settings: { - date_time_input_format: 'best_effort', + date_time_input_format: "best_effort", }, }); - redisPub.publish('event', JSON.stringify(transformEvent(event))); + redisPub.publish("event", JSON.stringify(transformEvent(event))); redis.set( `live:event:${event.project_id}:${event.profile_id}`, - '', - 'EX', - 60 * 5 + "", + "EX", + 60 * 5, ); return { @@ -270,7 +270,7 @@ export async function getEventList({ if (events && events.length > 0) { sb.where.events = `name IN (${join( events.map((n) => `'${n}'`), - ',' + ",", )})`; } @@ -285,7 +285,7 @@ export async function getEventList({ // sb.where.cursor = `created_at <= '${formatClickhouseDate(cursor)}'`; // } - sb.orderBy.created_at = 'created_at DESC'; + sb.orderBy.created_at = "created_at DESC"; return getEvents(getSql(), { profile: true, meta: true }); } @@ -295,7 +295,7 @@ export async function getEventsCount({ profileId, events, filters, -}: Omit) { +}: Omit) { const { sb, getSql, join } = createSqlBuilder(); sb.where.projectId = `project_id = '${projectId}'`; if (profileId) { @@ -305,7 +305,7 @@ export async function getEventsCount({ if (events && events.length > 0) { sb.where.events = `name IN (${join( events.map((n) => `'${n}'`), - ',' + ",", )})`; } @@ -317,7 +317,7 @@ export async function getEventsCount({ } const res = await chQuery<{ count: number }>( - getSql().replace('*', 'count(*) as count') + getSql().replace("*", "count(*) as count"), ); return res[0]?.count ?? 0; @@ -339,8 +339,8 @@ export function createBotEvent({ path, }: CreateBotEventPayload) { return ch.insert({ - table: 'events_bots', - format: 'JSONEachRow', + table: "events_bots", + format: "JSONEachRow", values: [ { name, diff --git a/packages/db/src/services/profile.service.ts b/packages/db/src/services/profile.service.ts index 3633b177..a64f6587 100644 --- a/packages/db/src/services/profile.service.ts +++ b/packages/db/src/services/profile.service.ts @@ -1,17 +1,17 @@ -import { toDots, toObject } from '@mixan/common'; -import type { IChartEventFilter } from '@mixan/validation'; +import { toDots, toObject } from "@openpanel/common"; +import type { IChartEventFilter } from "@openpanel/validation"; -import { ch, chQuery } from '../clickhouse-client'; -import { createSqlBuilder } from '../sql-builder'; -import { getEventFiltersWhereClause } from './chart.service'; +import { ch, chQuery } from "../clickhouse-client"; +import { createSqlBuilder } from "../sql-builder"; +import { getEventFiltersWhereClause } from "./chart.service"; export async function getProfileById(id: string) { - if (id === '') { + if (id === "") { return null; } const [profile] = await chQuery( - `SELECT * FROM profiles WHERE id = '${id}' ORDER BY created_at DESC LIMIT 1` + `SELECT * FROM profiles WHERE id = '${id}' ORDER BY created_at DESC LIMIT 1`, ); if (!profile) { @@ -30,15 +30,15 @@ interface GetProfileListOptions { function getProfileSelectFields() { return [ - 'id', - 'argMax(first_name, created_at) as first_name', - 'argMax(last_name, created_at) as last_name', - 'argMax(email, created_at) as email', - 'argMax(avatar, created_at) as avatar', - 'argMax(properties, created_at) as properties', - 'argMax(project_id, created_at) as project_id', - 'max(created_at) as max_created_at', - ].join(', '); + "id", + "argMax(first_name, created_at) as first_name", + "argMax(last_name, created_at) as last_name", + "argMax(email, created_at) as email", + "argMax(avatar, created_at) as avatar", + "argMax(properties, created_at) as properties", + "argMax(project_id, created_at) as project_id", + "max(created_at) as max_created_at", + ].join(", "); } interface GetProfilesOptions { @@ -53,9 +53,9 @@ export async function getProfiles({ ids }: GetProfilesOptions) { `SELECT ${getProfileSelectFields()} FROM profiles - WHERE id IN (${ids.map((id) => `'${id}'`).join(',')}) + WHERE id IN (${ids.map((id) => `'${id}'`).join(",")}) GROUP BY id - ` + `, ); return data.map(transformProfile); @@ -85,7 +85,7 @@ export async function getProfileList({ } sb.limit = take; sb.offset = (cursor ?? 0) * take; - sb.orderBy.created_at = 'max_created_at DESC'; + sb.orderBy.created_at = "max_created_at DESC"; const data = await chQuery(getSql()); return data.map(transformProfile); } @@ -93,9 +93,9 @@ export async function getProfileList({ export async function getProfileListCount({ projectId, filters, -}: Omit) { +}: Omit) { const { sb, getSql } = createSqlBuilder(); - sb.select.count = 'count(id) as count'; + sb.select.count = "count(id) as count"; sb.from = getProfileInnerSelect(projectId); if (filters) { sb.where = { @@ -109,7 +109,7 @@ export async function getProfileListCount({ export async function getProfilesByExternalId( externalId: string | null, - projectId: string + projectId: string, ) { if (externalId === null) { return []; @@ -121,7 +121,7 @@ export async function getProfilesByExternalId( FROM profiles GROUP BY id HAVING project_id = '${projectId}' AND external_id = '${externalId}' - ` + `, ); return data.map(transformProfile); @@ -129,7 +129,7 @@ export async function getProfilesByExternalId( export type IServiceProfile = Omit< IClickhouseProfile, - 'max_created_at' | 'properties' + "max_created_at" | "properties" > & { createdAt: Date; properties: Record; @@ -177,27 +177,27 @@ export async function upsertProfile({ projectId, }: IServiceUpsertProfile) { const [profile] = await chQuery( - `SELECT * FROM profiles WHERE id = '${id}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1` + `SELECT * FROM profiles WHERE id = '${id}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`, ); await ch.insert({ - table: 'profiles', - format: 'JSONEachRow', + table: "profiles", + format: "JSONEachRow", clickhouse_settings: { - date_time_input_format: 'best_effort', + date_time_input_format: "best_effort", }, values: [ { id, - first_name: firstName ?? profile?.first_name ?? '', - last_name: lastName ?? profile?.last_name ?? '', - email: email ?? profile?.email ?? '', - avatar: avatar ?? profile?.avatar ?? '', + first_name: firstName ?? profile?.first_name ?? "", + last_name: lastName ?? profile?.last_name ?? "", + email: email ?? profile?.email ?? "", + avatar: avatar ?? profile?.avatar ?? "", properties: toDots({ ...(profile?.properties ?? {}), ...(properties ?? {}), }), - project_id: projectId ?? profile?.project_id ?? '', + project_id: projectId ?? profile?.project_id ?? "", created_at: new Date(), }, ], diff --git a/packages/db/src/services/reports.service.ts b/packages/db/src/services/reports.service.ts index 5fd0d3e5..7a5cfa92 100644 --- a/packages/db/src/services/reports.service.ts +++ b/packages/db/src/services/reports.service.ts @@ -1,4 +1,4 @@ -import { alphabetIds, lineTypes, timeRanges } from '@mixan/constants'; +import { alphabetIds, lineTypes, timeRanges } from "@openpanel/constants"; import type { IChartBreakdown, IChartEvent, @@ -6,42 +6,42 @@ import type { IChartInput, IChartLineType, IChartRange, -} from '@mixan/validation'; +} from "@openpanel/validation"; -import { db } from '../prisma-client'; -import type { Report as DbReport } from '../prisma-client'; +import { db } from "../prisma-client"; +import type { Report as DbReport } from "../prisma-client"; export type IServiceReport = Awaited>; export function transformFilter( filter: Partial, - index: number + index: number, ): IChartEventFilter { return { - id: filter.id ?? alphabetIds[index] ?? 'A', - name: filter.name ?? 'Unknown Filter', - operator: filter.operator ?? 'is', + id: filter.id ?? alphabetIds[index] ?? "A", + name: filter.name ?? "Unknown Filter", + operator: filter.operator ?? "is", value: - typeof filter.value === 'string' ? [filter.value] : filter.value ?? [], + typeof filter.value === "string" ? [filter.value] : filter.value ?? [], }; } export function transformReportEvent( event: Partial, - index: number + index: number, ): IChartEvent { return { - segment: event.segment ?? 'event', + segment: event.segment ?? "event", filters: (event.filters ?? []).map(transformFilter), id: event.id ?? alphabetIds[index]!, - name: event.name || 'unknown_event', + name: event.name || "unknown_event", displayName: event.displayName, property: event.property, }; } export function transformReport( - report: DbReport + report: DbReport, ): IChartInput & { id: string } { return { id: report.id, @@ -51,11 +51,11 @@ export function transformReport( chartType: report.chart_type, lineType: (report.line_type as IChartLineType) ?? lineTypes.monotone, interval: report.interval, - name: report.name || 'Untitled', - range: (report.range as IChartRange) ?? timeRanges['1m'], + name: report.name || "Untitled", + range: (report.range as IChartRange) ?? timeRanges["1m"], previous: report.previous ?? false, formula: report.formula ?? undefined, - metric: report.metric ?? 'sum', + metric: report.metric ?? "sum", unit: report.unit ?? undefined, }; } diff --git a/packages/db/tsconfig.json b/packages/db/tsconfig.json index 73b1bbe4..a291eef2 100644 --- a/packages/db/tsconfig.json +++ b/packages/db/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "baseUrl": ".", "paths": { diff --git a/packages/queue/package.json b/packages/queue/package.json index 9fd49c94..f54ef843 100644 --- a/packages/queue/package.json +++ b/packages/queue/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/queue", + "name": "@openpanel/queue", "version": "0.0.1", "main": "index.ts", "scripts": { @@ -8,13 +8,13 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@mixan/db": "workspace:*", + "@openpanel/db": "workspace:*", "bullmq": "^5.1.1" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@types/node": "^18.16.0", "eslint": "^8.48.0", "prettier": "^3.0.3", @@ -23,8 +23,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/packages/queue/src/queues.ts b/packages/queue/src/queues.ts index b70976ac..dd957dc1 100644 --- a/packages/queue/src/queues.ts +++ b/packages/queue/src/queues.ts @@ -1,6 +1,6 @@ import { Queue } from 'bullmq'; -import type { IServiceCreateEventPayload } from '@mixan/db'; +import type { IServiceCreateEventPayload } from '@openpanel/db'; import { connection } from './connection'; diff --git a/packages/queue/tsconfig.json b/packages/queue/tsconfig.json index 73b1bbe4..a291eef2 100644 --- a/packages/queue/tsconfig.json +++ b/packages/queue/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "baseUrl": ".", "paths": { diff --git a/packages/redis/package.json b/packages/redis/package.json index adfdf5ec..f2245aa7 100644 --- a/packages/redis/package.json +++ b/packages/redis/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/redis", + "name": "@openpanel/redis", "version": "0.0.1", "main": "index.ts", "scripts": { @@ -12,9 +12,9 @@ "ioredis": "^5.3.2" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@types/node": "^18.16.0", "eslint": "^8.48.0", "prettier": "^3.0.3", @@ -24,8 +24,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/packages/redis/tsconfig.json b/packages/redis/tsconfig.json index 73b1bbe4..a291eef2 100644 --- a/packages/redis/tsconfig.json +++ b/packages/redis/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "baseUrl": ".", "paths": { diff --git a/packages/sdks/nextjs/index.tsx b/packages/sdks/nextjs/index.tsx index 32cdd748..3b028e0b 100644 --- a/packages/sdks/nextjs/index.tsx +++ b/packages/sdks/nextjs/index.tsx @@ -1,11 +1,11 @@ import Script from 'next/script'; import type { - MixanEventOptions, - MixanWebOptions, + OpenpanelEventOptions, + OpenpanelWebOptions, PostEventPayload, UpdateProfilePayload, -} from '@mixan/web'; +} from '@openpanel/web'; const CDN_URL = 'http://localhost:3002/op.js'; @@ -27,7 +27,7 @@ declare global { } } -type OpenpanelProviderProps = MixanWebOptions & { +type OpenpanelProviderProps = OpenpanelWebOptions & { profileId?: string; cdnUrl?: string; }; @@ -98,7 +98,7 @@ export function setProfileId(profileId: string) { export function increment( property: string, value: number, - options?: MixanEventOptions + options?: OpenpanelEventOptions ) { window.op('increment', property, value, options); } @@ -106,7 +106,7 @@ export function increment( export function decrement( property: string, value: number, - options?: MixanEventOptions + options?: OpenpanelEventOptions ) { window.op('decrement', property, value, options); } diff --git a/packages/sdks/nextjs/package.json b/packages/sdks/nextjs/package.json index 92e69484..419e3b6b 100644 --- a/packages/sdks/nextjs/package.json +++ b/packages/sdks/nextjs/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/nextjs", + "name": "@openpanel/nextjs", "version": "0.0.1", "module": "index.ts", "scripts": { @@ -10,16 +10,16 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@mixan/sdk": "workspace:*", - "@mixan/web": "workspace:*" + "@openpanel/sdk": "workspace:*", + "@openpanel/web": "workspace:*" }, "peerDependencies": { "next": "^13.0.0" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "eslint": "^8.48.0", "prettier": "^3.0.3", "tsup": "^7.2.0", @@ -28,8 +28,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/packages/sdks/nextjs/tsconfig.json b/packages/sdks/nextjs/tsconfig.json index a95a73e6..337e4067 100644 --- a/packages/sdks/nextjs/tsconfig.json +++ b/packages/sdks/nextjs/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "outDir": "dist" } diff --git a/packages/sdks/nextjs/tsup.config.ts b/packages/sdks/nextjs/tsup.config.ts index 99f2deb6..fed909b5 100644 --- a/packages/sdks/nextjs/tsup.config.ts +++ b/packages/sdks/nextjs/tsup.config.ts @@ -1,6 +1,6 @@ import { defineConfig } from 'tsup'; -import config from '@mixan/tsconfig/tsup.config.json' assert { type: 'json' }; +import config from '@openpanel/tsconfig/tsup.config.json' assert { type: 'json' }; export default defineConfig({ ...(config as any), diff --git a/packages/sdks/react-native/index.ts b/packages/sdks/react-native/index.ts index 62c89805..dc1d2eac 100644 --- a/packages/sdks/react-native/index.ts +++ b/packages/sdks/react-native/index.ts @@ -2,13 +2,13 @@ import { AppState, Platform } from 'react-native'; import * as Application from 'expo-application'; import Constants from 'expo-constants'; -import type { MixanOptions, PostEventPayload } from '@mixan/sdk'; -import { Mixan } from '@mixan/sdk'; +import type { OpenpanelOptions, PostEventPayload } from '@openpanel/sdk'; +import { Openpanel } from '@openpanel/sdk'; -type MixanNativeOptions = MixanOptions; +type OpenpanelNativeOptions = OpenpanelOptions; -export class MixanNative extends Mixan { - constructor(options: MixanNativeOptions) { +export class OpenpanelNative extends Openpanel { + constructor(options: OpenpanelNativeOptions) { super(options); this.api.headers['User-Agent'] = Constants.getWebViewUserAgentAsync(); diff --git a/packages/sdks/react-native/package.json b/packages/sdks/react-native/package.json index 7c368140..d65a459c 100644 --- a/packages/sdks/react-native/package.json +++ b/packages/sdks/react-native/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/react-native", + "name": "@openpanel/react-native", "version": "0.0.1", "module": "index.ts", "scripts": { @@ -9,12 +9,12 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@mixan/sdk": "workspace:*" + "@openpanel/sdk": "workspace:*" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "eslint": "^8.48.0", "prettier": "^3.0.3", "tsup": "^7.2.0", @@ -28,8 +28,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/packages/sdks/react-native/tsconfig.json b/packages/sdks/react-native/tsconfig.json index 257bf27a..f742bf0a 100644 --- a/packages/sdks/react-native/tsconfig.json +++ b/packages/sdks/react-native/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/sdk.json", + "extends": "@openpanel/tsconfig/sdk.json", "compilerOptions": { "outDir": "dist" } diff --git a/packages/sdks/react-native/tsup.config.ts b/packages/sdks/react-native/tsup.config.ts index e5f3031e..446d20ad 100644 --- a/packages/sdks/react-native/tsup.config.ts +++ b/packages/sdks/react-native/tsup.config.ts @@ -1,6 +1,6 @@ import { defineConfig } from 'tsup'; -import config from '@mixan/tsconfig/tsup.config.json' assert { type: 'json' }; +import config from '@openpanel/tsconfig/tsup.config.json' assert { type: 'json' }; export default defineConfig({ ...(config as any), diff --git a/packages/sdks/sdk/index.ts b/packages/sdks/sdk/index.ts index a8e39f4b..ac349042 100644 --- a/packages/sdks/sdk/index.ts +++ b/packages/sdks/sdk/index.ts @@ -1,6 +1,6 @@ // NEW -export interface MixanEventOptions { +export interface OpenpanelEventOptions { profileId?: string; } @@ -9,7 +9,7 @@ export interface PostEventPayload { timestamp: string; deviceId?: string; profileId?: string; - properties?: Record & MixanEventOptions; + properties?: Record & OpenpanelEventOptions; } export interface UpdateProfilePayload { @@ -33,7 +33,7 @@ export interface DecrementProfilePayload { value: number; } -export interface MixanOptions { +export interface OpenpanelOptions { url: string; clientId: string; clientSecret?: string; @@ -43,7 +43,7 @@ export interface MixanOptions { removeDeviceId?: () => void; } -export interface MixanState { +export interface OpenpanelState { deviceId?: string; profileId?: string; properties: Record; @@ -127,19 +127,19 @@ function createApi(_url: string) { }; } -export class Mixan { +export class Openpanel { public options: Options; public api: ReturnType; - private state: MixanState = { + private state: OpenpanelState = { properties: {}, }; constructor(options: Options) { this.options = options; this.api = createApi(options.url); - this.api.headers['mixan-client-id'] = options.clientId; + this.api.headers['openpanel-client-id'] = options.clientId; if (this.options.clientSecret) { - this.api.headers['mixan-client-secret'] = this.options.clientSecret; + this.api.headers['openpanel-client-secret'] = this.options.clientSecret; } } @@ -163,7 +163,7 @@ export class Mixan { public increment( property: string, value: number, - options?: MixanEventOptions + options?: OpenpanelEventOptions ) { const profileId = options?.profileId ?? this.state.profileId; if (!profileId) { @@ -179,7 +179,7 @@ export class Mixan { public decrement( property: string, value: number, - options?: MixanEventOptions + options?: OpenpanelEventOptions ) { const profileId = options?.profileId ?? this.state.profileId; if (!profileId) { diff --git a/packages/sdks/sdk/package.json b/packages/sdks/sdk/package.json index 8761ab3b..122fcca9 100644 --- a/packages/sdks/sdk/package.json +++ b/packages/sdks/sdk/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/sdk", + "name": "@openpanel/sdk", "version": "0.0.1", "module": "index.ts", "scripts": { @@ -10,9 +10,9 @@ }, "dependencies": {}, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "eslint": "^8.48.0", "prettier": "^3.0.3", "tsup": "^7.2.0", @@ -21,8 +21,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/packages/sdks/sdk/tsconfig.json b/packages/sdks/sdk/tsconfig.json index 257bf27a..f742bf0a 100644 --- a/packages/sdks/sdk/tsconfig.json +++ b/packages/sdks/sdk/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/sdk.json", + "extends": "@openpanel/tsconfig/sdk.json", "compilerOptions": { "outDir": "dist" } diff --git a/packages/sdks/sdk/tsup.config.ts b/packages/sdks/sdk/tsup.config.ts index 5fea5195..93de8b48 100644 --- a/packages/sdks/sdk/tsup.config.ts +++ b/packages/sdks/sdk/tsup.config.ts @@ -1,6 +1,6 @@ import { defineConfig } from 'tsup'; -import config from '@mixan/tsconfig/tsup.config.json' assert { +import config from '@openpanel/tsconfig/tsup.config.json' assert { type: 'json' } diff --git a/packages/sdks/web/cdn.ts b/packages/sdks/web/cdn.ts index 18382437..94c9828a 100644 --- a/packages/sdks/web/cdn.ts +++ b/packages/sdks/web/cdn.ts @@ -1,4 +1,4 @@ -import { MixanWeb as Openpanel } from './index'; +import { OpenpanelWeb as Openpanel } from './index'; declare global { interface Window { diff --git a/packages/sdks/web/index.ts b/packages/sdks/web/index.ts index 360b62f6..ff4d03b1 100644 --- a/packages/sdks/web/index.ts +++ b/packages/sdks/web/index.ts @@ -1,9 +1,9 @@ -import type { MixanOptions, PostEventPayload } from '@mixan/sdk'; -import { Mixan } from '@mixan/sdk'; +import type { OpenpanelOptions, PostEventPayload } from '@openpanel/sdk'; +import { Openpanel } from '@openpanel/sdk'; -export * from '@mixan/sdk'; +export * from '@openpanel/sdk'; -export type MixanWebOptions = MixanOptions & { +export type OpenpanelWebOptions = OpenpanelOptions & { trackOutgoingLinks?: boolean; trackScreenViews?: boolean; trackAttributes?: boolean; @@ -16,10 +16,10 @@ function toCamelCase(str: string) { ); } -export class MixanWeb extends Mixan { +export class OpenpanelWeb extends Openpanel { private lastPath = ''; - constructor(options: MixanWebOptions) { + constructor(options: OpenpanelWebOptions) { super(options); if (!this.isServer()) { diff --git a/packages/sdks/web/package.json b/packages/sdks/web/package.json index 07828d23..8c948184 100644 --- a/packages/sdks/web/package.json +++ b/packages/sdks/web/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/web", + "name": "@openpanel/web", "version": "0.0.1", "module": "index.ts", "scripts": { @@ -10,12 +10,12 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@mixan/sdk": "workspace:*" + "@openpanel/sdk": "workspace:*" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "eslint": "^8.48.0", "prettier": "^3.0.3", "tsup": "^7.2.0", @@ -24,8 +24,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/packages/sdks/web/tsconfig.json b/packages/sdks/web/tsconfig.json index 257bf27a..f742bf0a 100644 --- a/packages/sdks/web/tsconfig.json +++ b/packages/sdks/web/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/sdk.json", + "extends": "@openpanel/tsconfig/sdk.json", "compilerOptions": { "outDir": "dist" } diff --git a/packages/sdks/web/tsup.config.ts b/packages/sdks/web/tsup.config.ts index f98b6b5b..f27e5617 100644 --- a/packages/sdks/web/tsup.config.ts +++ b/packages/sdks/web/tsup.config.ts @@ -1,6 +1,6 @@ import { defineConfig } from 'tsup'; -import config from '@mixan/tsconfig/tsup.config.json' assert { type: 'json' }; +import config from '@openpanel/tsconfig/tsup.config.json' assert { type: 'json' }; export default defineConfig({ ...(config as any), diff --git a/packages/validation/package.json b/packages/validation/package.json index 3c646ce4..f947162f 100644 --- a/packages/validation/package.json +++ b/packages/validation/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/validation", + "name": "@openpanel/validation", "version": "0.0.1", "main": "index.ts", "scripts": { @@ -8,13 +8,13 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@mixan/constants": "workspace:*", + "@openpanel/constants": "workspace:*", "zod": "^3.22.4" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@types/node": "^18.16.0", "eslint": "^8.48.0", "prettier": "^3.0.3", @@ -24,8 +24,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/packages/validation/src/index.ts b/packages/validation/src/index.ts index 0dbaa74c..7ca07272 100644 --- a/packages/validation/src/index.ts +++ b/packages/validation/src/index.ts @@ -7,7 +7,7 @@ import { metrics, operators, timeRanges, -} from '@mixan/constants'; +} from '@openpanel/constants'; export function objectToZodEnums( obj: Record diff --git a/packages/validation/src/types.validation.ts b/packages/validation/src/types.validation.ts index 603d0763..73cc2f72 100644 --- a/packages/validation/src/types.validation.ts +++ b/packages/validation/src/types.validation.ts @@ -1,6 +1,6 @@ import type { z } from 'zod'; -import type { timeRanges } from '@mixan/constants'; +import type { timeRanges } from '@openpanel/constants'; import type { zChartBreakdown, diff --git a/packages/validation/tsconfig.json b/packages/validation/tsconfig.json index 73b1bbe4..a291eef2 100644 --- a/packages/validation/tsconfig.json +++ b/packages/validation/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "baseUrl": ".", "paths": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2f623f32..274ae57f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,7 +8,7 @@ importers: .: dependencies: - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: ^0.1.0 version: link:tooling/prettier dotenv-cli: @@ -35,16 +35,16 @@ importers: '@logtail/pino': specifier: ^0.4.19 version: 0.4.19(pino@8.19.0) - '@mixan/common': + '@openpanel/common': specifier: workspace:* version: link:../../packages/common - '@mixan/db': + '@openpanel/db': specifier: workspace:* version: link:../../packages/db - '@mixan/queue': + '@openpanel/queue': specifier: workspace:* version: link:../../packages/queue - '@mixan/redis': + '@openpanel/redis': specifier: workspace:* version: link:../../packages/redis fastify: @@ -72,16 +72,16 @@ importers: specifier: ^9.0.1 version: 9.0.1 devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../tooling/prettier - '@mixan/sdk': + '@openpanel/sdk': specifier: workspace:* version: link:../../packages/sdks/sdk - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../tooling/typescript '@types/ramda': @@ -120,19 +120,19 @@ importers: '@hookform/resolvers': specifier: ^3.3.4 version: 3.3.4(react-hook-form@7.50.1) - '@mixan/common': + '@openpanel/common': specifier: workspace:^ version: link:../../packages/common - '@mixan/constants': + '@openpanel/constants': specifier: workspace:^ version: link:../../packages/constants - '@mixan/db': + '@openpanel/db': specifier: workspace:^ version: link:../../packages/db - '@mixan/queue': + '@openpanel/queue': specifier: workspace:^ version: link:../../packages/queue - '@mixan/validation': + '@openpanel/validation': specifier: workspace:^ version: link:../../packages/validation '@radix-ui/react-accordion': @@ -346,13 +346,13 @@ importers: specifier: ^3.22.4 version: 3.22.4 devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../tooling/typescript '@types/bcrypt': @@ -428,13 +428,13 @@ importers: specifier: 18.2.0 version: 18.2.0(react@18.2.0) devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../tooling/typescript '@types/node': @@ -473,7 +473,7 @@ importers: apps/public: dependencies: - '@mixan/db': + '@openpanel/db': specifier: workspace:* version: link:../../packages/db '@radix-ui/react-alert-dialog': @@ -558,13 +558,13 @@ importers: specifier: ^3.22.4 version: 3.22.4 devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../tooling/typescript '@tailwindcss/typography': @@ -612,14 +612,14 @@ importers: apps/test: dependencies: - '@mixan-test/nextjs': - specifier: workspace:@mixan/nextjs@* + '@openpanel-test/nextjs': + specifier: workspace:@openpanel/nextjs@* version: link:../../packages/sdks/nextjs - '@mixan-test/sdk': - specifier: workspace:@mixan/sdk@* + '@openpanel-test/sdk': + specifier: workspace:@openpanel/sdk@* version: link:../../packages/sdks/sdk - '@mixan-test/web': - specifier: workspace:@mixan/web@* + '@openpanel-test/web': + specifier: workspace:@openpanel/web@* version: link:../../packages/sdks/web next: specifier: ~14.1.0 @@ -631,13 +631,13 @@ importers: specifier: 18.2.0 version: 18.2.0(react@18.2.0) devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../tooling/typescript '@types/react': @@ -685,16 +685,16 @@ importers: '@bull-board/express': specifier: ^5.13.0 version: 5.14.1 - '@mixan/common': + '@openpanel/common': specifier: workspace:* version: link:../../packages/common - '@mixan/db': + '@openpanel/db': specifier: workspace:* version: link:../../packages/db - '@mixan/queue': + '@openpanel/queue': specifier: workspace:* version: link:../../packages/queue - '@mixan/redis': + '@openpanel/redis': specifier: workspace:* version: link:../../packages/redis bullmq: @@ -707,13 +707,13 @@ importers: specifier: ^0.29.1 version: 0.29.1 devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../tooling/typescript '@types/express': @@ -744,13 +744,13 @@ importers: specifier: ^4.7.1 version: 4.7.1 devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../tooling/typescript '@types/node': @@ -774,13 +774,13 @@ importers: packages/constants: devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../tooling/typescript date-fns: @@ -807,16 +807,16 @@ importers: '@clickhouse/client': specifier: ^0.2.9 version: 0.2.9 - '@mixan/common': + '@openpanel/common': specifier: workspace:* version: link:../common - '@mixan/constants': + '@openpanel/constants': specifier: workspace:* version: link:../constants - '@mixan/redis': + '@openpanel/redis': specifier: workspace:* version: link:../redis - '@mixan/validation': + '@openpanel/validation': specifier: workspace:* version: link:../validation '@prisma/client': @@ -829,13 +829,13 @@ importers: specifier: ^9.0.1 version: 9.0.1 devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../tooling/typescript '@types/node': @@ -862,20 +862,20 @@ importers: packages/queue: dependencies: - '@mixan/db': + '@openpanel/db': specifier: workspace:* version: link:../db bullmq: specifier: ^5.1.1 version: 5.2.0 devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../tooling/typescript '@types/node': @@ -897,13 +897,13 @@ importers: specifier: ^5.3.2 version: 5.3.2 devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../tooling/typescript '@types/node': @@ -924,23 +924,23 @@ importers: packages/sdks/nextjs: dependencies: - '@mixan/sdk': + '@openpanel/sdk': specifier: workspace:* version: link:../sdk - '@mixan/web': + '@openpanel/web': specifier: workspace:* version: link:../web next: specifier: ^13.0.0 version: 13.4.19(react-dom@18.2.0)(react@18.2.0) devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../../tooling/typescript eslint: @@ -958,7 +958,7 @@ importers: packages/sdks/react-native: dependencies: - '@mixan/sdk': + '@openpanel/sdk': specifier: workspace:* version: link:../sdk expo-application: @@ -971,13 +971,13 @@ importers: specifier: ^0.72.5 version: 0.72.10(@babel/core@7.23.9)(@babel/preset-env@7.23.9)(react@18.2.0) devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../../tooling/typescript eslint: @@ -995,13 +995,13 @@ importers: packages/sdks/sdk: devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../../tooling/typescript eslint: @@ -1019,17 +1019,17 @@ importers: packages/sdks/web: dependencies: - '@mixan/sdk': + '@openpanel/sdk': specifier: workspace:* version: link:../sdk devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../../tooling/typescript eslint: @@ -1047,20 +1047,20 @@ importers: packages/validation: dependencies: - '@mixan/constants': + '@openpanel/constants': specifier: workspace:* version: link:../constants zod: specifier: ^3.22.4 version: 3.22.4 devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../../tooling/eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../../tooling/prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../../tooling/typescript '@types/node': @@ -1115,10 +1115,10 @@ importers: specifier: ^4.6.0 version: 4.6.0(eslint@8.56.0) devDependencies: - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../typescript eslint: @@ -1137,7 +1137,7 @@ importers: specifier: ^4.1.0 version: 4.1.1(prettier@3.2.5) devDependencies: - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../typescript eslint: @@ -1156,13 +1156,13 @@ importers: specifier: ^7.5.4 version: 7.6.0 devDependencies: - '@mixan/eslint-config': + '@openpanel/eslint-config': specifier: workspace:* version: link:../eslint - '@mixan/prettier-config': + '@openpanel/prettier-config': specifier: workspace:* version: link:../prettier - '@mixan/tsconfig': + '@openpanel/tsconfig': specifier: workspace:* version: link:../typescript '@types/eslint': diff --git a/tooling/eslint/package.json b/tooling/eslint/package.json index ef9c51a9..3cde3c6a 100644 --- a/tooling/eslint/package.json +++ b/tooling/eslint/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/eslint-config", + "name": "@openpanel/eslint-config", "version": "0.1.0", "private": true, "license": "MIT", @@ -28,8 +28,8 @@ "eslint-plugin-react-hooks": "^4.6.0" }, "devDependencies": { - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@types/eslint": "^8.44.2", "eslint": "^8.48.0", "prettier": "^3.0.3", @@ -41,5 +41,5 @@ "./base.js" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/tooling/eslint/tsconfig.json b/tooling/eslint/tsconfig.json index 115d8a35..fb0dc1a3 100644 --- a/tooling/eslint/tsconfig.json +++ b/tooling/eslint/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" }, diff --git a/tooling/prettier/index.mjs b/tooling/prettier/index.mjs index 9d339fa3..5ec65785 100644 --- a/tooling/prettier/index.mjs +++ b/tooling/prettier/index.mjs @@ -8,7 +8,7 @@ const config = { '^(react/(.*)$)|^(react$)|^(react-native(.*)$)', '', '', - '^@mixan/(.*)$', + '^@openpanel/(.*)$', '', '^~/', '^[../]', diff --git a/tooling/prettier/package.json b/tooling/prettier/package.json index e311d0dd..def347a7 100644 --- a/tooling/prettier/package.json +++ b/tooling/prettier/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/prettier-config", + "name": "@openpanel/prettier-config", "version": "0.1.0", "private": true, "main": "index.mjs", @@ -10,7 +10,7 @@ "@ianvs/prettier-plugin-sort-imports": "^4.1.0" }, "devDependencies": { - "@mixan/tsconfig": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "eslint": "^8.48.0", "prettier": "^3.0.3", "typescript": "^5.2.2" diff --git a/tooling/prettier/tsconfig.json b/tooling/prettier/tsconfig.json index 115d8a35..fb0dc1a3 100644 --- a/tooling/prettier/tsconfig.json +++ b/tooling/prettier/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" }, diff --git a/tooling/publish/package.json b/tooling/publish/package.json index 27ec99f3..77ee46f6 100644 --- a/tooling/publish/package.json +++ b/tooling/publish/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/publish", + "name": "@openpanel/publish", "version": "0.1.0", "private": true, "license": "MIT", @@ -13,9 +13,9 @@ "semver": "^7.5.4" }, "devDependencies": { - "@mixan/eslint-config": "workspace:*", - "@mixan/prettier-config": "workspace:*", - "@mixan/tsconfig": "workspace:*", + "@openpanel/eslint-config": "workspace:*", + "@openpanel/prettier-config": "workspace:*", + "@openpanel/tsconfig": "workspace:*", "@types/eslint": "^8.44.2", "@types/node": "^18.16.0", "@types/semver": "^7.5.4", @@ -26,8 +26,8 @@ "eslintConfig": { "root": true, "extends": [ - "@mixan/eslint-config/base" + "@openpanel/eslint-config/base" ] }, - "prettier": "@mixan/prettier-config" + "prettier": "@openpanel/prettier-config" } diff --git a/tooling/publish/publish.ts b/tooling/publish/publish.ts index b2f5a507..ef9e236f 100644 --- a/tooling/publish/publish.ts +++ b/tooling/publish/publish.ts @@ -4,8 +4,7 @@ import fs from 'node:fs'; import path from 'node:path'; import semver from 'semver'; -const sdkPackages = ['sdk', 'sdk-native', 'sdk-web', 'sdk-next']; -// const sdkPackages = ['sdk']; +const sdkPackages = ['sdk', 'react-native', 'web', 'nextjs']; const workspacePath = (relativePath: string) => path.resolve(__dirname, '../../', relativePath); @@ -59,7 +58,7 @@ function main() { dependencies: Object.entries(pkgJson.dependencies).reduce( (acc, [depName, depVersion]) => ({ ...acc, - [depName]: depName.startsWith('@mixan') ? version : depVersion, + [depName]: depName.startsWith('@openpanel') ? version : depVersion, }), {} ), @@ -74,7 +73,7 @@ function main() { try { for (const name of sdkPackages) { execSync('pnpm build', { - cwd: workspacePath(`./packages/${name}`), + cwd: workspacePath(`./packages/sdks/${name}`), }); } } catch (error) { diff --git a/tooling/publish/tsconfig.json b/tooling/publish/tsconfig.json index 75ade3d6..7cc67ac2 100644 --- a/tooling/publish/tsconfig.json +++ b/tooling/publish/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@mixan/tsconfig/base.json", + "extends": "@openpanel/tsconfig/base.json", "compilerOptions": { "module": "CommonJS", "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" diff --git a/tooling/typescript/package.json b/tooling/typescript/package.json index a881fe78..a3b08c25 100644 --- a/tooling/typescript/package.json +++ b/tooling/typescript/package.json @@ -1,5 +1,5 @@ { - "name": "@mixan/tsconfig", + "name": "@openpanel/tsconfig", "version": "0.1.0", "private": true, "files": [