feat: whyrating - initial project from turbostarter boilerplate

This commit is contained in:
Alejandro Gutiérrez
2026-02-04 01:54:52 +01:00
commit 5cdc07cd39
1618 changed files with 338230 additions and 0 deletions

View File

@@ -0,0 +1 @@
export { env, preset } from "./providers";

View File

@@ -0,0 +1 @@
export { captureException, identify, initialize } from "./providers";

View File

@@ -0,0 +1,2 @@
export * from "./posthog";
export * from "./posthog/env";

View File

@@ -0,0 +1,34 @@
/* eslint-disable turbo/no-undeclared-env-vars */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
import { defineEnv } from "envin";
import * as z from "zod";
import { envConfig } from "@turbostarter/shared/constants";
import type { Preset } from "envin/types";
export const preset = {
id: "posthog",
clientPrefix: "VITE_",
client: {
VITE_POSTHOG_KEY: z.string(),
VITE_POSTHOG_HOST: z
.string()
.optional()
.default("https://us.i.posthog.com"),
},
} as const satisfies Preset;
export const env = defineEnv({
...envConfig,
...preset,
env: {
VITE_POSTHOG_KEY: import.meta.env.VITE_POSTHOG_KEY,
VITE_POSTHOG_HOST: import.meta.env.VITE_POSTHOG_HOST,
},
skip:
(!!import.meta.env.SKIP_ENV_VALIDATION &&
["1", "true"].includes(import.meta.env.SKIP_ENV_VALIDATION)) ||
["lint", "postinstall"].includes(import.meta.env.npm_lifecycle_event),
});

View File

@@ -0,0 +1,62 @@
import { PostHog } from "posthog-js/dist/module.no-external";
import { v7 as uuidv7 } from "uuid";
import { env } from "./env";
import type { MonitoringProviderStrategy } from "@turbostarter/monitoring";
const posthog = new PostHog();
export async function getSharedDistinctId() {
const stored = await chrome.storage.local.get(["posthog_distinct_id"]);
if (stored.posthog_distinct_id) {
return stored.posthog_distinct_id as string;
}
const distinctId = uuidv7();
await chrome.storage.local.set({ posthog_distinct_id: distinctId });
return distinctId;
}
const init = async () => {
if (posthog.__loaded) {
return;
}
const distinctID = await getSharedDistinctId();
posthog.init(env.VITE_POSTHOG_KEY, {
bootstrap: {
distinctID,
},
api_host: env.VITE_POSTHOG_HOST,
disable_external_dependency_loading: true,
error_tracking: {
captureExtensionExceptions: true,
},
persistence: "localStorage",
});
};
export const { captureException, identify, initialize } = {
captureException: (exception) => {
void (async () => {
await init();
posthog.captureException(exception);
})();
},
identify: <T extends { id: string }>(user: T | null) => {
void (async () => {
await init();
if (user) {
posthog.identify(user.id);
} else {
posthog.reset();
}
})();
},
initialize: () => {
void (async () => {
await init();
})();
},
} satisfies MonitoringProviderStrategy;

View File

@@ -0,0 +1,33 @@
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable turbo/no-undeclared-env-vars */
import { defineEnv } from "envin";
import * as z from "zod";
import { envConfig, NodeEnv } from "@turbostarter/shared/constants";
import type { Preset } from "envin/types";
export const preset = {
id: "sentry",
clientPrefix: "VITE_",
client: {
VITE_SENTRY_DSN: z.string(),
VITE_SENTRY_ENVIRONMENT: z
.string()
.default(process.env.NODE_ENV ?? NodeEnv.DEVELOPMENT),
},
} as const satisfies Preset;
export const env = defineEnv({
...envConfig,
...preset,
env: {
VITE_SENTRY_DSN: import.meta.env.VITE_SENTRY_DSN,
VITE_SENTRY_ENVIRONMENT: import.meta.env.VITE_SENTRY_ENVIRONMENT,
},
skip:
(!!import.meta.env.SKIP_ENV_VALIDATION &&
["1", "true"].includes(import.meta.env.SKIP_ENV_VALIDATION)) ||
["lint", "postinstall"].includes(import.meta.env.npm_lifecycle_event),
});

View File

@@ -0,0 +1,45 @@
import * as Sentry from "@sentry/browser";
import { env } from "./env";
import type { MonitoringProviderStrategy } from "@turbostarter/monitoring";
export const { captureException, identify, initialize } = {
captureException: (exception) => {
Sentry.captureException(exception);
},
identify: (user: Sentry.User | null) => {
Sentry.setUser(user);
},
initialize: () => {
const environment = env.VITE_SENTRY_ENVIRONMENT;
Sentry.init({
dsn: env.VITE_SENTRY_DSN,
environment,
// Replay may only be enabled for the client-side
integrations: [
// add your desired integrations here
// https://docs.sentry.io/platforms/javascript/configuration/integrations/
],
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for performance monitoring.
// We recommend adjusting this value in production
tracesSampleRate: 1.0,
// Capture Replay for 10% of all sessions,
// plus for 100% of sessions with an error
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
// Adds more context data to events (IP address, cookies, user, etc.)
// For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
sendDefaultPii: true,
// Note: if you want to override the automatic release value, do not set a
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
// that it will also get attached to your source maps,
});
},
} satisfies MonitoringProviderStrategy;

View File

@@ -0,0 +1 @@
/// <reference types="vite/client" />