@sailfish-ai/sf-veritas 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,71 @@
1
+ /**
2
+ * BaseTransmitter is the base class responsible for transmitting GraphQL requests.
3
+ * It is used to send requests to a GraphQL endpoint, including default parameters
4
+ * like API key, service UUID, and session ID. It provides functionality for
5
+ * setting the operation name, endpoint, and additional variables.
6
+ */
7
+ export declare class BaseTransmitter {
8
+ /** The API key used for authentication. */
9
+ protected apiKey: string;
10
+ /** The GraphQL endpoint to which requests are sent. */
11
+ protected endpoint: string;
12
+ /** The type of GraphQL query (default is 'mutation'). */
13
+ protected queryType: string;
14
+ /** The operation name for the GraphQL query. */
15
+ protected operationName: string;
16
+ /** The UUID of the service from the configuration. */
17
+ protected serviceUUID: string;
18
+ private contextManager;
19
+ /**
20
+ * Constructor to initialize the `BaseTransmitter` with the provided API key.
21
+ * If no API key is provided, the one from the configuration will be used.
22
+ *
23
+ * @param apiKey - The API key to authenticate with (optional, defaults to config value).
24
+ */
25
+ constructor();
26
+ /**
27
+ * Getter for the query name used in GraphQL requests.
28
+ * The operation name is converted to camel case (first letter lowercased).
29
+ *
30
+ * @returns The formatted query name based on the operation name.
31
+ */
32
+ protected get queryName(): string;
33
+ /**
34
+ * Generates default variables to be included in GraphQL queries.
35
+ * These variables include the API key, service UUID, session ID, and timestamp.
36
+ *
37
+ * @returns An object containing the default variables for the request.
38
+ */
39
+ protected getDefaultVariables(): {
40
+ apiKey: string;
41
+ serviceUuid: string;
42
+ sessionId: string;
43
+ timestampMs: string;
44
+ };
45
+ /**
46
+ * Merges the default variables with any additional variables passed as arguments.
47
+ * Optionally, a session ID can be provided to override the default one.
48
+ *
49
+ * @param additionalVariables - Additional variables to include in the request.
50
+ * @returns A merged object containing all variables for the GraphQL query.
51
+ */
52
+ protected getVariables(additionalVariables?: Record<string, any>): Record<string, any>;
53
+ /**
54
+ * Sets the operation name for the GraphQL query.
55
+ *
56
+ * @param name - The name of the operation to set.
57
+ */
58
+ setOperationName(name: string): void;
59
+ /**
60
+ * Sets the GraphQL endpoint to use for the requests.
61
+ *
62
+ * @param endpoint - The endpoint URL to set.
63
+ */
64
+ setEndpoint(endpoint: string): void;
65
+ /**
66
+ * Sets the service UUID to be used in the GraphQL request.
67
+ *
68
+ * @param serviceUUID - The service UUID to set.
69
+ */
70
+ setServiceUUID(serviceUUID: string): void;
71
+ }
@@ -0,0 +1,35 @@
1
+ import { Traits } from "./utils";
2
+ /**
3
+ * Main transmitter class for managing metadata collection and user identification.
4
+ * This class coordinates the metadata transmission and handles user identification.
5
+ */
6
+ export declare class SailfishTransmitter {
7
+ private apiKey;
8
+ private metadataTransmitter;
9
+ /**
10
+ * Creates an instance of SailfishTransmitter.
11
+ *
12
+ * @param apiKey - The API key to authenticate requests.
13
+ */
14
+ constructor(apiKey: string);
15
+ /**
16
+ * Identifies a user and either adds or updates metadata for them.
17
+ * If neither traits nor traitsJson is provided, empty metadata is sent.
18
+ *
19
+ * @param userId - Unique identifier for the user, typically a username or email.
20
+ * @param traits - Optional dictionary of traits to add or update.
21
+ * @param traitsJson - Optional JSON string of traits to add or update.
22
+ * @param override - Optional flag to override existing traits.
23
+ */
24
+ identify(userId: string, traits?: Traits, traitsJson?: string, override?: boolean): void;
25
+ /**
26
+ * Adds or updates metadata for a user.
27
+ * Sends the provided traits or traitsJson to update user information.
28
+ *
29
+ * @param userId - Unique identifier for the user, typically a username or email.
30
+ * @param traits - Optional dictionary of traits to add or update.
31
+ * @param traitsJson - Optional JSON string of traits to add or update.
32
+ * @param override - Optional flag to override existing traits.
33
+ */
34
+ addOrUpdateMetadata(userId: string, traits?: Traits, traitsJson?: string, override?: boolean): void;
35
+ }
@@ -0,0 +1,28 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ export declare const context: AsyncLocalStorage<Map<string, any>>;
3
+ type Context = {
4
+ traceId?: string;
5
+ handledExceptions: Set<any>;
6
+ reentrancyGuardLoggingActive: boolean;
7
+ reentrancyGuardLoggingPreActive: boolean;
8
+ reentrancyGuardPrintActive: boolean;
9
+ reentrancyGuardPrintPreActive: boolean;
10
+ reentrancyGuardExceptionActive: boolean;
11
+ reentrancyGuardExceptionPreActive: boolean;
12
+ };
13
+ export declare class ContextManager {
14
+ private static instance;
15
+ private constructor();
16
+ static getInstance(): ContextManager;
17
+ getCurrentContext(): Context;
18
+ private setCurrentContext;
19
+ getTraceId(): string | undefined;
20
+ setTraceId(traceId: string): void;
21
+ getOrSetSfTraceId(newTraceIdIfNotSet?: string, isAssociatedWithInboundRequest?: boolean): string;
22
+ getHandledExceptions(): Set<any>;
23
+ markExceptionHandled(exception: any): void;
24
+ hasHandledException(exception: any): boolean;
25
+ resetHandledExceptions(): void;
26
+ }
27
+ export declare function runWithContext(fn: Function): void;
28
+ export {};
@@ -0,0 +1,39 @@
1
+ import { BaseTransmitter } from "./baseTransmitter";
2
+ /**
3
+ * DataTransmitter class extends BaseTransmitter to handle sending data,
4
+ * including sending app identifiers and specific contents to a designated endpoint.
5
+ */
6
+ export declare class DataTransmitter extends BaseTransmitter {
7
+ private serviceIdentifier;
8
+ /**
9
+ * Constructor for DataTransmitter.
10
+ */
11
+ constructor();
12
+ /**
13
+ * Checks if the contents should be ignored. Override this function to define specific logic for ignoring content.
14
+ * @param contents - The contents to check.
15
+ * @returns boolean - Whether the contents should be ignored.
16
+ */
17
+ protected checkIfContentsShouldBeIgnored(contents: any): boolean;
18
+ /**
19
+ * Sends the application identifier by invoking the serviceIdentifier.
20
+ * This function ensures the app identifier is sent before any other data.
21
+ */
22
+ sendAppIdentifier(): Promise<void>;
23
+ /**
24
+ * Main method to send data.
25
+ * This first sends the application identifier and then sends the actual content.
26
+ * @param args - The arguments to be sent, including contents and level.
27
+ */
28
+ doSend(args: any): Promise<void>;
29
+ /**
30
+ * Sends the contents to the server endpoint. It checks the contents type and prepares the request.
31
+ * @param contents - The content to be sent, which can be a string or an array of strings.
32
+ */
33
+ send(contents: string | string[]): Promise<void>;
34
+ /**
35
+ * Constructs the GraphQL query string based on operation details.
36
+ * @returns string - The formatted query string with required parameters.
37
+ */
38
+ private getQuery;
39
+ }
@@ -0,0 +1,22 @@
1
+ import { DataTransmitter } from "./dataTransmitter";
2
+ /**
3
+ * DomainsToNotPassHeaderToTransmitter class extends DataTransmitter to handle sending domains data
4
+ * that should not pass the header to the server endpoint.
5
+ */
6
+ export declare class DomainsToNotPassHeaderToTransmitter extends DataTransmitter {
7
+ /**
8
+ * Constructor for DomainsToNotPassHeaderToTransmitter.
9
+ * Sets the operation name to 'DomainsToNotPassHeaderTo' upon instantiation.
10
+ */
11
+ constructor();
12
+ /**
13
+ * Main method to send data. This method sends the app identifier and then calls the send method to send the domains.
14
+ * @param args - Arguments passed for sending, typically includes domains.
15
+ */
16
+ doSend(args: any): Promise<void>;
17
+ /**
18
+ * Sends a list of domains that should not pass the header to the server.
19
+ * @param domains - An array of domain strings that need to be sent to the server.
20
+ */
21
+ send(domains: string[]): Promise<void>;
22
+ }
@@ -0,0 +1,2 @@
1
+ import { ExceptionTransmitter } from "./exceptionTransmitter";
2
+ export declare function initializeExceptionInterceptor(transmitter: ExceptionTransmitter): void;
@@ -0,0 +1,44 @@
1
+ import { BaseTransmitter } from "./baseTransmitter";
2
+ import { FrameInfo } from "./types";
3
+ /**
4
+ * The ExceptionTransmitter class handles the process of sending exception data
5
+ * (message and stack trace) to a designated endpoint, specifically for collecting
6
+ * exceptions. It inherits from the BaseTransmitter class and is responsible for
7
+ * encoding the exception trace, constructing the request, and sending it to the
8
+ * server.
9
+ */
10
+ export declare class ExceptionTransmitter extends BaseTransmitter {
11
+ private serviceIdentifier;
12
+ /**
13
+ * Constructor for ExceptionTransmitter. It initializes the operation name
14
+ * and inherits from BaseTransmitter.
15
+ */
16
+ constructor();
17
+ /**
18
+ * Sends the application identifier to the server to associate the exception
19
+ * data with the application.
20
+ */
21
+ sendAppIdentifier(): Promise<void>;
22
+ /**
23
+ * Primary method to send exception data. It triggers the process of sending
24
+ * the application identifier and exception details (message and stack trace).
25
+ *
26
+ * @param contents The exception message.
27
+ * @param trace An array of FrameInfo objects representing the stack trace.
28
+ */
29
+ doSend(contents: string, trace: FrameInfo[]): Promise<void>;
30
+ /**
31
+ * Sends the exception data (message, trace, session ID) to the server using
32
+ * a non-blocking post request. The exception trace is first encoded as a JSON string.
33
+ *
34
+ * @param exceptionMessage The exception message to report.
35
+ * @param trace An array of FrameInfo objects that describe the stack trace.
36
+ */
37
+ send(exceptionMessage: string, trace: FrameInfo[]): Promise<void>;
38
+ /**
39
+ * Generates the GraphQL mutation query for reporting the exception.
40
+ *
41
+ * @returns The GraphQL mutation query string.
42
+ */
43
+ protected getQuery(): string;
44
+ }
@@ -0,0 +1 @@
1
+ export { addOrUpdateMetadata, identify, setupInterceptors, } from "./unifiedInterceptor";
@@ -0,0 +1,2 @@
1
+ import { DataTransmitter } from "./dataTransmitter";
2
+ export declare function initializeLogInterceptor(transmitter: DataTransmitter): void;
@@ -0,0 +1,13 @@
1
+ export declare class RequestInterceptor {
2
+ private headerNameTracing;
3
+ private domainsToNotPropagateHeadersTo;
4
+ private contextManager;
5
+ private domainCache;
6
+ constructor();
7
+ private extractDomain;
8
+ private domainMatchesExclusionList;
9
+ addHeaders(headers: Record<string, string>, url: string): void;
10
+ getDomainsToNotPropagateHeadersTo(customDomains?: string[]): void;
11
+ }
12
+ export declare function patchHttp(domainsToNotPropagateHeadersTo?: string[]): void;
13
+ export declare function patchRequests(domainsToNotPropagateHeadersTo?: string[]): void;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Sends a non-blocking POST request to a GraphQL endpoint.
3
+ * The request is sent asynchronously, and any response errors or issues are logged.
4
+ *
5
+ * @param {string} url - The URL of the GraphQL endpoint.
6
+ * @param {string} operationName - The name of the GraphQL operation being invoked.
7
+ * @param {string} query - The GraphQL query string.
8
+ * @param {Record<string, any>} variables - The variables to be sent with the GraphQL query.
9
+ * @returns {Promise<void>} Resolves when the request has been handled.
10
+ */
11
+ export declare function nonBlockingPost(url: string, operationName: string, query: string, variables: Record<string, any>): Promise<void>;
@@ -0,0 +1,27 @@
1
+ import { BaseTransmitter } from "./baseTransmitter";
2
+ /**
3
+ * ServiceIdentifier is responsible for identifying the service details.
4
+ * It sends a request to a GraphQL endpoint to identify the service and logs the response.
5
+ */
6
+ export declare class ServiceIdentifier extends BaseTransmitter {
7
+ /**
8
+ * Constructor for the ServiceIdentifier class.
9
+ * Initializes the operation name and calls the parent constructor.
10
+ */
11
+ constructor();
12
+ /**
13
+ * Main method for sending the identification request.
14
+ * It checks if the service identification has already been received and attempts to send it.
15
+ *
16
+ * @param {any} args - Arguments for the request (not used in this method).
17
+ * @returns {Promise<void>} - Resolves when the identification process is complete.
18
+ */
19
+ doSend(args: any): Promise<void>;
20
+ /**
21
+ * Constructs and sends the GraphQL query to identify the service.
22
+ * This function sends the request asynchronously and processes the response.
23
+ *
24
+ * @returns {Promise<void>} - Resolves when the send operation is complete.
25
+ */
26
+ private send;
27
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Interface for setting up options for the service configuration.
3
+ */
4
+ export interface SetupOptions {
5
+ apiKey?: string;
6
+ /**
7
+ * Optional identifier for api key
8
+ */
9
+ apiGraphqlEndpoint?: string;
10
+ /**
11
+ * Optional identifier for debug
12
+ */
13
+ debug?: boolean;
14
+ /**
15
+ * Optional identifier for the service.
16
+ */
17
+ serviceIdentifier?: string;
18
+ /**
19
+ * Optional version of the service.
20
+ */
21
+ serviceVersion?: string;
22
+ /**
23
+ * Optional the depth of exception locals.
24
+ */
25
+ stackDepthLocals?: string;
26
+ /**
27
+ * Optional additional metadata for the service. It can contain key-value pairs
28
+ * where values can be strings, numbers, null, or undefined.
29
+ * Defaults to `undefined`.
30
+ */
31
+ serviceAdditionalMetadata?: Record<string, string | number | null | undefined>;
32
+ /**
33
+ * Profiling mode argument to enable or disable profiling.
34
+ * Defaults to `false`.
35
+ */
36
+ profilingModeEnabled?: boolean;
37
+ /**
38
+ * Maximum depth for profiling.
39
+ * Defaults to `5`.
40
+ */
41
+ profilingMaxDepth?: number;
42
+ /**
43
+ * Maximum variable size in KB for profiling.
44
+ * Defaults to `25`.
45
+ */
46
+ profilingMaxVariableSizeKb?: number;
47
+ /**
48
+ * Optional list of domains for which headers should not be propagated.
49
+ */
50
+ domainsToNotPropagateHeadersTo?: string[];
51
+ /**
52
+ * Optional list of site and distribution packages for which local variables should be collected.
53
+ */
54
+ siteAndDistPackagesToCollectLocalVariablesOn?: string[];
55
+ }
56
+ declare class AppConfig {
57
+ apiKey: string;
58
+ apiGraphqlEndpoint: string;
59
+ sfDebug: boolean;
60
+ serviceIdentifier: string;
61
+ serviceVersion: string;
62
+ serviceUUID: string;
63
+ serviceAdditionalMetadata: Record<string, string | number | null | undefined>;
64
+ profilingModeEnabled: boolean;
65
+ profilingMaxDepth: number;
66
+ profilingMaxVariableSizeKb: number;
67
+ domainsToNotPropagateHeadersTo: string[];
68
+ siteAndDistPackagesToCollectLocalVariablesOn: string[];
69
+ printConfigurationStatuses: string;
70
+ logLevel: string;
71
+ stackDepthLocals: number;
72
+ stackDepthCodeTraceDepth: number;
73
+ packageLibraryType: string;
74
+ version: string;
75
+ private _serviceIdentificationReceived;
76
+ constructor(options: SetupOptions);
77
+ private getPackageVersion;
78
+ get serviceIdentificationReceived(): boolean;
79
+ setServiceIdentificationReceived(value: boolean): void;
80
+ }
81
+ /**
82
+ * Initializes the global configuration with the provided SetupOptions.
83
+ * This should be called once at the start of the application.
84
+ */
85
+ export declare function initializeConfig(options: SetupOptions): void;
86
+ /**
87
+ * Retrieves the global configuration instance.
88
+ * Ensures the configuration is initialized before accessing.
89
+ */
90
+ export declare function getConfig(): AppConfig;
91
+ export {};
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Interface representing frame information data used to initialize a `FrameInfo` instance.
3
+ */
4
+ export interface FrameInfoData {
5
+ file: string;
6
+ line: number;
7
+ function: string;
8
+ code: string;
9
+ locals?: {
10
+ [key: string]: any;
11
+ };
12
+ offender?: boolean;
13
+ }
14
+ /**
15
+ * Class representing detailed information about a specific frame in a code trace.
16
+ */
17
+ export declare class FrameInfo {
18
+ file: string;
19
+ line: number;
20
+ function: string;
21
+ code: string;
22
+ locals: {
23
+ [key: string]: any;
24
+ };
25
+ offender: boolean;
26
+ /**
27
+ * Initializes a new instance of the `FrameInfo` class with provided frame data.
28
+ *
29
+ * @param file - The file where the frame is located.
30
+ * @param line - The line number of the frame.
31
+ * @param function - The function name associated with the frame.
32
+ * @param code - The code snippet for this frame.
33
+ * @param locals - The local variables within the frame scope (optional).
34
+ * @param offender - Indicates if this frame is considered an "offender" (optional).
35
+ */
36
+ constructor({ file, line, function: func, code, locals, offender, }: FrameInfoData);
37
+ /**
38
+ * Converts the `FrameInfo` instance to a dictionary format, serializing local variables as strings.
39
+ *
40
+ * @returns An object representing the frame, with locals as serialized strings.
41
+ */
42
+ toDict(): {
43
+ [key: string]: any;
44
+ };
45
+ /**
46
+ * Converts the `FrameInfo` instance to a JSON string representation.
47
+ *
48
+ * @returns A JSON string representing the frame information.
49
+ */
50
+ toJson(): string;
51
+ }
52
+ /**
53
+ * A custom encoder for serializing `FrameInfo` objects to JSON, handling nested structures.
54
+ */
55
+ export declare class CustomJSONEncoderForFrameInfo {
56
+ /**
57
+ * Encodes an object or array, recursively handling `FrameInfo` objects and nested structures.
58
+ *
59
+ * @param obj - The object to encode.
60
+ * @returns The encoded object with `FrameInfo` instances converted to dictionaries.
61
+ */
62
+ static encode(obj: any): any;
63
+ /**
64
+ * Converts an object to a JSON string, using a custom encoding process for `FrameInfo` instances.
65
+ *
66
+ * @param obj - The object to stringify.
67
+ * @returns A JSON string representation of the object.
68
+ */
69
+ static stringify(obj: any): string;
70
+ }
@@ -0,0 +1,35 @@
1
+ import { SetupOptions } from "./setupConfig";
2
+ import { Traits } from "./utils";
3
+ /**
4
+ * Main function to initialize all interceptors and configure data transmission.
5
+ *
6
+ * Initializes configuration settings for the application, checks for required
7
+ * configuration variables, and sets up log, exception, and metadata interceptors.
8
+ */
9
+ export declare function setupInterceptors(options?: SetupOptions): void;
10
+ /**
11
+ * Identifies a user and optionally updates their metadata.
12
+ *
13
+ * Uses `SailfishTransmitter` to either add or update the user's metadata in the
14
+ * configured service endpoint.
15
+ *
16
+ * @param {string} userId - Unique identifier for the user, typically a username or email.
17
+ * @param {Traits} [traits] - Optional dictionary of user traits to add or update.
18
+ * @param {string} [traitsJson] - Optional JSON string containing user traits.
19
+ * @param {boolean} [override=false] - Whether to override existing traits. Defaults to false.
20
+ */
21
+ export declare function identify(userId: string, traits?: Traits, traitsJson?: string, override?: boolean): void;
22
+ /**
23
+ * Adds or updates metadata for a user.
24
+ *
25
+ * Uses `SailfishTransmitter` to add or update a user's metadata at the configured
26
+ * service endpoint. If both `traits` and `traitsJson` are provided, the function
27
+ * will prioritize `traits`.
28
+ *
29
+ * @param {string} userId - Unique identifier for the user, typically a username or email.
30
+ * @param {Traits} [traits={}] - Optional dictionary of user traits to add or update.
31
+ * Defaults to an empty object.
32
+ * @param {string} [traitsJson] - Optional JSON string of user traits to add or update.
33
+ * @param {boolean} [override=false] - Whether to override existing traits. Defaults to false.
34
+ */
35
+ export declare function addOrUpdateMetadata(userId: string, traits?: Traits, traitsJson?: string, override?: boolean): void;
@@ -0,0 +1,6 @@
1
+ import { DataTransmitter } from "./dataTransmitter";
2
+ export declare class UpdateServiceIdentifierTransmitter extends DataTransmitter {
3
+ constructor();
4
+ doSend(): Promise<void>;
5
+ send(): Promise<void>;
6
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Interface representing a set of key-value pairs where keys are strings
3
+ * and values can be of any type.
4
+ */
5
+ export interface Traits {
6
+ [key: string]: any;
7
+ }
8
+ /**
9
+ * Serializes an object to a JSON string, excluding non-serializable fields.
10
+ *
11
+ * @param inputObj - The input object to be serialized.
12
+ * @returns An object containing:
13
+ * - `traitsJson`: A JSON string of the serializable fields.
14
+ * - `excludedFields`: An array of keys for fields that were not serializable.
15
+ */
16
+ export declare function serializeJsonWithExclusions(inputObj: Record<string, any> | null): {
17
+ traitsJson: string;
18
+ excludedFields: string[];
19
+ };
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@sailfish-ai/sf-veritas",
3
+ "version": "0.1.0",
4
+ "publishPublicly": true,
5
+ "main": "dist/sf-veritas.cjs",
6
+ "types": "dist/types/index.d.ts",
7
+ "scripts": {
8
+ "dev": "vite-node src/index.ts",
9
+ "build": "vite build && tsc --emitDeclarationOnly && npm run copy-worker",
10
+ "test": "vite-node --config vite.config.ts",
11
+ "check-types": "tsc --noEmit",
12
+ "prepublish": "npm run check-types && npm run build",
13
+ "copy-worker": "cp src/debuggerWorker.js dist/debuggerWorker.js",
14
+ "artifactregistry-login": "npx google-artifactregistry-auth",
15
+ "publish-local": "npm publish --registry http://localhost:4873 --//localhost:4873/:_authToken=none"
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "exports": {
21
+ ".": {
22
+ "import": "./dist/sf-veritas.mjs",
23
+ "require": "./dist/sf-veritas.cjs",
24
+ "types": "./dist/types/index.d.ts"
25
+ }
26
+ },
27
+ "dependencies": {
28
+ "cross-fetch": "^4.0.0",
29
+ "run": "^1.5.0",
30
+ "tldts": "^6.1.61",
31
+ "url": "^0.11.4",
32
+ "util": "^0.12.5",
33
+ "uuid": "^10.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "@rollup/plugin-commonjs": "^28.0.1",
37
+ "@rollup/plugin-node-resolve": "^15.3.0",
38
+ "@rollup/plugin-terser": "^0.4.4",
39
+ "@types/uuid": "^10.0.0",
40
+ "@urql/core": "^5.0.8",
41
+ "rollup-plugin-dts": "^6.1.1",
42
+ "rollup-plugin-polyfill-node": "^0.13.0",
43
+ "rollup-plugin-visualizer": "^5.12.0",
44
+ "ts-node": "^10.9.2",
45
+ "typescript": "^5.6.3",
46
+ "vite": "^5.4.11",
47
+ "vite-node": "^0.28.0",
48
+ "vite-plugin-compression": "^0.5.1",
49
+ "vite-tsconfig-paths": "^5.1.2",
50
+ "vitest": "^2.1.5"
51
+ }
52
+ }