npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@wfp99/data-gateway

v0.6.1

Published

A lightweight, extensible data gateway for Node.js supporting multiple data sources, custom providers and middleware.

Readme

Data Gateway

English | 繁體中文

NPM version License Tests

一個輕量級、可擴展、型別安全的 Node.js 資料存取閘道。支援多種資料來源(MySQL、PostgreSQL、SQLite、遠端 API)、自訂資料提供者和中介軟體。非常適合建構現代、資料驅動的應用程式。

✨ 主要功能

  • 🎯 型別安全: 完整的 TypeScript 支援,編譯時期錯誤檢測
  • 🔄 流暢 API: QueryBuilder 模式,直觀的鏈式呼叫
  • 🔍 智慧警告: 自動偵測 JOIN 查詢中的欄位衝突
  • �� 多資料來源: 支援 MySQL、PostgreSQL、SQLite、遠端 API
  • 🔌 可擴展: 輕鬆新增自訂資料提供者
  • 🎭 中介軟體: 支援請求/回應攔截
  • 📦 輕量級: 核心程式碼 < 15KB (壓縮後)
  • 🧪 高測試覆蓋: 257 個測試全部通過,12 個測試套件

安裝

# 安裝核心函式庫
npm install @wfp99/data-gateway

# 依需求安裝資料庫驅動程式(延遲載入)
npm install mysql2              # MySQL 支援
npm install pg @types/pg        # PostgreSQL 支援
npm install sqlite3             # SQLite 支援
# 遠端 API 不需要額外依賴 🎉

延遲載入: 只需安裝實際使用的驅動程式。函式庫會按需匯入提供者。

快速入門

import { DataGateway, MySQLProviderOptions } from '@wfp99/data-gateway';

const config = {
  providers: {
    mysql: {
      type: 'mysql',
      options: {
        host: 'localhost',
        user: 'root',
        password: '',
        database: 'test'
      } as MySQLProviderOptions
    }
  },
  repositories: {
    user: { provider: 'mysql', table: 'users' }
  }
};

const gateway = await DataGateway.build(config);
const userRepo = gateway.getRepository('user');

// 查詢活躍使用者
const users = await userRepo?.find({
  where: { field: 'status', op: '=', value: 'active' }
});

await gateway.disconnectAll();

型別安全功能 (2025-10) ✨

1. FieldReference 型別系統

具有 IDE 自動完成的型別安全欄位引用:

import { tableField, repoField } from '@wfp99/data-gateway';

// 之前:容易出錯的字串
await userRepo.find({ fields: ['users.id', 'users.name'] });

// 現在:型別安全的引用
await userRepo.find({
  fields: [
    tableField('users', 'id'),      // 自動完成
    tableField('users', 'name')
  ]
});

2. QueryBuilder 模式

用於複雜查詢的流暢 API:

import { QueryBuilder } from '@wfp99/data-gateway';

const query = new QueryBuilder('users')
  .select('id', 'name', 'email')
  .where(w => w
    .equals('status', 'active')
    .greaterThan('age', 18)
  )
  .orderBy('createdAt', 'DESC')
  .limit(10)
  .build();

const users = await userRepo.find(query);

3. 欄位衝突檢測

自動警告 JOIN 查詢中的模糊欄位:

// ⚠️ 觸發警告
await userRepo.find({
  fields: ['id', 'name'],  // 哪個資料表的 'id'?
  joins: [{ type: 'LEFT', source: { repository: 'posts' }, ... }]
});

// ✅ 解決方案:使用前綴欄位
await userRepo.find({
  fields: [tableField('users', 'id'), tableField('posts', 'title')]
});

了解更多: 型別安全指南

核心概念

  • DataGateway: 提供者和儲存庫的中央協調器
  • DataProvider: 資料來源的抽象介面(MySQL、PostgreSQL、SQLite、遠端 API)
  • Repository: 特定資料表的 CRUD 和查詢操作
  • QueryObject: 統一的查詢格式,支援條件、分頁、排序、聚合
  • Middleware: 攔截和處理查詢(驗證、日誌、快取)
  • EntityFieldMapper: 資料庫欄位與應用程式屬性之間的轉換

CRUD 操作

建立

const userId = await userRepo.insert({
  name: 'John Doe',
  email: '[email protected]',
  age: 30
});

讀取

const users = await userRepo.find({
  fields: ['id', 'name', 'email'],
  where: {
    and: [
      { field: 'status', op: '=', value: 'active' },
      { field: 'age', op: '>', value: 18 }
    ]
  },
  orderBy: [{ field: 'createdAt', direction: 'DESC' }],
  limit: 10
});

更新

const affected = await userRepo.update(
  { status: 'inactive' },
  { field: 'id', op: '=', value: userId }
);

刪除

const deleted = await userRepo.delete(
  { field: 'id', op: '=', value: userId }
);

進階功能

JOIN 查詢

const orders = await orderRepo.find({
  fields: ['id', 'total', 'user.name', 'user.email'],
  joins: [{
    type: 'INNER',
    source: { repository: 'users' },
    on: { field: 'user_id', op: '=', value: 'users.id' }
  }],
  where: { field: 'status', op: '=', value: 'completed' }
});

支援的 JOIN 類型: INNER, LEFT, RIGHT, FULL(MySQL/SQLite 不支援 FULL)

中介軟體

import { Middleware } from '@wfp99/data-gateway';

const loggingMiddleware: Middleware = async (query, next) => {
  console.log('Query:', query);
  const result = await next(query);
  console.log('Result:', result);
  return result;
};

// 附加到儲存庫
repositories: {
  user: {
    provider: 'mysql',
    table: 'users',
    middlewares: [loggingMiddleware]
  }
}

連線池

providers: {
  mysql: {
    type: 'mysql',
    options: {
      // ... 連線選項
      pool: {
        usePool: true,          // 啟用連線池(預設:true)
        connectionLimit: 10,    // 最大連線數(預設:10)
        acquireTimeout: 60000,  // 超時時間(預設:60000ms)
        timeout: 600000         // 閒置超時(預設:600000ms)
      }
    }
  }
}

// 監控連線池狀態
const status = gateway.getProviderPoolStatus('mysql');
console.log(`連線池: ${status.activeConnections}/${status.maxConnections}`);

日誌

import { LogLevel } from '@wfp99/data-gateway';

const config = {
  // ...
  logging: {
    level: LogLevel.INFO,  // ALL, DEBUG, INFO, WARN, ERROR, OFF
    format: 'pretty'       // 'pretty' 或 'json'
  }
};

說明文件

📚 完整說明文件

指南

提供者

API 參考

自訂提供者

實作 DataProvider 介面:

import { DataProvider, PreparedQuery, QueryResult } from '@wfp99/data-gateway';

class CustomProvider implements DataProvider {
  async connect(): Promise<void> { /* ... */ }
  async disconnect(): Promise<void> { /* ... */ }
  async executeQuery<T = any>(query: PreparedQuery): Promise<QueryResult<T>> { /* ... */ }
}

支援的資料來源

| 提供者 | 需要的套件 | 狀態 | |----------|------------------|--------| | MySQL | mysql2 | ✅ 穩定 | | PostgreSQL | pg, @types/pg | ✅ 穩定 | | SQLite | sqlite3 | ✅ 穩定 | | 遠端 API | 無 | ✅ 穩定 | | 自訂 | 實作介面 | ✅ 支援 |

需求

  • Node.js: >= 18.0.0
  • TypeScript: >= 5.0.0(可選)

授權

MIT License - 查看 LICENSE

貢獻

歡迎在 GitHub 上提出 Issue 和 Pull Request。

作者

Wang Feng Ping


最新更新: 2025 年 10 月 - FieldReference、QueryBuilder 和欄位衝突檢測的型別安全改進。更新日誌