@hasna/calendar 0.1.9 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -3484,9 +3484,25 @@ function rowToAvailability(row) {
3484
3484
  updated_at: row.updated_at
3485
3485
  };
3486
3486
  }
3487
+ function parseAvailabilityTime(value) {
3488
+ const match = /^([01]\d|2[0-3]):([0-5]\d)$/.exec(value);
3489
+ if (!match) {
3490
+ throw new RangeError("Availability times must use HH:mm format between 00:00 and 23:59");
3491
+ }
3492
+ return Number(match[1]) * 60 + Number(match[2]);
3493
+ }
3494
+ function assertValidAvailabilityWindow(dayOfWeek, startTime, endTime) {
3495
+ if (!Number.isInteger(dayOfWeek) || dayOfWeek < 0 || dayOfWeek > 6) {
3496
+ throw new RangeError("Availability day_of_week must be an integer from 0 to 6");
3497
+ }
3498
+ if (parseAvailabilityTime(endTime) <= parseAvailabilityTime(startTime)) {
3499
+ throw new RangeError("Availability end_time must be after start_time");
3500
+ }
3501
+ }
3487
3502
  function createAvailability(input, db) {
3488
3503
  db = db || getDatabase();
3489
3504
  const id = crypto.randomUUID().slice(0, 8);
3505
+ assertValidAvailabilityWindow(input.day_of_week, input.start_time, input.end_time);
3490
3506
  db.run(`INSERT INTO availability (id, agent_id, org_id, day_of_week, start_time, end_time, exceptions) VALUES (?, ?, ?, ?, ?, ?, ?)`, [id, input.agent_id, input.org_id, input.day_of_week, input.start_time, input.end_time, input.exceptions ? JSON.stringify(input.exceptions) : null]);
3491
3507
  return getAvailability(id, db);
3492
3508
  }
@@ -3512,6 +3528,7 @@ function deleteAvailability(id, db) {
3512
3528
  }
3513
3529
  function upsertAgentAvailability(agentId, orgId, dayOfWeek, startTime, endTime, db) {
3514
3530
  db = db || getDatabase();
3531
+ assertValidAvailabilityWindow(dayOfWeek, startTime, endTime);
3515
3532
  const existing = db.query("SELECT * FROM availability WHERE agent_id = ? AND org_id = ? AND day_of_week = ?").all(agentId, orgId, dayOfWeek);
3516
3533
  for (const row of existing) {
3517
3534
  db.run(`DELETE FROM availability WHERE id = ?`, [row.id]);
@@ -1 +1 @@
1
- {"version":3,"file":"availability.d.ts","sourceRoot":"","sources":["../../src/db/availability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAiB/E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,CAU9F;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,IAAI,CAI9E;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,EAAE,CAStG;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,CAW7J;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAIrE;AAED,kGAAkG;AAClG,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,CAU1J"}
1
+ {"version":3,"file":"availability.d.ts","sourceRoot":"","sources":["../../src/db/availability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAoC/E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,CAW9F;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,IAAI,CAI9E;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,EAAE,CAStG;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,CAc7J;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAIrE;AAED,kGAAkG;AAClG,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,CAW1J"}
package/dist/index.js CHANGED
@@ -782,9 +782,25 @@ function rowToAvailability(row) {
782
782
  updated_at: row.updated_at
783
783
  };
784
784
  }
785
+ function parseAvailabilityTime(value) {
786
+ const match = /^([01]\d|2[0-3]):([0-5]\d)$/.exec(value);
787
+ if (!match) {
788
+ throw new RangeError("Availability times must use HH:mm format between 00:00 and 23:59");
789
+ }
790
+ return Number(match[1]) * 60 + Number(match[2]);
791
+ }
792
+ function assertValidAvailabilityWindow(dayOfWeek, startTime, endTime) {
793
+ if (!Number.isInteger(dayOfWeek) || dayOfWeek < 0 || dayOfWeek > 6) {
794
+ throw new RangeError("Availability day_of_week must be an integer from 0 to 6");
795
+ }
796
+ if (parseAvailabilityTime(endTime) <= parseAvailabilityTime(startTime)) {
797
+ throw new RangeError("Availability end_time must be after start_time");
798
+ }
799
+ }
785
800
  function createAvailability(input, db) {
786
801
  db = db || getDatabase();
787
802
  const id = crypto.randomUUID().slice(0, 8);
803
+ assertValidAvailabilityWindow(input.day_of_week, input.start_time, input.end_time);
788
804
  db.run(`INSERT INTO availability (id, agent_id, org_id, day_of_week, start_time, end_time, exceptions) VALUES (?, ?, ?, ?, ?, ?, ?)`, [id, input.agent_id, input.org_id, input.day_of_week, input.start_time, input.end_time, input.exceptions ? JSON.stringify(input.exceptions) : null]);
789
805
  return getAvailability(id, db);
790
806
  }
@@ -808,7 +824,10 @@ function updateAvailability(id, updates, db) {
808
824
  const existing = getAvailability(id, db);
809
825
  if (!existing)
810
826
  throw new NotFoundError("Availability", id);
811
- db.run(`UPDATE availability SET start_time = ?, end_time = ?, exceptions = ?, updated_at = datetime('now') WHERE id = ?`, [updates.start_time ?? existing.start_time, updates.end_time ?? existing.end_time, updates.exceptions !== undefined ? updates.exceptions ? JSON.stringify(updates.exceptions) : null : existing.exceptions ? JSON.stringify(existing.exceptions) : null, id]);
827
+ const startTime = updates.start_time ?? existing.start_time;
828
+ const endTime = updates.end_time ?? existing.end_time;
829
+ assertValidAvailabilityWindow(existing.day_of_week, startTime, endTime);
830
+ db.run(`UPDATE availability SET start_time = ?, end_time = ?, exceptions = ?, updated_at = datetime('now') WHERE id = ?`, [startTime, endTime, updates.exceptions !== undefined ? updates.exceptions ? JSON.stringify(updates.exceptions) : null : existing.exceptions ? JSON.stringify(existing.exceptions) : null, id]);
812
831
  return getAvailability(id, db);
813
832
  }
814
833
  function deleteAvailability(id, db) {
@@ -818,6 +837,7 @@ function deleteAvailability(id, db) {
818
837
  }
819
838
  function upsertAgentAvailability(agentId, orgId, dayOfWeek, startTime, endTime, db) {
820
839
  db = db || getDatabase();
840
+ assertValidAvailabilityWindow(dayOfWeek, startTime, endTime);
821
841
  const existing = db.query("SELECT * FROM availability WHERE agent_id = ? AND org_id = ? AND day_of_week = ?").all(agentId, orgId, dayOfWeek);
822
842
  for (const row of existing) {
823
843
  db.run(`DELETE FROM availability WHERE id = ?`, [row.id]);
package/dist/mcp/index.js CHANGED
@@ -4672,9 +4672,25 @@ function rowToAvailability(row) {
4672
4672
  updated_at: row.updated_at
4673
4673
  };
4674
4674
  }
4675
+ function parseAvailabilityTime(value) {
4676
+ const match = /^([01]\d|2[0-3]):([0-5]\d)$/.exec(value);
4677
+ if (!match) {
4678
+ throw new RangeError("Availability times must use HH:mm format between 00:00 and 23:59");
4679
+ }
4680
+ return Number(match[1]) * 60 + Number(match[2]);
4681
+ }
4682
+ function assertValidAvailabilityWindow(dayOfWeek, startTime, endTime) {
4683
+ if (!Number.isInteger(dayOfWeek) || dayOfWeek < 0 || dayOfWeek > 6) {
4684
+ throw new RangeError("Availability day_of_week must be an integer from 0 to 6");
4685
+ }
4686
+ if (parseAvailabilityTime(endTime) <= parseAvailabilityTime(startTime)) {
4687
+ throw new RangeError("Availability end_time must be after start_time");
4688
+ }
4689
+ }
4675
4690
  function createAvailability(input, db) {
4676
4691
  db = db || getDatabase();
4677
4692
  const id = crypto.randomUUID().slice(0, 8);
4693
+ assertValidAvailabilityWindow(input.day_of_week, input.start_time, input.end_time);
4678
4694
  db.run(`INSERT INTO availability (id, agent_id, org_id, day_of_week, start_time, end_time, exceptions) VALUES (?, ?, ?, ?, ?, ?, ?)`, [id, input.agent_id, input.org_id, input.day_of_week, input.start_time, input.end_time, input.exceptions ? JSON.stringify(input.exceptions) : null]);
4679
4695
  return getAvailability(id, db);
4680
4696
  }
@@ -4695,6 +4711,7 @@ function getAvailabilityForAgent(agentId, orgId, db) {
4695
4711
  }
4696
4712
  function upsertAgentAvailability(agentId, orgId, dayOfWeek, startTime, endTime, db) {
4697
4713
  db = db || getDatabase();
4714
+ assertValidAvailabilityWindow(dayOfWeek, startTime, endTime);
4698
4715
  const existing = db.query("SELECT * FROM availability WHERE agent_id = ? AND org_id = ? AND day_of_week = ?").all(agentId, orgId, dayOfWeek);
4699
4716
  for (const row of existing) {
4700
4717
  db.run(`DELETE FROM availability WHERE id = ?`, [row.id]);
@@ -21319,9 +21319,25 @@ function rowToAvailability(row) {
21319
21319
  updated_at: row.updated_at
21320
21320
  };
21321
21321
  }
21322
+ function parseAvailabilityTime(value) {
21323
+ const match = /^([01]\d|2[0-3]):([0-5]\d)$/.exec(value);
21324
+ if (!match) {
21325
+ throw new RangeError("Availability times must use HH:mm format between 00:00 and 23:59");
21326
+ }
21327
+ return Number(match[1]) * 60 + Number(match[2]);
21328
+ }
21329
+ function assertValidAvailabilityWindow(dayOfWeek, startTime, endTime) {
21330
+ if (!Number.isInteger(dayOfWeek) || dayOfWeek < 0 || dayOfWeek > 6) {
21331
+ throw new RangeError("Availability day_of_week must be an integer from 0 to 6");
21332
+ }
21333
+ if (parseAvailabilityTime(endTime) <= parseAvailabilityTime(startTime)) {
21334
+ throw new RangeError("Availability end_time must be after start_time");
21335
+ }
21336
+ }
21322
21337
  function createAvailability(input, db) {
21323
21338
  db = db || getDatabase();
21324
21339
  const id = crypto.randomUUID().slice(0, 8);
21340
+ assertValidAvailabilityWindow(input.day_of_week, input.start_time, input.end_time);
21325
21341
  db.run(`INSERT INTO availability (id, agent_id, org_id, day_of_week, start_time, end_time, exceptions) VALUES (?, ?, ?, ?, ?, ?, ?)`, [id, input.agent_id, input.org_id, input.day_of_week, input.start_time, input.end_time, input.exceptions ? JSON.stringify(input.exceptions) : null]);
21326
21342
  return getAvailability(id, db);
21327
21343
  }
@@ -21342,6 +21358,7 @@ function getAvailabilityForAgent(agentId, orgId, db) {
21342
21358
  }
21343
21359
  function upsertAgentAvailability(agentId, orgId, dayOfWeek, startTime, endTime, db) {
21344
21360
  db = db || getDatabase();
21361
+ assertValidAvailabilityWindow(dayOfWeek, startTime, endTime);
21345
21362
  const existing = db.query("SELECT * FROM availability WHERE agent_id = ? AND org_id = ? AND day_of_week = ?").all(agentId, orgId, dayOfWeek);
21346
21363
  for (const row of existing) {
21347
21364
  db.run(`DELETE FROM availability WHERE id = ?`, [row.id]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/calendar",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Universal calendar management for AI coding agents - CLI + MCP server + interactive TUI",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",