wip
This commit is contained in:
committed by
Carl-Gerhard Lindesvärd
parent
15e997129a
commit
2226cb463d
@@ -1,68 +1,21 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
const VALID_PATHS = [
|
||||
'/profile',
|
||||
'/profile/increment',
|
||||
'/profile/decrement',
|
||||
'/event',
|
||||
];
|
||||
|
||||
function getIp(req: Request) {
|
||||
if (req.headers.get('X-Forwarded-For')) {
|
||||
return req.headers.get('X-Forwarded-For')?.split(',')[0];
|
||||
}
|
||||
return req.headers.get('x-real-ip') ?? '0.0.0.0';
|
||||
}
|
||||
|
||||
function getPath(params?: Record<string, unknown>) {
|
||||
const segments = params?.op;
|
||||
if (segments && Array.isArray(segments)) {
|
||||
const path = `/${segments.join('/')}`;
|
||||
if (VALID_PATHS.includes(path)) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function createNextRouteHandler({
|
||||
clientId,
|
||||
clientSecret,
|
||||
url = 'https://api.openpanel.dev',
|
||||
apiUrl = 'https://api.openpanel.dev',
|
||||
}: {
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
url?: string;
|
||||
apiUrl?: string;
|
||||
}) {
|
||||
return {
|
||||
POST: async function POST(
|
||||
req: Request,
|
||||
{ params }: { params: Record<string, unknown> }
|
||||
) {
|
||||
const path = getPath(params);
|
||||
if (!path) {
|
||||
return NextResponse.json('Invalid path');
|
||||
}
|
||||
|
||||
const headers = {
|
||||
'user-agent': req.headers.get('user-agent')!,
|
||||
'Content-Type': req.headers.get('Content-Type')!,
|
||||
'openpanel-client-id': clientId,
|
||||
'openpanel-client-secret': clientSecret,
|
||||
'x-client-ip': getIp(req)!,
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await fetch(`${url}${path}`, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: JSON.stringify(await req.json()),
|
||||
});
|
||||
return NextResponse.json(await res.text());
|
||||
} catch (e) {
|
||||
return NextResponse.json(e);
|
||||
}
|
||||
},
|
||||
return async function POST(req: Request) {
|
||||
const headers = new Headers(req.headers);
|
||||
try {
|
||||
const res = await fetch(`${apiUrl}/track`, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: JSON.stringify(await req.json()),
|
||||
});
|
||||
return NextResponse.json(await res.text());
|
||||
} catch (e) {
|
||||
return NextResponse.json(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import React from 'react';
|
||||
'use client';
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import Script from 'next/script';
|
||||
|
||||
import type {
|
||||
@@ -11,13 +13,27 @@ import type {
|
||||
} from '@openpanel/web';
|
||||
|
||||
export * from '@openpanel/web';
|
||||
export { createNextRouteHandler } from './createNextRouteHandler';
|
||||
|
||||
const CDN_URL = 'https://openpanel.dev/op.js';
|
||||
|
||||
type OpenPanelComponentProps = OpenPanelOptions & {
|
||||
type OpenPanelComponentProps = Omit<OpenPanelOptions, 'filter'> & {
|
||||
profileId?: string;
|
||||
cdnUrl?: string;
|
||||
filter?: string;
|
||||
};
|
||||
|
||||
const stringify = (obj: unknown) => {
|
||||
if (typeof obj === 'object' && obj !== null && obj !== undefined) {
|
||||
const entries = Object.entries(obj).map(([key, value]) => {
|
||||
if (key === 'filter') {
|
||||
return `"${key}":${value}`;
|
||||
}
|
||||
return `"${key}":${JSON.stringify(value)}`;
|
||||
});
|
||||
return `{${entries.join(',')}}`;
|
||||
}
|
||||
|
||||
return JSON.stringify(obj);
|
||||
};
|
||||
|
||||
export function OpenPanelComponent({
|
||||
@@ -51,7 +67,7 @@ export function OpenPanelComponent({
|
||||
__html: `window.op = window.op || function(...args) {(window.op.q = window.op.q || []).push(args)};
|
||||
${methods
|
||||
.map((method) => {
|
||||
return `window.op('${method.name}', ${JSON.stringify(method.value)});`;
|
||||
return `window.op('${method.name}', ${stringify(method.value)});`;
|
||||
})
|
||||
.join('\n')}`,
|
||||
}}
|
||||
@@ -67,7 +83,7 @@ export function IdentifyComponent(props: IdentifyComponentProps) {
|
||||
<>
|
||||
<Script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `window.op('setProfile', ${JSON.stringify(props)});`,
|
||||
__html: `window.op('identify', ${JSON.stringify(props)});`,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
||||
1
packages/sdks/nextjs/server.ts
Normal file
1
packages/sdks/nextjs/server.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { createNextRouteHandler } from './createNextRouteHandler';
|
||||
@@ -4,6 +4,6 @@ import config from '@openpanel/tsconfig/tsup.config.json' assert { type: 'json'
|
||||
|
||||
export default defineConfig({
|
||||
...(config as any),
|
||||
entry: ['index.tsx'],
|
||||
entry: ['index.tsx', 'server.ts'],
|
||||
external: ['react', 'next'],
|
||||
});
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"module": "index.ts",
|
||||
"scripts": {
|
||||
"build": "rm -rf dist && tsup",
|
||||
"build-for-openpanel": "pnpm build && cp dist/src/tracker.global.js ../../../apps/public/public/tracker.js",
|
||||
"lint": "eslint .",
|
||||
"format": "prettier --check \"**/*.{mjs,ts,md,json}\"",
|
||||
"typecheck": "tsc --noEmit"
|
||||
|
||||
Reference in New Issue
Block a user