chore: migrate workspace packages to ESM

- Add "type": "module" to all workspace package.json files
- Replace __dirname with import.meta.url-based resolveCliPath() helper
- Convert stream-json/stream-chain CJS named imports to default + destructure
  for ESM compatibility
- Use createRequire() for @node-rs/jieba native module loading in ESM context

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
diguaandCursor authored and digua committed 2026-05-26 23:19:47 +08:00
1 parent 83151fd8e7
commit 0ba9ae04a6
22 files changed
+92 -40

No files matched your search

+4 -3
View File
@@ -24,6 +24,7 @@ import {
executeReadonlySql,
} from '@openchatlab/core'
import { getVersion } from './version'
import { resolveCliPath } from './paths'
const program = new Command()
@@ -291,7 +292,7 @@ program
let webRoot: string | undefined
if (options.web !== undefined) {
const webDir = typeof options.web === 'string' ? options.web : path.resolve(__dirname, '../dist-web')
const webDir = typeof options.web === 'string' ? options.web : resolveCliPath('dist-web')
if (fs.existsSync(webDir)) {
webRoot = path.resolve(webDir)
} else {
@@ -349,7 +350,7 @@ program
.action(async (options) => {
const { startHttpServer } = await import('./http')
const port = parseInt(options.port, 10)
const webDir = path.resolve(__dirname, '../dist-web')
const webDir = resolveCliPath('dist-web')
let webRoot: string | undefined
if (fs.existsSync(webDir)) {
@@ -434,7 +435,7 @@ function openBrowser(url: string): void {
*/
function resolveNativeBinding(): string | undefined {
if (process.versions.electron) return undefined
const nativePath = path.resolve(__dirname, '../native/better_sqlite3.node')
const nativePath = resolveCliPath('native/better_sqlite3.node')
if (fs.existsSync(nativePath)) return nativePath
return undefined
}
+2 -2
View File
@@ -6,7 +6,6 @@
*/
import * as fs from 'fs'
import * as path from 'path'
import * as crypto from 'crypto'
import type { FastifyInstance } from 'fastify'
import { loadConfig, writeConfigField, MigrationRunner, ALL_MIGRATIONS } from '@openchatlab/config'
@@ -28,6 +27,7 @@ import { registerAiRoutes } from './routes/ai'
import { registerPreferencesRoutes } from './routes/preferences'
import { initServerAiLogger, closeServerAiLogger } from '../ai/logger'
import { initSync, cleanupSync } from '../sync'
import { resolveCliPath } from '../paths'
let server: FastifyInstance | null = null
let dbManager: DatabaseManager | null = null
@@ -43,7 +43,7 @@ export interface HttpServerOptions {
function resolveNativeBinding(): string | undefined {
if (process.versions.electron) return undefined
const nativePath = path.resolve(__dirname, '../../native/better_sqlite3.node')
const nativePath = resolveCliPath('native/better_sqlite3.node')
if (fs.existsSync(nativePath)) return nativePath
return undefined
}
+2 -2
View File
@@ -3,9 +3,9 @@
*/
import * as fs from 'fs'
import * as path from 'path'
import type { TimeFilter } from '@openchatlab/shared-types'
import type { DatabaseManager } from '@openchatlab/node-runtime'
import { resolveCliPath } from '../../../paths'
export function parseTimeFilter(query: Record<string, string | undefined>): TimeFilter | undefined {
const { startTs, endTs, memberId } = query
@@ -19,7 +19,7 @@ export function parseTimeFilter(query: Record<string, string | undefined>): Time
export function resolveNativeBinding(): string | undefined {
if (process.versions.electron) return undefined
const nativePath = path.resolve(__dirname, '../../../../native/better_sqlite3.node')
const nativePath = resolveCliPath('native/better_sqlite3.node')
if (fs.existsSync(nativePath)) return nativePath
return undefined
}
+2 -2
View File
@@ -5,7 +5,6 @@
*/
import fs from 'fs'
import path from 'path'
import { loadConfig } from '@openchatlab/config'
import {
NodePathProvider,
@@ -15,10 +14,11 @@ import {
} from '@openchatlab/node-runtime'
import { startMcpServer } from 'chatlab-mcp'
import { getVersion } from './version'
import { resolveCliPath } from './paths'
function resolveNativeBinding(): string | undefined {
if (process.versions.electron) return undefined
const nativePath = path.resolve(__dirname, '../native/better_sqlite3.node')
const nativePath = resolveCliPath('native/better_sqlite3.node')
if (fs.existsSync(nativePath)) return nativePath
return undefined
}
+8
View File
@@ -0,0 +1,8 @@
import path from 'path'
import { fileURLToPath } from 'url'
export function resolveCliPath(...segments: string[]): string {
const moduleDir = path.dirname(fileURLToPath(import.meta.url))
const packageRoot = path.basename(moduleDir) === 'dist' ? path.dirname(moduleDir) : path.resolve(moduleDir, '..')
return path.resolve(packageRoot, ...segments)
}
+2 -1
View File
@@ -17,6 +17,7 @@ import type { DatabaseManager } from '@openchatlab/node-runtime'
import { openBetterSqliteDatabase } from '@openchatlab/node-runtime'
import { parseFile } from '../import/chatlab-reader'
import { importData } from '../import/importer'
import { resolveCliPath } from '../paths'
function getTempFilePath(ext: string): string {
const id = crypto.randomBytes(8).toString('hex')
@@ -52,7 +53,7 @@ export class NodeFetcher implements HttpFetcher {
function resolveNativeBinding(): string | undefined {
if (process.versions.electron) return undefined
const nativePath = path.resolve(__dirname, '../../native/better_sqlite3.node')
const nativePath = resolveCliPath('native/better_sqlite3.node')
if (fs.existsSync(nativePath)) return nativePath
return undefined
}
+2 -2
View File
@@ -1,5 +1,5 @@
import { readFileSync } from 'fs'
import { resolve } from 'path'
import { resolveCliPath } from './paths'
let cached: string | undefined
@@ -10,7 +10,7 @@ let cached: string | undefined
export function getVersion(): string {
if (cached) return cached
try {
const pkgPath = resolve(__dirname, '../package.json')
const pkgPath = resolveCliPath('package.json')
cached = JSON.parse(readFileSync(pkgPath, 'utf-8')).version
} catch {
cached = '0.0.0-dev'
+1
View File
@@ -3,6 +3,7 @@
"version": "0.0.0",
"private": true,
"description": "ChatLab 配置读取层:TOML/JSON 文件 + 环境变量 + Zod 校验",
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"dependencies": {
+1
View File
@@ -3,6 +3,7 @@
"version": "0.0.0",
"private": true,
"description": "ChatLab 平台无关的共享核心:抽象接口、查询逻辑、分析算法",
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts"
}
+1
View File
@@ -2,6 +2,7 @@
"name": "chatlab-mcp",
"version": "0.1.0",
"description": "ChatLab MCP Server — shared core for CLI and Desktop, also usable standalone via npx",
"type": "module",
"main": "./dist/index.mjs",
"bin": {
"chatlab-mcp": "bin/chatlab-mcp.js"
+2 -1
View File
@@ -7,6 +7,7 @@
import * as fs from 'fs'
import * as path from 'path'
import { createRequire } from 'module'
import type {
SupportedLocale,
PosFilterMode,
@@ -24,6 +25,7 @@ interface JiebaInstance {
let _nlpDir: string | null = null
const jiebaInstances = new Map<DictType, JiebaInstance>()
const require = createRequire(import.meta.url)
/**
* 设置自定义词库目录路径(由应用初始化时调用)
@@ -65,7 +67,6 @@ export function getJieba(dictType: DictType = 'default'): JiebaInstance {
}
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const { Jieba } = require('@node-rs/jieba')
let instance: JiebaInstance
const diskDict = tryLoadDictFromDisk(effectiveType)
+1
View File
@@ -3,6 +3,7 @@
"version": "0.0.0",
"private": true,
"description": "ChatLab 多格式聊天记录解析器(14+ 格式)",
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"dependencies": {
+9 -4
View File
@@ -9,10 +9,10 @@
*/
import * as fs from 'fs'
import { parser } from 'stream-json'
import { pick } from 'stream-json/filters/Pick'
import { streamValues } from 'stream-json/streamers/StreamValues'
import { chain } from 'stream-chain'
import streamJson from 'stream-json'
import pickModule from 'stream-json/filters/Pick.js'
import streamValuesModule from 'stream-json/streamers/StreamValues.js'
import streamChain from 'stream-chain'
import { KNOWN_PLATFORMS, ChatType } from '@openchatlab/shared-types'
import type {
FormatFeature,
@@ -27,6 +27,11 @@ import type {
import { getFileSize, createProgress, readFileHeadBytes } from '../utils'
import * as path from 'path'
const { parser } = streamJson
const { pick } = pickModule
const { streamValues } = streamValuesModule
const { chain } = streamChain
// ==================== 辅助函数 ====================
/**
@@ -19,10 +19,10 @@
import * as fs from 'fs'
import * as path from 'path'
import { parser } from 'stream-json'
import { pick } from 'stream-json/filters/Pick'
import { streamValues } from 'stream-json/streamers/StreamValues'
import { chain } from 'stream-chain'
import streamJson from 'stream-json'
import pickModule from 'stream-json/filters/Pick.js'
import streamValuesModule from 'stream-json/streamers/StreamValues.js'
import streamChain from 'stream-chain'
import { KNOWN_PLATFORMS, ChatType, MessageType } from '@openchatlab/shared-types'
import type {
FormatFeature,
@@ -36,6 +36,11 @@ import type {
} from '../types'
import { getFileSize, createProgress, readFileHeadBytes, parseTimestamp, isValidYear } from '../utils'
const { parser } = streamJson
const { pick } = pickModule
const { streamValues } = streamValuesModule
const { chain } = streamChain
// ==================== 特征定义 ====================
export const feature: FormatFeature = {
@@ -9,13 +9,18 @@
import * as fs from 'fs'
import * as path from 'path'
import * as os from 'os'
import { parser } from 'stream-json'
import { pick } from 'stream-json/filters/Pick'
import { streamValues } from 'stream-json/streamers/StreamValues'
import { chain } from 'stream-chain'
import streamJson from 'stream-json'
import pickModule from 'stream-json/filters/Pick.js'
import streamValuesModule from 'stream-json/streamers/StreamValues.js'
import streamChain from 'stream-chain'
import type { ParseProgress, Preprocessor } from '../types'
import { getFileSize, createProgress } from '../utils'
const { parser } = streamJson
const { pick } = pickModule
const { streamValues } = streamValuesModule
const { chain } = streamChain
/** 预处理阈值:50MB */
const PREPROCESS_THRESHOLD = 50 * 1024 * 1024
@@ -15,9 +15,9 @@
*/
import * as fs from 'fs'
import { chain } from 'stream-chain'
import { parser } from 'stream-json'
import { streamValues } from 'stream-json/streamers/StreamValues'
import streamChain from 'stream-chain'
import streamJson from 'stream-json'
import streamValuesModule from 'stream-json/streamers/StreamValues.js'
import { KNOWN_PLATFORMS, ChatType } from '@openchatlab/shared-types'
import type {
@@ -34,6 +34,10 @@ import { getFileSize, createProgress } from '../utils'
import { mapChatType, extractPlatformId, detectMessageType, buildContent } from './utils/telegram-utils'
import type { TelegramChat } from './utils/telegram-utils'
const { chain } = streamChain
const { parser } = streamJson
const { streamValues } = streamValuesModule
// ==================== 特征定义 ====================
export const feature: FormatFeature = {
@@ -16,10 +16,10 @@
*/
import * as fs from 'fs'
import { chain } from 'stream-chain'
import { parser } from 'stream-json'
import { pick } from 'stream-json/filters/Pick'
import { streamValues } from 'stream-json/streamers/StreamValues'
import streamChain from 'stream-chain'
import streamJson from 'stream-json'
import pickModule from 'stream-json/filters/Pick.js'
import streamValuesModule from 'stream-json/streamers/StreamValues.js'
import { KNOWN_PLATFORMS, ChatType } from '@openchatlab/shared-types'
import type {
@@ -36,6 +36,11 @@ import { getFileSize, createProgress } from '../utils'
import { mapChatType, extractPlatformId, detectMessageType, buildContent } from './utils/telegram-utils'
import type { TelegramChat } from './utils/telegram-utils'
const { chain } = streamChain
const { parser } = streamJson
const { pick } = pickModule
const { streamValues } = streamValuesModule
// ==================== 类型定义 ====================
/** Telegram 聊天信息(扫描结果) */
@@ -9,10 +9,10 @@
*/
import * as fs from 'fs'
import { parser } from 'stream-json'
import { pick } from 'stream-json/filters/Pick'
import { streamValues } from 'stream-json/streamers/StreamValues'
import { chain } from 'stream-chain'
import streamJson from 'stream-json'
import pickModule from 'stream-json/filters/Pick.js'
import streamValuesModule from 'stream-json/streamers/StreamValues.js'
import streamChain from 'stream-chain'
import { KNOWN_PLATFORMS, ChatType, MessageType, type MemberRole } from '@openchatlab/shared-types'
import type {
FormatFeature,
@@ -26,6 +26,11 @@ import type {
} from '../types'
import { getFileSize, createProgress, readFileHeadBytes } from '../utils'
const { parser } = streamJson
const { pick } = pickModule
const { streamValues } = streamValuesModule
const { chain } = streamChain
// ==================== Discord 数据结构定义 ====================
interface DiscordGuild {
+9 -4
View File
@@ -17,10 +17,10 @@
import * as fs from 'fs'
import * as path from 'path'
import { parser } from 'stream-json'
import { pick } from 'stream-json/filters/Pick'
import { streamValues } from 'stream-json/streamers/StreamValues'
import { chain } from 'stream-chain'
import streamJson from 'stream-json'
import pickModule from 'stream-json/filters/Pick.js'
import streamValuesModule from 'stream-json/streamers/StreamValues.js'
import streamChain from 'stream-chain'
import { KNOWN_PLATFORMS, ChatType, MessageType } from '@openchatlab/shared-types'
import type {
FormatFeature,
@@ -34,6 +34,11 @@ import type {
} from '../types'
import { getFileSize, createProgress, readFileHeadBytes } from '../utils'
const { parser } = streamJson
const { pick } = pickModule
const { streamValues } = streamValuesModule
const { chain } = streamChain
// ==================== 辅助函数 ====================
/**
+1
View File
@@ -3,6 +3,7 @@
"version": "0.0.0",
"private": true,
"description": "ChatLab 跨平台共享类型定义",
"type": "module",
"main": "./index.ts",
"types": "./index.ts"
}
+1
View File
@@ -3,6 +3,7 @@
"version": "0.0.0",
"private": true,
"description": "ChatLab platform-agnostic data sync engine: config, data source, pull scheduler",
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts"
}
+1
View File
@@ -3,6 +3,7 @@
"version": "0.0.0",
"private": true,
"description": "ChatLab AI 工具链:工具定义 + 平台无关 handler,服务于 MCP/HTTP/Electron",
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"dependencies": {