mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
Organize server actions (#30)
This commit is contained in:
parent
01e6eada6d
commit
b0b85f5535
31 changed files with 210 additions and 239 deletions
|
|
@ -1,11 +1,12 @@
|
|||
// pnpm test src/lib/server/__tests__/syncCurrentUser.test.ts
|
||||
// pnpm test src/actions/__tests__/syncCurrentUser.test.ts
|
||||
|
||||
import { db } from '@/db';
|
||||
import { users, orgs } from '@/db/schema';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
import { logger } from '@/lib/server/logger';
|
||||
|
||||
import { syncCurrentUser } from '../sync';
|
||||
import { logger } from '../logger';
|
||||
|
||||
const testUserId = 'fake-user-id';
|
||||
const testOrgId = 'fake-org-id';
|
||||
|
|
@ -21,11 +22,8 @@ vi.mock('@clerk/nextjs/server', () => ({
|
|||
}),
|
||||
}));
|
||||
|
||||
vi.mock('../logger', () => ({
|
||||
logger: {
|
||||
info: vi.fn(),
|
||||
error: vi.fn(),
|
||||
},
|
||||
vi.mock('@/lib/server/logger', () => ({
|
||||
logger: { info: vi.fn(), error: vi.fn() },
|
||||
}));
|
||||
|
||||
describe('syncCurrentUser', () => {
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
// pnpm test src/lib/server/__tests__/syncOrg.test.ts
|
||||
// pnpm test src/actions/__tests__/syncOrg.test.ts
|
||||
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { clerkClient } from '@clerk/nextjs/server';
|
||||
|
||||
import { db } from '@/db';
|
||||
import { orgs } from '@/db/schema';
|
||||
import { logger } from '@/lib/server/logger';
|
||||
|
||||
import { syncOrg } from '../sync';
|
||||
import { logger } from '../logger';
|
||||
|
||||
vi.mock('@clerk/nextjs/server', () => ({
|
||||
clerkClient: vi.fn().mockResolvedValue({
|
||||
|
|
@ -22,11 +22,8 @@ vi.mock('@clerk/nextjs/server', () => ({
|
|||
}),
|
||||
}));
|
||||
|
||||
vi.mock('../logger', () => ({
|
||||
logger: {
|
||||
info: vi.fn(),
|
||||
error: vi.fn(),
|
||||
},
|
||||
vi.mock('@/lib/server/logger', () => ({
|
||||
logger: { info: vi.fn(), error: vi.fn() },
|
||||
}));
|
||||
|
||||
describe('syncOrg', () => {
|
||||
|
|
@ -1,10 +1,41 @@
|
|||
'use server';
|
||||
|
||||
import { z } from 'zod';
|
||||
import { TelemetryEventName } from '@roo-code/types';
|
||||
|
||||
import { type TimePeriod } from '@/schemas';
|
||||
import { client } from '@/lib/server/analytics';
|
||||
import {
|
||||
TelemetryEventName,
|
||||
type RooCodeTelemetryEvent,
|
||||
} from '@roo-code/types';
|
||||
|
||||
import type { TimePeriod } from '@/types';
|
||||
import { analytics } from '@/lib/server';
|
||||
|
||||
/**
|
||||
* captureEvent
|
||||
*/
|
||||
|
||||
type AnalyticsEvent = {
|
||||
id: string;
|
||||
orgId: string;
|
||||
userId: string;
|
||||
timestamp: number;
|
||||
event: RooCodeTelemetryEvent;
|
||||
};
|
||||
|
||||
export const captureEvent = async ({
|
||||
event: { properties, ...cloudEvent },
|
||||
...analyticsEvent
|
||||
}: AnalyticsEvent) => {
|
||||
// The destructuring here flattens the `AnalyticsEvent` to match the ClickHouse
|
||||
// schema.
|
||||
const value = { ...analyticsEvent, ...cloudEvent, ...properties };
|
||||
|
||||
await analytics.insert({
|
||||
table: 'events',
|
||||
values: [value],
|
||||
format: 'JSONEachRow',
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Usage
|
||||
|
|
@ -38,7 +69,7 @@ export const getUsage = async ({
|
|||
return {};
|
||||
}
|
||||
|
||||
const resultSet = await client.query({
|
||||
const resultSet = await analytics.query({
|
||||
query: `
|
||||
SELECT
|
||||
type,
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
import { auth } from '@clerk/nextjs/server';
|
||||
import { logger } from '@/lib/server/logger';
|
||||
|
||||
export type ApiResponse = {
|
||||
success: boolean;
|
||||
message?: string;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates user authentication and organization membership
|
||||
* @returns User and organization IDs if authenticated, or error response if not
|
||||
*/
|
||||
export async function validateAuth(): Promise<
|
||||
{ userId: string; orgId: string } | ApiResponse
|
||||
> {
|
||||
const { userId, orgId } = await auth();
|
||||
|
||||
if (!userId) {
|
||||
return { success: false, error: 'Unauthorized: User required' };
|
||||
}
|
||||
|
||||
if (!orgId) {
|
||||
return { success: false, error: 'Unauthorized: Organization required' };
|
||||
}
|
||||
|
||||
return { userId, orgId };
|
||||
}
|
||||
|
||||
export function isAuthSuccess(
|
||||
result: { userId: string; orgId: string } | ApiResponse,
|
||||
): result is { userId: string; orgId: string } {
|
||||
return !('error' in result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic error handler for all operations
|
||||
* @param error The caught error
|
||||
* @param eventPrefix Prefix for logging events
|
||||
* @returns Error response
|
||||
*/
|
||||
export function handleError(error: unknown, eventPrefix: string): ApiResponse {
|
||||
logger.error({
|
||||
event: `${eventPrefix}_update_error`,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
});
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error:
|
||||
error instanceof Error ? error.message : 'An unexpected error occurred',
|
||||
};
|
||||
}
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
import { eq, gte, and, desc } from 'drizzle-orm';
|
||||
|
||||
import { db } from '@/db';
|
||||
import { auditLogs, type AuditLog } from '@/db/schema';
|
||||
import { logger } from '@/lib/server/logger';
|
||||
import { logger } from '@/lib/server';
|
||||
import { db, type DB_OR_TX } from '@/db';
|
||||
import { auditLogs, type AuditLog, type CreateAuditLog } from '@/db/schema';
|
||||
|
||||
export const getAuditLogs = async ({
|
||||
orgId,
|
||||
|
|
@ -57,3 +57,27 @@ export const getAuditLogs = async ({
|
|||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export async function insertAuditLog(
|
||||
db: DB_OR_TX,
|
||||
values: CreateAuditLog,
|
||||
): Promise<void> {
|
||||
await db.insert(auditLogs).values(values);
|
||||
const { userId, orgId, targetType } = values;
|
||||
logger.info({ userId, orgId, targetType });
|
||||
}
|
||||
|
||||
export async function createAuditLog(values: CreateAuditLog): Promise<{
|
||||
success: boolean;
|
||||
error?: string | Record<string, unknown>;
|
||||
}> {
|
||||
try {
|
||||
await insertAuditLog(db, values);
|
||||
return { success: true };
|
||||
} catch (e) {
|
||||
const error =
|
||||
e instanceof Error ? e.message : 'An unexpected error occurred';
|
||||
logger.error({ event: 'audit_log_creation_error', error });
|
||||
return { success: false, error };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
51
src/actions/auth.ts
Normal file
51
src/actions/auth.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
'use server';
|
||||
|
||||
import { auth } from '@clerk/nextjs/server';
|
||||
|
||||
import type { ApiResponse } from '@/types';
|
||||
import { Env, logger } from '@/lib/server';
|
||||
|
||||
export async function validateAuth(): Promise<
|
||||
{ userId: string; orgId: string } | ApiResponse
|
||||
> {
|
||||
const { userId, orgId } = await auth();
|
||||
|
||||
if (!userId) {
|
||||
return { success: false, error: 'Unauthorized: User required' };
|
||||
}
|
||||
|
||||
if (!orgId) {
|
||||
return { success: false, error: 'Unauthorized: Organization required' };
|
||||
}
|
||||
|
||||
return { userId, orgId };
|
||||
}
|
||||
|
||||
// Default expiration is 30 days (2592000 seconds).
|
||||
export async function getSignInToken(
|
||||
userId: string,
|
||||
): Promise<string | undefined> {
|
||||
const response = await fetch('https://api.clerk.com/v1/sign_in_tokens', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${Env.CLERK_SECRET_KEY}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ user_id: userId }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
logger.error({
|
||||
event: 'sign_in_token_creation_failed',
|
||||
error: await response.json(),
|
||||
userId,
|
||||
});
|
||||
|
||||
throw new Error('Failed to create sign-in token');
|
||||
}
|
||||
|
||||
// TODO: Validate response with a schema.
|
||||
const data = await response.json();
|
||||
logger.info({ event: 'sign_in_token_created', userId });
|
||||
return data.token;
|
||||
}
|
||||
|
|
@ -1,18 +1,15 @@
|
|||
'use server';
|
||||
|
||||
import { sql } from 'drizzle-orm';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { type ApiResponse, ORGANIZATION_ALLOW_ALL } from '@/types';
|
||||
import { db } from '@/db';
|
||||
import { AuditLogTargetType, orgSettings } from '@/db/schema';
|
||||
import { insertAuditLog } from '@/lib/server/auditLogs';
|
||||
import {
|
||||
handleError,
|
||||
isAuthSuccess,
|
||||
validateAuth,
|
||||
type ApiResponse,
|
||||
} from './apiUtils';
|
||||
import { sql } from 'drizzle-orm';
|
||||
import { ORGANIZATION_ALLOW_ALL } from '@/schemas';
|
||||
import { isAuthSuccess, handleError } from '@/lib/server';
|
||||
|
||||
import { validateAuth } from './auth';
|
||||
import { insertAuditLog } from './auditLogs';
|
||||
|
||||
const defaultParametersSchema = z.object({
|
||||
experimentalPowerSteering: z.boolean().optional(),
|
||||
|
|
|
|||
|
|
@ -1,24 +1,23 @@
|
|||
'use server';
|
||||
|
||||
import { auth } from '@clerk/nextjs/server';
|
||||
import { db } from '@/db';
|
||||
import { AuditLogTargetType, orgSettings } from '@/db/schema';
|
||||
import { eq, sql } from 'drizzle-orm';
|
||||
import { auth } from '@clerk/nextjs/server';
|
||||
import { z } from 'zod';
|
||||
|
||||
import {
|
||||
type ApiResponse,
|
||||
ORGANIZATION_ALLOW_ALL,
|
||||
ORGANIZATION_DEFAULT,
|
||||
type OrganizationSettings,
|
||||
organizationAllowListSchema,
|
||||
organizationDefaultSettingsSchema,
|
||||
} from '@/schemas';
|
||||
import { z } from 'zod';
|
||||
import {
|
||||
handleError,
|
||||
isAuthSuccess,
|
||||
validateAuth,
|
||||
type ApiResponse,
|
||||
} from './apiUtils';
|
||||
import { insertAuditLog } from '@/lib/server/auditLogs';
|
||||
} from '@/types';
|
||||
import { db } from '@/db';
|
||||
import { AuditLogTargetType, orgSettings } from '@/db/schema';
|
||||
import { handleError, isAuthSuccess } from '@/lib/server';
|
||||
|
||||
import { validateAuth } from './auth';
|
||||
import { insertAuditLog } from './auditLogs';
|
||||
|
||||
export async function getOrganizationSettings(): Promise<
|
||||
OrganizationSettings | undefined
|
||||
|
|
|
|||
|
|
@ -2,14 +2,12 @@
|
|||
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { ApiResponse } from '@/types';
|
||||
import { handleError, isAuthSuccess } from '@/lib/server';
|
||||
import { AuditLogTargetType } from '@/db/schema';
|
||||
import { createAuditLog } from '@/lib/server/auditLogs';
|
||||
import {
|
||||
handleError,
|
||||
isAuthSuccess,
|
||||
validateAuth,
|
||||
type ApiResponse,
|
||||
} from './apiUtils';
|
||||
|
||||
import { validateAuth } from './auth';
|
||||
import { createAuditLog } from './auditLogs';
|
||||
|
||||
const allowAllProvidersSchema = z.object({
|
||||
allowAllProviders: z.boolean(),
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
'use server';
|
||||
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { clerkClient, currentUser } from '@clerk/nextjs/server';
|
||||
|
||||
import { db } from '@/db';
|
||||
import { users, type CreateUser, orgs, type CreateOrg } from '@/db/schema';
|
||||
|
||||
import { logger } from './logger';
|
||||
import { logger } from '../lib/server/logger';
|
||||
|
||||
export async function syncCurrentUser({
|
||||
userId,
|
||||
|
|
@ -4,8 +4,8 @@ import { useState } from 'react';
|
|||
import { useAuth } from '@clerk/nextjs';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { type TimePeriod, timePeriods } from '@/types';
|
||||
import type { AuditLog } from '@/db/schema';
|
||||
import { timePeriods, type TimePeriod } from '@/schemas';
|
||||
import { getAuditLogs } from '@/actions/auditLogs';
|
||||
import {
|
||||
Button,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {
|
|||
|
||||
import { updateDefaultParameters } from '@/actions/defaultParameters';
|
||||
import { getOrganizationSettings } from '@/actions/organizationSettings';
|
||||
import { type OrganizationSettings } from '@/schemas';
|
||||
import { type OrganizationSettings } from '@/types';
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
|
|
|
|||
|
|
@ -3,19 +3,20 @@
|
|||
import { useTranslations } from 'next-intl';
|
||||
import { useState } from 'react';
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
import { type ProviderName } from '@roo-code/types';
|
||||
|
||||
import {
|
||||
type OrganizationAllowList,
|
||||
type OrganizationSettings,
|
||||
ORGANIZATION_ALLOW_ALL,
|
||||
} from '@/types';
|
||||
import {
|
||||
getOrganizationSettings,
|
||||
updateOrganization,
|
||||
} from '@/actions/organizationSettings';
|
||||
import { Badge, Button, Checkbox, Label } from '@/components/ui';
|
||||
import { toast } from 'sonner';
|
||||
import {
|
||||
ORGANIZATION_ALLOW_ALL,
|
||||
type OrganizationAllowList,
|
||||
type OrganizationSettings,
|
||||
} from '@/schemas';
|
||||
import { type ProviderName } from '@roo-code/types';
|
||||
|
||||
type ProviderSetting = {
|
||||
allowAll: boolean;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||
|
||||
import { rooCodeTelemetryEventSchema } from '@roo-code/types';
|
||||
|
||||
import { captureEvent } from '@/lib/server/analytics';
|
||||
import { captureEvent } from '@/actions/analytics';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
const { userId, orgId } = await auth();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { auth } from '@clerk/nextjs/server';
|
||||
import { NextResponse } from 'next/server';
|
||||
import { auth } from '@clerk/nextjs/server';
|
||||
|
||||
import { type OrganizationSettings, ORGANIZATION_ALLOW_ALL } from '@/types';
|
||||
import { getOrganizationSettings } from '@/actions/organizationSettings';
|
||||
import { ORGANIZATION_ALLOW_ALL, type OrganizationSettings } from '@/schemas';
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { redirect } from 'next/navigation';
|
||||
import { auth } from '@clerk/nextjs/server';
|
||||
|
||||
import { getSignInToken } from '@/lib/server/clerk';
|
||||
import { Env } from '@/lib/server/env';
|
||||
import { Env } from '@/lib/server';
|
||||
import { getSignInToken } from '@/actions/auth';
|
||||
|
||||
import { DeepLink } from './DeepLink';
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { getLocale, getTranslations, setRequestLocale } from 'next-intl/server';
|
|||
import { auth } from '@clerk/nextjs/server';
|
||||
|
||||
import { getClerkLocale } from '@/i18n/locale';
|
||||
import { syncAuth } from '@/lib/server/sync';
|
||||
import { syncAuth } from '@/actions/sync';
|
||||
import { Toaster } from '@/components/ui';
|
||||
import {
|
||||
ThemeProvider,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { ArrowRightIcon } from 'lucide-react';
|
|||
|
||||
import { TelemetryEventName } from '@roo-code/types';
|
||||
|
||||
import { type TimePeriod, timePeriods } from '@/schemas';
|
||||
import { type TimePeriod, timePeriods } from '@/types';
|
||||
import { getUsage } from '@/actions/analytics';
|
||||
import { formatCurrency } from '@/lib/formatters';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { drizzle } from 'drizzle-orm/node-postgres';
|
||||
import { Pool } from 'pg';
|
||||
|
||||
import { Env } from '@/lib/server/env';
|
||||
import { Env } from '@/lib/server';
|
||||
|
||||
const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL,
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ import {
|
|||
import { relations } from 'drizzle-orm';
|
||||
|
||||
import {
|
||||
ORGANIZATION_ALLOW_ALL,
|
||||
type OrganizationDefaultSettings,
|
||||
type OrganizationAllowList,
|
||||
} from '@/schemas';
|
||||
ORGANIZATION_ALLOW_ALL,
|
||||
} from '@/types';
|
||||
|
||||
/**
|
||||
* users
|
||||
|
|
|
|||
|
|
@ -1,35 +1,9 @@
|
|||
import { createClient } from '@clickhouse/client';
|
||||
|
||||
import type { RooCodeTelemetryEvent } from '@roo-code/types';
|
||||
|
||||
import { Env } from './env';
|
||||
|
||||
export const client = createClient({
|
||||
export const analytics = createClient({
|
||||
url: Env.CLICKHOUSE_URL,
|
||||
username: Env.CLICKHOUSE_USERNAME,
|
||||
password: Env.CLICKHOUSE_PASSWORD,
|
||||
});
|
||||
|
||||
type AnalyticsEvent = {
|
||||
id: string;
|
||||
orgId: string;
|
||||
userId: string;
|
||||
timestamp: number;
|
||||
event: RooCodeTelemetryEvent;
|
||||
};
|
||||
|
||||
export const captureEvent = async ({
|
||||
event: { properties, ...cloudEvent },
|
||||
...analyticsEvent
|
||||
}: AnalyticsEvent) => {
|
||||
// The destructuring here flattens the `AnalyticsEvent` to match the ClickHouse
|
||||
// schema.
|
||||
const value = { ...analyticsEvent, ...cloudEvent, ...properties };
|
||||
console.log(`captureEvent`, value);
|
||||
|
||||
await client.insert({
|
||||
table: 'events',
|
||||
values: [value],
|
||||
format: 'JSONEachRow',
|
||||
});
|
||||
};
|
||||
|
|
|
|||
14
src/lib/server/api.ts
Normal file
14
src/lib/server/api.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import type { ApiResponse } from '@/types';
|
||||
import { logger } from '@/lib/server';
|
||||
|
||||
export function isAuthSuccess(
|
||||
result: { userId: string; orgId: string } | ApiResponse,
|
||||
): result is { userId: string; orgId: string } {
|
||||
return !('error' in result);
|
||||
}
|
||||
|
||||
export function handleError(e: unknown, eventPrefix: string): ApiResponse {
|
||||
const error = e instanceof Error ? e.message : 'Unknown error';
|
||||
logger.error({ event: `${eventPrefix}_error`, error });
|
||||
return { success: false, error };
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
import { db, type DB_OR_TX } from '@/db';
|
||||
import { auditLogs, type CreateAuditLog } from '@/db/schema';
|
||||
import { logger } from '@/lib/server/logger';
|
||||
|
||||
export async function insertAuditLog(
|
||||
db: DB_OR_TX,
|
||||
values: CreateAuditLog,
|
||||
): Promise<void> {
|
||||
await db.insert(auditLogs).values(values);
|
||||
const { userId, orgId, targetType } = values;
|
||||
logger.info({ userId, orgId, targetType });
|
||||
}
|
||||
|
||||
export async function createAuditLog(values: CreateAuditLog): Promise<{
|
||||
success: boolean;
|
||||
error?: string | Record<string, unknown>;
|
||||
}> {
|
||||
try {
|
||||
await insertAuditLog(db, values);
|
||||
return { success: true };
|
||||
} catch (e) {
|
||||
const error =
|
||||
e instanceof Error ? e.message : 'An unexpected error occurred';
|
||||
logger.error({ event: 'audit_log_creation_error', error });
|
||||
return { success: false, error };
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
import { Env } from './env';
|
||||
import { logger } from './logger';
|
||||
|
||||
export async function getSignInToken(
|
||||
userId: string,
|
||||
): Promise<string | undefined> {
|
||||
const response = await fetch('https://api.clerk.com/v1/sign_in_tokens', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${Env.CLERK_SECRET_KEY}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
user_id: userId,
|
||||
// Default expiration is 30 days (2592000 seconds)
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
logger.error({
|
||||
event: 'sign_in_token_creation_failed',
|
||||
error: errorData,
|
||||
userId,
|
||||
});
|
||||
|
||||
throw new Error("Failed to create sign-in token");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
logger.info({
|
||||
event: 'sign_in_token_created',
|
||||
userId,
|
||||
});
|
||||
|
||||
return data.token;
|
||||
}
|
||||
4
src/lib/server/index.ts
Normal file
4
src/lib/server/index.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export { Env } from './env';
|
||||
export { logger } from './logger';
|
||||
export { isAuthSuccess, handleError } from './api';
|
||||
export { analytics } from './analytics';
|
||||
|
|
@ -1,22 +1,17 @@
|
|||
import type { DestinationStream } from 'pino';
|
||||
import logtail from '@logtail/pino';
|
||||
import pino from 'pino';
|
||||
import pino, { type DestinationStream } from 'pino';
|
||||
import pretty from 'pino-pretty';
|
||||
import logtail from '@logtail/pino';
|
||||
|
||||
import { Env } from './env';
|
||||
|
||||
let stream: DestinationStream;
|
||||
|
||||
if (Env.LOGTAIL_SOURCE_TOKEN) {
|
||||
stream = pino.multistream([
|
||||
await logtail({
|
||||
sourceToken: Env.LOGTAIL_SOURCE_TOKEN,
|
||||
options: { sendLogsToBetterStack: true },
|
||||
}),
|
||||
{ stream: pretty() }, // Prints logs to the console.
|
||||
]);
|
||||
} else {
|
||||
stream = pretty({ colorize: true });
|
||||
}
|
||||
const stream: DestinationStream = Env.LOGTAIL_SOURCE_TOKEN
|
||||
? pino.multistream([
|
||||
await logtail({
|
||||
sourceToken: Env.LOGTAIL_SOURCE_TOKEN,
|
||||
options: { sendLogsToBetterStack: true },
|
||||
}),
|
||||
{ stream: pretty() }, // Prints logs to the console.
|
||||
])
|
||||
: pretty({ colorize: true });
|
||||
|
||||
export const logger = pino({ base: undefined }, stream);
|
||||
|
|
|
|||
5
src/types/api.ts
Normal file
5
src/types/api.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export type ApiResponse = {
|
||||
success: boolean;
|
||||
message?: string;
|
||||
error?: string;
|
||||
};
|
||||
3
src/types/index.ts
Normal file
3
src/types/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from './api';
|
||||
export * from './org';
|
||||
export * from './time-period';
|
||||
|
|
@ -1,14 +1,6 @@
|
|||
/**
|
||||
* TimePeriod
|
||||
*/
|
||||
|
||||
import { providerNames } from '@roo-code/types';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const timePeriods = [7, 30, 90] as const;
|
||||
|
||||
export type TimePeriod = (typeof timePeriods)[number];
|
||||
|
||||
export const organizationAllowListSchema = z.object({
|
||||
allowAll: z.boolean(),
|
||||
providers: z.record(
|
||||
3
src/types/time-period.ts
Normal file
3
src/types/time-period.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export const timePeriods = [7, 30, 90] as const;
|
||||
|
||||
export type TimePeriod = (typeof timePeriods)[number];
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { sql } from 'drizzle-orm';
|
||||
|
||||
import { Env } from '@/lib/server/env';
|
||||
import { Env } from '@/lib/server';
|
||||
import { testDb, disconnect } from '@/db';
|
||||
|
||||
async function resetTestDatabase() {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue