@hasna/calendar 0.1.7 → 0.1.8
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 +41 -0
- package/dist/db/events.d.ts.map +1 -1
- package/dist/index.js +41 -0
- package/dist/mcp/index.js +42 -0
- package/dist/server/index.js +42 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -3266,9 +3266,47 @@ function rowToEvent(row) {
|
|
|
3266
3266
|
updated_at: row.updated_at
|
|
3267
3267
|
};
|
|
3268
3268
|
}
|
|
3269
|
+
var ISO_DATE_TIME_RE = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,9})?(Z|[+-]\d{2}:\d{2})$/;
|
|
3270
|
+
function parseEventTimestamp(value) {
|
|
3271
|
+
const match = ISO_DATE_TIME_RE.exec(value);
|
|
3272
|
+
if (!match) {
|
|
3273
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
3274
|
+
}
|
|
3275
|
+
const year = Number(match[1]);
|
|
3276
|
+
const month = Number(match[2]);
|
|
3277
|
+
const day = Number(match[3]);
|
|
3278
|
+
const hour = Number(match[4]);
|
|
3279
|
+
const minute = Number(match[5]);
|
|
3280
|
+
const second = Number(match[6]);
|
|
3281
|
+
const offset = match[7];
|
|
3282
|
+
const maxDay = month >= 1 && month <= 12 ? new Date(Date.UTC(year, month, 0)).getUTCDate() : 0;
|
|
3283
|
+
if (month < 1 || month > 12 || day < 1 || day > maxDay || hour > 23 || minute > 59 || second > 59) {
|
|
3284
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
3285
|
+
}
|
|
3286
|
+
if (offset !== "Z") {
|
|
3287
|
+
const offsetHour = Number(offset.slice(1, 3));
|
|
3288
|
+
const offsetMinute = Number(offset.slice(4, 6));
|
|
3289
|
+
if (offsetHour > 23 || offsetMinute > 59) {
|
|
3290
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
3291
|
+
}
|
|
3292
|
+
}
|
|
3293
|
+
const timestamp = Date.parse(value);
|
|
3294
|
+
if (!Number.isFinite(timestamp)) {
|
|
3295
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
3296
|
+
}
|
|
3297
|
+
return timestamp;
|
|
3298
|
+
}
|
|
3299
|
+
function assertEventEndsAfterStart(startAt, endAt) {
|
|
3300
|
+
const start = parseEventTimestamp(startAt);
|
|
3301
|
+
const end = parseEventTimestamp(endAt);
|
|
3302
|
+
if (end <= start) {
|
|
3303
|
+
throw new RangeError("Event end_at must be after start_at");
|
|
3304
|
+
}
|
|
3305
|
+
}
|
|
3269
3306
|
function createEvent2(input, db) {
|
|
3270
3307
|
db = db || getDatabase();
|
|
3271
3308
|
const id = crypto.randomUUID().slice(0, 8);
|
|
3309
|
+
assertEventEndsAfterStart(input.start_at, input.end_at);
|
|
3272
3310
|
db.run(`INSERT INTO events (id, calendar_id, org_id, title, description, location, start_at, end_at, all_day, timezone, status, busy_type, visibility, recurrence_rule, recurrence_exception_dates, source_task_id, created_by, metadata)
|
|
3273
3311
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [id, input.calendar_id, input.org_id, input.title, input.description || null, input.location || null, input.start_at, input.end_at, input.all_day ? 1 : 0, input.timezone || "UTC", input.status || "confirmed", input.busy_type || "busy", input.visibility || "default", input.recurrence_rule || null, input.recurrence_exception_dates ? JSON.stringify(input.recurrence_exception_dates) : null, input.source_task_id || null, input.created_by || null, JSON.stringify(input.metadata || {})]);
|
|
3274
3312
|
return getEvent(id, db);
|
|
@@ -3321,6 +3359,9 @@ function updateEvent(id, input, db) {
|
|
|
3321
3359
|
const existing = getEvent(id, db);
|
|
3322
3360
|
if (!existing)
|
|
3323
3361
|
throw new NotFoundError("Event", id);
|
|
3362
|
+
const startAt = input.start_at ?? existing.start_at;
|
|
3363
|
+
const endAt = input.end_at ?? existing.end_at;
|
|
3364
|
+
assertEventEndsAfterStart(startAt, endAt);
|
|
3324
3365
|
db.run(`UPDATE events SET title = ?, description = ?, location = ?, start_at = ?, end_at = ?, all_day = ?, timezone = ?, status = ?, busy_type = ?, visibility = ?, recurrence_rule = ?, recurrence_exception_dates = ?, source_task_id = ?, metadata = ?, updated_at = datetime('now') WHERE id = ?`, [input.title ?? existing.title, input.description !== undefined ? input.description : existing.description, input.location !== undefined ? input.location : existing.location, input.start_at ?? existing.start_at, input.end_at ?? existing.end_at, input.all_day !== undefined ? input.all_day ? 1 : 0 : existing.all_day ? 1 : 0, input.timezone ?? existing.timezone, input.status ?? existing.status, input.busy_type ?? existing.busy_type, input.visibility ?? existing.visibility, input.recurrence_rule !== undefined ? input.recurrence_rule : existing.recurrence_rule, input.recurrence_exception_dates !== undefined ? input.recurrence_exception_dates ? JSON.stringify(input.recurrence_exception_dates) : null : existing.recurrence_exception_dates ? JSON.stringify(existing.recurrence_exception_dates) : null, input.source_task_id !== undefined ? input.source_task_id : existing.source_task_id, JSON.stringify(input.metadata ?? existing.metadata), id]);
|
|
3325
3366
|
return getEvent(id, db);
|
|
3326
3367
|
}
|
package/dist/db/events.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/db/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/db/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AA0EnF,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,CAYzE;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,IAAI,CAIhE;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,UAAU,CAAC,MAAM,GAAE,gBAAqB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAmBhF;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,CAcrF;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAI9D;AAID,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAWnH;AAED,0FAA0F;AAC1F,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAarH;AAID,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAWlF"}
|
package/dist/index.js
CHANGED
|
@@ -543,9 +543,47 @@ function rowToEvent(row) {
|
|
|
543
543
|
updated_at: row.updated_at
|
|
544
544
|
};
|
|
545
545
|
}
|
|
546
|
+
var ISO_DATE_TIME_RE = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,9})?(Z|[+-]\d{2}:\d{2})$/;
|
|
547
|
+
function parseEventTimestamp(value) {
|
|
548
|
+
const match = ISO_DATE_TIME_RE.exec(value);
|
|
549
|
+
if (!match) {
|
|
550
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
551
|
+
}
|
|
552
|
+
const year = Number(match[1]);
|
|
553
|
+
const month = Number(match[2]);
|
|
554
|
+
const day = Number(match[3]);
|
|
555
|
+
const hour = Number(match[4]);
|
|
556
|
+
const minute = Number(match[5]);
|
|
557
|
+
const second = Number(match[6]);
|
|
558
|
+
const offset = match[7];
|
|
559
|
+
const maxDay = month >= 1 && month <= 12 ? new Date(Date.UTC(year, month, 0)).getUTCDate() : 0;
|
|
560
|
+
if (month < 1 || month > 12 || day < 1 || day > maxDay || hour > 23 || minute > 59 || second > 59) {
|
|
561
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
562
|
+
}
|
|
563
|
+
if (offset !== "Z") {
|
|
564
|
+
const offsetHour = Number(offset.slice(1, 3));
|
|
565
|
+
const offsetMinute = Number(offset.slice(4, 6));
|
|
566
|
+
if (offsetHour > 23 || offsetMinute > 59) {
|
|
567
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
const timestamp = Date.parse(value);
|
|
571
|
+
if (!Number.isFinite(timestamp)) {
|
|
572
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
573
|
+
}
|
|
574
|
+
return timestamp;
|
|
575
|
+
}
|
|
576
|
+
function assertEventEndsAfterStart(startAt, endAt) {
|
|
577
|
+
const start = parseEventTimestamp(startAt);
|
|
578
|
+
const end = parseEventTimestamp(endAt);
|
|
579
|
+
if (end <= start) {
|
|
580
|
+
throw new RangeError("Event end_at must be after start_at");
|
|
581
|
+
}
|
|
582
|
+
}
|
|
546
583
|
function createEvent(input, db) {
|
|
547
584
|
db = db || getDatabase();
|
|
548
585
|
const id = crypto.randomUUID().slice(0, 8);
|
|
586
|
+
assertEventEndsAfterStart(input.start_at, input.end_at);
|
|
549
587
|
db.run(`INSERT INTO events (id, calendar_id, org_id, title, description, location, start_at, end_at, all_day, timezone, status, busy_type, visibility, recurrence_rule, recurrence_exception_dates, source_task_id, created_by, metadata)
|
|
550
588
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [id, input.calendar_id, input.org_id, input.title, input.description || null, input.location || null, input.start_at, input.end_at, input.all_day ? 1 : 0, input.timezone || "UTC", input.status || "confirmed", input.busy_type || "busy", input.visibility || "default", input.recurrence_rule || null, input.recurrence_exception_dates ? JSON.stringify(input.recurrence_exception_dates) : null, input.source_task_id || null, input.created_by || null, JSON.stringify(input.metadata || {})]);
|
|
551
589
|
return getEvent(id, db);
|
|
@@ -598,6 +636,9 @@ function updateEvent(id, input, db) {
|
|
|
598
636
|
const existing = getEvent(id, db);
|
|
599
637
|
if (!existing)
|
|
600
638
|
throw new NotFoundError("Event", id);
|
|
639
|
+
const startAt = input.start_at ?? existing.start_at;
|
|
640
|
+
const endAt = input.end_at ?? existing.end_at;
|
|
641
|
+
assertEventEndsAfterStart(startAt, endAt);
|
|
601
642
|
db.run(`UPDATE events SET title = ?, description = ?, location = ?, start_at = ?, end_at = ?, all_day = ?, timezone = ?, status = ?, busy_type = ?, visibility = ?, recurrence_rule = ?, recurrence_exception_dates = ?, source_task_id = ?, metadata = ?, updated_at = datetime('now') WHERE id = ?`, [input.title ?? existing.title, input.description !== undefined ? input.description : existing.description, input.location !== undefined ? input.location : existing.location, input.start_at ?? existing.start_at, input.end_at ?? existing.end_at, input.all_day !== undefined ? input.all_day ? 1 : 0 : existing.all_day ? 1 : 0, input.timezone ?? existing.timezone, input.status ?? existing.status, input.busy_type ?? existing.busy_type, input.visibility ?? existing.visibility, input.recurrence_rule !== undefined ? input.recurrence_rule : existing.recurrence_rule, input.recurrence_exception_dates !== undefined ? input.recurrence_exception_dates ? JSON.stringify(input.recurrence_exception_dates) : null : existing.recurrence_exception_dates ? JSON.stringify(existing.recurrence_exception_dates) : null, input.source_task_id !== undefined ? input.source_task_id : existing.source_task_id, JSON.stringify(input.metadata ?? existing.metadata), id]);
|
|
602
643
|
return getEvent(id, db);
|
|
603
644
|
}
|
package/dist/mcp/index.js
CHANGED
|
@@ -4448,9 +4448,46 @@ function rowToEvent(row) {
|
|
|
4448
4448
|
updated_at: row.updated_at
|
|
4449
4449
|
};
|
|
4450
4450
|
}
|
|
4451
|
+
function parseEventTimestamp(value) {
|
|
4452
|
+
const match = ISO_DATE_TIME_RE.exec(value);
|
|
4453
|
+
if (!match) {
|
|
4454
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
4455
|
+
}
|
|
4456
|
+
const year = Number(match[1]);
|
|
4457
|
+
const month = Number(match[2]);
|
|
4458
|
+
const day = Number(match[3]);
|
|
4459
|
+
const hour = Number(match[4]);
|
|
4460
|
+
const minute = Number(match[5]);
|
|
4461
|
+
const second = Number(match[6]);
|
|
4462
|
+
const offset = match[7];
|
|
4463
|
+
const maxDay = month >= 1 && month <= 12 ? new Date(Date.UTC(year, month, 0)).getUTCDate() : 0;
|
|
4464
|
+
if (month < 1 || month > 12 || day < 1 || day > maxDay || hour > 23 || minute > 59 || second > 59) {
|
|
4465
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
4466
|
+
}
|
|
4467
|
+
if (offset !== "Z") {
|
|
4468
|
+
const offsetHour = Number(offset.slice(1, 3));
|
|
4469
|
+
const offsetMinute = Number(offset.slice(4, 6));
|
|
4470
|
+
if (offsetHour > 23 || offsetMinute > 59) {
|
|
4471
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
4472
|
+
}
|
|
4473
|
+
}
|
|
4474
|
+
const timestamp = Date.parse(value);
|
|
4475
|
+
if (!Number.isFinite(timestamp)) {
|
|
4476
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
4477
|
+
}
|
|
4478
|
+
return timestamp;
|
|
4479
|
+
}
|
|
4480
|
+
function assertEventEndsAfterStart(startAt, endAt) {
|
|
4481
|
+
const start = parseEventTimestamp(startAt);
|
|
4482
|
+
const end = parseEventTimestamp(endAt);
|
|
4483
|
+
if (end <= start) {
|
|
4484
|
+
throw new RangeError("Event end_at must be after start_at");
|
|
4485
|
+
}
|
|
4486
|
+
}
|
|
4451
4487
|
function createEvent(input, db) {
|
|
4452
4488
|
db = db || getDatabase();
|
|
4453
4489
|
const id = crypto.randomUUID().slice(0, 8);
|
|
4490
|
+
assertEventEndsAfterStart(input.start_at, input.end_at);
|
|
4454
4491
|
db.run(`INSERT INTO events (id, calendar_id, org_id, title, description, location, start_at, end_at, all_day, timezone, status, busy_type, visibility, recurrence_rule, recurrence_exception_dates, source_task_id, created_by, metadata)
|
|
4455
4492
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [id, input.calendar_id, input.org_id, input.title, input.description || null, input.location || null, input.start_at, input.end_at, input.all_day ? 1 : 0, input.timezone || "UTC", input.status || "confirmed", input.busy_type || "busy", input.visibility || "default", input.recurrence_rule || null, input.recurrence_exception_dates ? JSON.stringify(input.recurrence_exception_dates) : null, input.source_task_id || null, input.created_by || null, JSON.stringify(input.metadata || {})]);
|
|
4456
4493
|
return getEvent(id, db);
|
|
@@ -4503,6 +4540,9 @@ function updateEvent(id, input, db) {
|
|
|
4503
4540
|
const existing = getEvent(id, db);
|
|
4504
4541
|
if (!existing)
|
|
4505
4542
|
throw new NotFoundError("Event", id);
|
|
4543
|
+
const startAt = input.start_at ?? existing.start_at;
|
|
4544
|
+
const endAt = input.end_at ?? existing.end_at;
|
|
4545
|
+
assertEventEndsAfterStart(startAt, endAt);
|
|
4506
4546
|
db.run(`UPDATE events SET title = ?, description = ?, location = ?, start_at = ?, end_at = ?, all_day = ?, timezone = ?, status = ?, busy_type = ?, visibility = ?, recurrence_rule = ?, recurrence_exception_dates = ?, source_task_id = ?, metadata = ?, updated_at = datetime('now') WHERE id = ?`, [input.title ?? existing.title, input.description !== undefined ? input.description : existing.description, input.location !== undefined ? input.location : existing.location, input.start_at ?? existing.start_at, input.end_at ?? existing.end_at, input.all_day !== undefined ? input.all_day ? 1 : 0 : existing.all_day ? 1 : 0, input.timezone ?? existing.timezone, input.status ?? existing.status, input.busy_type ?? existing.busy_type, input.visibility ?? existing.visibility, input.recurrence_rule !== undefined ? input.recurrence_rule : existing.recurrence_rule, input.recurrence_exception_dates !== undefined ? input.recurrence_exception_dates ? JSON.stringify(input.recurrence_exception_dates) : null : existing.recurrence_exception_dates ? JSON.stringify(existing.recurrence_exception_dates) : null, input.source_task_id !== undefined ? input.source_task_id : existing.source_task_id, JSON.stringify(input.metadata ?? existing.metadata), id]);
|
|
4507
4547
|
return getEvent(id, db);
|
|
4508
4548
|
}
|
|
@@ -4527,9 +4567,11 @@ function searchEvents(query, orgId, db) {
|
|
|
4527
4567
|
ORDER BY e.start_at`).all(query, ...orgId ? [orgId] : []);
|
|
4528
4568
|
return rows.map(rowToEvent);
|
|
4529
4569
|
}
|
|
4570
|
+
var ISO_DATE_TIME_RE;
|
|
4530
4571
|
var init_events = __esm(() => {
|
|
4531
4572
|
init_database();
|
|
4532
4573
|
init_types2();
|
|
4574
|
+
ISO_DATE_TIME_RE = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,9})?(Z|[+-]\d{2}:\d{2})$/;
|
|
4533
4575
|
});
|
|
4534
4576
|
|
|
4535
4577
|
// src/db/attendees.ts
|
package/dist/server/index.js
CHANGED
|
@@ -21095,9 +21095,46 @@ function rowToEvent(row) {
|
|
|
21095
21095
|
updated_at: row.updated_at
|
|
21096
21096
|
};
|
|
21097
21097
|
}
|
|
21098
|
+
function parseEventTimestamp(value) {
|
|
21099
|
+
const match = ISO_DATE_TIME_RE.exec(value);
|
|
21100
|
+
if (!match) {
|
|
21101
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
21102
|
+
}
|
|
21103
|
+
const year = Number(match[1]);
|
|
21104
|
+
const month = Number(match[2]);
|
|
21105
|
+
const day = Number(match[3]);
|
|
21106
|
+
const hour = Number(match[4]);
|
|
21107
|
+
const minute = Number(match[5]);
|
|
21108
|
+
const second = Number(match[6]);
|
|
21109
|
+
const offset = match[7];
|
|
21110
|
+
const maxDay = month >= 1 && month <= 12 ? new Date(Date.UTC(year, month, 0)).getUTCDate() : 0;
|
|
21111
|
+
if (month < 1 || month > 12 || day < 1 || day > maxDay || hour > 23 || minute > 59 || second > 59) {
|
|
21112
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
21113
|
+
}
|
|
21114
|
+
if (offset !== "Z") {
|
|
21115
|
+
const offsetHour = Number(offset.slice(1, 3));
|
|
21116
|
+
const offsetMinute = Number(offset.slice(4, 6));
|
|
21117
|
+
if (offsetHour > 23 || offsetMinute > 59) {
|
|
21118
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
21119
|
+
}
|
|
21120
|
+
}
|
|
21121
|
+
const timestamp = Date.parse(value);
|
|
21122
|
+
if (!Number.isFinite(timestamp)) {
|
|
21123
|
+
throw new RangeError("Event start_at and end_at must be valid ISO 8601 date-time strings");
|
|
21124
|
+
}
|
|
21125
|
+
return timestamp;
|
|
21126
|
+
}
|
|
21127
|
+
function assertEventEndsAfterStart(startAt, endAt) {
|
|
21128
|
+
const start = parseEventTimestamp(startAt);
|
|
21129
|
+
const end = parseEventTimestamp(endAt);
|
|
21130
|
+
if (end <= start) {
|
|
21131
|
+
throw new RangeError("Event end_at must be after start_at");
|
|
21132
|
+
}
|
|
21133
|
+
}
|
|
21098
21134
|
function createEvent(input, db) {
|
|
21099
21135
|
db = db || getDatabase();
|
|
21100
21136
|
const id = crypto.randomUUID().slice(0, 8);
|
|
21137
|
+
assertEventEndsAfterStart(input.start_at, input.end_at);
|
|
21101
21138
|
db.run(`INSERT INTO events (id, calendar_id, org_id, title, description, location, start_at, end_at, all_day, timezone, status, busy_type, visibility, recurrence_rule, recurrence_exception_dates, source_task_id, created_by, metadata)
|
|
21102
21139
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [id, input.calendar_id, input.org_id, input.title, input.description || null, input.location || null, input.start_at, input.end_at, input.all_day ? 1 : 0, input.timezone || "UTC", input.status || "confirmed", input.busy_type || "busy", input.visibility || "default", input.recurrence_rule || null, input.recurrence_exception_dates ? JSON.stringify(input.recurrence_exception_dates) : null, input.source_task_id || null, input.created_by || null, JSON.stringify(input.metadata || {})]);
|
|
21103
21140
|
return getEvent(id, db);
|
|
@@ -21150,6 +21187,9 @@ function updateEvent(id, input, db) {
|
|
|
21150
21187
|
const existing = getEvent(id, db);
|
|
21151
21188
|
if (!existing)
|
|
21152
21189
|
throw new NotFoundError("Event", id);
|
|
21190
|
+
const startAt = input.start_at ?? existing.start_at;
|
|
21191
|
+
const endAt = input.end_at ?? existing.end_at;
|
|
21192
|
+
assertEventEndsAfterStart(startAt, endAt);
|
|
21153
21193
|
db.run(`UPDATE events SET title = ?, description = ?, location = ?, start_at = ?, end_at = ?, all_day = ?, timezone = ?, status = ?, busy_type = ?, visibility = ?, recurrence_rule = ?, recurrence_exception_dates = ?, source_task_id = ?, metadata = ?, updated_at = datetime('now') WHERE id = ?`, [input.title ?? existing.title, input.description !== undefined ? input.description : existing.description, input.location !== undefined ? input.location : existing.location, input.start_at ?? existing.start_at, input.end_at ?? existing.end_at, input.all_day !== undefined ? input.all_day ? 1 : 0 : existing.all_day ? 1 : 0, input.timezone ?? existing.timezone, input.status ?? existing.status, input.busy_type ?? existing.busy_type, input.visibility ?? existing.visibility, input.recurrence_rule !== undefined ? input.recurrence_rule : existing.recurrence_rule, input.recurrence_exception_dates !== undefined ? input.recurrence_exception_dates ? JSON.stringify(input.recurrence_exception_dates) : null : existing.recurrence_exception_dates ? JSON.stringify(existing.recurrence_exception_dates) : null, input.source_task_id !== undefined ? input.source_task_id : existing.source_task_id, JSON.stringify(input.metadata ?? existing.metadata), id]);
|
|
21154
21194
|
return getEvent(id, db);
|
|
21155
21195
|
}
|
|
@@ -21174,9 +21214,11 @@ function searchEvents(query, orgId, db) {
|
|
|
21174
21214
|
ORDER BY e.start_at`).all(query, ...orgId ? [orgId] : []);
|
|
21175
21215
|
return rows.map(rowToEvent);
|
|
21176
21216
|
}
|
|
21217
|
+
var ISO_DATE_TIME_RE;
|
|
21177
21218
|
var init_events = __esm(() => {
|
|
21178
21219
|
init_database();
|
|
21179
21220
|
init_types3();
|
|
21221
|
+
ISO_DATE_TIME_RE = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,9})?(Z|[+-]\d{2}:\d{2})$/;
|
|
21180
21222
|
});
|
|
21181
21223
|
|
|
21182
21224
|
// src/db/attendees.ts
|