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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@qingu-x/msgraph-orm-js

v0.1.26

Published

Microsoft Graph JavaScript SDK for Qingu-X

Readme

@qingu-x/msgraph-orm-js

npm version License: MIT

Microsoft Graph 的 ORM 封装,提供简洁、类型安全、符合 ORM 规范的 API 调用方式。

⚠️ 本项目包括文档大部分由 AI 完成,如遇到问题请提 Issue

✨ 特性

  • 🏗️ 标准 ORM 架构: 仓储模式 + 服务层,职责清晰
  • 🎯 类型安全: 100% TypeScript,完整的类型推导
  • 🔗 关系映射: 支持实体关系的访问和管理
  • 🌏 国家云支持: 全球版/中国版/美国政府版
  • 🚀 95%+ API 覆盖: 覆盖 Graph v1.0 绝大多数常用接口
  • 🔍 强大查询构建器: 支持复杂查询、分页、排序
  • 高级功能: Delta Query、批处理、Webhooks
  • 📦 模块化设计: 按需使用仓储和服务
  • 🐛 统一调试: 所有请求支持 getDebug()getRaw() 调试功能
  • 🔧 自定义 Headers: 统一的自定义 header 管理

🆕 新版本亮点

清晰的三层架构

┌─────────────────────────────────────┐
│         GraphORM (入口层)            │
│    统一访问入口,管理仓储和服务         │
└─────────────────────────────────────┘
          │                    │
          ▼                    ▼
┌───────────────────┐  ┌───────────────────┐
│ Repositories      │  │  Services         │
│ - UserRepository  │  │  - FileService    │
│ - GroupRepository │  │  - MailService    │
│ - DeviceRepository│  │  - CalendarService│
│ ...               │  │  ...              │
└───────────────────┘  └───────────────────┘
          │                    │
          └────────┬───────────┘
                   ▼
         ┌──────────────────┐
         │  QueryBuilder    │
         │  查询构建器        │
         └──────────────────┘

📦 安装

npm install @qingu-x/msgraph-orm-js

🚀 快速开始

import { GraphClient, defaultEndpoints, createGraphORM } from '@qingu-x/msgraph-orm-js';

// 1. 创建 Graph 客户端
const graphClient = new GraphClient(
  {
    tenantId: 'your-tenant-id',
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret'
  },
  defaultEndpoints.global  // 全球版端点
);

// 2. 获取底层 Graph Client
const client = graphClient.getGraphClient();

// 3. 创建 ORM 实例(可选:设置默认时区)
const orm = createGraphORM(client, 'Asia/Shanghai');

// 或者动态设置时区
// orm.setDefaultTimeZone('Asia/Shanghai');

// 4. 开始使用
// 用户管理(仓储)
const users = await orm.users
  .query()
  .where('department', 'eq', 'IT')
  .select(['displayName', 'mail'])
  .top(10)
  .get();

// 调试信息(新功能)
const debugInfo = orm.users.query().getDebug();
console.log('请求调试信息:', debugInfo);

// 文件操作(服务)
await orm.files.uploadSmallFile('user-id', '/path/file.pdf', buffer);

// 邮件操作(服务)
await orm.mail.send('user-id', {
  subject: '测试邮件',
  toRecipients: [{ emailAddress: { address: '[email protected]' } }],
  body: { contentType: 'Text', content: '邮件内容' }
});

📚 核心概念

1. 仓储 (Repositories)

仓储负责实体的 CRUD 操作和关系访问:

// 用户仓储
const user = await orm.users.findById('user-id');
const userByEmail = await orm.users.findByEmail('[email protected]');
const exists = await orm.users.exists('user-id');
const count = await orm.users.count({ department: 'IT' });

// 关系访问
const userGroups = await orm.users.groups('user-id').findMany();
const userMessages = await orm.users.messages('user-id').findMany();
const manager = await orm.users.getManager('user-id');

// 组仓储
const group = await orm.groups.findById('group-id');
const members = await orm.groups.members('group-id').findMany();
await orm.groups.addMember('group-id', 'user-id');

2. 服务 (Services)

服务负责特定领域的业务逻辑:

// 文件服务
const files = orm.files;
await files.uploadSmallFile(userId, path, content);
await files.createFolder(userId, parentId, 'Documents');
const items = await files.search(userId, 'report');
await files.createShareLink(userId, itemId, 'view', 'organization');

// 邮件服务
const mail = orm.mail;
await mail.send(userId, message);
const inbox = await mail.getInbox(userId);
await mail.reply(userId, messageId, '谢谢');
await mail.markAsRead(userId, messageId);

// 日历服务
const calendar = orm.calendar;
await calendar.createEvent(userId, event);
const view = await calendar.getCalendarView(userId, start, end);
await calendar.acceptEvent(userId, eventId);
const rooms = await calendar.findRooms(userId);

3. 查询构建器

强大的链式查询:

const results = await orm.users
  .query()
  .where('department', 'eq', 'IT')
  .and('city', 'Beijing')
  .or('jobTitle', 'contains', 'Manager')
  .select(['id', 'displayName', 'mail', 'jobTitle'])
  .orderBy('displayName', 'asc')
  .top(20)
  .get();

// 分页迭代
for await (const user of orm.users.query().pagination()) {
  console.log(user.displayName);
}

// 搜索
const searchResults = await orm.users
  .query()
  .search('displayName', 'John')
  .get();

🌟 常用场景

用户管理

// 查询和过滤
const itUsers = await orm.users
  .query()
  .where('department', 'eq', 'IT')
  .orderBy('displayName')
  .get();

// 创建用户
const newUser = await orm.users.create({
  displayName: '张三',
  userPrincipalName: '[email protected]',
  mailNickname: 'zhangsan',
  accountEnabled: true,
  passwordProfile: {
    password: 'TempPassword123!',
    forceChangePasswordNextSignIn: true
  }
});

// 更新用户
await orm.users.update('user-id', {
  jobTitle: '高级工程师',
  department: '技术部'
});

// 许可证管理
await orm.users.assignLicense('user-id', [
  { skuId: 'sku-id' }
], []);

// 用户关系(使用 Repository,支持查询构建器)
const groups = await orm.users.groups('user-id').findMany();

// 获取用户未读邮件
const unreadMessages = await orm.users.messages('user-id')
  .query()
  .where('isRead', 'eq', false)
  .orderBy('receivedDateTime', 'desc')
  .top(10)
  .get();

// 获取用户本周事件
const thisWeekEvents = await orm.users.events('user-id')
  .query()
  .where('start/dateTime', 'ge', '2024-01-01T00:00:00Z')
  .orderBy('start/dateTime', 'asc')
  .get();

组管理

// 创建组
const group = await orm.groups.create({
  displayName: '技术部',
  mailNickname: 'techteam',
  mailEnabled: true,
  securityEnabled: true,
  groupTypes: ['Unified']
});

// 成员管理
await orm.groups.addMember('group-id', 'user-id');
await orm.groups.removeMember('group-id', 'user-id');
const isMember = await orm.groups.isMember('group-id', 'user-id');

// 获取成员和所有者
const members = await orm.groups.members('group-id').findMany();
const owners = await orm.groups.owners('group-id').findMany();

文件操作

// === Repository 方式:使用查询构建器查询文件 ===
// 查询所有文件夹
const folders = await orm.users.driveItems('user-id')
  .query()
  .where('folder', 'ne', null)
  .select(['id', 'name', 'folder'])
  .get();

// 查询最近修改的文件
const recentFiles = await orm.users.driveItems('user-id')
  .query()
  .where('file', 'ne', null)
  .orderBy('lastModifiedDateTime', 'desc')
  .top(10)
  .get();

// CRUD 操作
const item = await orm.users.driveItems('user-id').findById('item-id');
await orm.users.driveItems('user-id').update('item-id', { name: '新名称.pdf' });
await orm.users.driveItems('user-id').delete('item-id');

// === Service 方式:业务逻辑操作 ===
// 上传和下载
await orm.files.uploadSmallFile('user-id', '/Documents/report.pdf', buffer);
const downloadUrl = await orm.files.downloadFile('user-id', 'file-id');

// 文件夹管理
await orm.files.createFolder('user-id', 'root', '工作文档');
const children = await orm.files.listChildren('user-id', 'folder-id');

// 移动、复制
await orm.files.move('user-id', 'item-id', 'target-folder-id');
await orm.files.copy('user-id', 'item-id', 'target-folder-id');

// 共享和权限
const link = await orm.files.createShareLink('user-id', 'item-id', 'view', 'organization');
await orm.files.invite('user-id', 'item-id', ['[email protected]'], ['read']);

// 搜索
const results = await orm.files.search('user-id', '财务报告');

邮件操作

// === Repository 方式:使用查询构建器查询邮件 ===
// 查询未读邮件
const unreadMails = await orm.users.messages('user-id')
  .query()
  .where('isRead', 'eq', false)
  .orderBy('receivedDateTime', 'desc')
  .select(['id', 'subject', 'from', 'receivedDateTime'])
  .top(20)
  .get();

// 查询重要邮件
const importantMails = await orm.users.messages('user-id')
  .query()
  .where('importance', 'eq', 'high')
  .get();

// CRUD 操作
const message = await orm.users.messages('user-id').findById('message-id');
await orm.users.messages('user-id').update('message-id', { isRead: true });
await orm.users.messages('user-id').delete('message-id');

// 邮件特定操作(Repository 方法)
await orm.users.messages('user-id').reply('message-id', '收到');
await orm.users.messages('user-id').forward('message-id', recipients, '请查看');
await orm.users.messages('user-id').markAsRead('message-id');

// === Service 方式:业务逻辑操作 ===
// 发送邮件
await orm.mail.send('user-id', {
  subject: '会议通知',
  toRecipients: [
    { emailAddress: { address: '[email protected]', name: '同事' } }
  ],
  body: {
    contentType: 'HTML',
    content: '<h1>会议通知</h1><p>明天下午2点开会</p>'
  }
});

// 快捷访问常用文件夹
const inbox = await orm.mail.getInbox('user-id', 20);
const sent = await orm.mail.getSentItems('user-id', 20);
const drafts = await orm.mail.getDrafts('user-id');

// 文件夹管理
const folders = await orm.mail.getMailFolders('user-id');
await orm.mail.createMailFolder('user-id', '工作邮件');

日历操作

// === Repository 方式:使用查询构建器查询事件 ===
// 查询本周事件
const thisWeekEvents = await orm.users.events('user-id')
  .query()
  .where('start/dateTime', 'ge', '2024-01-01T00:00:00Z')
  .where('end/dateTime', 'le', '2024-01-07T23:59:59Z')
  .orderBy('start/dateTime', 'asc')
  .get();

// 查询包含特定关键词的会议
const meetings = await orm.users.events('user-id')
  .query()
  .where('subject', 'contains', '团队会议')
  .get();

// CRUD 操作(自动应用默认时区)
const event = await orm.users.events('user-id').findById('event-id');

// 创建事件(自动应用 ORM 的默认时区)
await orm.users.events('user-id').create({
  subject: '团队会议',
  start: { dateTime: '2024-01-15T10:00:00' },  // 自动应用 Asia/Shanghai
  end: { dateTime: '2024-01-15T11:00:00' }     // 自动应用 Asia/Shanghai
});

// 或者手动指定时区(会覆盖默认时区)
await orm.users.events('user-id').create({
  subject: '团队会议',
  start: { dateTime: '2024-01-15T10:00:00', timeZone: 'America/New_York' },
  end: { dateTime: '2024-01-15T11:00:00', timeZone: 'America/New_York' }
});

await orm.users.events('user-id').update('event-id', { subject: '更新的标题' });
await orm.users.events('user-id').delete('event-id');

// 事件特定操作(Repository 方法)
await orm.users.events('user-id').accept('event-id', '我会参加');
await orm.users.events('user-id').decline('event-id', '时间冲突');
await orm.users.events('user-id').cancel('event-id', '会议取消');

// === Service 方式:业务逻辑操作 ===
// 日历视图(特殊 API)
const calendarView = await orm.calendar.getCalendarView(
  'user-id',
  '2024-01-01T00:00:00Z',
  '2024-01-31T23:59:59Z'
);

// 日历管理
const calendars = await orm.calendar.getCalendars('user-id');
await orm.calendar.createCalendar('user-id', { name: '工作日历' });

// 会议室查找
const rooms = await orm.calendar.findRooms('user-id');
const roomLists = await orm.calendar.findRoomLists('user-id');

// 查找会议时间
const suggestions = await orm.calendar.findMeetingTimes(
  [{ emailAddress: { address: '[email protected]' }, type: 'required' }],
  { timeslots: [{ start: startTime, end: endTime }] },
  'PT1H'  // 1小时会议
);

// 忙闲时间表
const schedule = await orm.calendar.getSchedule(
  ['[email protected]', '[email protected]'],
  startTime,
  endTime
);

⚡ 高级功能

调试和监控

// 获取请求调试信息
const query = orm.users.query().where('department', 'eq', 'IT');
const debugInfo = query.getDebug();
console.log('请求方法:', debugInfo.method);
console.log('请求 URL:', debugInfo.url);
console.log('请求头:', debugInfo.headers);

// 获取原始请求参数(不执行请求)
const rawParams = query.getRaw();
console.log('请求参数:', rawParams);

// 执行请求后获取调试信息
const users = await query.get();
const lastDebugInfo = query.getDebug();
console.log('最后请求的调试信息:', lastDebugInfo);

自定义 Headers

// 为所有请求添加自定义 header
const query = orm.users.query()
  .header('ConsistencyLevel', 'eventual')
  .header('Prefer', 'outlook.timezone="Asia/Shanghai"')
  .where('displayName', 'startswith', '张')
  .get();

// 服务层也支持自定义 headers
await orm.mail.send('user-id', message, {
  'X-Custom-Header': 'value'
});

增量查询 (Delta Query)

// 首次查询
const delta = await orm.deltaUsers();
console.log('用户数:', delta.data.length);

// 保存 deltaLink
const deltaLink = delta.meta.deltaLink;

// 后续查询(只返回变化)
const changes = await orm.deltaUsers(deltaLink);
console.log('变化的用户:', changes.data);

// 其他资源
const groupDelta = await orm.deltaGroups();
const messageDelta = await orm.deltaMessages('user-id');
const eventDelta = await orm.deltaEvents('user-id');
const fileDelta = await orm.deltaDriveItems('user-id');

批处理请求

const response = await orm.batch([
  { id: '1', method: 'GET', url: '/users/[email protected]' },
  { id: '2', method: 'GET', url: '/users/[email protected]' },
  {
    id: '3',
    method: 'PATCH',
    url: '/users/[email protected]',
    body: { jobTitle: '工程师' }
  }
]);

response.responses.forEach(res => {
  console.log(`请求 ${res.id}: 状态 ${res.status}`);
});

搜索 API

// 搜索用户
const userResults = await orm.searchUsers('John Doe', 10);

// 搜索邮件
const mailResults = await orm.searchMessages('project report', 20);

// 搜索文件
const fileResults = await orm.searchFiles('budget.xlsx', 10);

// 自定义搜索
const customSearch = await orm.search({
  entityTypes: ['driveItem', 'message'],
  query: { queryString: '财务报告' },
  from: 0,
  size: 25
});

🌏 国家云支持

import { GraphClient, defaultEndpoints, createGraphORM } from '@qingu-x/msgraph-orm-js';

// 中国版(21Vianet)
const graphClientCN = new GraphClient(
  {
    tenantId: 'your-tenant-id',
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret'
  },
  defaultEndpoints.cn  // 中国版端点
);

// 美国政府版(GCC)
const graphClientGCC = new GraphClient(
  {
    tenantId: 'your-tenant-id',
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret'
  },
  defaultEndpoints.usGCC  // 美国政府版 GCC 端点
);

// 美国政府版(GCC High)
const graphClientGCCHigh = new GraphClient(
  {
    tenantId: 'your-tenant-id',
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret'
  },
  defaultEndpoints.usGCCHigh  // 美国政府版 GCC High 端点
);

// 美国政府版(DoD)
const graphClientDoD = new GraphClient(
  {
    tenantId: 'your-tenant-id',
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret'
  },
  defaultEndpoints.usDOD  // 美国政府版 DoD 端点
);

// 创建 ORM
const orm = createGraphORM(graphClientCN.getGraphClient());

📖 文档

🤝 贡献

欢迎贡献代码!请查看 贡献指南

📄 许可证

MIT © qingu-x

⚠️ 免责声明

本项目不是微软官方项目,仅为 Microsoft Graph API 的封装。使用前请确保:

  1. 具有适当的 API 权限
  2. 遵守微软 Graph API 的使用条款
  3. 了解国家云的功能限制

📮 反馈

遇到问题或有建议?请: