fix sdk api
This commit is contained in:
80
apps/sdk-api/Dockerfile
Normal file
80
apps/sdk-api/Dockerfile
Normal file
@@ -0,0 +1,80 @@
|
||||
# Dockerfile that builds the web app only
|
||||
|
||||
FROM --platform=linux/amd64 node:20-slim AS base
|
||||
|
||||
ARG DATABASE_URL
|
||||
ENV DATABASE_URL=$DATABASE_URL
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
|
||||
RUN corepack enable
|
||||
|
||||
ARG NODE_VERSION=20
|
||||
|
||||
RUN apt update \
|
||||
&& apt install -y curl \
|
||||
&& curl -L https://raw.githubusercontent.com/tj/n/master/bin/n -o n \
|
||||
&& bash n $NODE_VERSION \
|
||||
&& rm n \
|
||||
&& npm install -g n
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json package.json
|
||||
COPY pnpm-lock.yaml pnpm-lock.yaml
|
||||
COPY pnpm-workspace.yaml pnpm-workspace.yaml
|
||||
COPY apps/sdk-api/package.json apps/sdk-api/package.json
|
||||
COPY packages/db/package.json packages/db/package.json
|
||||
COPY packages/queue/package.json packages/queue/package.json
|
||||
COPY packages/types/package.json packages/types/package.json
|
||||
|
||||
# BUILD
|
||||
FROM base AS build
|
||||
|
||||
WORKDIR /app/apps/sdk-api
|
||||
RUN pnpm install --frozen-lockfile --ignore-scripts
|
||||
|
||||
WORKDIR /app
|
||||
COPY apps apps
|
||||
COPY packages packages
|
||||
COPY tooling tooling
|
||||
RUN pnpm db:codegen
|
||||
|
||||
WORKDIR /app/apps/sdk-api
|
||||
RUN pnpm run build
|
||||
|
||||
# PROD
|
||||
FROM base AS prod
|
||||
|
||||
WORKDIR /app/apps/sdk-api
|
||||
RUN pnpm install --frozen-lockfile --prod --ignore-scripts
|
||||
|
||||
# FINAL
|
||||
FROM base AS runner
|
||||
|
||||
COPY --from=build /app/package.json /app/package.json
|
||||
COPY --from=prod /app/node_modules /app/node_modules
|
||||
|
||||
# Apps
|
||||
COPY --from=build /app/apps/sdk-api /app/apps/sdk-api
|
||||
|
||||
# Apps node_modules
|
||||
COPY --from=prod /app/apps/sdk-api/node_modules /app/apps/sdk-api/node_modules
|
||||
|
||||
# Packages
|
||||
COPY --from=build /app/packages/db /app/packages/db
|
||||
COPY --from=build /app/packages/queue /app/packages/queue
|
||||
|
||||
# Packages node_modules
|
||||
COPY --from=prod /app/packages/db/node_modules /app/packages/db/node_modules
|
||||
COPY --from=prod /app/packages/queue/node_modules /app/packages/queue/node_modules
|
||||
|
||||
RUN pnpm db:codegen
|
||||
|
||||
WORKDIR /app/apps/sdk-api
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["pnpm", "start"]
|
||||
@@ -1,6 +1,7 @@
|
||||
import { parseIp } from '@/utils/parseIp';
|
||||
import { parseUserAgent } from '@/utils/parseUserAgent';
|
||||
import type { FastifyReply, FastifyRequest } from 'fastify';
|
||||
import { omit } from 'ramda';
|
||||
import { getClientIp } from 'request-ip';
|
||||
|
||||
import { generateProfileId, getTime, toISOString } from '@mixan/common';
|
||||
@@ -8,19 +9,44 @@ import type { IServiceCreateEventPayload } from '@mixan/db';
|
||||
import { getSalts } from '@mixan/db';
|
||||
import type { JobsOptions } from '@mixan/queue';
|
||||
import { eventsQueue, findJobByPrefix } from '@mixan/queue';
|
||||
|
||||
export interface PostEventPayload {
|
||||
profileId?: string;
|
||||
name: string;
|
||||
timestamp: string;
|
||||
properties: Record<string, unknown>;
|
||||
referrer: string | undefined;
|
||||
path: string;
|
||||
}
|
||||
import type { PostEventPayload } from '@mixan/types';
|
||||
|
||||
const SESSION_TIMEOUT = 1000 * 30 * 1;
|
||||
const SESSION_END_TIMEOUT = SESSION_TIMEOUT + 1000;
|
||||
|
||||
function parseSearchParams(params: URLSearchParams): Record<string, string> {
|
||||
const result: Record<string, string> = {};
|
||||
for (const [key, value] of params.entries()) {
|
||||
result[key] = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function parsePath(path?: string): {
|
||||
query?: Record<string, unknown>;
|
||||
path: string;
|
||||
hash?: string;
|
||||
} {
|
||||
if (!path) {
|
||||
return {
|
||||
path: '',
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const url = new URL(path);
|
||||
return {
|
||||
query: parseSearchParams(url.searchParams),
|
||||
path: url.pathname,
|
||||
hash: url.hash,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
path,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function postEvent(
|
||||
request: FastifyRequest<{
|
||||
Body: PostEventPayload;
|
||||
@@ -30,7 +56,10 @@ export async function postEvent(
|
||||
let profileId: string | null = null;
|
||||
const projectId = request.projectId;
|
||||
const body = request.body;
|
||||
const path = body.path;
|
||||
const { path, hash, query } = parsePath(
|
||||
body.properties?.path as string | undefined
|
||||
);
|
||||
const referrer = body.properties?.referrer as string | undefined;
|
||||
const ip = getClientIp(request)!;
|
||||
const origin = request.headers.origin!;
|
||||
const ua = request.headers['user-agent']!;
|
||||
@@ -101,7 +130,10 @@ export async function postEvent(
|
||||
name: body.name,
|
||||
profileId,
|
||||
projectId,
|
||||
properties: body.properties,
|
||||
properties: Object.assign({}, omit(['path', 'referrer'], body.properties), {
|
||||
hash,
|
||||
query,
|
||||
}),
|
||||
createdAt: body.timestamp,
|
||||
country: geo.country,
|
||||
city: geo.city,
|
||||
@@ -115,13 +147,11 @@ export async function postEvent(
|
||||
brand: uaInfo.brand,
|
||||
model: uaInfo.model,
|
||||
duration: 0,
|
||||
path,
|
||||
referrer: body.referrer, // TODO
|
||||
referrerName: body.referrer, // TODO
|
||||
path: path,
|
||||
referrer,
|
||||
referrerName: referrer, // TODO
|
||||
};
|
||||
|
||||
console.log(payload);
|
||||
|
||||
const job = findJobByPrefix(eventsJobs, `event:${projectId}:${profileId}:`);
|
||||
|
||||
if (job?.isDelayed && job.data.type === 'createEvent') {
|
||||
|
||||
@@ -11,7 +11,7 @@ declare module 'fastify' {
|
||||
}
|
||||
}
|
||||
|
||||
const port = parseInt(process.env.API_PORT || '3030', 10);
|
||||
const port = parseInt(process.env.API_PORT || '3000', 10);
|
||||
|
||||
const startServer = async () => {
|
||||
try {
|
||||
@@ -43,7 +43,7 @@ const startServer = async () => {
|
||||
fastify.log.error(error);
|
||||
});
|
||||
fastify.get('/', (request, reply) => {
|
||||
reply.send({ name: 'fastify-typescript' });
|
||||
reply.send({ name: 'openpanel sdk api' });
|
||||
});
|
||||
// fastify.get('/health-check', async (request, reply) => {
|
||||
// try {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { MixanWeb } from '@mixan-test/sdk-web';
|
||||
// import { MixanWeb } from '@mixan-test/sdk-web';
|
||||
|
||||
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,
|
||||
});
|
||||
// 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,
|
||||
// });
|
||||
|
||||
mixan.init({
|
||||
appVersion: '1.0.0',
|
||||
});
|
||||
mixan.trackOutgoingLinks();
|
||||
// mixan.init({
|
||||
// appVersion: '1.0.0',
|
||||
// });
|
||||
// mixan.trackOutgoingLinks();
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { useEffect } from 'react';
|
||||
import { mixan } from '@/analytics';
|
||||
// import { mixan } from '@/analytics';
|
||||
import type { AppProps } from 'next/app';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
export default function MyApp({ Component, pageProps }: AppProps) {
|
||||
const router = useRouter();
|
||||
useEffect(() => {
|
||||
mixan.screenView();
|
||||
return router.events.on('routeChangeComplete', () => {
|
||||
mixan.screenView();
|
||||
});
|
||||
}, []);
|
||||
// useEffect(() => {
|
||||
// mixan.screenView();
|
||||
// return router.events.on('routeChangeComplete', () => {
|
||||
// mixan.screenView();
|
||||
// });
|
||||
// }, []);
|
||||
return <Component {...pageProps} />;
|
||||
}
|
||||
|
||||
21
apps/test/src/pages/_document.tsx
Normal file
21
apps/test/src/pages/_document.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { Head, Html, Main, NextScript } from 'next/document';
|
||||
|
||||
export default function Document() {
|
||||
return (
|
||||
<Html>
|
||||
<Head>
|
||||
<script
|
||||
async
|
||||
src="/cdn.global.js"
|
||||
client-id="568b4ed1-5d00-4f27-88a7-b8959e6674bd"
|
||||
client-secret="1e362905-d352-44c4-9263-e037a2ad52fb"
|
||||
track-screen-views="true"
|
||||
/>
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user