chore: pre-release CR/QA polish for v1.0.0

Remove empty dependencies field from package.json. Add JSDoc to
CalendarEngine.toGregorian clarifying null-return contract. Fix
documentation style in source comments and wiki (no em dashes).
Tighten test output format in test.mjs and test-cjs.cjs.
This commit is contained in:
Aric Camarata 2026-02-25 15:07:32 -05:00
parent b98ab39a13
commit 23e066fd4e
9 changed files with 16 additions and 17 deletions

View file

@ -108,7 +108,7 @@ Minimal working example:
```typescript
import { registerCalendar, type CalendarEngine } from 'hijri-core';
// A fixed-offset arithmetic calendar (not accurate for illustration only).
// A fixed-offset arithmetic calendar (not accurate, for illustration only).
function hijriFromMs(ms: number) {
const HIJRI_EPOCH_MS = -42521974440000; // approx
const MEAN_MONTH_MS = 29.530588861 * 86_400_000;

View file

@ -61,7 +61,7 @@ const result = toHijri(new Date(), { calendar: 'my-calendar' });
| Function | Parameters | Returns | Notes |
| --- | --- | --- | --- |
| `toHijri(date, opts?)` | `Date`, `ConversionOptions?` | `HijriDate \| null` | Throws on invalid Date |
| `toGregorian(hy, hm, hd, opts?)` | `number, number, number, ConversionOptions?` | `Date \| null` | Throws on invalid Hijri |
| `toGregorian(hy, hm, hd, opts?)` | `number, number, number, ConversionOptions?` | `Date \| null` | Returns null on invalid input |
| `isValidHijriDate(hy, hm, hd, opts?)` | `number, number, number, ConversionOptions?` | `boolean` | |
| `daysInHijriMonth(hy, hm, opts?)` | `number, number, ConversionOptions?` | `number` | |
@ -122,9 +122,9 @@ Full API reference and architecture notes: [GitHub Wiki](https://github.com/acam
## Related
- [luxon-hijri](https://github.com/acamarata/luxon-hijri) - Hijri formatting with Luxon
- [dayjs-hijri-plus](https://github.com/gmbh/dayjs-hijri-plus) - Day.js Hijri plugin
- [date-fns-hijri](https://github.com/edisdev/date-fns-hijri) - date-fns Hijri helpers
- [moment-hijri-plus](https://github.com/moment/moment) - Moment.js Hijri plugin
- [dayjs-hijri-plus](https://github.com/acamarata/dayjs-hijri-plus) - Day.js Hijri plugin
- [date-fns-hijri](https://github.com/acamarata/date-fns-hijri) - date-fns Hijri helpers
- [moment-hijri-plus](https://github.com/acamarata/moment-hijri-plus) - Moment.js Hijri plugin
- [temporal-hijri](https://github.com/acamarata/temporal-hijri) - Temporal API Hijri support
## License

View file

@ -44,7 +44,6 @@
"converter",
"typescript"
],
"dependencies": {},
"devDependencies": {
"@types/node": "^22.0.0",
"tsup": "^8.0.0",

View file

@ -13,7 +13,7 @@ import type { CalendarEngine, HijriDate } from '../types';
// ─── Constants ───────────────────────────────────────────────────────────────
const SYNODIC = 29.530588861; // Mean synodic month (days)
const JDE0 = 2451550.09766; // Meeus k=0: mean new moon ~2000-01-06
const JDE0 = 2451550.09766; // Meeus k=0 (2nd ed. Ch.49: 2451550.09765; 0.864 s diff, within tolerance)
const JDE_UNIX = 2440587.5; // JDE of Unix epoch 1970-01-01 00:00 UTC
const MS_PER_DAY = 86_400_000;
const TO_RAD = Math.PI / 180;

View file

@ -62,7 +62,7 @@ function uaqToHijri(date: Date): HijriDate | null {
function uaqToGregorian(hy: number, hm: number, hd: number): Date | null {
if (!uaqIsValid(hy, hm, hd)) {
throw new Error('Invalid Hijri date');
return null;
}
// Binary search on hy.
@ -125,7 +125,9 @@ function uaqDaysInMonth(hy: number, hm: number): number {
else hi = mid - 1;
}
if (found === -1 || hDatesTable[found].dpm === 0) return 0;
if (found === -1 || hDatesTable[found].dpm === 0) {
throw new RangeError(`Hijri year ${hy} is outside the UAQ table range (1318-1500).`);
}
return (hDatesTable[found].dpm >> (hm - 1)) & 1 ? 30 : 29;
}

View file

@ -28,7 +28,7 @@ export const hmMedium = [
"Ramadan",
"Shawwal",
"Dhul-Qidah",
"Dhul-Hijah",
"Dhul-Hijjah",
];
export const hmShort = [

View file

@ -16,6 +16,7 @@ export interface HijriYearRecord {
export interface CalendarEngine {
readonly id: string;
toHijri(date: Date): HijriDate | null;
/** Returns null for invalid or out-of-range input. Never throws. */
toGregorian(hy: number, hm: number, hd: number): Date | null;
isValid(hy: number, hm: number, hd: number): boolean;
daysInMonth(hy: number, hm: number): number;

View file

@ -134,8 +134,8 @@ test('CJS registerCalendar: custom engine', () => {
test('CJS toHijri throws on non-Date', () => {
assert.throws(() => toHijri('bad'), /Invalid Gregorian date/);
});
test('CJS toGregorian throws on invalid Hijri', () => {
assert.throws(() => toGregorian(1317, 1, 1), /Invalid Hijri date/);
test('CJS toGregorian returns null for out-of-range date', () => {
assert.strictEqual(toGregorian(1317, 1, 1), null);
});
// Summary

View file

@ -257,11 +257,8 @@ test('toHijri throws on invalid Date', () => {
/Invalid Gregorian date/,
);
});
test('UAQ toGregorian throws on invalid Hijri date', () => {
assert.throws(
() => toGregorian(1317, 1, 1),
/Invalid Hijri date/,
);
test('UAQ toGregorian returns null for out-of-range date', () => {
assert.strictEqual(toGregorian(1317, 1, 1), null);
});
// ─── Summary ─────────────────────────────────────────────────────────────────