Calendar library for the NBTCA ICS feed
  • TypeScript 93.4%
  • JavaScript 6.6%
Find a file
2026-08-13 11:58:01 +08:00
.github/workflows fix: harden recurrence queries and all-day dates 2026-08-13 11:58:01 +08:00
scripts fix: harden recurrence queries and all-day dates 2026-08-13 11:58:01 +08:00
src fix: harden recurrence queries and all-day dates 2026-08-13 11:58:01 +08:00
.gitignore feat(core): 实现核心功能模块 2026-01-16 15:46:13 +08:00
.prettierignore feat: prepare @nbtca/nbtcal 0.4.0 (#15) 2026-08-12 14:02:30 +08:00
.prettierrc.json feat: prepare @nbtca/nbtcal 0.4.0 (#15) 2026-08-12 14:02:30 +08:00
eslint.config.js feat: prepare @nbtca/nbtcal 0.4.0 (#15) 2026-08-12 14:02:30 +08:00
LICENSE release: nbtcal 0.3.7 (#14) 2026-08-04 12:13:45 +08:00
package-lock.json feat: prepare @nbtca/nbtcal 0.4.0 (#15) 2026-08-12 14:02:30 +08:00
package.json feat: prepare @nbtca/nbtcal 0.4.0 (#15) 2026-08-12 14:02:30 +08:00
README.md feat: prepare @nbtca/nbtcal 0.4.0 (#15) 2026-08-12 14:02:30 +08:00
SECURITY.md feat: add authenticated personal timetable support 2026-07-11 23:11:49 +08:00
tsconfig.build.json feat: prepare @nbtca/nbtcal 0.4.0 (#15) 2026-08-12 14:02:30 +08:00
tsconfig.json feat: prepare @nbtca/nbtcal 0.4.0 (#15) 2026-08-12 14:02:30 +08:00

@nbtca/nbtcal

Typed ESM library for NBTCA calendar feeds and personal academic timetables. It handles parsing, recurrence expansion, date queries, heatmaps, and ICS generation without owning credentials, sessions, files, or UI.

Install

npm install @nbtca/nbtcal

Usage

import { loadCalendar } from '@nbtca/nbtcal';

const calendar = await loadCalendar();
const start = new Date('2026-09-01T00:00:00Z');
const end = new Date('2026-10-01T00:00:00Z');

const upcoming = calendar.upcoming({ days: 30 });
const nextFive = calendar.next(5);
const range = calendar.inRange(start, end);
const dailyCounts = calendar.heatmap({ start, end, bucket: 'day' });

Recurring events are expanded within each query window. Heatmaps are dense and include zero-count day or week buckets. Lower-level feed, parser, query, and ICS functions are available from the package root.

Personal timetable

The @nbtca/nbtcal/timetable subpath accepts an authenticated transport for the campus JWXT protocol:

import {
  createNbtTimetableClient,
  createTimetableSchedule,
  findAcademicTerm,
  timetableToIcs,
} from '@nbtca/nbtcal/timetable';

const client = createNbtTimetableClient(authenticatedTransport, {
  baseUrl: 'https://jwxt-443.webvpn.nbt.edu.cn',
});

const terms = await client.listTerms();
const current = findAcademicTerm(terms);
if (!current) throw new Error('No current academic term');
const timetable = await client.fetchTerm(current);
const schedule = createTimetableSchedule(timetable, { weekOneMonday: '2026-09-07' });
const week = schedule.weekAt(new Date());
const today = schedule.meetingsOnDay(week, schedule.weekdayAt(new Date()));
const nextClass = schedule.next();

const ics = timetableToIcs(timetable, {
  // Confirm this date for the selected term.
  weekOneMonday: '2026-09-07',
});

findAcademicTerm accepts an opaque year:code selector or the year-1, year-2, and year-3 semester aliases.

The host injects an authenticated transport; this package never receives credentials or a cookie jar. If JWXT omits authoritative calendar dates, weekOneMonday is required. Malformed rows produce structured warnings, and unresolved practice rows retain only allowlisted, identity-free fields.

Quality checks

npm run check

License

MIT