refactor(common): extract leaf utilities into @snowluma/common package

Phase 1 of the 4-package split called out in RoadMap #3. Moves the
"infrastructure" leaves — files with zero business dependencies that
@snowluma/bridge, @snowluma/core, and @snowluma/onebot all consume —
into a dedicated workspace package. Mirrors what #4 (proto-defs)
did for wire-protobuf definitions.

Why
---
- Cleaner layering: these were never bridge- or onebot-specific.
  Logger / hex codec / runtime config sit at the bottom of every
  module's import graph; giving them their own package makes that
  graph readable and prevents future leaks the other direction.
- Sets up #3's bridge + onebot extractions: those need a clean leaf
  to depend on. Without this, every cross-package import would have
  to re-export through core, which defeats the split.
- Mirrors @snowluma/proto-defs layout — per-file subpath exports
  (`@snowluma/common/logger`, `@snowluma/common/hex`, …) keep import
  sites unambiguous and let bundlers tree-shake aggressively.

Layout
------
Moved (via `git mv` — history preserved):
  packages/core/src/utils/logger.ts             → @snowluma/common/logger
  packages/core/src/utils/hex.ts                → @snowluma/common/hex
  packages/core/src/utils/log-file-transport.ts → @snowluma/common/log-file-transport
  packages/core/src/utils/log-summary.ts        → @snowluma/common/log-summary
  packages/core/src/protocol/packet-sender.ts   → @snowluma/common/packet-sender
  packages/core/src/protocol/types.ts           → @snowluma/common/protocol-types
  packages/core/src/common/runtime.ts           → @snowluma/common/runtime

Not moved (deferred to Phase 2): `packages/core/src/utils/event-format.ts`
— it has reverse imports on `bridge/events`, `bridge/identity-service`,
`onebot/message-store`, `onebot/types`. It moves into @snowluma/bridge
in Phase 2, with the MessageStore parameter decoupled via a structural
type so bridge doesn't end up depending on onebot.

Changes
-------
- New package `packages/common/` (package.json, tsconfig.json — no
  src/index.ts barrel, callers use the subpath exports directly to
  avoid pulling in `node:fs` when only the hex codec is needed).
- 7 `.ts` files moved via `git mv`.
- 50+ import sites rewritten via sed across `packages/core/src` and
  `packages/core/tests`. Old shapes (`../utils/logger`,
  `../../protocol/types`, `./common/runtime`, `../src/utils/hex`)
  all collapse to `@snowluma/common/<sub>`.
- `@snowluma/core` depends on `@snowluma/common` (workspace:*).
- `packages/core/src/{protocol,common}/` directories removed (empty).

Verification
------------
- core typecheck: clean
- common typecheck: clean
- Full workspace `pnpm -r typecheck`: all 9 projects clean
- core test suite: 552 passed / 552 total (pre-existing
  websocket-darwin-arm64.node addon failure unchanged — same baseline
  as the previous refactor commits)
- Vite build with stubbed native binary: clean (143 modules, 2.84 MB
  bundle, 224 KB gzip — same size envelope as before)

Note: `utils/event-format.ts` is the only file remaining under the
old `utils/` namespace. It moves into @snowluma/bridge alongside the
events / identity-service / packet-pipeline trio in Phase 2.
This commit is contained in:
DrSmoothl
2026-05-21 08:27:05 +08:00
parent e1c9ede9de
commit 46b302f738
64 changed files with 138 additions and 65 deletions
+47
View File
@@ -0,0 +1,47 @@
{
"name": "@snowluma/common",
"version": "1.9.0",
"private": true,
"type": "module",
"description": "SnowLuma shared infrastructure — leaf-package utilities with zero business dependencies. Logger / hex codec / log file transport / log line summariser / packet sender wire-protocol types / runtime config loader. Consumed by @snowluma/bridge, @snowluma/core, and @snowluma/onebot. Per-file subpath exports keep import sites unambiguous and let the bundler tree-shake aggressively (importing `@snowluma/common/hex` doesn't pull in `node:fs` from the logger transport).",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"default": "./src/index.ts"
},
"./logger": {
"types": "./src/logger.ts",
"default": "./src/logger.ts"
},
"./hex": {
"types": "./src/hex.ts",
"default": "./src/hex.ts"
},
"./log-file-transport": {
"types": "./src/log-file-transport.ts",
"default": "./src/log-file-transport.ts"
},
"./log-summary": {
"types": "./src/log-summary.ts",
"default": "./src/log-summary.ts"
},
"./packet-sender": {
"types": "./src/packet-sender.ts",
"default": "./src/packet-sender.ts"
},
"./protocol-types": {
"types": "./src/protocol-types.ts",
"default": "./src/protocol-types.ts"
},
"./runtime": {
"types": "./src/runtime.ts",
"default": "./src/runtime.ts"
}
},
"devDependencies": {
"@types/node": "^24.12.2",
"typescript": "catalog:"
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["node"],
"noEmit": true
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules"
]
}
+1
View File
@@ -14,6 +14,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@snowluma/common": "workspace:*",
"@snowluma/proto-defs": "workspace:*",
"@snowluma/proton": "workspace:*",
"@snowluma/websocket": "workspace:*"
+1 -1
View File
@@ -20,7 +20,7 @@ import type {
SendLongMsgResp,
} from '@snowluma/proto-defs/longmsg';
import type { FileExtra, PushMsg, PushMsgBody } from '@snowluma/proto-defs/message';
import type { PacketInfo } from '../../protocol/types';
import type { PacketInfo } from '@snowluma/common/protocol-types';
import type { BridgeContext } from '../bridge-context';
import type { Bridge } from '../bridge';
import { buildSendElems } from '../element-builder';
+2 -2
View File
@@ -10,8 +10,8 @@
// (`fetchNtv2DownloadUrl`, the upload-ext builder) live in one file.
import { protobuf_decode, protobuf_encode } from '@snowluma/proton';
import { toHexUpper } from '../../utils/hex';
import { createLogger } from '../../utils/logger';
import { toHexUpper } from '@snowluma/common/hex';
import { createLogger } from '@snowluma/common/logger';
import type { BridgeContext } from '../bridge-context';
import type { Bridge } from '../bridge';
import { makeOidbEnvelope, runOidb } from '../bridge-oidb';
+1 -1
View File
@@ -25,7 +25,7 @@
import type { IdentityService } from './identity-service';
import type { BridgeEventBus } from './event-bus';
import type { ApiHub } from './apis';
import type { SendPacketResult } from '../protocol/packet-sender';
import type { SendPacketResult } from '@snowluma/common/packet-sender';
import type { UploadedFileMeta } from './bridge';
export interface BridgeContext {
+2 -2
View File
@@ -1,5 +1,5 @@
import type { PacketSender, SendPacketResult } from '../protocol/packet-sender';
import type { PacketInfo } from '../protocol/types';
import type { PacketSender, SendPacketResult } from '@snowluma/common/packet-sender';
import type { PacketInfo } from '@snowluma/common/protocol-types';
import type { BridgeInterface } from './bridge-interface';
import { IdentityService } from './identity-service';
import { MSG_PUSH_CMD, parseMsgPush } from './msg-push';
+1 -1
View File
@@ -1,4 +1,4 @@
import { createLogger } from '../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import type { QQEventVariant } from './events';
type EventKind = QQEventVariant['kind'];
@@ -1,4 +1,4 @@
import { createLogger } from '../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import type { Bridge } from '../bridge';
import type { MessageElement } from '../events';
import { GROUP_IMAGE_CMD_ID, PRIVATE_IMAGE_CMD_ID } from './highway-client';
+1 -1
View File
@@ -1,6 +1,6 @@
import { protobuf_decode, protobuf_encode } from '@snowluma/proton';
import crypto from 'crypto';
import { createLogger } from '../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import type { Bridge } from '../bridge';
import { makeOidbEnvelope } from '../bridge-oidb';
import type {
@@ -2,7 +2,7 @@ import crypto from 'crypto';
import fs from 'fs';
import path from 'path';
import { createLogger } from '../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import type { Bridge } from '../bridge';
import type { MessageElement } from '../events';
import { defaultPttTempDir, encodeSilk } from './ffmpeg-addon';
@@ -2,7 +2,7 @@ import crypto from 'crypto';
import fs from 'fs';
import os from 'os';
import path from 'path';
import { createLogger } from '../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import type { Bridge } from '../bridge';
import type { MessageElement } from '../events';
import { getFFmpegAddon } from './ffmpeg-addon';
+1 -1
View File
@@ -6,7 +6,7 @@ import type {
FriendInfo, GroupMemberInfo, QQGroupInfo,
UserProfileInfo, GroupRequestInfo,
} from './qq-info';
import { createLogger, type Logger } from '../utils/logger';
import { createLogger, type Logger } from '@snowluma/common/logger';
const moduleLogger = createLogger('Identity');
+3 -3
View File
@@ -1,6 +1,6 @@
import type { PacketSender } from '../protocol/packet-sender';
import type { PacketInfo } from '../protocol/types';
import { createLogger } from '../utils/logger';
import type { PacketSender } from '@snowluma/common/packet-sender';
import type { PacketInfo } from '@snowluma/common/protocol-types';
import { createLogger } from '@snowluma/common/logger';
import { Bridge } from './bridge';
import { IdentityService } from './identity-service';
+1 -1
View File
@@ -1,5 +1,5 @@
import { protobuf_decode } from '@snowluma/proton';
import type { PacketInfo } from '../../protocol/types';
import type { PacketInfo } from '@snowluma/common/protocol-types';
import type { IdentityService } from '../identity-service';
import type { ContentHead, MessageBody, PushMsg, ResponseHead } from '@snowluma/proto-defs/message';
@@ -1,5 +1,5 @@
import { protobuf_decode } from '@snowluma/proton';
import { createLogger } from '../../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import type {
FriendAddEvent,
FriendPokeEvent,
@@ -1,5 +1,5 @@
import { protobuf_decode } from '@snowluma/proton';
import { createLogger } from '../../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import type {
GroupEssenceEvent,
GroupMsgEmojiLikeEvent,
+1 -1
View File
@@ -1,4 +1,4 @@
import type { PacketInfo } from '../../protocol/types';
import type { PacketInfo } from '@snowluma/common/protocol-types';
import type { QQEventVariant } from '../events';
import type { IdentityService } from '../identity-service';
import { buildContext } from './context';
@@ -1,4 +1,4 @@
import { createLogger } from '../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import type { QQEventVariant } from '../events';
import type { MsgPushContext } from './context';
import type { PkgType } from './enums';
@@ -1,5 +1,5 @@
import { protobuf_decode } from '@snowluma/proton';
import { toHexUpper } from '../../utils/hex';
import { toHexUpper } from '@snowluma/common/hex';
import type { MessageElement } from '../events';
import type {
Elem,
+2 -2
View File
@@ -1,6 +1,6 @@
import type { PacketInfo } from '../protocol/types';
import type { PacketInfo } from '@snowluma/common/protocol-types';
import { formatEvent } from '../utils/event-format';
import { createLogger, type Logger } from '../utils/logger';
import { createLogger, type Logger } from '@snowluma/common/logger';
import type { BridgeEventBus } from './event-bus';
import type { QQEventVariant } from './events';
import type { IdentityService } from './identity-service';
@@ -1,5 +1,5 @@
import { RequestUtil, cookieToString, getBknFromCookie } from './request-util';
import { createLogger } from '../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
const log = createLogger('Bridge.Web');
+1 -1
View File
@@ -1,5 +1,5 @@
import { RequestUtil, cookieToString } from './request-util';
import { createLogger } from '../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
const log = createLogger('Bridge.Web');
+1 -1
View File
@@ -1,6 +1,6 @@
import { RequestUtil, cookieToString } from './request-util';
import https from 'node:https';
import { createLogger } from '../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
const log = createLogger('Bridge.Web');
+2 -2
View File
@@ -1,7 +1,7 @@
import fs from 'fs';
import type { BridgeManager } from '../bridge/manager';
import type { PacketSink } from '../protocol/types';
import { createLogger, type Logger } from '../utils/logger';
import type { PacketSink } from '@snowluma/common/protocol-types';
import { createLogger, type Logger } from '@snowluma/common/logger';
import {
injectHookProcess,
listHookProcesses,
+1 -1
View File
@@ -1,4 +1,4 @@
import type { PacketSender, SendPacketResult } from '../protocol/packet-sender';
import type { PacketSender, SendPacketResult } from '@snowluma/common/packet-sender';
import { QqHookClient, type QqHookSendReply } from './qq-hook-client';
export class HookPacketClient implements PacketSender {
+2 -2
View File
@@ -1,6 +1,6 @@
import { EventEmitter } from 'events';
import type { PacketSink } from '../protocol/types';
import { createLogger, type Logger } from '../utils/logger';
import type { PacketSink } from '@snowluma/common/protocol-types';
import { createLogger, type Logger } from '@snowluma/common/logger';
import { HookPacketClient } from './hook-packet-client';
import type { HookInjectResult } from './injector';
import type { QqHookClient, QqHookLoginState, QqHookPacket } from './qq-hook-client';
+1 -1
View File
@@ -1,5 +1,5 @@
import { EventEmitter } from 'events';
import { createLogger, type Logger } from '../utils/logger';
import { createLogger, type Logger } from '@snowluma/common/logger';
import type { HookProcessBaseInfo } from './injector';
const DEFAULT_INTERVAL_MS = 1500;
+2 -2
View File
@@ -1,7 +1,7 @@
import { BridgeManager } from './bridge/manager';
import { OneBotManager } from './onebot/manager';
import { loadRuntimeConfig } from './common/runtime';
import { closeLogger, createLogger } from './utils/logger';
import { loadRuntimeConfig } from '@snowluma/common/runtime';
import { closeLogger, createLogger } from '@snowluma/common/logger';
import { HookManager } from './hook/hook-manager';
const runtimeConfig = loadRuntimeConfig();
+2 -2
View File
@@ -2,8 +2,8 @@ import type { JsonObject, JsonValue, MessageMeta } from './types';
import type { ForwardPreviewMeta } from './modules/message-actions';
import type { BridgeInterface } from '../bridge/bridge-interface';
import { RETCODE, failedResponse } from './types';
import { createLogger, type Logger } from '../utils/logger';
import { summarizeParams } from '../utils/log-summary';
import { createLogger, type Logger } from '@snowluma/common/logger';
import { summarizeParams } from '@snowluma/common/log-summary';
const moduleLog = createLogger('Bridge.Action');
+1 -1
View File
@@ -1,7 +1,7 @@
import fs from 'fs';
import path from 'path';
import { randomBytes } from 'crypto';
import { createLogger } from '../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import type {
HttpClientNetwork,
HttpServerNetwork,
+1 -1
View File
@@ -1,7 +1,7 @@
import type { MessageElement } from '../bridge/events';
import type { DownloadRKeyInfo } from '../bridge/bridge';
import type { BridgeInterface } from '../bridge/bridge-interface';
import { createLogger } from '../utils/logger';
import { createLogger } from '@snowluma/common/logger';
const log = createLogger('OneBot');
+1 -1
View File
@@ -19,7 +19,7 @@ import {
HttpPostAdapter,
type NetworkAdapterContext,
} from './network';
import { createLogger, type Logger } from '../utils/logger';
import { createLogger, type Logger } from '@snowluma/common/logger';
import { formatGroup, formatMessageSegments, formatReply, formatUser } from '../utils/event-format';
const moduleLog = createLogger('Event');
+1 -1
View File
@@ -1,6 +1,6 @@
import type { BridgeInterface } from '../bridge/bridge-interface';
import type { BridgeManager } from '../bridge/manager';
import { createLogger } from '../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import { loadOneBotConfig } from './config';
import { OneBotInstance } from './instance';
+1 -1
View File
@@ -1,5 +1,5 @@
import type { MessageElement } from '../bridge/events';
import { createLogger } from '../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import type { JsonValue } from './types';
const log = createLogger('MsgParser');
@@ -1,5 +1,5 @@
import type { BridgeInterface } from '../../bridge/bridge-interface';
import { createLogger } from '../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import type { MediaStore } from '../media-store';
import type { JsonObject } from '../types';
@@ -1,6 +1,6 @@
import type { BridgeInterface } from '../../bridge/bridge-interface';
import type { ForwardNodePayload, MessageElement } from '../../bridge/events';
import { createLogger } from '../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import type { MessageSendResult } from '../api-handler';
import { elementsToOneBotSegments } from '../event-converter';
import { segmentsToRawMessage } from '../event-converter/utils';
@@ -1,4 +1,4 @@
import { createLogger, type Logger } from '../../utils/logger';
import { createLogger, type Logger } from '@snowluma/common/logger';
import {
pickDispatchJson,
resolveReportOptions,
@@ -4,7 +4,7 @@ import {
type Server,
type ServerResponse,
} from 'http';
import { createLogger, type Logger } from '../../utils/logger';
import { createLogger, type Logger } from '@snowluma/common/logger';
import type { DispatchPayload } from '../event-filter';
import type { HttpServerNetwork, JsonObject, JsonValue } from '../types';
import { IOneBotNetworkAdapter, NetworkReloadType, type NetworkAdapterContext } from './adapter';
@@ -1,4 +1,4 @@
import { createLogger } from '../../utils/logger';
import { createLogger } from '@snowluma/common/logger';
import { buildDispatchPayload } from '../event-filter';
import type { JsonObject, NetworkBase } from '../types';
import { IOneBotNetworkAdapter } from './adapter';
@@ -1,5 +1,5 @@
import { WebSocket } from '@snowluma/websocket';
import { createLogger, type Logger } from '../../utils/logger';
import { createLogger, type Logger } from '@snowluma/common/logger';
import {
pickDispatchJson,
resolveReportOptions,
@@ -1,6 +1,6 @@
import { WebSocket, WebSocketServer } from '@snowluma/websocket';
import type { IncomingMessage } from 'http';
import { createLogger, type Logger } from '../../utils/logger';
import { createLogger, type Logger } from '@snowluma/common/logger';
import {
pickDispatchJson,
resolveReportOptions,
+1 -1
View File
@@ -1,7 +1,7 @@
import { randomBytes, scryptSync, timingSafeEqual } from 'crypto';
import fs from 'fs';
import path from 'path';
import { createLogger } from '../utils/logger';
import { createLogger } from '@snowluma/common/logger';
const log = createLogger('WebUI.Auth');
+1 -1
View File
@@ -2,7 +2,7 @@ import { serve } from '@hono/node-server';
import { serveStatic } from '@hono/node-server/serve-static';
import { Hono, type Context } from 'hono';
import { describeTrustProxy, makeClientIpResolver, parseTrustProxy } from './client-ip';
import { createLogger, getLogLevel, getRecentLogs, LOG_LEVELS, setLogLevel, subscribeLogs } from '../utils/logger';
import { createLogger, getLogLevel, getRecentLogs, LOG_LEVELS, setLogLevel, subscribeLogs } from '@snowluma/common/logger';
import { randomBytes } from 'crypto';
import type { OneBotManager } from '../onebot/manager';
import { loadOneBotConfig, saveOneBotConfig } from '../onebot/config';
+1 -1
View File
@@ -14,7 +14,7 @@
// via `mockBridge({ apis: { message: ... } })`.
import { vi } from 'vitest';
import type { SendPacketResult } from '../../src/protocol/packet-sender';
import type { SendPacketResult } from '@snowluma/common/packet-sender';
/** Default receipt returned by sendGroup / sendPrivate / sendC2cFile mocks. */
const STUB_RECEIPT = { messageId: 1, sequence: 1, clientSequence: 0, random: 1, timestamp: 0 };
@@ -6,8 +6,8 @@
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { ApiHandler } from '../src/onebot/api-handler';
import { subscribeLogs, type LogEntry } from '../src/utils/logger';
import { summarizeParams } from '../src/utils/log-summary';
import { subscribeLogs, type LogEntry } from '@snowluma/common/logger';
import { summarizeParams } from '@snowluma/common/log-summary';
// Minimal context — we never reach the real action handlers; we
// register our own via registerAction.
@@ -3,7 +3,7 @@ import { Bridge } from '../src/bridge/bridge';
import { IdentityService } from '../src/bridge/identity-service';
import type { GroupMemberInfo, QQGroupInfo } from '../src/bridge/qq-info';
import type { GroupMemberJoin, QQEventVariant } from '../src/bridge/events';
import type { PacketInfo } from '../src/protocol/types';
import type { PacketInfo } from '@snowluma/common/protocol-types';
const SELF_UIN = '10001';
const GROUP_ID = 123456789;
@@ -1,6 +1,6 @@
import { describe, expect, it, vi } from 'vitest';
import { protobuf_decode, protobuf_encode } from '@snowluma/proton';
import type { SendPacketResult } from '../src/protocol/packet-sender';
import type { SendPacketResult } from '@snowluma/common/packet-sender';
import type { SendMessageRequest, SendMessageResponse } from '@snowluma/proto-defs/action';
import type { FileExtra } from '@snowluma/proto-defs/message';
@@ -15,7 +15,7 @@ import type { GroupMsgEmojiLikeEvent, QQEventVariant } from '../src/bridge/event
import { convertGroupMsgEmojiLike } from '../src/onebot/event-converter/to-notice';
import { GROUP_MESSAGE_EVENT, hashMessageIdInt32 } from '../src/onebot/message-id';
import { formatEvent } from '../src/utils/event-format';
import { subscribeLogs, type LogEntry } from '../src/utils/logger';
import { subscribeLogs, type LogEntry } from '@snowluma/common/logger';
const SELF_UIN = '10001';
const GROUP_ID = 123456789;
+1 -1
View File
@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest';
import { toHex, fromHex, hexPreview } from '../src/utils/hex';
import { toHex, fromHex, hexPreview } from '@snowluma/common/hex';
describe('toHex', () => {
it('converts empty buffer', () => {
+1 -1
View File
@@ -8,7 +8,7 @@ import { PipeWatcher } from '../src/hook/pipe-watcher';
import type { ManualMapHandle } from '../src/hook/injector';
import type { BridgeManager } from '../src/bridge/manager';
import type { QqHookClient } from '../src/hook/qq-hook-client';
import { createLogger } from '../src/utils/logger';
import { createLogger } from '@snowluma/common/logger';
const DUMMY_HANDLE: ManualMapHandle = { base: 0n, entry: 0n, exceptionTable: 0n, size: 0 };
const flush = () => new Promise<void>(r => setImmediate(r));
+1 -1
View File
@@ -3,7 +3,7 @@ import { EventEmitter } from 'events';
import { HookSession } from '../src/hook/hook-session';
import type { ManualMapHandle } from '../src/hook/injector';
import type { QqHookClient, QqHookPacket } from '../src/hook/qq-hook-client';
import type { PacketSink } from '../src/protocol/types';
import type { PacketSink } from '@snowluma/common/protocol-types';
const DUMMY_HANDLE: ManualMapHandle = { base: 0n, entry: 0n, exceptionTable: 0n, size: 0 };
@@ -6,7 +6,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { FileTransport } from '../src/utils/log-file-transport';
import { FileTransport } from '@snowluma/common/log-file-transport';
let tmpDir: string;
const ENV_KEYS = [
+2 -2
View File
@@ -11,8 +11,8 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { createLogger, getLogLevel, setLogLevel, subscribeLogs, type LogEntry } from '../src/utils/logger';
import { _resetFileTransportForTesting } from '../src/utils/log-file-transport';
import { createLogger, getLogLevel, setLogLevel, subscribeLogs, type LogEntry } from '@snowluma/common/logger';
import { _resetFileTransportForTesting } from '@snowluma/common/log-file-transport';
let tmpDir: string;
const ENV_KEYS = [
+2 -2
View File
@@ -24,8 +24,8 @@ import type {
// we avoid an `import { FriendRecall as X }` that collides with the
// proton import above.
type FriendRecallEvent = Extract<QQEventVariant, { kind: 'friend_recall' }>;
import type { PacketInfo } from '../src/protocol/types';
import { subscribeLogs } from '../src/utils/logger';
import type { PacketInfo } from '@snowluma/common/protocol-types';
import { subscribeLogs } from '@snowluma/common/logger';
const SELF_UIN = '10001';
const GROUP_ID = 123456789;
@@ -11,7 +11,7 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { protobuf_encode } from '@snowluma/proton';
import { subscribeLogs, type LogEntry } from '../src/utils/logger';
import { subscribeLogs, type LogEntry } from '@snowluma/common/logger';
vi.mock('../src/bridge/highway/highway-client', () => ({
fetchHighwaySession: vi.fn(async () => ({ sessionId: 'fake-session' })),
+12
View File
@@ -48,8 +48,20 @@ importers:
specifier: ^8.58.2
version: 8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2)
packages/common:
devDependencies:
'@types/node':
specifier: ^24.12.2
version: 24.12.2
typescript:
specifier: 'catalog:'
version: 6.0.2
packages/core:
dependencies:
'@snowluma/common':
specifier: workspace:*
version: link:../common
'@snowluma/proto-defs':
specifier: workspace:*
version: link:../proto-defs