chore: resolve remaining knip issues (#1991)

## Summary

Resolve all remaining knip issues — removes unused exports/types, adds missing direct dependencies, deletes dead code, and updates knip config.

**Dependency fixes:**
- Root: swapped unused `eslint-config-next`/`eslint-plugin-react-hooks` for actually-imported `@eslint/js`, `typescript-eslint`, `tslib`
- App: added directly-used transitive deps (`@codemirror/*`, `react-resizable`, `postcss-simple-vars`, `rimraf`, `serve`, `@next/eslint-plugin-next`, `eslint-plugin-react`); removed unused `@storybook/react`

**Dead code removal:**
- Removed ~100 unused exports/types across api and app packages (removed `export` keyword where used locally, deleted entirely where not)
- Fixed duplicate `DBRowTableIconButton` default+named export; updated consumers to use named import

**knip.json updates:**
- Added `fixtures.ts` entry point and `opamp/**` ignore for api package
- Excluded `enumMembers` and `duplicates` issue types
- Enabled `ignoreExportsUsedInFile`

### How to test locally or on Vercel

1. `yarn install && yarn knip` — should produce zero output
2. `make ci-lint` — all packages pass
3. `make ci-unit` — all unit tests pass
This commit is contained in:
Brandon Pereira 2026-03-27 14:17:47 -06:00 committed by GitHub
parent acd117abcf
commit c72d7baa7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
52 changed files with 427 additions and 640 deletions

View file

@ -12,9 +12,15 @@
]
},
"packages/api": {
"entry": ["src/index.ts", "src/tasks/index.ts", "scripts/*.ts"],
"entry": [
"src/index.ts",
"src/tasks/index.ts",
"scripts/*.ts",
"src/fixtures.ts"
],
"project": ["src/**/*.ts"],
"ignoreDependencies": ["pino-pretty", "aws4"]
"ignoreDependencies": ["pino-pretty", "aws4"],
"ignore": ["src/opamp/**", "src/utils/logParser.ts"]
},
"packages/common-utils": {
"entry": ["src/**/*.ts", "!src/__tests__/**", "!src/**/*.test.*"],
@ -26,5 +32,6 @@
"concurrently",
"dotenv",
"babel-plugin-react-compiler"
]
],
"exclude": ["enumMembers", "duplicates"]
}

View file

@ -9,6 +9,7 @@
"devDependencies": {
"@changesets/cli": "^2.26.2",
"@dotenvx/dotenvx": "^1.51.1",
"@eslint/js": "^9.39.1",
"@types/ungap__structured-clone": "^1.2.0",
"@ungap/structured-clone": "^1.3.0",
"babel-plugin-react-compiler": "^1.0.0",
@ -17,18 +18,18 @@
"dotenv-cli": "^8.0.0",
"dotenv-expand": "^12.0.1",
"eslint": "^9.39.1",
"eslint-config-next": "16.0.7",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-n": "^16.4.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-security": "^3.0.1",
"eslint-plugin-simple-import-sort": "^12.1.1",
"husky": "^8.0.3",
"knip": "^6.0.1",
"lint-staged": "^13.1.2",
"nx": "21.3.11",
"prettier": "3.3.3"
"prettier": "3.3.3",
"tslib": "^2.6.0",
"typescript-eslint": "^8.46.0"
},
"scripts": {
"setup": "yarn install && husky install",

View file

@ -190,7 +190,7 @@ function normalizeParsedDate(parsed?: chrono.ParsedComponents): Date | null {
return parsedDate;
}
export function parseTimeRangeInput(
function parseTimeRangeInput(
str: string,
isUTC: boolean = false,
): [Date | null, Date | null] {
@ -216,62 +216,6 @@ export function parseTimeRangeInput(
}
}
export const LIVE_TAIL_TIME_QUERY = 'Live Tail';
export const RELATIVE_TIME_OPTIONS: ([string, string] | 'divider')[] = [
// ['Last 15 seconds', '15s'],
// ['Last 30 seconds', '30s'],
// 'divider',
['Last 1 minute', '1m'],
['Last 5 minutes', '5m'],
['Last 15 minutes', '15m'],
['Last 30 minutes', '30m'],
['Last 45 minutes', '45m'],
'divider',
['Last 1 hour', '1h'],
['Last 3 hours', '3h'],
['Last 6 hours', '6h'],
['Last 12 hours', '12h'],
'divider',
['Last 1 days', '1d'],
['Last 2 days', '2d'],
['Last 7 days', '7d'],
['Last 14 days', '14d'],
['Last 30 days', '30d'],
];
export const DURATION_OPTIONS = [
'30s',
'1m',
'5m',
'15m',
'30m',
'1h',
'3h',
'6h',
'12h',
];
export const DURATIONS: Record<string, any> = {
'30s': { seconds: 30 },
'1m': { minutes: 1 },
'5m': { minutes: 5 },
'15m': { minutes: 15 },
'30m': { minutes: 30 },
'1h': { hours: 1 },
'3h': { hours: 3 },
'6h': { hours: 6 },
'12h': { hours: 12 },
};
export const dateParser = (input?: string) => {
if (!input) {
return null;
}
const parsed = chrono.casual.parse(input)[0];
return normalizeParsedDate(parsed?.start);
};
// TODO: Dedup from DBSearchPageFilters
function isFieldPrimary(tableMetadata: TableMetadata | undefined, key: string) {
return tableMetadata?.primary_key?.includes(key);
@ -279,7 +223,7 @@ function isFieldPrimary(tableMetadata: TableMetadata | undefined, key: string) {
// TODO: Dedup w/ app/src/utils.ts
// Date formatting
export const mergePath = (path: string[], jsonColumns: string[] = []) => {
const mergePath = (path: string[], jsonColumns: string[] = []) => {
const [key, ...rest] = path;
if (rest.length === 0) {
return key;

View file

@ -16,14 +16,6 @@ export function findUserByEmail(email: string) {
return User.findOne({ email: email.toLowerCase() });
}
export async function findUserByEmailInTeam(
email: string,
team: string | ObjectId,
) {
// Case-insensitive email search - lowercase the email since User model stores emails in lowercase
return User.findOne({ email: email.toLowerCase(), team });
}
export function findUsersByTeam(team: string | ObjectId) {
return User.find({ team }).sort({ createdAt: 1 });
}

View file

@ -2,6 +2,4 @@ import cors from 'cors';
import { FRONTEND_URL } from '@/config';
export const noCors = cors();
export default cors({ credentials: true, origin: FRONTEND_URL });

View file

@ -7,8 +7,7 @@ import mongoose, { Schema } from 'mongoose';
import type { ObjectId } from '.';
export interface IPresetDashboardFilter
extends Omit<PresetDashboardFilter, 'source'> {
interface IPresetDashboardFilter extends Omit<PresetDashboardFilter, 'source'> {
_id: ObjectId;
team: ObjectId;
source: ObjectId;

View file

@ -1,7 +1,7 @@
import mongoose, { Schema } from 'mongoose';
import ms from 'ms';
export interface ITeamInvite {
interface ITeamInvite {
createdAt: Date;
email: string;
name?: string;

View file

@ -119,7 +119,7 @@ export const formatValueToMatchThreshold = (
}).format(value);
};
export const notifyChannel = async ({
const notifyChannel = async ({
channel,
message,
}: {

View file

@ -10,7 +10,7 @@ export type Json =
| Json[]
| { [key: string]: Json };
export const useTry = <T>(fn: () => T): [null | Error | unknown, null | T] => {
const useTry = <T>(fn: () => T): [null | Error | unknown, null | T] => {
let output: null | T = null;
let error: null | Error | unknown = null;
try {
@ -42,9 +42,6 @@ export const truncateString = (str: string, length: number) => {
return str;
};
export const sleep = (ms: number) =>
new Promise(resolve => setTimeout(resolve, ms));
export const convertMsToGranularityString = (ms: number): Granularity => {
const granularitySizeSeconds = Math.ceil(ms / 1000);

View file

@ -50,24 +50,6 @@ export class Api404Error extends BaseError {
}
}
export class Api401Error extends BaseError {
constructor(name: string) {
super(name, StatusCode.UNAUTHORIZED, true, 'Unauthorized');
}
}
export class Api403Error extends BaseError {
constructor(name: string) {
super(name, StatusCode.FORBIDDEN, true, 'Forbidden');
}
}
export class Api409Error extends BaseError {
constructor(name: string) {
super(name, StatusCode.CONFLICT, true, 'Conflict');
}
}
export const isOperationalError = (error: Error) => {
if (error instanceof BaseError) {
return error.isOperational;

View file

@ -4,7 +4,7 @@ import type { Json, JSONBlob } from './common';
import { tryJSONStringify } from './common';
export type KeyPath = string[];
export enum AggregationTemporality {
enum AggregationTemporality {
Delta = 1,
Cumulative = 2,
}
@ -197,21 +197,6 @@ export type VectorLog = _VectorLogFields &
tso: number; // observed timestamp
};
export type VectorSpan = {
atrs: JSONBlob; // attributes
authorization?: string | null;
et: number; // end timestamp
hdx_platform: string;
hdx_token: string | null;
n: string; // name
p_id: string; // parent id
r: string; // raw
s_id: string; // span id
st: number; // start timestamp
t_id: string; // trace id
tso: number; // observed timestamp
};
export type VectorMetric = {
at: number; // aggregation temporality
authorization?: string;
@ -302,15 +287,3 @@ class VectorRrwebParser extends ParsingInterface<VectorLog, RrwebEventModel> {
};
}
}
// TODO: do this on the ingestor side ?
export const extractApiKey = (log: VectorLog | VectorSpan | VectorMetric) => {
if (log.authorization?.includes('Bearer')) {
return log.authorization.split('Bearer ')[1];
}
return log.hdx_token;
};
export const vectorLogParser = new VectorLogParser();
export const vectorMetricParser = new VectorMetricParser();
export const vectorRrwebParser = new VectorRrwebParser();

View file

@ -17,13 +17,13 @@ export const objectIdSchema = z.string().refine(val => {
return Types.ObjectId.isValid(val);
});
export const sourceTableSchema = z.union([
const sourceTableSchema = z.union([
z.literal('logs'),
z.literal('rrweb'),
z.literal('metrics'),
]);
export type SourceTable = z.infer<typeof sourceTableSchema>;
type SourceTable = z.infer<typeof sourceTableSchema>;
// ================================
// Charts & Dashboards (old format)
@ -93,7 +93,7 @@ const searchChartSeriesSchema = z.object({
whereLanguage: whereLanguageSchema,
});
export type SearchChartSeries = z.infer<typeof searchChartSeriesSchema>;
type SearchChartSeries = z.infer<typeof searchChartSeriesSchema>;
const markdownChartSeriesSchema = z.object({
type: z.literal('markdown'),
@ -124,7 +124,7 @@ const chartSeriesSchema = z.discriminatedUnion('type', [
markdownChartSeriesSchema,
]);
export type ChartSeries = z.infer<typeof chartSeriesSchema>;
type ChartSeries = z.infer<typeof chartSeriesSchema>;
export const tagsSchema = z.array(z.string().max(32)).max(50).optional();
@ -150,7 +150,7 @@ export const externalDashboardSavedFilterValueSchema = z.object({
condition: z.string().max(10000),
});
export type ExternalDashboardSavedFilterValue = z.infer<
type ExternalDashboardSavedFilterValue = z.infer<
typeof externalDashboardSavedFilterValueSchema
>;
@ -318,7 +318,7 @@ const externalDashboardBuilderTileConfigSchema = z.discriminatedUnion(
],
);
export type ExternalDashboardBuilderTileConfig = z.infer<
type ExternalDashboardBuilderTileConfig = z.infer<
typeof externalDashboardBuilderTileConfigSchema
>;
@ -441,7 +441,7 @@ export const externalDashboardTileSchema = z
export type ExternalDashboardTile = z.infer<typeof externalDashboardTileSchema>;
export const externalDashboardTileSchemaWithOptionalId =
const externalDashboardTileSchemaWithOptionalId =
externalDashboardTileSchema.and(
z.object({
// User defined ID
@ -449,7 +449,7 @@ export const externalDashboardTileSchemaWithOptionalId =
}),
);
export type ExternalDashboardTileWithOptionalId = z.infer<
type ExternalDashboardTileWithOptionalId = z.infer<
typeof externalDashboardTileSchemaWithOptionalId
>;
@ -485,18 +485,18 @@ export const externalDashboardTileListSchema = z
// ==============================
// Alerts
// ==============================
export const zChannel = z.object({
const zChannel = z.object({
type: z.literal('webhook'),
webhookId: z.string().min(1),
});
export const zSavedSearchAlert = z.object({
const zSavedSearchAlert = z.object({
source: z.literal(AlertSource.SAVED_SEARCH),
groupBy: z.string().optional(),
savedSearchId: z.string().min(1),
});
export const zTileAlert = z.object({
const zTileAlert = z.object({
source: z.literal(AlertSource.TILE),
tileId: z.string().min(1),
dashboardId: z.string().min(1),

View file

@ -26,8 +26,11 @@
"knip": "knip"
},
"dependencies": {
"@codemirror/autocomplete": "^6.0.0",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-sql": "^6.7.0",
"@codemirror/lint": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@dagrejs/dagre": "^1.1.5",
"@hookform/resolvers": "^3.9.0",
"@hyperdx/browser": "^0.22.0",
@ -80,6 +83,7 @@
"react-hotkeys-hook": "^4.3.7",
"react-json-tree": "^0.20.0",
"react-markdown": "^10.1.0",
"react-resizable": "^3.0.4",
"recharts": "^2.12.7",
"rrweb": "2.0.0-alpha.8",
"sass": "^1.54.8",
@ -97,13 +101,13 @@
"@chromatic-com/storybook": "^4.1.3",
"@eslint/compat": "^2.0.0",
"@jedmao/location": "^3.0.0",
"@next/eslint-plugin-next": "^16.0.10",
"@playwright/test": "^1.57.0",
"@storybook/addon-docs": "^10.1.4",
"@storybook/addon-links": "^10.1.4",
"@storybook/addon-styling-webpack": "^3.0.0",
"@storybook/addon-themes": "^10.1.4",
"@storybook/nextjs": "^10.1.4",
"@storybook/react": "^10.1.4",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^16.3.0",
@ -124,6 +128,7 @@
"@types/sqlstring": "^2.3.2",
"eslint-config-next": "^16.0.10",
"eslint-plugin-playwright": "^2.4.0",
"eslint-plugin-react": "^7.37.0",
"eslint-plugin-react-hook-form": "^0.3.1",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-storybook": "10.1.4",
@ -135,7 +140,10 @@
"msw-storybook-addon": "^2.0.2",
"postcss": "^8.4.38",
"postcss-preset-mantine": "^1.15.0",
"postcss-simple-vars": "^7.0.0",
"prettier": "^3.3.2",
"rimraf": "^4.4.1",
"serve": "^14.0.0",
"storybook": "^10.2.10",
"stylelint": "^16.26.1",
"stylelint-config-standard-scss": "^16.0.0",

View file

@ -33,34 +33,21 @@ import {
TMetricSource,
TSource,
} from '@hyperdx/common-utils/dist/types';
import { SegmentedControl } from '@mantine/core';
import { notifications } from '@mantine/notifications';
import DateRangeIndicator from './components/charts/DateRangeIndicator';
import { MVOptimizationExplanationResult } from './hooks/useMVOptimizationExplanation';
import { getMetricNameSql } from './otelSemanticConventions';
import {
AggFn,
ChartSeries,
MetricsDataType,
SourceTable,
TableChartSeries,
TimeChartSeries,
} from './types';
import { AggFn, TableChartSeries, TimeChartSeries } from './types';
import { NumberFormat } from './types';
import { getColorProps, getLogLevelColorOrder, logLevelColor } from './utils';
export const SORT_ORDER = [
const SORT_ORDER = [
{ value: 'asc' as const, label: 'Ascending' },
{ value: 'desc' as const, label: 'Descending' },
];
export type SortOrder = (typeof SORT_ORDER)[number]['value'];
export const TABLES = [
{ value: 'logs' as const, label: 'Logs / Spans' },
{ value: 'metrics' as const, label: 'Metrics' },
];
type SortOrder = (typeof SORT_ORDER)[number]['value'];
export const AGG_FNS = [
{ value: 'count' as const, label: 'Count of Events', isAttributable: false },
@ -81,37 +68,6 @@ export const AGG_FNS = [
{ value: 'none' as const, label: 'Custom' },
];
export const getMetricAggFns = (
dataType: MetricsDataType,
): { value: AggFn; label: string }[] => {
if (dataType === MetricsDataType.Histogram) {
return [
{ value: 'p99', label: '99th Percentile' },
{ value: 'p95', label: '95th Percentile' },
{ value: 'p90', label: '90th Percentile' },
{ value: 'p50', label: 'Median' },
];
} else if (dataType === MetricsDataType.Summary) {
return [
{ value: 'sum', label: 'Sum' },
{ value: 'max', label: 'Maximum' },
{ value: 'min', label: 'Minimum' },
{ value: 'count', label: 'Sample Count' },
];
}
return [
{ value: 'sum', label: 'Sum' },
{ value: 'p99', label: '99th Percentile' },
{ value: 'p95', label: '95th Percentile' },
{ value: 'p90', label: '90th Percentile' },
{ value: 'p50', label: 'Median' },
{ value: 'avg', label: 'Average' },
{ value: 'max', label: 'Maximum' },
{ value: 'min', label: 'Minimum' },
];
};
export const DEFAULT_CHART_CONFIG: Omit<
BuilderSavedChartConfig,
'source' | 'connection'
@ -132,10 +88,6 @@ export const DEFAULT_CHART_CONFIG: Omit<
alignDateRangeToGranularity: true,
};
export const isGranularity = (value: string): value is Granularity => {
return Object.values(Granularity).includes(value as Granularity);
};
function getTimeChartGranularity(
granularity: string | undefined,
dateRange: [Date, Date],
@ -216,82 +168,6 @@ export function useTimeChartSettings(
}, [config]);
}
export function seriesToSearchQuery({
series,
groupByValue,
}: {
series: ChartSeries[];
groupByValue?: string;
}) {
const queries = series
.map((s, i) => {
if (s.type === 'time' || s.type === 'table' || s.type === 'number') {
const { where, aggFn, field } = s;
return `${where.trim()}${
aggFn !== 'count' && field ? ` ${field}:*` : ''
}${
'groupBy' in s && s.groupBy != null && s.groupBy.length > 0
? ` ${s.groupBy}:${groupByValue ?? '*'}`
: ''
}`.trim();
}
})
.filter(q => q != null && q.length > 0);
const q =
queries.length > 1
? queries.map(q => `(${q})`).join(' OR ')
: queries.join('');
return q;
}
export function seriesToUrlSearchQueryParam({
series,
dateRange,
groupByValue = '*',
}: {
series: ChartSeries[];
dateRange: [Date, Date];
groupByValue?: string | undefined;
}) {
const q = seriesToSearchQuery({ series, groupByValue });
return new URLSearchParams({
q,
from: `${dateRange[0].getTime()}`,
to: `${dateRange[1].getTime()}`,
});
}
export function TableToggle({
table,
setTableAndAggFn,
}: {
setTableAndAggFn: (table: SourceTable, fn: AggFn) => void;
table: string;
}) {
return (
<SegmentedControl
value={table}
onChange={(value: string) => {
const val = value ?? 'logs';
if (val === 'logs') {
setTableAndAggFn('logs', 'count');
} else if (val === 'metrics') {
// TODO: This should set rate if metric field is a sum
// or we should just reset the field if changing tables
setTableAndAggFn('metrics', 'max');
}
}}
data={[
{ label: 'Logs/Spans', value: 'logs' },
{ label: 'Metrics', value: 'metrics' },
]}
/>
);
}
export const ChartKeyJoiner = ' · ';
export const PreviousPeriodSuffix = ' (previous)';
@ -483,13 +359,6 @@ export const INTEGER_NUMBER_FORMAT: NumberFormat = {
thousandSeparated: true,
};
export const SINGLE_DECIMAL_NUMBER_FORMAT: NumberFormat = {
factor: 1,
output: 'number',
mantissa: 1,
thousandSeparated: true,
};
export const MS_NUMBER_FORMAT: NumberFormat = {
factor: 1,
output: 'number',
@ -516,10 +385,6 @@ export const K8S_MEM_NUMBER_FORMAT: NumberFormat = {
output: 'byte',
};
export const K8S_NETWORK_NUMBER_FORMAT: NumberFormat = {
output: 'byte',
};
function inferValueColumns(
meta: Array<{ name: string; type: string }>,
excluded: Set<string>,
@ -859,7 +724,7 @@ export function formatResponseForTimeChart({
}
// Define a mapping from app AggFn to common-utils AggregateFunction
export const mapV1AggFnToV2 = (aggFn?: AggFn): AggFnV2 | undefined => {
const mapV1AggFnToV2 = (aggFn?: AggFn): AggFnV2 | undefined => {
if (aggFn == null) {
return aggFn;
}
@ -905,7 +770,7 @@ export const mapV1AggFnToV2 = (aggFn?: AggFn): AggFnV2 | undefined => {
throw new Error(`Unsupported aggregation function in v2: ${aggFn}`);
};
export const convertV1GroupByToV2 = (
const convertV1GroupByToV2 = (
metricSource: TMetricSource,
groupBy: string[],
): string => {

View file

@ -26,7 +26,7 @@ import { useSources } from './source';
import { parseTimeQuery, useNewTimeQuery } from './timeQuery';
// The % of requests sampled is 1 / sampling factor
export const SAMPLING_FACTORS = [
const SAMPLING_FACTORS = [
{
value: 100,
label: '1%',

View file

@ -3,7 +3,7 @@ import { useController, UseControllerProps } from 'react-hook-form';
import { Granularity } from '@hyperdx/common-utils/dist/core/utils';
import { Select } from '@mantine/core';
export default function GranularityPicker({
function GranularityPicker({
value,
onChange,
disabled,
@ -70,9 +70,7 @@ export default function GranularityPicker({
);
}
export function GranularityPickerControlledComponent(
props: UseControllerProps<any>,
) {
function GranularityPickerControlledComponent(props: UseControllerProps<any>) {
const {
field,
fieldState: { invalid, isTouched, isDirty },

View file

@ -206,7 +206,7 @@ function ExpandableLegendItem({
);
}
export const LegendRenderer = memo<{
const LegendRenderer = memo<{
payload?: {
dataKey: string;
value: string;

View file

@ -66,7 +66,7 @@ export const SectionWrapper: React.FC<
/**
* Stacktrace elements
*/
export const StacktraceValue = ({
const StacktraceValue = ({
label,
value,
}: {
@ -103,7 +103,7 @@ const StacktraceRowExpandButton = ({
);
};
export const StacktraceRow = ({
const StacktraceRow = ({
row,
table,
}: {
@ -205,7 +205,7 @@ export const StacktraceRow = ({
);
};
export const stacktraceColumns: ColumnDef<StacktraceFrame>[] = [
const stacktraceColumns: ColumnDef<StacktraceFrame>[] = [
{
accessorKey: 'filename',
cell: StacktraceRow,
@ -256,7 +256,7 @@ const LevelChip = React.memo(({ level }: { level?: string }) => {
);
});
export const breadcrumbColumns: ColumnDef<StacktraceBreadcrumb>[] = [
const breadcrumbColumns: ColumnDef<StacktraceBreadcrumb>[] = [
{
accessorKey: 'category',
header: 'Category',
@ -339,7 +339,7 @@ export const breadcrumbColumns: ColumnDef<StacktraceBreadcrumb>[] = [
},
];
export const useShowMoreRows = <T extends object>({
const useShowMoreRows = <T extends object>({
rows,
maxRows = 5,
}: {
@ -520,7 +520,7 @@ export const LogSidePanelKbdShortcuts = () => {
);
};
export const SourceMapsFtux = () => {
const SourceMapsFtux = () => {
const [isDismissed, setIsDismissed] = useLocalStorage(
'sourceMapsFtuxDismissed',
false,

View file

@ -40,7 +40,7 @@ type ServicesResponse = {
>;
};
export function loginHook(request: Request, options: any, response: Response) {
function loginHook(request: Request, options: any, response: Response) {
// marketing pages
const WHITELIST_PATHS = [
'/',
@ -60,7 +60,7 @@ export function loginHook(request: Request, options: any, response: Response) {
}
}
export const server = ky.create({
const server = ky.create({
prefixUrl: '/api',
credentials: 'include',
hooks: {

View file

@ -9,7 +9,7 @@ type AggFnValues = (typeof AGG_FNS)[number]['value'];
type OnChangeValue =
| { aggFn?: AggFnValues }
| { aggFn: 'quantile'; level: number };
export default function AggFnSelect({
function AggFnSelect({
value,
defaultValue,
onChange,

View file

@ -17,7 +17,7 @@ import { intervalToDateRange, intervalToGranularity } from '@/utils/alerts';
import { getAlertReferenceLines } from './Alerts';
export type AlertPreviewChartProps = {
type AlertPreviewChartProps = {
source: TSource;
where?: SearchCondition | null;
whereLanguage?: SearchConditionLanguage | null;

View file

@ -504,7 +504,7 @@ function ChartSeriesEditorComponent({
}
const ChartSeriesEditor = ChartSeriesEditorComponent;
export const ErrorNotificationMessage = ({
const ErrorNotificationMessage = ({
errors,
}: {
errors: { path: Path<ChartEditorFormState>; message: string }[];

View file

@ -202,7 +202,7 @@ const PatternTrendChartTooltip = () => {
return null;
};
export const PatternTrendChart = ({
const PatternTrendChart = ({
data,
dateRange,
color,
@ -1430,7 +1430,7 @@ export function useConfigWithPrimaryAndPartitionKey(
return mergedConfig;
}
export function selectColumnMapWithoutAdditionalKeys(
function selectColumnMapWithoutAdditionalKeys(
selectMeta: ColumnMetaType[] | undefined,
additionalKeysLength: number | undefined,
): Map<

View file

@ -112,7 +112,7 @@ type FilterCheckboxProps = {
isPercentageLoading?: boolean;
};
export const TextButton = ({
const TextButton = ({
onClick,
label,
ms,
@ -159,7 +159,7 @@ const FilterPercentage = ({ percentage, isLoading }: FilterPercentageProps) => {
);
};
export const FilterCheckbox = ({
const FilterCheckbox = ({
value,
label,
pinned,
@ -1505,10 +1505,7 @@ const DBSearchPageFiltersComponent = ({
);
};
export function isFieldPrimary(
tableMetadata: TableMetadata | undefined,
key: string,
) {
function isFieldPrimary(tableMetadata: TableMetadata | undefined, key: string) {
return tableMetadata?.primary_key?.includes(key);
}
export const DBSearchPageFilters = memo(DBSearchPageFiltersComponent);

View file

@ -14,7 +14,7 @@ import { FilterGroup } from '../DBSearchPageFilters';
import classes from '../../../styles/SearchPage.module.scss';
export type NestedFilterGroupProps = {
type NestedFilterGroupProps = {
name: string;
childFilters: {
key: string;

View file

@ -6,7 +6,7 @@ import { IconCopy, IconFilter, IconFilterX } from '@tabler/icons-react';
import { RowSidePanelContext } from '../DBRowSidePanel';
import DBRowTableIconButton from './DBRowTableIconButton';
import { DBRowTableIconButton } from './DBRowTableIconButton';
import styles from '../../../styles/LogTable.module.scss';

View file

@ -61,5 +61,3 @@ export const DBRowTableIconButton: React.FC<DBRowTableIconButtonProps> = ({
</Tooltip>
);
};
export default DBRowTableIconButton;

View file

@ -3,7 +3,7 @@ import { IconCopy, IconLink, IconTextWrap } from '@tabler/icons-react';
import { INTERNAL_ROW_FIELDS, RowWhereResult } from '@/hooks/useRowWhere';
import DBRowTableIconButton from './DBRowTableIconButton';
import { DBRowTableIconButton } from './DBRowTableIconButton';
import styles from '../../../styles/LogTable.module.scss';

View file

@ -7,7 +7,7 @@ import { useTablesDirect } from '@/clickhouse';
import SourceSchemaPreview from './SourceSchemaPreview';
import { SourceSelectRightSection } from './SourceSelect';
export default function DBTableSelect({
function DBTableSelect({
database,
setTable,
table,

View file

@ -14,7 +14,7 @@ type DatabaseSelectProps = {
connectionId: string | undefined;
};
export default function DatabaseSelect({
function DatabaseSelect({
database,
setDatabase,
connectionId,

View file

@ -20,9 +20,9 @@ import { Table, TableCellButton } from './Table';
import styles from '../../styles/LogSidePanel.module.scss';
// https://github.com/TanStack/table/discussions/3192#discussioncomment-3873093
export const UNDEFINED_WIDTH = 99999;
const UNDEFINED_WIDTH = 99999;
export const parseEvents = (__events?: string) => {
const parseEvents = (__events?: string) => {
try {
return JSON.parse(__events || '[]')[0].fields.reduce(
(acc: any, field: any) => {
@ -40,7 +40,7 @@ export const parseEvents = (__events?: string) => {
}
};
export const getFirstFrame = (frames?: TStacktraceFrame[]) => {
const getFirstFrame = (frames?: TStacktraceFrame[]) => {
if (!frames || !frames.length) {
return null;
}
@ -52,7 +52,7 @@ export const getFirstFrame = (frames?: TStacktraceFrame[]) => {
);
};
export const StacktraceFrame = ({
const StacktraceFrame = ({
filename,
function: functionName,
lineno,
@ -96,7 +96,7 @@ export const StacktraceFrame = ({
);
};
export type StacktraceBreadcrumbCategory =
type StacktraceBreadcrumbCategory =
| 'ui.click'
| 'fetch'
| 'xhr'
@ -104,7 +104,7 @@ export type StacktraceBreadcrumbCategory =
| 'navigation'
| string;
export type StacktraceBreadcrumb = {
type StacktraceBreadcrumb = {
type?: string;
level?: string;
event_id?: string;
@ -114,7 +114,7 @@ export type StacktraceBreadcrumb = {
timestamp: number;
};
export const CollapsibleSection = ({
const CollapsibleSection = ({
title,
children,
initiallyCollapsed,
@ -156,7 +156,7 @@ export const SectionWrapper: React.FC<
/**
* Stacktrace elements
*/
export const StacktraceValue = ({
const StacktraceValue = ({
label,
value,
}: {
@ -193,7 +193,7 @@ const StacktraceRowExpandButton = ({
);
};
export const StacktraceRow = ({
const StacktraceRow = ({
row,
table,
}: {
@ -291,7 +291,7 @@ export const StacktraceRow = ({
);
};
export const stacktraceColumns: ColumnDef<TStacktraceFrame>[] = [
const stacktraceColumns: ColumnDef<TStacktraceFrame>[] = [
{
accessorKey: 'filename',
cell: StacktraceRow,
@ -342,7 +342,7 @@ const LevelChip = React.memo(({ level }: { level?: string }) => {
);
});
export const breadcrumbColumns: ColumnDef<StacktraceBreadcrumb>[] = [
const breadcrumbColumns: ColumnDef<StacktraceBreadcrumb>[] = [
{
accessorKey: 'category',
header: 'Category',
@ -450,7 +450,7 @@ export const useShowMoreRows = <T extends object>({
return { visibleRows, hiddenRowsCount, handleToggleMoreRows, isExpanded };
};
export type ExceptionValues = {
type ExceptionValues = {
type: string;
value: string;
mechanism?: {

View file

@ -84,22 +84,6 @@ export const ExpandedLogRow = memo(
},
);
export interface ExpandableRowTableProps {
// Expansion state management
expandedRows: Record<string, boolean>;
onToggleRowExpansion: (rowId: string) => void;
onExpandedRowsChange?: (hasExpandedRows: boolean) => void;
collapseAllRows?: boolean;
showExpandButton?: boolean;
// Row data
source?: TSource;
getRowId: (row: Record<string, any>) => string;
// Table display
highlightedLineId?: string;
}
// Hook for managing expansion state
export const useExpandableRows = (
onExpandedRowsChange?: (hasExpandedRows: boolean) => void,

View file

@ -7,8 +7,6 @@ import {
InputProps,
PasswordInput,
PasswordInputProps,
Switch,
SwitchProps,
TextInput,
TextInputProps,
} from '@mantine/core';
@ -48,17 +46,6 @@ interface CheckboxControlledProps<T extends FieldValues>
rules?: Parameters<Control<T>['register']>[1];
}
interface SwitchControlledProps<T extends FieldValues>
extends Omit<SwitchProps, 'name' | 'style'>,
Omit<
React.InputHTMLAttributes<HTMLInputElement>,
'name' | 'size' | 'color'
> {
name: Path<T>;
control: Control<T>;
rules?: Parameters<Control<T>['register']>[1];
}
export function TextInputControlled<T extends FieldValues>({
name,
control,
@ -135,21 +122,3 @@ export function CheckBoxControlled<T extends FieldValues>({
/>
);
}
export function SwitchControlled<T extends FieldValues>({
name,
control,
rules,
...props
}: SwitchControlledProps<T>) {
return (
<Controller
name={name}
control={control}
rules={rules}
render={({ field: { value, ...field }, fieldState: { error } }) => (
<Switch {...props} {...field} checked={value} error={error?.message} />
)}
/>
);
}

View file

@ -105,7 +105,7 @@ const generateCurl = ({
return curl;
};
export const NetworkBody = ({
const NetworkBody = ({
body,
theme,
emptyMessage,

View file

@ -123,7 +123,7 @@ const TableSchemaPreview = ({
);
};
export interface SourceSchemaPreviewSource {
interface SourceSchemaPreviewSource {
connection: TSource['connection'];
from: TSource['from'];
metricTables?: TMetricSource['metricTables'];
@ -132,7 +132,7 @@ export interface SourceSchemaPreviewSource {
materializedViews?: TLogSource['materializedViews'];
}
export interface SourceSchemaPreviewProps {
interface SourceSchemaPreviewProps {
source?: SourceSchemaPreviewSource;
iconStyles?: Pick<TextProps, 'size' | 'color'>;
variant?: 'icon' | 'text';

View file

@ -1062,7 +1062,7 @@ function OrderByFormRow({
);
}
export function LogTableModelForm(props: TableModelProps) {
function LogTableModelForm(props: TableModelProps) {
const { control } = props;
const brandName = useBrandDisplayName();
const databaseName = useWatch({
@ -1323,7 +1323,7 @@ export function LogTableModelForm(props: TableModelProps) {
);
}
export function TraceTableModelForm(props: TableModelProps) {
function TraceTableModelForm(props: TableModelProps) {
const { control } = props;
const brandName = useBrandDisplayName();
const databaseName = useWatch({
@ -1616,7 +1616,7 @@ export function TraceTableModelForm(props: TableModelProps) {
);
}
export function SessionTableModelForm({ control }: TableModelProps) {
function SessionTableModelForm({ control }: TableModelProps) {
const brandName = useBrandDisplayName();
const databaseName = useWatch({
control,
@ -1672,7 +1672,7 @@ interface TableModelProps {
setValue: UseFormSetValue<TSource>;
}
export function MetricTableModelForm({ control, setValue }: TableModelProps) {
function MetricTableModelForm({ control, setValue }: TableModelProps) {
const brandName = useBrandDisplayName();
const databaseName = useWatch({
control,

View file

@ -6,7 +6,7 @@
// Recursively flattens nested objects/arrays into dot-notation keys.
// Empty objects produce an empty {} entry; empty arrays produce an empty [] entry.
// Based on https://stackoverflow.com/a/19101235
export function flattenData(data: Record<string, any>) {
function flattenData(data: Record<string, any>) {
const result: Record<string, any> = {};
function recurse(cur: Record<string, any>, prop: string) {
if (Object(cur) !== cur) {

View file

@ -8,11 +8,7 @@ export const HDX_LOCAL_DEFAULT_CONNECTIONS = env(
export const HDX_LOCAL_DEFAULT_SOURCES = env(
'NEXT_PUBLIC_HDX_LOCAL_DEFAULT_SOURCES',
);
export const HDX_DISABLE_METADATA_FIELD_FETCH = env(
'NEXT_PUBLIC_HDX_DISABLE_METADATA_FIELD_FETCH',
);
export const NODE_ENV = process.env.NODE_ENV as string;
const NODE_ENV = process.env.NODE_ENV as string;
export const HDX_API_KEY = process.env.HYPERDX_API_KEY as string; // for nextjs server
export const HDX_SERVICE_NAME =
process.env.NEXT_PUBLIC_OTEL_SERVICE_NAME ?? 'hdx-oss-dev-app';
@ -21,9 +17,7 @@ export const HDX_EXPORTER_ENABLED =
export const HDX_COLLECTOR_URL =
process.env.NEXT_PUBLIC_OTEL_EXPORTER_OTLP_ENDPOINT ??
'http://localhost:4318';
export const IS_CI = NODE_ENV === 'ci';
export const IS_DEV = NODE_ENV === 'development';
export const IS_PROD = NODE_ENV === 'production';
export const IS_OSS = process.env.NEXT_PUBLIC_IS_OSS ?? 'true' === 'true';
export const IS_LOCAL_MODE = //true;

View file

@ -1,9 +1,9 @@
export type FontConfig = {
type FontConfig = {
variable: string;
fallback: string;
};
export const FONT_CONFIG: Record<string, FontConfig> = {
const FONT_CONFIG: Record<string, FontConfig> = {
'IBM Plex Mono': {
variable: 'var(--font-ibm-plex-mono)',
fallback: 'monospace',
@ -22,7 +22,7 @@ export const FONT_CONFIG: Record<string, FontConfig> = {
},
};
export const DEFAULT_FONT_CONFIG = FONT_CONFIG.Inter;
const DEFAULT_FONT_CONFIG = FONT_CONFIG.Inter;
// Derived maps for convenience
export const FONT_VAR_MAP = Object.entries(FONT_CONFIG).reduce(
@ -42,7 +42,6 @@ export const MANTINE_FONT_MAP = Object.entries(FONT_CONFIG).reduce(
);
export const DEFAULT_FONT_VAR = DEFAULT_FONT_CONFIG.variable;
export const DEFAULT_MANTINE_FONT = `${DEFAULT_FONT_CONFIG.variable}, ${DEFAULT_FONT_CONFIG.fallback}`;
// UI options for font selection
export const OPTIONS_FONTS = [

View file

@ -7,12 +7,12 @@ export interface CsvColumn {
displayName: string;
}
export interface CsvExportOptions {
interface CsvExportOptions {
maxRows?: number;
groupColumnName?: string;
}
export interface CsvExportResult {
interface CsvExportResult {
csvData: Record<string, any>[];
maxRows: number;
isDataEmpty: boolean;

View file

@ -104,7 +104,7 @@ async function mineEventPatterns(logs: string[], pyodide: any) {
export const PATTERN_COLUMN_ALIAS = '__hdx_pattern_field';
export const TIMESTAMP_COLUMN_ALIAS = '__hdx_timestamp';
export const SEVERITY_TEXT_COLUMN_ALIAS = '__hdx_severity_text';
export const STATUS_CODE_COLUMN_ALIAS = '__hdx_status_code';
const STATUS_CODE_COLUMN_ALIAS = '__hdx_status_code';
export type SampleLog = {
[PATTERN_COLUMN_ALIAS]: string;

View file

@ -270,6 +270,3 @@ export function getTheme(name: ThemeName = DEFAULT_THEME): ThemeConfig {
// Re-export types
export type { ThemeConfig, ThemeName } from './types';
// Re-export for backwards compatibility
export { makeTheme, theme } from './themes/hyperdx/mantineTheme';

View file

@ -24,7 +24,7 @@ import componentClasses from '../components.module.scss';
* Primary color: Yellow/Gold accent
* Style: Modern, professional
*/
export const makeTheme = ({
const makeTheme = ({
fontFamily = '"Inter", sans-serif',
}: {
fontFamily?: string;

View file

@ -16,7 +16,7 @@ import focusClasses from '../../../../styles/focus.module.scss';
import variantClasses from '../../../../styles/variants.module.scss';
import componentClasses from '../components.module.scss';
export const makeTheme = ({
const makeTheme = ({
fontFamily = '"IBM Plex Sans", monospace',
}: {
fontFamily?: string;

View file

@ -63,7 +63,7 @@ export function parseTimeQuery(
return parseTimeRangeInput(timeQuery, isUTC);
}
export function parseValidTimeRange(
function parseValidTimeRange(
timeQuery: string,
isUTC: boolean,
): [Date, Date] | undefined {

View file

@ -3,7 +3,6 @@ import {
Alert,
AlertsPageItem as _AlertsPageItem,
BuilderChartConfig,
DashboardSchema,
Filter,
NumberFormat as _NumberFormat,
SavedSearchSchema,
@ -11,7 +10,7 @@ import {
export type NumberFormat = _NumberFormat;
export type KeyValuePairs = {
type KeyValuePairs = {
'bool.names': string[];
'bool.values': number[];
'number.names': string[];
@ -20,22 +19,6 @@ export type KeyValuePairs = {
'string.values': string[];
};
export type LogStreamModel = KeyValuePairs & {
_host?: string;
_namespace?: string;
_platform: string;
_service?: string;
_source: string; // raw log
body: string;
id: string;
observed_timestamp: number;
severity_number: number;
severity_text: string;
span_id?: string;
timestamp: string;
trace_id?: string;
};
export type AlertsPageItem = _AlertsPageItem;
export type AlertWithCreatedBy = Alert & {
@ -60,23 +43,6 @@ export type SearchConfig = {
orderBy?: string | null;
};
export type Session = {
errorCount: string;
maxTimestamp: string;
minTimestamp: string;
rrwebEventCount: string;
sessionCount: string;
sessionId: string;
teamId: string;
teamName: string;
userEmail: string;
userName: string;
};
export type Dictionary<T> = {
[key: string]: T;
};
export type StacktraceFrame = {
filename: string;
function: string;
@ -178,45 +144,6 @@ export type TableChartSeries = {
color?: string;
} & SeriesDBDataSource;
export type ChartSeries =
| TimeChartSeries
| TableChartSeries
| ({
table: SourceTable;
type: 'histogram';
field: string | undefined;
where: string;
} & SeriesDBDataSource)
| ({
type: 'search';
fields: string[];
where: string;
} & SeriesDBDataSource)
| ({
type: 'number';
table: SourceTable;
aggFn: AggFn;
field: string | undefined;
where: string;
numberFormat?: NumberFormat;
color?: string;
} & SeriesDBDataSource)
| {
type: 'markdown';
content: string;
};
export type Chart = {
id: string;
name: string;
x: number;
y: number;
w: number;
h: number;
series: ChartSeries[];
seriesReturnType: 'ratio' | 'column';
};
// https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/receiver/k8sclusterreceiver/documentation.md#k8spodphase
export enum KubePhase {
Pending = 1,

View file

@ -65,39 +65,3 @@ export const QueryParamProvider = ({
</QueryParamContext.Provider>
);
};
export function useQueryParam<T>(
key: string,
defaultValue: T,
options: {
queryParamConfig: {
encode: (
value: T | undefined,
) => string | (string | null)[] | null | undefined;
decode: (
input: string | (string | null)[] | null | undefined,
) => T | undefined;
};
} = {
queryParamConfig: {
encode: (value: T | undefined) => JSON.stringify(value),
decode: (input: string | (string | null)[] | null | undefined) =>
Array.isArray(input)
? input.map(i => (i != null ? JSON.parse(i) : undefined))
: input != null
? JSON.parse(input)
: undefined,
},
},
): [T, (value: T) => void] {
const qParamContext = useContext(QueryParamContext);
const setValue = (value: T) => {
qParamContext.setState({ [key]: options.queryParamConfig.encode(value) });
};
const value =
options.queryParamConfig.decode(qParamContext[key]) ?? defaultValue;
return [value, setValue];
}

View file

@ -194,7 +194,7 @@ const storageWithMigration = {
},
};
export const userPreferencesAtom = atomWithStorage<UserPreferences>(
const userPreferencesAtom = atomWithStorage<UserPreferences>(
STORAGE_KEY,
DEFAULT_PREFERENCES,
storageWithMigration,

View file

@ -27,43 +27,6 @@ export function omit<T extends object, K extends keyof T>(
} as Omit<T, K>;
}
export function generateSearchUrl({
query,
dateRange,
lineId,
isUTC,
savedSearchId,
}: {
savedSearchId?: string;
query?: string;
dateRange?: [Date, Date];
lineId?: string;
isUTC?: boolean;
}) {
const fromDate = dateRange ? dateRange[0] : new Date(NOW);
const toDate = dateRange ? dateRange[1] : new Date(NOW);
const qparams = new URLSearchParams({
q: query ?? '',
from: fromDate.getTime().toString(),
to: toDate.getTime().toString(),
tq: dateRangeToString([fromDate, toDate], isUTC ?? false),
...(lineId ? { lid: lineId } : {}),
});
return `/search${
savedSearchId != null ? `/${savedSearchId}` : ''
}?${qparams.toString()}`;
}
export function useFirstNonNullValue<T>(value: T): T {
const [firstNonNullValue, setFirstNonNullValue] = useState<T>(value);
useEffect(() => {
if (value != null) {
setFirstNonNullValue(v => (v == null ? value : v));
}
}, [value]);
return firstNonNullValue;
}
// From: https://usehooks.com/useWindowSize/
export function useWindowSize() {
// Initialize state with undefined width/height so server and client renders match
@ -103,15 +66,6 @@ export const isValidUrl = (input: string) => {
}
};
export const isValidJson = (input: string) => {
try {
JSON.parse(input);
return true;
} catch {
return false;
}
};
export const capitalizeFirstLetter = (input: string) => {
return input.charAt(0).toUpperCase() + input.slice(1);
};
@ -189,7 +143,7 @@ export const QUERY_LOCAL_STORAGE = {
LIMIT: 10, // cache up to 10
};
export function getLocalStorageValue<T>(key: string): T | null {
function getLocalStorageValue<T>(key: string): T | null {
if (typeof window === 'undefined') {
return null;
}
@ -414,7 +368,7 @@ export const getLogLevelClass = (lvl: string | undefined) => {
// Chart color palette - single source of truth
// Colors from Observable categorical palette, with custom brand green
// https://observablehq.com/@d3/color-schemes
export const CHART_PALETTE = {
const CHART_PALETTE = {
green: '#00c28a', // Brand green (Mantine green.5) - used as primary chart color
blue: '#4269d0',
orange: '#efb118',
@ -433,7 +387,7 @@ export const CHART_PALETTE = {
// ClickStack theme chart color palette - Observable 10 categorical palette
// https://observablehq.com/@d3/color-schemes
export const CLICKSTACK_CHART_PALETTE = {
const CLICKSTACK_CHART_PALETTE = {
blue: '#437EEF', // Primary color for ClickStack
orange: '#efb118',
red: '#ff725c',
@ -497,7 +451,7 @@ function detectActiveTheme(): 'clickstack' | 'hyperdx' {
* This is expected behavior - charts typically render after data fetching (client-side),
* so hydration mismatches are rare. If needed, wrap chart components with suppressHydrationWarning.
*/
export function getColorFromCSSVariable(index: number): string {
function getColorFromCSSVariable(index: number): string {
const colorArrayLength = COLORS.length;
if (typeof window === 'undefined') {
@ -685,21 +639,6 @@ export const truncateMiddle = (str: string, maxLen = 10) => {
)}`;
};
export const useIsBlog = () => {
const router = useRouter();
return router?.pathname.startsWith('/blog');
};
export const useIsDocs = () => {
const router = useRouter();
return router?.pathname.startsWith('/docs');
};
export const useIsTerms = () => {
const router = useRouter();
return router?.pathname.startsWith('/terms');
};
export const usePrevious = <T>(value: T): T | undefined => {
const ref = useRef<T | undefined>(undefined);
useEffect(() => {
@ -765,15 +704,6 @@ export const formatUptime = (seconds: number) => {
};
// FIXME: eventually we want to separate metric name into two fields
export const legacyMetricNameToNameAndDataType = (metricName?: string) => {
const [mName, mDataType] = (metricName ?? '').split(' - ');
return {
name: mName,
dataType: mDataType as MetricsDataType,
};
};
// Date formatting
export const mergePath = (path: string[], jsonColumns: string[] = []) => {
const [key, ...rest] = path;
@ -792,7 +722,7 @@ export const mergePath = (path: string[], jsonColumns: string[] = []) => {
: `${key}['${rest.join("']['")}']`;
};
export const _useTry = <T>(fn: () => T): [null | Error | unknown, null | T] => {
const _useTry = <T>(fn: () => T): [null | Error | unknown, null | T] => {
let output = null;
let error = null;
try {

View file

@ -1,4 +1,4 @@
export const DEFAULT_TIME_WINDOWS_SECONDS = [
const DEFAULT_TIME_WINDOWS_SECONDS = [
6 * 60 * 60, // 6h
6 * 60 * 60, // 6h
12 * 60 * 60, // 12h

View file

@ -7,14 +7,14 @@ import { IconBrandSlack, IconLink, IconMail } from '@tabler/icons-react';
import { IncidentIOIcon } from '@/SVGIcons';
export interface ServiceConfig {
interface ServiceConfig {
name: string;
icon: React.ReactElement;
order: number;
}
// Service type configuration with icons and display names
export const WEBHOOK_SERVICE_CONFIG: Record<WebhookService, ServiceConfig> = {
const WEBHOOK_SERVICE_CONFIG: Record<WebhookService, ServiceConfig> = {
[WebhookService.Slack]: {
name: 'Slack',
icon: <IconBrandSlack size={16} />,
@ -33,7 +33,7 @@ export const WEBHOOK_SERVICE_CONFIG: Record<WebhookService, ServiceConfig> = {
} as const;
// Channel icons for alert display (smaller sizes)
export const CHANNEL_ICONS: Record<WebhookService, React.ReactElement> = {
const CHANNEL_ICONS: Record<WebhookService, React.ReactElement> = {
[WebhookService.Generic]: <IconLink size={16} />,
[WebhookService.Slack]: <IconBrandSlack size={16} />,
[WebhookService.IncidentIO]: <IncidentIOIcon width={16} />,
@ -52,13 +52,6 @@ export const getWebhookServiceConfig = (
/**
* Get webhook service icon for display in lists/headers
*/
export const getWebhookServiceIcon = (
serviceType: string | undefined,
): React.ReactElement => {
const config = getWebhookServiceConfig(serviceType);
return config?.icon || WEBHOOK_SERVICE_CONFIG[WebhookService.Generic].icon;
};
/**
* Get webhook channel icon for alert tabs/smaller displays
*/

359
yarn.lock
View file

@ -3968,6 +3968,13 @@ __metadata:
languageName: node
linkType: hard
"@eslint/js@npm:^9.39.1":
version: 9.39.4
resolution: "@eslint/js@npm:9.39.4"
checksum: 10c0/5aa7dea2cbc5decf7f5e3b0c6f86a084ccee0f792d288ca8e839f8bc1b64e03e227068968e49b26096e6f71fd857ab6e42691d1b993826b9a3883f1bdd7a0e46
languageName: node
linkType: hard
"@eslint/object-schema@npm:^2.1.7":
version: 2.1.7
resolution: "@eslint/object-schema@npm:2.1.7"
@ -4200,8 +4207,11 @@ __metadata:
resolution: "@hyperdx/app@workspace:packages/app"
dependencies:
"@chromatic-com/storybook": "npm:^4.1.3"
"@codemirror/autocomplete": "npm:^6.0.0"
"@codemirror/lang-json": "npm:^6.0.1"
"@codemirror/lang-sql": "npm:^6.7.0"
"@codemirror/lint": "npm:^6.0.0"
"@codemirror/state": "npm:^6.0.0"
"@dagrejs/dagre": "npm:^1.1.5"
"@eslint/compat": "npm:^2.0.0"
"@hookform/resolvers": "npm:^3.9.0"
@ -4216,13 +4226,13 @@ __metadata:
"@mantine/hooks": "npm:^7.17.8"
"@mantine/notifications": "npm:^7.17.8"
"@mantine/spotlight": "npm:^7.17.8"
"@next/eslint-plugin-next": "npm:^16.0.10"
"@playwright/test": "npm:^1.57.0"
"@storybook/addon-docs": "npm:^10.1.4"
"@storybook/addon-links": "npm:^10.1.4"
"@storybook/addon-styling-webpack": "npm:^3.0.0"
"@storybook/addon-themes": "npm:^10.1.4"
"@storybook/nextjs": "npm:^10.1.4"
"@storybook/react": "npm:^10.1.4"
"@tabler/icons-react": "npm:^3.39.0"
"@tanstack/react-query": "npm:^5.56.2"
"@tanstack/react-query-devtools": "npm:^5.56.2"
@ -4256,6 +4266,7 @@ __metadata:
dayjs: "npm:^1.11.19"
eslint-config-next: "npm:^16.0.10"
eslint-plugin-playwright: "npm:^2.4.0"
eslint-plugin-react: "npm:^7.37.0"
eslint-plugin-react-hook-form: "npm:^0.3.1"
eslint-plugin-react-hooks: "npm:^7.0.1"
eslint-plugin-storybook: "npm:10.1.4"
@ -4284,6 +4295,7 @@ __metadata:
papaparse: "npm:^5.4.1"
postcss: "npm:^8.4.38"
postcss-preset-mantine: "npm:^1.15.0"
postcss-simple-vars: "npm:^7.0.0"
prettier: "npm:^3.3.2"
react: "npm:^19.2.3"
react-copy-to-clipboard: "npm:^5.1.0"
@ -4295,10 +4307,13 @@ __metadata:
react-hotkeys-hook: "npm:^4.3.7"
react-json-tree: "npm:^0.20.0"
react-markdown: "npm:^10.1.0"
react-resizable: "npm:^3.0.4"
recharts: "npm:^2.12.7"
rimraf: "npm:^4.4.1"
rrweb: "npm:2.0.0-alpha.8"
sass: "npm:^1.54.8"
serialize-query-params: "npm:^2.0.2"
serve: "npm:^14.0.0"
sqlstring: "npm:^2.3.3"
store2: "npm:^2.14.3"
storybook: "npm:^10.2.10"
@ -5844,12 +5859,12 @@ __metadata:
languageName: node
linkType: hard
"@next/eslint-plugin-next@npm:16.0.7":
version: 16.0.7
resolution: "@next/eslint-plugin-next@npm:16.0.7"
"@next/eslint-plugin-next@npm:^16.0.10":
version: 16.2.1
resolution: "@next/eslint-plugin-next@npm:16.2.1"
dependencies:
fast-glob: "npm:3.3.1"
checksum: 10c0/dce7be827de6686d11c68e1ae22f136e926bf63d9373a9f6c5fc8a2ce4a0ab92857c4becec9cd07c7293bb4ce6e0fa5c8407521e3632d61a42ad82769e190a8c
checksum: 10c0/cb6870ee6846d1a683393bdb303ce0bfcd0f60389ac976c019bca90818bc1adba55c3c2d2896541f7607f92dfa348111fd04440042036ae6ba888329ceb17abe
languageName: node
linkType: hard
@ -8894,7 +8909,7 @@ __metadata:
languageName: node
linkType: hard
"@storybook/react@npm:10.1.4, @storybook/react@npm:^10.1.4":
"@storybook/react@npm:10.1.4":
version: 10.1.4
resolution: "@storybook/react@npm:10.1.4"
dependencies:
@ -10775,6 +10790,13 @@ __metadata:
languageName: node
linkType: hard
"@zeit/schemas@npm:2.36.0":
version: 2.36.0
resolution: "@zeit/schemas@npm:2.36.0"
checksum: 10c0/858c3ae46d23122f65d576013dc74f120af0ca7f3256c4b7077bcd12e952c8f71d8241a5165c23d18f6378e198a1db7e93bc8fae8ed0769e4cf4e2df953ee955
languageName: node
linkType: hard
"@zkochan/js-yaml@npm:0.0.7":
version: 0.0.7
resolution: "@zkochan/js-yaml@npm:0.0.7"
@ -10994,6 +11016,18 @@ __metadata:
languageName: node
linkType: hard
"ajv@npm:8.18.0, ajv@npm:^8.17.1":
version: 8.18.0
resolution: "ajv@npm:8.18.0"
dependencies:
fast-deep-equal: "npm:^3.1.3"
fast-uri: "npm:^3.0.1"
json-schema-traverse: "npm:^1.0.0"
require-from-string: "npm:^2.0.2"
checksum: 10c0/e7517c426173513a07391be951879932bdf3348feaebd2199f5b901c20f99d60db8cd1591502d4d551dc82f594e82a05c4fe1c70139b15b8937f7afeaed9532f
languageName: node
linkType: hard
"ajv@npm:^6.12.4, ajv@npm:^6.12.5":
version: 6.12.6
resolution: "ajv@npm:6.12.6"
@ -11030,15 +11064,12 @@ __metadata:
languageName: node
linkType: hard
"ajv@npm:^8.17.1":
version: 8.18.0
resolution: "ajv@npm:8.18.0"
"ansi-align@npm:^3.0.1":
version: 3.0.1
resolution: "ansi-align@npm:3.0.1"
dependencies:
fast-deep-equal: "npm:^3.1.3"
fast-uri: "npm:^3.0.1"
json-schema-traverse: "npm:^1.0.0"
require-from-string: "npm:^2.0.2"
checksum: 10c0/e7517c426173513a07391be951879932bdf3348feaebd2199f5b901c20f99d60db8cd1591502d4d551dc82f594e82a05c4fe1c70139b15b8937f7afeaed9532f
string-width: "npm:^4.1.0"
checksum: 10c0/ad8b755a253a1bc8234eb341e0cec68a857ab18bf97ba2bda529e86f6e30460416523e0ec58c32e5c21f0ca470d779503244892873a5895dbd0c39c788e82467
languageName: node
linkType: hard
@ -11130,6 +11161,20 @@ __metadata:
languageName: node
linkType: hard
"arch@npm:^2.2.0":
version: 2.2.0
resolution: "arch@npm:2.2.0"
checksum: 10c0/4ceaf8d8207817c216ebc4469742052cb0a097bc45d9b7fcd60b7507220da545a28562ab5bdd4dfe87921bb56371a0805da4e10d704e01f93a15f83240f1284c
languageName: node
linkType: hard
"arg@npm:5.0.2":
version: 5.0.2
resolution: "arg@npm:5.0.2"
checksum: 10c0/ccaf86f4e05d342af6666c569f844bec426595c567d32a8289715087825c2ca7edd8a3d204e4d2fb2aa4602e09a57d0c13ea8c9eea75aac3dbb4af5514e6800e
languageName: node
linkType: hard
"arg@npm:^4.1.0":
version: 4.1.3
resolution: "arg@npm:4.1.3"
@ -11838,6 +11883,22 @@ __metadata:
languageName: node
linkType: hard
"boxen@npm:7.0.0":
version: 7.0.0
resolution: "boxen@npm:7.0.0"
dependencies:
ansi-align: "npm:^3.0.1"
camelcase: "npm:^7.0.0"
chalk: "npm:^5.0.1"
cli-boxes: "npm:^3.0.0"
string-width: "npm:^5.1.2"
type-fest: "npm:^2.13.0"
widest-line: "npm:^4.0.1"
wrap-ansi: "npm:^8.0.1"
checksum: 10c0/af5e8bc3f1486ac50ec7485ae482eb1d4db905233d7ab2acafc406b576375be85bdc60b53fab99c842c42c274328b7219c7ae79adab13161f4c84e139f4b06ae
languageName: node
linkType: hard
"brace-expansion@npm:^2.0.2":
version: 2.0.2
resolution: "brace-expansion@npm:2.0.2"
@ -12108,7 +12169,7 @@ __metadata:
languageName: node
linkType: hard
"bytes@npm:~3.1.2":
"bytes@npm:3.1.2, bytes@npm:~3.1.2":
version: 3.1.2
resolution: "bytes@npm:3.1.2"
checksum: 10c0/76d1c43cbd602794ad8ad2ae94095cddeb1de78c5dddaa7005c51af10b0176c69971a6d88e805a90c2b6550d76636e43c40d8427a808b8645ede885de4a0358e
@ -12256,6 +12317,13 @@ __metadata:
languageName: node
linkType: hard
"camelcase@npm:^7.0.0":
version: 7.0.1
resolution: "camelcase@npm:7.0.1"
checksum: 10c0/3adfc9a0e96d51b3a2f4efe90a84dad3e206aaa81dfc664f1bd568270e1bf3b010aad31f01db16345b4ffe1910e16ab411c7273a19a859addd1b98ef7cf4cfbd
languageName: node
linkType: hard
"caniuse-lite@npm:^1.0.30001579, caniuse-lite@npm:^1.0.30001754":
version: 1.0.30001756
resolution: "caniuse-lite@npm:1.0.30001756"
@ -12297,6 +12365,15 @@ __metadata:
languageName: node
linkType: hard
"chalk-template@npm:0.4.0":
version: 0.4.0
resolution: "chalk-template@npm:0.4.0"
dependencies:
chalk: "npm:^4.1.2"
checksum: 10c0/6a4cb4252966475f0bd3ee1cd8780146e1ba69f445e59c565cab891ac18708c8143515d23e2b0fb7e192574fb7608d429ea5b28f3b7b9507770ad6fccd3467e3
languageName: node
linkType: hard
"chalk@npm:4.1.2, chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2":
version: 4.1.2
resolution: "chalk@npm:4.1.2"
@ -12307,6 +12384,13 @@ __metadata:
languageName: node
linkType: hard
"chalk@npm:5.0.1":
version: 5.0.1
resolution: "chalk@npm:5.0.1"
checksum: 10c0/97898611ae40cfdeda9778901731df1404ea49fac0eb8253804e8d21b8064917df9823e29c0c9d766aab623da1a0b43d0e072d19a73d4f62d0d9115aef4c64e6
languageName: node
linkType: hard
"chalk@npm:^2.0.0, chalk@npm:^2.1.0, chalk@npm:^2.4.2":
version: 2.4.2
resolution: "chalk@npm:2.4.2"
@ -12318,6 +12402,13 @@ __metadata:
languageName: node
linkType: hard
"chalk@npm:^5.0.1":
version: 5.6.2
resolution: "chalk@npm:5.6.2"
checksum: 10c0/99a4b0f0e7991796b1e7e3f52dceb9137cae2a9dfc8fc0784a550dc4c558e15ab32ed70b14b21b52beb2679b4892b41a0aa44249bcb996f01e125d58477c6976
languageName: node
linkType: hard
"char-regex@npm:^1.0.2":
version: 1.0.2
resolution: "char-regex@npm:1.0.2"
@ -12510,6 +12601,13 @@ __metadata:
languageName: node
linkType: hard
"cli-boxes@npm:^3.0.0":
version: 3.0.0
resolution: "cli-boxes@npm:3.0.0"
checksum: 10c0/4db3e8fbfaf1aac4fb3a6cbe5a2d3fa048bee741a45371b906439b9ffc821c6e626b0f108bdcd3ddf126a4a319409aedcf39a0730573ff050fdd7b6731e99fb9
languageName: node
linkType: hard
"cli-cursor@npm:3.1.0, cli-cursor@npm:^3.1.0":
version: 3.1.0
resolution: "cli-cursor@npm:3.1.0"
@ -12580,6 +12678,17 @@ __metadata:
languageName: node
linkType: hard
"clipboardy@npm:3.0.0":
version: 3.0.0
resolution: "clipboardy@npm:3.0.0"
dependencies:
arch: "npm:^2.2.0"
execa: "npm:^5.1.1"
is-wsl: "npm:^2.2.0"
checksum: 10c0/299d66e13fcaccf656306e76d629ce6927eaba8ba58ae5328e3379ae627e469e29df8ef87408cdb234e2ad0e25f0024dd203393f7e59c67ae79772579c4de052
languageName: node
linkType: hard
"cliui@npm:7.0.4":
version: 7.0.4
resolution: "cliui@npm:7.0.4"
@ -12815,7 +12924,7 @@ __metadata:
languageName: node
linkType: hard
"compressible@npm:~2.0.16":
"compressible@npm:~2.0.16, compressible@npm:~2.0.18":
version: 2.0.18
resolution: "compressible@npm:2.0.18"
dependencies:
@ -12824,6 +12933,21 @@ __metadata:
languageName: node
linkType: hard
"compression@npm:1.8.1":
version: 1.8.1
resolution: "compression@npm:1.8.1"
dependencies:
bytes: "npm:3.1.2"
compressible: "npm:~2.0.18"
debug: "npm:2.6.9"
negotiator: "npm:~0.6.4"
on-headers: "npm:~1.1.0"
safe-buffer: "npm:5.2.1"
vary: "npm:~1.1.2"
checksum: 10c0/85114b0b91c16594dc8c671cd9b05ef5e465066a60e5a4ed8b4551661303559a896ed17bb72c4234c04064e078f6ca86a34b8690349499a43f6fc4b844475da4
languageName: node
linkType: hard
"compression@npm:^1.7.4":
version: 1.7.4
resolution: "compression@npm:1.7.4"
@ -12890,6 +13014,13 @@ __metadata:
languageName: node
linkType: hard
"content-disposition@npm:0.5.2":
version: 0.5.2
resolution: "content-disposition@npm:0.5.2"
checksum: 10c0/49eebaa0da1f9609b192e99d7fec31d1178cb57baa9d01f5b63b29787ac31e9d18b5a1033e854c68c9b6cce790e700a6f7fa60e43f95e2e416404e114a8f2f49
languageName: node
linkType: hard
"content-disposition@npm:~0.5.4":
version: 0.5.4
resolution: "content-disposition@npm:0.5.4"
@ -13671,6 +13802,13 @@ __metadata:
languageName: node
linkType: hard
"deep-extend@npm:^0.6.0":
version: 0.6.0
resolution: "deep-extend@npm:0.6.0"
checksum: 10c0/1c6b0abcdb901e13a44c7d699116d3d4279fdb261983122a3783e7273844d5f2537dc2e1c454a23fcf645917f93fbf8d07101c1d03c015a87faa662755212566
languageName: node
linkType: hard
"deep-is@npm:^0.1.3":
version: 0.1.4
resolution: "deep-is@npm:0.1.4"
@ -14772,29 +14910,6 @@ __metadata:
languageName: node
linkType: hard
"eslint-config-next@npm:16.0.7":
version: 16.0.7
resolution: "eslint-config-next@npm:16.0.7"
dependencies:
"@next/eslint-plugin-next": "npm:16.0.7"
eslint-import-resolver-node: "npm:^0.3.6"
eslint-import-resolver-typescript: "npm:^3.5.2"
eslint-plugin-import: "npm:^2.32.0"
eslint-plugin-jsx-a11y: "npm:^6.10.0"
eslint-plugin-react: "npm:^7.37.0"
eslint-plugin-react-hooks: "npm:^7.0.0"
globals: "npm:16.4.0"
typescript-eslint: "npm:^8.46.0"
peerDependencies:
eslint: ">=9.0.0"
typescript: ">=3.3.1"
peerDependenciesMeta:
typescript:
optional: true
checksum: 10c0/ca3e974c6c1c0821d6ff9ec8590ff334417b2cb615b92b119dd7bd05303c9c987256668e90209d2a74c6b088df9fbcbdbe44e79cb24c52b2b00f3ef9d0f0a061
languageName: node
linkType: hard
"eslint-config-next@npm:^16.0.10":
version: 16.0.10
resolution: "eslint-config-next@npm:16.0.10"
@ -17054,6 +17169,7 @@ __metadata:
dependencies:
"@changesets/cli": "npm:^2.26.2"
"@dotenvx/dotenvx": "npm:^1.51.1"
"@eslint/js": "npm:^9.39.1"
"@types/ungap__structured-clone": "npm:^1.2.0"
"@ungap/structured-clone": "npm:^1.3.0"
babel-plugin-react-compiler: "npm:^1.0.0"
@ -17062,11 +17178,9 @@ __metadata:
dotenv-cli: "npm:^8.0.0"
dotenv-expand: "npm:^12.0.1"
eslint: "npm:^9.39.1"
eslint-config-next: "npm:16.0.7"
eslint-config-prettier: "npm:^9.1.0"
eslint-plugin-n: "npm:^16.4.0"
eslint-plugin-prettier: "npm:^5.2.1"
eslint-plugin-react-hooks: "npm:^7.0.1"
eslint-plugin-security: "npm:^3.0.1"
eslint-plugin-simple-import-sort: "npm:^12.1.1"
husky: "npm:^8.0.3"
@ -17074,6 +17188,8 @@ __metadata:
lint-staged: "npm:^13.1.2"
nx: "npm:21.3.11"
prettier: "npm:3.3.3"
tslib: "npm:^2.6.0"
typescript-eslint: "npm:^8.46.0"
languageName: unknown
linkType: soft
@ -17255,7 +17371,7 @@ __metadata:
languageName: node
linkType: hard
"ini@npm:^1.3.5":
"ini@npm:^1.3.5, ini@npm:~1.3.0":
version: 1.3.8
resolution: "ini@npm:1.3.8"
checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a
@ -17715,6 +17831,13 @@ __metadata:
languageName: node
linkType: hard
"is-port-reachable@npm:4.0.0":
version: 4.0.0
resolution: "is-port-reachable@npm:4.0.0"
checksum: 10c0/f0fddd9b5c082f7c32356faab38c3c6eab5ea5b54491184f5688f3189d482017d2142c648927ee5964299e4a62da83d41ee52a1d73bf1f700325c370c9ed0cef
languageName: node
linkType: hard
"is-potential-custom-element-name@npm:^1.0.1":
version: 1.0.1
resolution: "is-potential-custom-element-name@npm:1.0.1"
@ -20563,6 +20686,22 @@ __metadata:
languageName: node
linkType: hard
"mime-db@npm:~1.33.0":
version: 1.33.0
resolution: "mime-db@npm:1.33.0"
checksum: 10c0/79172ce5468c8503b49dddfdddc18d3f5fe2599f9b5fe1bc321a8cbee14c96730fc6db22f907b23701b05b2936f865795f62ec3a78a7f3c8cb2450bb68c6763e
languageName: node
linkType: hard
"mime-types@npm:2.1.18":
version: 2.1.18
resolution: "mime-types@npm:2.1.18"
dependencies:
mime-db: "npm:~1.33.0"
checksum: 10c0/a96a8d12f4bb98bc7bfac6a8ccbd045f40368fc1030d9366050c3613825d3715d1c1f393e10a75a885d2cdc1a26cd6d5e11f3a2a0d5c4d361f00242139430a0f
languageName: node
linkType: hard
"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34":
version: 2.1.35
resolution: "mime-types@npm:2.1.35"
@ -20634,6 +20773,15 @@ __metadata:
languageName: node
linkType: hard
"minimatch@npm:3.1.5":
version: 3.1.5
resolution: "minimatch@npm:3.1.5"
dependencies:
brace-expansion: "npm:^1.1.7"
checksum: 10c0/2ecbdc0d33f07bddb0315a8b5afbcb761307a8778b48f0b312418ccbced99f104a2d17d8aca7573433c70e8ccd1c56823a441897a45e384ea76ef401a26ace70
languageName: node
linkType: hard
"minimatch@npm:9.0.3":
version: 9.0.3
resolution: "minimatch@npm:9.0.3"
@ -21057,6 +21205,13 @@ __metadata:
languageName: node
linkType: hard
"negotiator@npm:~0.6.4":
version: 0.6.4
resolution: "negotiator@npm:0.6.4"
checksum: 10c0/3e677139c7fb7628a6f36335bf11a885a62c21d5390204590a1a214a5631fcbe5ea74ef6a610b60afe84b4d975cbe0566a23f20ee17c77c73e74b80032108dea
languageName: node
linkType: hard
"neo-async@npm:^2.6.2":
version: 2.6.2
resolution: "neo-async@npm:2.6.2"
@ -22195,6 +22350,13 @@ __metadata:
languageName: node
linkType: hard
"path-is-inside@npm:1.0.2":
version: 1.0.2
resolution: "path-is-inside@npm:1.0.2"
checksum: 10c0/7fdd4b41672c70461cce734fc222b33e7b447fa489c7c4377c95e7e6852d83d69741f307d88ec0cc3b385b41cb4accc6efac3c7c511cd18512e95424f5fa980c
languageName: node
linkType: hard
"path-key@npm:^3.0.0, path-key@npm:^3.1.0":
version: 3.1.1
resolution: "path-key@npm:3.1.1"
@ -22226,6 +22388,13 @@ __metadata:
languageName: node
linkType: hard
"path-to-regexp@npm:3.3.0":
version: 3.3.0
resolution: "path-to-regexp@npm:3.3.0"
checksum: 10c0/ffa0ebe7088d38d435a8d08b0fe6e8c93ceb2a81a65d4dd1d9a538f52e09d5e3474ed5f553cb3b180d894b0caa10698a68737ab599fd1e56b4663d1a64c9f77b
languageName: node
linkType: hard
"path-to-regexp@npm:^6.2.0":
version: 6.2.2
resolution: "path-to-regexp@npm:6.2.2"
@ -23230,6 +23399,13 @@ __metadata:
languageName: node
linkType: hard
"range-parser@npm:1.2.0":
version: 1.2.0
resolution: "range-parser@npm:1.2.0"
checksum: 10c0/c7aef4f6588eb974c475649c157f197d07437d8c6c8ff7e36280a141463fb5ab7a45918417334ebd7b665c6b8321cf31c763f7631dd5f5db9372249261b8b02a
languageName: node
linkType: hard
"range-parser@npm:^1.2.1, range-parser@npm:~1.2.1":
version: 1.2.1
resolution: "range-parser@npm:1.2.1"
@ -23249,6 +23425,20 @@ __metadata:
languageName: node
linkType: hard
"rc@npm:^1.0.1, rc@npm:^1.1.6":
version: 1.2.8
resolution: "rc@npm:1.2.8"
dependencies:
deep-extend: "npm:^0.6.0"
ini: "npm:~1.3.0"
minimist: "npm:^1.2.0"
strip-json-comments: "npm:~2.0.1"
bin:
rc: ./cli.js
checksum: 10c0/24a07653150f0d9ac7168e52943cc3cb4b7a22c0e43c7dff3219977c2fdca5a2760a304a029c20811a0e79d351f57d46c9bde216193a0f73978496afc2b85b15
languageName: node
linkType: hard
"react-base16-styling@npm:^0.10.0":
version: 0.10.0
resolution: "react-base16-styling@npm:0.10.0"
@ -23883,6 +24073,25 @@ __metadata:
languageName: node
linkType: hard
"registry-auth-token@npm:3.3.2":
version: 3.3.2
resolution: "registry-auth-token@npm:3.3.2"
dependencies:
rc: "npm:^1.1.6"
safe-buffer: "npm:^5.0.1"
checksum: 10c0/934b5d504ec6d94d78672dc5e74646c52793e74a6e400c1cffc78838bbb12c5f45e3ef3edba506f3295db794d4dda76f924f2948d48fe1f8e83b6500b0ba53c5
languageName: node
linkType: hard
"registry-url@npm:3.1.0":
version: 3.1.0
resolution: "registry-url@npm:3.1.0"
dependencies:
rc: "npm:^1.0.1"
checksum: 10c0/345cf9638f99d95863d92800b3f595ac312c19d6865595e499fbeb33fcda04021a0dbdafbb5e61a838a89a558bc239d78752a1f90eb68cf53fdf0d91da816a7c
languageName: node
linkType: hard
"regjsparser@npm:^0.9.1":
version: 0.9.1
resolution: "regjsparser@npm:0.9.1"
@ -24716,6 +24925,21 @@ __metadata:
languageName: node
linkType: hard
"serve-handler@npm:6.1.7":
version: 6.1.7
resolution: "serve-handler@npm:6.1.7"
dependencies:
bytes: "npm:3.0.0"
content-disposition: "npm:0.5.2"
mime-types: "npm:2.1.18"
minimatch: "npm:3.1.5"
path-is-inside: "npm:1.0.2"
path-to-regexp: "npm:3.3.0"
range-parser: "npm:1.2.0"
checksum: 10c0/35afb68d81afd3c38d15792a5bc2451915b739bef2898a47ebd190db6a4e29846530ac00292b8008fe7297a819257c3948be2deaf4ffd32c96689e8947cf0ae9
languageName: node
linkType: hard
"serve-static@npm:^1.16.0":
version: 1.16.3
resolution: "serve-static@npm:1.16.3"
@ -24728,6 +24952,27 @@ __metadata:
languageName: node
linkType: hard
"serve@npm:^14.0.0":
version: 14.2.6
resolution: "serve@npm:14.2.6"
dependencies:
"@zeit/schemas": "npm:2.36.0"
ajv: "npm:8.18.0"
arg: "npm:5.0.2"
boxen: "npm:7.0.0"
chalk: "npm:5.0.1"
chalk-template: "npm:0.4.0"
clipboardy: "npm:3.0.0"
compression: "npm:1.8.1"
is-port-reachable: "npm:4.0.0"
serve-handler: "npm:6.1.7"
update-check: "npm:1.5.4"
bin:
serve: build/main.js
checksum: 10c0/7e1668e0d187719dbe4f3de967012ce2263c967f6135d9c630f803b0f173334e1442ab326fcc4c8e6cd4e293d8bd8c773aebab2746ecaa0fb1ab29a36079763b
languageName: node
linkType: hard
"set-blocking@npm:^2.0.0":
version: 2.0.0
resolution: "set-blocking@npm:2.0.0"
@ -25702,6 +25947,13 @@ __metadata:
languageName: node
linkType: hard
"strip-json-comments@npm:~2.0.1":
version: 2.0.1
resolution: "strip-json-comments@npm:2.0.1"
checksum: 10c0/b509231cbdee45064ff4f9fd73609e2bcc4e84a4d508e9dd0f31f70356473fde18abfb5838c17d56fb236f5a06b102ef115438de0600b749e818a35fbbc48c43
languageName: node
linkType: hard
"strnum@npm:^1.0.5":
version: 1.1.2
resolution: "strnum@npm:1.1.2"
@ -26866,7 +27118,7 @@ __metadata:
languageName: node
linkType: hard
"type-fest@npm:^2.14.0":
"type-fest@npm:^2.13.0, type-fest@npm:^2.14.0":
version: 2.19.0
resolution: "type-fest@npm:2.19.0"
checksum: 10c0/a5a7ecf2e654251613218c215c7493574594951c08e52ab9881c9df6a6da0aeca7528c213c622bc374b4e0cb5c443aa3ab758da4e3c959783ce884c3194e12cb
@ -27313,6 +27565,16 @@ __metadata:
languageName: node
linkType: hard
"update-check@npm:1.5.4":
version: 1.5.4
resolution: "update-check@npm:1.5.4"
dependencies:
registry-auth-token: "npm:3.3.2"
registry-url: "npm:3.1.0"
checksum: 10c0/ac4b8dafa5db9b1c8ff5d0cfcc3b4c5687c390526b3218155e27173c7ca647572ea9e523dd3463523e698ef94d273768b395748da54655fe773dada59ac9c7b0
languageName: node
linkType: hard
"uplot-react@npm:^1.2.2":
version: 1.2.2
resolution: "uplot-react@npm:1.2.2"
@ -27978,6 +28240,15 @@ __metadata:
languageName: node
linkType: hard
"widest-line@npm:^4.0.1":
version: 4.0.1
resolution: "widest-line@npm:4.0.1"
dependencies:
string-width: "npm:^5.0.1"
checksum: 10c0/7da9525ba45eaf3e4ed1a20f3dcb9b85bd9443962450694dae950f4bdd752839747bbc14713522b0b93080007de8e8af677a61a8c2114aa553ad52bde72d0f9c
languageName: node
linkType: hard
"winston-transport@npm:^4.7.0":
version: 4.7.0
resolution: "winston-transport@npm:4.7.0"
@ -28018,7 +28289,7 @@ __metadata:
languageName: node
linkType: hard
"wrap-ansi@npm:^8.1.0":
"wrap-ansi@npm:^8.0.1, wrap-ansi@npm:^8.1.0":
version: 8.1.0
resolution: "wrap-ansi@npm:8.1.0"
dependencies: