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": [