slotlock 0.2.0 → 0.5.0
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/CHANGELOG.md +582 -0
- package/CONTRIBUTING.md +35 -8
- package/GOVERNANCE.md +4 -2
- package/MAINTAINERS.md +3 -2
- package/NOTICE +4 -4
- package/README.md +498 -65
- package/SECURITY.md +31 -2
- package/SPEC.md +142 -15
- package/agent-server.d.ts +62 -10
- package/agent-server.js +577 -105
- package/agent-store-backend.d.ts +12 -0
- package/agent-store-backend.js +1115 -55
- package/api-keys.d.ts +11 -3
- package/api-keys.js +29 -6
- package/application-api.d.ts +35 -1
- package/application-api.js +683 -12
- package/booking-rules.d.ts +84 -0
- package/booking-rules.js +149 -0
- package/config.d.ts +112 -0
- package/config.js +225 -0
- package/dashboard.d.ts +67 -5
- package/dashboard.js +1012 -140
- package/ddl.d.ts +45 -3
- package/ddl.js +1124 -13
- package/engine.d.ts +5 -0
- package/engine.js +23 -6
- package/event-feed.d.ts +178 -0
- package/event-feed.js +435 -0
- package/event-schema.d.ts +59 -0
- package/event-schema.js +85 -0
- package/ical-worker-thread.js +4 -2
- package/ical-worker.d.ts +8 -5
- package/ical-worker.js +9 -2
- package/index.d.ts +12 -6
- package/index.js +9 -4
- package/interop.d.ts +117 -0
- package/interop.js +356 -0
- package/maintenance.d.ts +27 -5
- package/maintenance.js +92 -28
- package/mcp-app.d.ts +7 -1
- package/mcp-app.js +259 -40
- package/metrics.d.ts +24 -0
- package/metrics.js +167 -0
- package/node-server.d.ts +9 -1
- package/node-server.js +7 -2
- package/openapi.json +10970 -0
- package/package.json +3 -2
- package/rate-limit.d.ts +80 -0
- package/rate-limit.js +741 -0
- package/rest-api.d.ts +22 -0
- package/rest-api.js +166 -11
- package/rules.js +6 -3
- package/self-host.d.ts +45 -8
- package/self-host.js +616 -46
- package/slotlock-manifest.schema.json +7 -1
- package/slotlock.manifest.json +8 -2
- package/store.d.ts +647 -28
- package/store.js +2982 -327
- package/sync.d.ts +43 -2
- package/sync.js +1515 -323
- package/timezone.d.ts +58 -3
- package/timezone.js +249 -20
- package/types.d.ts +300 -9
- package/types.js +0 -2
- package/webhooks.d.ts +91 -0
- package/webhooks.js +300 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const SLOTLOCK_EVENT_OUTPUT: z.ZodObject<{
|
|
3
|
+
id: z.ZodString;
|
|
4
|
+
resource_id: z.ZodString;
|
|
5
|
+
starts_at: z.ZodString;
|
|
6
|
+
ends_at: z.ZodString;
|
|
7
|
+
timezone: z.ZodString;
|
|
8
|
+
title: z.ZodNullable<z.ZodString>;
|
|
9
|
+
description: z.ZodNullable<z.ZodString>;
|
|
10
|
+
location: z.ZodNullable<z.ZodString>;
|
|
11
|
+
organizer: z.ZodNullable<z.ZodObject<{
|
|
12
|
+
address: z.ZodString;
|
|
13
|
+
name: z.ZodNullable<z.ZodString>;
|
|
14
|
+
}, z.core.$strict>>;
|
|
15
|
+
attendees: z.ZodArray<z.ZodObject<{
|
|
16
|
+
address: z.ZodString;
|
|
17
|
+
name: z.ZodNullable<z.ZodString>;
|
|
18
|
+
role: z.ZodEnum<{
|
|
19
|
+
chair: "chair";
|
|
20
|
+
non_participant: "non_participant";
|
|
21
|
+
optional: "optional";
|
|
22
|
+
required: "required";
|
|
23
|
+
}>;
|
|
24
|
+
participation_status: z.ZodEnum<{
|
|
25
|
+
accepted: "accepted";
|
|
26
|
+
declined: "declined";
|
|
27
|
+
delegated: "delegated";
|
|
28
|
+
needs_action: "needs_action";
|
|
29
|
+
tentative: "tentative";
|
|
30
|
+
}>;
|
|
31
|
+
rsvp: z.ZodBoolean;
|
|
32
|
+
}, z.core.$strict>>;
|
|
33
|
+
reminders: z.ZodArray<z.ZodObject<{
|
|
34
|
+
minutes_before: z.ZodNumber;
|
|
35
|
+
channel: z.ZodEnum<{
|
|
36
|
+
display: "display";
|
|
37
|
+
email: "email";
|
|
38
|
+
}>;
|
|
39
|
+
}, z.core.$strict>>;
|
|
40
|
+
status: z.ZodEnum<{
|
|
41
|
+
cancelled: "cancelled";
|
|
42
|
+
confirmed: "confirmed";
|
|
43
|
+
tentative: "tentative";
|
|
44
|
+
}>;
|
|
45
|
+
transparency: z.ZodEnum<{
|
|
46
|
+
opaque: "opaque";
|
|
47
|
+
transparent: "transparent";
|
|
48
|
+
}>;
|
|
49
|
+
sequence: z.ZodNumber;
|
|
50
|
+
revision: z.ZodNumber;
|
|
51
|
+
recurrence_rule: z.ZodNullable<z.ZodString>;
|
|
52
|
+
recurrence_exceptions: z.ZodArray<z.ZodObject<{
|
|
53
|
+
recurrence_id: z.ZodString;
|
|
54
|
+
cancelled: z.ZodBoolean;
|
|
55
|
+
starts_at: z.ZodNullable<z.ZodString>;
|
|
56
|
+
ends_at: z.ZodNullable<z.ZodString>;
|
|
57
|
+
}, z.core.$strict>>;
|
|
58
|
+
recurrence_id: z.ZodNullable<z.ZodString>;
|
|
59
|
+
}, z.core.$strict>;
|
package/event-schema.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// A calendar event as the event tools return it, and as the application API returns any of a
|
|
2
|
+
// tenant's events. Its own module because both the agent server and the application API describe
|
|
3
|
+
// events with it, and the application API imports nothing from the agent server at runtime (the
|
|
4
|
+
// agent server imports it, so the reverse would be a cycle).
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
const DATE_TIME = z.string().datetime({ offset: true });
|
|
7
|
+
const RESOURCE_ID = z.string().trim().min(1).max(200);
|
|
8
|
+
const EVENT_ID = z.string().trim().min(1).max(500);
|
|
9
|
+
const REVISION = z.number().int().positive();
|
|
10
|
+
// Output bounds mirror the trusted store's byte ceilings. A value admitted by a UTF-8 byte
|
|
11
|
+
// ceiling can never exceed that many UTF-16 code units, so every valid stored/provider event is
|
|
12
|
+
// serializable without truncating recurrence semantics or calendar identities.
|
|
13
|
+
const TRUSTED_SUMMARY_OUTPUT_MAX = 4_096;
|
|
14
|
+
const TRUSTED_TEXT_OUTPUT_MAX = 16_384;
|
|
15
|
+
const TRUSTED_PERSON_NAME_OUTPUT_MAX = 1_024;
|
|
16
|
+
const TRUSTED_RECURRENCE_EXCEPTION_OUTPUT_MAX = 1_000;
|
|
17
|
+
const TRUSTED_REMINDER_MINUTES_OUTPUT_MAX = 366 * 24 * 60;
|
|
18
|
+
// The grammar the store keeps an address in (normalizeEmail in sync.ts), so every stored one can be
|
|
19
|
+
// returned: an address from an imported feed need not be one z.email() takes (ops@localhost).
|
|
20
|
+
const STORED_ADDRESS = z
|
|
21
|
+
.string()
|
|
22
|
+
.min(3)
|
|
23
|
+
.max(320)
|
|
24
|
+
.refine((value) => /^[^\s@]+@[^\s@]+$/.test(value), {
|
|
25
|
+
message: 'must be one @ between characters other than spaces',
|
|
26
|
+
});
|
|
27
|
+
const ORGANIZER = z
|
|
28
|
+
.object({
|
|
29
|
+
address: STORED_ADDRESS,
|
|
30
|
+
name: z.string().trim().max(TRUSTED_PERSON_NAME_OUTPUT_MAX).nullable(),
|
|
31
|
+
})
|
|
32
|
+
.strict();
|
|
33
|
+
const ATTENDEE = z
|
|
34
|
+
.object({
|
|
35
|
+
address: STORED_ADDRESS,
|
|
36
|
+
name: z.string().trim().max(TRUSTED_PERSON_NAME_OUTPUT_MAX).nullable(),
|
|
37
|
+
role: z.enum(['chair', 'required', 'optional', 'non_participant']),
|
|
38
|
+
participation_status: z.enum([
|
|
39
|
+
'needs_action',
|
|
40
|
+
'accepted',
|
|
41
|
+
'declined',
|
|
42
|
+
'tentative',
|
|
43
|
+
'delegated',
|
|
44
|
+
]),
|
|
45
|
+
rsvp: z.boolean(),
|
|
46
|
+
})
|
|
47
|
+
.strict();
|
|
48
|
+
const REMINDER = z
|
|
49
|
+
.object({
|
|
50
|
+
minutes_before: z.number().int().min(0).max(TRUSTED_REMINDER_MINUTES_OUTPUT_MAX),
|
|
51
|
+
channel: z.enum(['display', 'email']),
|
|
52
|
+
})
|
|
53
|
+
.strict();
|
|
54
|
+
const RECURRENCE_EXCEPTION = z
|
|
55
|
+
.object({
|
|
56
|
+
recurrence_id: DATE_TIME,
|
|
57
|
+
cancelled: z.boolean(),
|
|
58
|
+
starts_at: DATE_TIME.nullable(),
|
|
59
|
+
ends_at: DATE_TIME.nullable(),
|
|
60
|
+
})
|
|
61
|
+
.strict();
|
|
62
|
+
export const SLOTLOCK_EVENT_OUTPUT = z
|
|
63
|
+
.object({
|
|
64
|
+
id: EVENT_ID,
|
|
65
|
+
resource_id: RESOURCE_ID,
|
|
66
|
+
starts_at: DATE_TIME,
|
|
67
|
+
ends_at: DATE_TIME,
|
|
68
|
+
timezone: z.string().min(1).max(100),
|
|
69
|
+
title: z.string().max(TRUSTED_SUMMARY_OUTPUT_MAX).nullable(),
|
|
70
|
+
description: z.string().max(TRUSTED_TEXT_OUTPUT_MAX).nullable(),
|
|
71
|
+
location: z.string().max(TRUSTED_TEXT_OUTPUT_MAX).nullable(),
|
|
72
|
+
organizer: ORGANIZER.nullable(),
|
|
73
|
+
attendees: z.array(ATTENDEE).max(100),
|
|
74
|
+
reminders: z.array(REMINDER).max(20),
|
|
75
|
+
status: z.enum(['tentative', 'confirmed', 'cancelled']),
|
|
76
|
+
transparency: z.enum(['opaque', 'transparent']),
|
|
77
|
+
sequence: z.number().int().nonnegative(),
|
|
78
|
+
revision: REVISION,
|
|
79
|
+
recurrence_rule: z.string().max(TRUSTED_SUMMARY_OUTPUT_MAX).nullable(),
|
|
80
|
+
recurrence_exceptions: z
|
|
81
|
+
.array(RECURRENCE_EXCEPTION)
|
|
82
|
+
.max(TRUSTED_RECURRENCE_EXCEPTION_OUTPUT_MAX),
|
|
83
|
+
recurrence_id: DATE_TIME.nullable(),
|
|
84
|
+
})
|
|
85
|
+
.strict();
|
package/ical-worker-thread.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// One worker of createICalendarWorkerPool: reads the feeds it is sent with the ordinary parsers and
|
|
2
2
|
// posts back what they return, or the code of the CalendarContractError they throw.
|
|
3
3
|
import { parentPort } from 'node:worker_threads';
|
|
4
|
-
import { CalendarContractError, CalendarExpansionLimitError, parseICalendarChanges, parseTrustedICalendarEvents, } from './sync.js';
|
|
4
|
+
import { CalendarContractError, CalendarExpansionLimitError, parseICalendarChanges, parseICalendarFeed, parseTrustedICalendarEvents, } from './sync.js';
|
|
5
5
|
const port = parentPort;
|
|
6
6
|
if (!port)
|
|
7
7
|
throw new Error('slotlock: ical-worker-thread runs only as a worker thread');
|
|
@@ -10,7 +10,9 @@ port.on('message', (request) => {
|
|
|
10
10
|
try {
|
|
11
11
|
const value = request.op === 'changes'
|
|
12
12
|
? parseICalendarChanges(request.input, request.calendarTimezone, request.window)
|
|
13
|
-
:
|
|
13
|
+
: request.op === 'feed'
|
|
14
|
+
? parseICalendarFeed(request.input, request.calendarTimezone, request.window)
|
|
15
|
+
: parseTrustedICalendarEvents(request.input, request.calendarTimezone);
|
|
14
16
|
reply = { id: request.id, ok: true, value };
|
|
15
17
|
}
|
|
16
18
|
catch (error) {
|
package/ical-worker.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { CalendarContractError, type ExternalCalendarChange, type ICalendarExpansionWindow } from './sync.js';
|
|
1
|
+
import { CalendarContractError, type ExternalCalendarChange, type ICalendarExpansionWindow, type ICalendarFeedRead } from './sync.js';
|
|
2
2
|
import type { TrustedICalendarEvent } from './types.js';
|
|
3
3
|
/** What the pool posts to a worker. */
|
|
4
4
|
export type ICalendarWorkerRequest = {
|
|
5
5
|
id: number;
|
|
6
|
-
op: 'changes';
|
|
6
|
+
op: 'changes' | 'feed';
|
|
7
7
|
input: string;
|
|
8
8
|
calendarTimezone: string | undefined;
|
|
9
9
|
window: ICalendarExpansionWindow | undefined;
|
|
@@ -29,8 +29,8 @@ export interface ICalendarWorkerPoolOptions {
|
|
|
29
29
|
size?: number;
|
|
30
30
|
/**
|
|
31
31
|
* How long one parse may run on its worker, in ms, before the worker is stopped and the feed
|
|
32
|
-
* refused (CalendarExpansionLimitError), 100-60,000. Defaults to 3,000:
|
|
33
|
-
*
|
|
32
|
+
* refused (CalendarExpansionLimitError), 100-60,000. Defaults to 3,000: several times what the
|
|
33
|
+
* parser's step budget takes, with room for a new worker to start.
|
|
34
34
|
*/
|
|
35
35
|
deadlineMs?: number;
|
|
36
36
|
/** Parses that may wait for a worker, 0-10,000; more are refused at once. Defaults to 64. */
|
|
@@ -46,6 +46,8 @@ export interface ICalendarWorkerPoolOptions {
|
|
|
46
46
|
export interface ICalendarWorkerPool {
|
|
47
47
|
/** `parseICalendarChanges`, run on a worker. */
|
|
48
48
|
parseICalendarChanges(input: string, calendarTimezone?: string, expansionWindow?: ICalendarExpansionWindow): Promise<ExternalCalendarChange[]>;
|
|
49
|
+
/** `parseICalendarFeed`, run on a worker. */
|
|
50
|
+
parseICalendarFeed(input: string, calendarTimezone?: string, expansionWindow?: ICalendarExpansionWindow): Promise<ICalendarFeedRead>;
|
|
49
51
|
/** `parseTrustedICalendarEvents`, run on a worker. */
|
|
50
52
|
parseTrustedICalendarEvents(input: string, calendarTimezone?: string): Promise<TrustedICalendarEvent[]>;
|
|
51
53
|
/** Refuse waiting parses and stop every worker. */
|
|
@@ -63,7 +65,8 @@ export declare class ICalendarWorkerPoolClosedError extends Error {
|
|
|
63
65
|
}
|
|
64
66
|
/**
|
|
65
67
|
* A pool of worker threads that read untrusted iCalendar for the calling thread. Results and
|
|
66
|
-
* errors are those of `parseICalendarChanges
|
|
68
|
+
* errors are those of `parseICalendarChanges`, `parseICalendarFeed` and
|
|
69
|
+
* `parseTrustedICalendarEvents` (the same
|
|
67
70
|
* `CalendarContractError` codes), plus CalendarExpansionLimitError when a worker passes its
|
|
68
71
|
* deadline or its heap, ICalendarWorkerBusyError when the queue is full, and
|
|
69
72
|
* ICalendarWorkerPoolClosedError after `close()`. Idle workers do not keep the process alive.
|
package/ical-worker.js
CHANGED
|
@@ -31,7 +31,8 @@ function workerFailure(error) {
|
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
33
|
* A pool of worker threads that read untrusted iCalendar for the calling thread. Results and
|
|
34
|
-
* errors are those of `parseICalendarChanges
|
|
34
|
+
* errors are those of `parseICalendarChanges`, `parseICalendarFeed` and
|
|
35
|
+
* `parseTrustedICalendarEvents` (the same
|
|
35
36
|
* `CalendarContractError` codes), plus CalendarExpansionLimitError when a worker passes its
|
|
36
37
|
* deadline or its heap, ICalendarWorkerBusyError when the queue is full, and
|
|
37
38
|
* ICalendarWorkerPoolClosedError after `close()`. Idle workers do not keep the process alive.
|
|
@@ -134,7 +135,7 @@ export function createICalendarWorkerPool(options = {}) {
|
|
|
134
135
|
if (request.calendarTimezone !== undefined && typeof request.calendarTimezone !== 'string') {
|
|
135
136
|
throw new CalendarContractError('invalid_icalendar');
|
|
136
137
|
}
|
|
137
|
-
if (request.op
|
|
138
|
+
if (request.op !== 'trusted' &&
|
|
138
139
|
request.window !== undefined &&
|
|
139
140
|
!(request.window?.start instanceof Date && request.window.end instanceof Date)) {
|
|
140
141
|
throw new CalendarContractError('invalid_icalendar');
|
|
@@ -172,6 +173,12 @@ export function createICalendarWorkerPool(options = {}) {
|
|
|
172
173
|
window,
|
|
173
174
|
}));
|
|
174
175
|
},
|
|
176
|
+
async parseICalendarFeed(input, calendarTimezone, expansionWindow) {
|
|
177
|
+
const window = expansionWindow
|
|
178
|
+
? { start: expansionWindow.start, end: expansionWindow.end }
|
|
179
|
+
: undefined;
|
|
180
|
+
return (await run({ op: 'feed', input, calendarTimezone, window }));
|
|
181
|
+
},
|
|
175
182
|
async parseTrustedICalendarEvents(input, calendarTimezone) {
|
|
176
183
|
return (await run({ op: 'trusted', input, calendarTimezone }));
|
|
177
184
|
},
|
package/index.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
/// <reference types="node" preserve="true" />
|
|
2
2
|
export { findNextAvailable, mergeIntervals, subtractBusy } from './engine.js';
|
|
3
|
+
export { type SlotlockBookingRule, type SlotlockBookingRules, bookingRuleBroken, bookingSearch, nextStepStart, parseBookingRules, } from './booking-rules.js';
|
|
4
|
+
export { type CreateWebhookEndpointResult, type ListChangesResult, SLOTLOCK_CHANGE_RETENTION_DAYS, SLOTLOCK_CHANGE_TYPES, SLOTLOCK_MAX_WEBHOOK_ENDPOINTS, SLOTLOCK_WEBHOOK_FAILING_LIMIT_MS, type SlotlockChange, type SlotlockChangeType, type SlotlockEventFeed, type SlotlockWebhookClaim, type SlotlockWebhookEndpoint, } from './event-feed.js';
|
|
5
|
+
export { type SlotlockCloudEvent, type SlotlockWebhookPassResult, type SlotlockWebhookResponse, type SlotlockWebhookScheduler, type SlotlockWebhookSender, createSlotlockWebhookSender, deliverSlotlockWebhooks, isPrivateAddress, signSlotlockWebhook, slotlockCloudEvent, slotlockWebhookRetryDelayMs, startSlotlockWebhookDelivery, } from './webhooks.js';
|
|
6
|
+
export { type SlotlockMetrics, createSlotlockMetrics } from './metrics.js';
|
|
3
7
|
export { expandRules } from './rules.js';
|
|
4
8
|
export { availabilityRuleProblem, parseAvailabilityRules, rulesToWeeklyHours, SLOTLOCK_MAX_AVAILABILITY_RULES, weeklyHoursToRules, } from './weekly-hours.js';
|
|
5
9
|
export type { HoursWindow, Weekday, WeeklyHours } from './weekly-hours.js';
|
|
10
|
+
export { emitVAvailability, parseVAvailability, recurrenceRuleFromRRule, SLOTLOCK_MAX_VAVAILABILITY_CHARACTERS, toJSCalendarEvent, } from './interop.js';
|
|
11
|
+
export type { EmitVAvailabilityOptions, JSCalendarAlert, JSCalendarEvent, JSCalendarParticipant, JSCalendarRecurrenceRule, ParsedVAvailability, } from './interop.js';
|
|
6
12
|
export { createTimeZoneConverter, zonedCalendarDate, zonedDateTimeToUtc, zonedWallTime, } from './timezone.js';
|
|
7
13
|
export type { LocalDateTime, TimeZoneConverter, ZonedCalendarDate, ZonedWallTime, } from './timezone.js';
|
|
8
14
|
export { createSlotlockAgentServer, clientSupportsSlotlockMcpApp, invokeSlotlockAgentOperation, isSlotlockAgentOperation, slotlockAgentTools, slotlockApplicationOperations, slotlockOpenApi, slotlockCalendarResourceUri, slotlockMcpToolResult, parseSlotlockA2ATimestamp, resolveSlotlockAgentOperation, slotlockAgentOperationScope, SLOTLOCK_A2A_PROTOCOL_VERSION, SLOTLOCK_A2A_TASK_PAGE_SIZE, SLOTLOCK_A2A_TASK_STATES, SLOTLOCK_AGENT_OPERATION_LEGACY_NAMES, SLOTLOCK_AGENT_SERVER_VERSION, SLOTLOCK_MCP_LEGACY_PROTOCOL_VERSION, SLOTLOCK_MCP_PROTOCOL_VERSION, SLOTLOCK_MCP_RATE_LIMITED_ERROR_CODE, SLOTLOCK_MCP_RESOURCE_URI_TEMPLATE, SLOTLOCK_MCP_SUPPORTED_PROTOCOL_VERSIONS, SLOTLOCK_MCP_APP_HTML, SLOTLOCK_MCP_APP_MIME_TYPE, SLOTLOCK_MCP_APP_RESOURCE, SLOTLOCK_MCP_APP_RESOURCE_URI, SLOTLOCK_MCP_APPS_EXTENSION, SlotlockAgentOperationError, } from './agent-server.js';
|
|
@@ -16,13 +22,13 @@ export type { SlotlockApplicationBackend, SlotlockApplicationInvocationContext,
|
|
|
16
22
|
export { maintainSlotlockTenant, startSlotlockMaintenance, withSlotlockMaintenanceLock, } from './maintenance.js';
|
|
17
23
|
export type { SlotlockMaintenanceResult, SlotlockMaintenanceScheduler, SlotlockMaintenanceSchedulerOptions, } from './maintenance.js';
|
|
18
24
|
export { createSlotlockApiKeyAuthenticator, createSlotlockApiKeyStore, generateSlotlockApiKey, isSlotlockApiKey, slotlockApiKeyDigest, SLOTLOCK_API_KEY_ACTIVE_LIMIT, SLOTLOCK_API_KEY_MAX_LIFETIME_DAYS, SLOTLOCK_API_KEY_PREFIX, SLOTLOCK_API_KEY_RETAINED_LIMIT, SLOTLOCK_API_KEY_SCOPES, } from './api-keys.js';
|
|
19
|
-
export { createSlotlockDashboard, createSlotlockDashboardResources, createSlotlockDashboardState, createSlotlockMemoryDashboardState, SLOTLOCK_DASHBOARD_MAX_RESOURCES, } from './dashboard.js';
|
|
25
|
+
export { createSlotlockDashboard, createSlotlockDashboardResources, createSlotlockAcceptanceRecords, createSlotlockDashboardState, createSlotlockMemoryDashboardState, SLOTLOCK_DASHBOARD_MAX_RESOURCES, } from './dashboard.js';
|
|
20
26
|
export type { SlotlockDashboard, SlotlockDashboardOptions, SlotlockDashboardResources, SlotlockDashboardState, } from './dashboard.js';
|
|
21
27
|
export type { CreateSlotlockApiKeyInput, SlotlockApiKey, SlotlockApiKeyAuthenticatorOptions, SlotlockApiKeyIdentity, SlotlockApiKeyScope, SlotlockApiKeyStore, } from './api-keys.js';
|
|
22
28
|
export { ICalendarWorkerBusyError, ICalendarWorkerPoolClosedError, createICalendarWorkerPool, } from './ical-worker.js';
|
|
23
29
|
export type { ICalendarWorkerPool, ICalendarWorkerPoolOptions } from './ical-worker.js';
|
|
24
|
-
export { CalendarContractError, CalendarExpansionLimitError, emitICalendar, emitITipCalendar, expandCalendarEventOccurrences, normalizeCalendarEventContent, normalizeExternalCalendarChange, parseICalendarChanges, parseTrustedICalendarEvents, } from './sync.js';
|
|
25
|
-
export type { ExternalCalendarChange, ExternalCalendarChangeInput, ExternalCalendarStatus, ICalendarEvent, ICalendarExpansionWindow, ITipMethod, } from './sync.js';
|
|
26
|
-
export { createSlotlockApplicationRoleGrantsDdl, createSlotlockTenantRlsDdl, SLOTLOCK_API_KEY_FUNCTIONS, SLOTLOCK_API_KEY_TABLES, SLOTLOCK_CORE_DDL, SLOTLOCK_DASHBOARD_FUNCTIONS, SLOTLOCK_DASHBOARD_TABLES, SLOTLOCK_DEFINER_FUNCTIONS, SLOTLOCK_DEFINER_TABLES, SLOTLOCK_TENANT_CONTEXT_SETTING, SLOTLOCK_TENANT_RLS_DDL, SLOTLOCK_TENANT_TABLES, } from './ddl.js';
|
|
27
|
-
export { calendarEventRollingHorizon, createSlotlockStore, SLOTLOCK_AGENT_OWNER_COMMAND_QUOTA, SLOTLOCK_AGENT_OWNER_EVENT_QUOTA, SLOTLOCK_CALENDAR_HORIZON_DAYS, SLOTLOCK_EVENT_COMMAND_RETENTION_DAYS, SLOTLOCK_INTERNAL_EVENT_OWNER_REF, SLOTLOCK_LOCAL_RECURRENCE_COVERAGE_SOURCE, SLOTLOCK_MAX_EVENT_DURATION_DAYS, type SlotlockHoldTenantOptions, type SlotlockSql, type SlotlockStore, type SlotlockStoreOptions, type SlotlockTenantStore, } from './store.js';
|
|
28
|
-
export type { AcquireHoldResult, CalendarAttendee, CalendarAttendeeRole, CalendarCoverageAssessment, CalendarCoverageCommand, CalendarCoverageResult, CalendarEventContent, CalendarEventOccurrence, CalendarEventRetentionResult, CalendarEventStatus, CalendarFreeBusy, CalendarHorizonRollCursor, CalendarHorizonRollResult, CalendarOrganizer, CalendarParticipationStatus, CalendarRecurrence, CalendarRecurrenceException, CalendarReminder, CalendarTransparency, ConfirmHoldResult, CancelCalendarEventResult, CancelExternalReservationResult, CreateReservationResult, ExternalReservationCommand, ExternalReservationResult, Interval, SlotlockHold, SlotlockCalendarEvent, SlotlockReservation, SlotlockResource, PutCalendarEventCommand, PutCalendarEventResult, ReleaseHoldResult, TrustedICalendarEvent, WeeklyAvailabilityRule, } from './types.js';
|
|
30
|
+
export { CalendarContractError, CalendarExpansionLimitError, emitICalendar, emitITipCalendar, expandCalendarEventOccurrences, normalizeCalendarEventContent, normalizeExternalCalendarChange, parseICalendarChanges, parseICalendarFeed, parseTrustedICalendarEvents, recurrenceRuleProblem, storedCalendarEventProblem, } from './sync.js';
|
|
31
|
+
export type { ExternalCalendarChange, ExternalCalendarChangeInput, ExternalCalendarStatus, ICalendarEvent, ICalendarExpansionWindow, ICalendarFeedRead, ICalendarSeriesRefusal, ITipMethod, } from './sync.js';
|
|
32
|
+
export { createSlotlockApplicationRoleGrantsDdl, createSlotlockTenantRlsDdl, SLOTLOCK_API_KEY_FUNCTIONS, SLOTLOCK_API_KEY_TABLES, SLOTLOCK_CORE_DDL, SLOTLOCK_DASHBOARD_FUNCTIONS, SLOTLOCK_DASHBOARD_TABLES, SLOTLOCK_DEFINER_FUNCTIONS, SLOTLOCK_DEFINER_TABLES, SLOTLOCK_OPERATOR_FUNCTIONS, SLOTLOCK_SCHEMA_FUNCTIONS, SLOTLOCK_SCHEMA_TABLES, SLOTLOCK_SCHEMA_VERSION, SLOTLOCK_TENANT_ADMIN_FUNCTIONS, SLOTLOCK_TENANT_ADMIN_TABLES, SLOTLOCK_TENANT_CONTEXT_SETTING, SLOTLOCK_TENANT_RLS_DDL, SLOTLOCK_TENANT_TABLES, } from './ddl.js';
|
|
33
|
+
export { assertSlotlockSchemaCurrent, calendarEventRollingHorizon, createSlotlockStore, readSlotlockSchemaVersion, SLOTLOCK_AGENT_OWNER_COMMAND_QUOTA, SLOTLOCK_AGENT_OWNER_EVENT_QUOTA, SLOTLOCK_CALENDAR_HORIZON_DAYS, SLOTLOCK_EVENT_COMMAND_RETENTION_DAYS, SLOTLOCK_INTERNAL_EVENT_OWNER_REF, SLOTLOCK_LOCAL_RECURRENCE_COVERAGE_SOURCE, SLOTLOCK_MATERIALIZATION_WINDOW_DAYS, SLOTLOCK_MAX_EVENT_DURATION_DAYS, SLOTLOCK_TENANT_WRITE_METHODS, type SlotlockHoldTenantOptions, type SlotlockMigrationOptions, type SlotlockSql, type SlotlockStore, type SlotlockStoreOptions, type SlotlockTenantLimits, type SlotlockTenantStore, } from './store.js';
|
|
34
|
+
export type { AcquireHoldResult, BookingRetentionResult, CalendarAttendee, CalendarAttendeeRole, CalendarCoverageAssessment, CalendarCoverageCommand, CalendarCoverageResult, CalendarEventContent, CalendarEventOccurrence, CalendarEventRetentionResult, CalendarEventStatus, CalendarFreeBusy, CalendarHorizonRollCursor, CalendarHorizonRollResult, CalendarOrganizer, CalendarParticipationStatus, CalendarRecurrence, CalendarRecurrenceException, CalendarReminder, CalendarTransparency, ConfirmHoldResult, CancelCalendarEventResult, CancelExternalReservationResult, CreateReservationResult, DeleteResourceResult, ExternalReservationCommand, ExternalReservationResult, Interval, SlotlockAgendaEntry, SlotlockHold, SlotlockCalendarEvent, SlotlockReservation, SlotlockResource, SlotlockTenantErasure, PutCalendarEventCommand, PutCalendarEventResult, ReleaseHoldResult, TrustedICalendarEvent, WeeklyAvailabilityRule, } from './types.js';
|
package/index.js
CHANGED
|
@@ -4,8 +4,13 @@
|
|
|
4
4
|
// TypeScript 6 default) still loads @types/node.
|
|
5
5
|
/// <reference types="node" preserve="true" />
|
|
6
6
|
export { findNextAvailable, mergeIntervals, subtractBusy } from './engine.js';
|
|
7
|
+
export { bookingRuleBroken, bookingSearch, nextStepStart, parseBookingRules, } from './booking-rules.js';
|
|
8
|
+
export { SLOTLOCK_CHANGE_RETENTION_DAYS, SLOTLOCK_CHANGE_TYPES, SLOTLOCK_MAX_WEBHOOK_ENDPOINTS, SLOTLOCK_WEBHOOK_FAILING_LIMIT_MS, } from './event-feed.js';
|
|
9
|
+
export { createSlotlockWebhookSender, deliverSlotlockWebhooks, isPrivateAddress, signSlotlockWebhook, slotlockCloudEvent, slotlockWebhookRetryDelayMs, startSlotlockWebhookDelivery, } from './webhooks.js';
|
|
10
|
+
export { createSlotlockMetrics } from './metrics.js';
|
|
7
11
|
export { expandRules } from './rules.js';
|
|
8
12
|
export { availabilityRuleProblem, parseAvailabilityRules, rulesToWeeklyHours, SLOTLOCK_MAX_AVAILABILITY_RULES, weeklyHoursToRules, } from './weekly-hours.js';
|
|
13
|
+
export { emitVAvailability, parseVAvailability, recurrenceRuleFromRRule, SLOTLOCK_MAX_VAVAILABILITY_CHARACTERS, toJSCalendarEvent, } from './interop.js';
|
|
9
14
|
export { createTimeZoneConverter, zonedCalendarDate, zonedDateTimeToUtc, zonedWallTime, } from './timezone.js';
|
|
10
15
|
export { createSlotlockAgentServer, clientSupportsSlotlockMcpApp, invokeSlotlockAgentOperation, isSlotlockAgentOperation, slotlockAgentTools, slotlockApplicationOperations, slotlockOpenApi, slotlockCalendarResourceUri, slotlockMcpToolResult, parseSlotlockA2ATimestamp, resolveSlotlockAgentOperation, slotlockAgentOperationScope, SLOTLOCK_A2A_PROTOCOL_VERSION, SLOTLOCK_A2A_TASK_PAGE_SIZE, SLOTLOCK_A2A_TASK_STATES, SLOTLOCK_AGENT_OPERATION_LEGACY_NAMES, SLOTLOCK_AGENT_SERVER_VERSION, SLOTLOCK_MCP_LEGACY_PROTOCOL_VERSION, SLOTLOCK_MCP_PROTOCOL_VERSION, SLOTLOCK_MCP_RATE_LIMITED_ERROR_CODE, SLOTLOCK_MCP_RESOURCE_URI_TEMPLATE, SLOTLOCK_MCP_SUPPORTED_PROTOCOL_VERSIONS, SLOTLOCK_MCP_APP_HTML, SLOTLOCK_MCP_APP_MIME_TYPE, SLOTLOCK_MCP_APP_RESOURCE, SLOTLOCK_MCP_APP_RESOURCE_URI, SLOTLOCK_MCP_APPS_EXTENSION, SlotlockAgentOperationError, } from './agent-server.js';
|
|
11
16
|
export { createSlotlockNodeServer } from './node-server.js';
|
|
@@ -13,8 +18,8 @@ export { createSlotlockStoreAgentBackend, createSlotlockStoreApplicationBackend,
|
|
|
13
18
|
export { SLOTLOCK_APPLICATION_OPERATIONS, SLOTLOCK_APPLICATION_SCOPE, isSlotlockApplicationOperation, } from './application-api.js';
|
|
14
19
|
export { maintainSlotlockTenant, startSlotlockMaintenance, withSlotlockMaintenanceLock, } from './maintenance.js';
|
|
15
20
|
export { createSlotlockApiKeyAuthenticator, createSlotlockApiKeyStore, generateSlotlockApiKey, isSlotlockApiKey, slotlockApiKeyDigest, SLOTLOCK_API_KEY_ACTIVE_LIMIT, SLOTLOCK_API_KEY_MAX_LIFETIME_DAYS, SLOTLOCK_API_KEY_PREFIX, SLOTLOCK_API_KEY_RETAINED_LIMIT, SLOTLOCK_API_KEY_SCOPES, } from './api-keys.js';
|
|
16
|
-
export { createSlotlockDashboard, createSlotlockDashboardResources, createSlotlockDashboardState, createSlotlockMemoryDashboardState, SLOTLOCK_DASHBOARD_MAX_RESOURCES, } from './dashboard.js';
|
|
21
|
+
export { createSlotlockDashboard, createSlotlockDashboardResources, createSlotlockAcceptanceRecords, createSlotlockDashboardState, createSlotlockMemoryDashboardState, SLOTLOCK_DASHBOARD_MAX_RESOURCES, } from './dashboard.js';
|
|
17
22
|
export { ICalendarWorkerBusyError, ICalendarWorkerPoolClosedError, createICalendarWorkerPool, } from './ical-worker.js';
|
|
18
|
-
export { CalendarContractError, CalendarExpansionLimitError, emitICalendar, emitITipCalendar, expandCalendarEventOccurrences, normalizeCalendarEventContent, normalizeExternalCalendarChange, parseICalendarChanges, parseTrustedICalendarEvents, } from './sync.js';
|
|
19
|
-
export { createSlotlockApplicationRoleGrantsDdl, createSlotlockTenantRlsDdl, SLOTLOCK_API_KEY_FUNCTIONS, SLOTLOCK_API_KEY_TABLES, SLOTLOCK_CORE_DDL, SLOTLOCK_DASHBOARD_FUNCTIONS, SLOTLOCK_DASHBOARD_TABLES, SLOTLOCK_DEFINER_FUNCTIONS, SLOTLOCK_DEFINER_TABLES, SLOTLOCK_TENANT_CONTEXT_SETTING, SLOTLOCK_TENANT_RLS_DDL, SLOTLOCK_TENANT_TABLES, } from './ddl.js';
|
|
20
|
-
export { calendarEventRollingHorizon, createSlotlockStore, SLOTLOCK_AGENT_OWNER_COMMAND_QUOTA, SLOTLOCK_AGENT_OWNER_EVENT_QUOTA, SLOTLOCK_CALENDAR_HORIZON_DAYS, SLOTLOCK_EVENT_COMMAND_RETENTION_DAYS, SLOTLOCK_INTERNAL_EVENT_OWNER_REF, SLOTLOCK_LOCAL_RECURRENCE_COVERAGE_SOURCE, SLOTLOCK_MAX_EVENT_DURATION_DAYS, } from './store.js';
|
|
23
|
+
export { CalendarContractError, CalendarExpansionLimitError, emitICalendar, emitITipCalendar, expandCalendarEventOccurrences, normalizeCalendarEventContent, normalizeExternalCalendarChange, parseICalendarChanges, parseICalendarFeed, parseTrustedICalendarEvents, recurrenceRuleProblem, storedCalendarEventProblem, } from './sync.js';
|
|
24
|
+
export { createSlotlockApplicationRoleGrantsDdl, createSlotlockTenantRlsDdl, SLOTLOCK_API_KEY_FUNCTIONS, SLOTLOCK_API_KEY_TABLES, SLOTLOCK_CORE_DDL, SLOTLOCK_DASHBOARD_FUNCTIONS, SLOTLOCK_DASHBOARD_TABLES, SLOTLOCK_DEFINER_FUNCTIONS, SLOTLOCK_DEFINER_TABLES, SLOTLOCK_OPERATOR_FUNCTIONS, SLOTLOCK_SCHEMA_FUNCTIONS, SLOTLOCK_SCHEMA_TABLES, SLOTLOCK_SCHEMA_VERSION, SLOTLOCK_TENANT_ADMIN_FUNCTIONS, SLOTLOCK_TENANT_ADMIN_TABLES, SLOTLOCK_TENANT_CONTEXT_SETTING, SLOTLOCK_TENANT_RLS_DDL, SLOTLOCK_TENANT_TABLES, } from './ddl.js';
|
|
25
|
+
export { assertSlotlockSchemaCurrent, calendarEventRollingHorizon, createSlotlockStore, readSlotlockSchemaVersion, SLOTLOCK_AGENT_OWNER_COMMAND_QUOTA, SLOTLOCK_AGENT_OWNER_EVENT_QUOTA, SLOTLOCK_CALENDAR_HORIZON_DAYS, SLOTLOCK_EVENT_COMMAND_RETENTION_DAYS, SLOTLOCK_INTERNAL_EVENT_OWNER_REF, SLOTLOCK_LOCAL_RECURRENCE_COVERAGE_SOURCE, SLOTLOCK_MATERIALIZATION_WINDOW_DAYS, SLOTLOCK_MAX_EVENT_DURATION_DAYS, SLOTLOCK_TENANT_WRITE_METHODS, } from './store.js';
|
package/interop.d.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { SlotlockCalendarEvent, WeeklyAvailabilityRule } from './types.js';
|
|
2
|
+
/** The longest VAVAILABILITY text `parseVAvailability` reads. */
|
|
3
|
+
export declare const SLOTLOCK_MAX_VAVAILABILITY_CHARACTERS = 65536;
|
|
4
|
+
export interface EmitVAvailabilityOptions {
|
|
5
|
+
/** The resource's weekly rules, in `timezone`. */
|
|
6
|
+
rules: readonly WeeklyAvailabilityRule[];
|
|
7
|
+
/** The IANA zone the rules are read in: every DTSTART names it as its TZID. */
|
|
8
|
+
timezone: string;
|
|
9
|
+
/** The VAVAILABILITY's UID; each AVAILABLE's is this with its index. */
|
|
10
|
+
uid: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A VCALENDAR with one VAVAILABILITY holding an AVAILABLE per rule: DTSTART on the rule's first day
|
|
14
|
+
* in a reference week of January 2024, with the IANA zone as TZID (no VTIMEZONE: RFC 7809 lets the
|
|
15
|
+
* two sides agree on IANA names), DURATION and the rule's RRULE. `[]` is a VAVAILABILITY with no
|
|
16
|
+
* AVAILABLE: never bookable. CRLF line endings, folded at 75 octets.
|
|
17
|
+
*/
|
|
18
|
+
export declare function emitVAvailability({ rules, timezone, uid }: EmitVAvailabilityOptions): string;
|
|
19
|
+
export interface ParsedVAvailability {
|
|
20
|
+
/** The TZID every AVAILABLE named, `UTC` for UTC times, or null when they are all floating. */
|
|
21
|
+
timezone: string | null;
|
|
22
|
+
rules: WeeklyAvailabilityRule[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Weekly rules from an iCalendar VAVAILABILITY (RFC 7953): one VAVAILABILITY, each AVAILABLE a
|
|
26
|
+
* weekly RRULE with a time of day and a length. Refuses (`invalid_availability`) what weekly
|
|
27
|
+
* rules cannot say: a VAVAILABILITY bounded by DTSTART or DTEND, more than one, an AVAILABLE
|
|
28
|
+
* without RRULE, with RDATE, EXDATE or RECURRENCE-ID, a whole-day DTSTART, seconds, AVAILABLEs in
|
|
29
|
+
* different zones, and any rule `parseAvailabilityRules` refuses. An RRULE without BYDAY takes
|
|
30
|
+
* DTSTART's day, as RFC 5545 reads it.
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseVAvailability(text: string): ParsedVAvailability;
|
|
33
|
+
/** A JSCalendar Event object (RFC 8984 §5.1): the properties Slotlock fills. */
|
|
34
|
+
export interface JSCalendarEvent {
|
|
35
|
+
'@type': 'Event';
|
|
36
|
+
uid: string;
|
|
37
|
+
updated: string;
|
|
38
|
+
created: string;
|
|
39
|
+
sequence: number;
|
|
40
|
+
prodId: string;
|
|
41
|
+
title: string;
|
|
42
|
+
description?: string;
|
|
43
|
+
start: string;
|
|
44
|
+
timeZone: string;
|
|
45
|
+
duration: string;
|
|
46
|
+
status: 'confirmed' | 'tentative';
|
|
47
|
+
freeBusyStatus: 'free' | 'busy';
|
|
48
|
+
locations?: Record<string, {
|
|
49
|
+
'@type': 'Location';
|
|
50
|
+
name: string;
|
|
51
|
+
}>;
|
|
52
|
+
participants?: Record<string, JSCalendarParticipant>;
|
|
53
|
+
alerts?: Record<string, JSCalendarAlert>;
|
|
54
|
+
recurrenceRules?: JSCalendarRecurrenceRule[];
|
|
55
|
+
recurrenceOverrides?: Record<string, {
|
|
56
|
+
excluded: true;
|
|
57
|
+
} | {
|
|
58
|
+
start: string;
|
|
59
|
+
duration: string;
|
|
60
|
+
}>;
|
|
61
|
+
/** The RRULE the recurrence was written as, kept verbatim (RFC 8984 §3.3 vendor property). */
|
|
62
|
+
'slotlock.pylota.io:rrule'?: string;
|
|
63
|
+
}
|
|
64
|
+
export interface JSCalendarParticipant {
|
|
65
|
+
'@type': 'Participant';
|
|
66
|
+
name?: string;
|
|
67
|
+
email: string;
|
|
68
|
+
sendTo: {
|
|
69
|
+
imip: string;
|
|
70
|
+
};
|
|
71
|
+
roles: Record<string, true>;
|
|
72
|
+
participationStatus?: 'needs-action' | 'accepted' | 'declined' | 'tentative' | 'delegated';
|
|
73
|
+
expectReply?: boolean;
|
|
74
|
+
}
|
|
75
|
+
export interface JSCalendarAlert {
|
|
76
|
+
'@type': 'Alert';
|
|
77
|
+
trigger: {
|
|
78
|
+
'@type': 'OffsetTrigger';
|
|
79
|
+
offset: string;
|
|
80
|
+
relativeTo: 'start';
|
|
81
|
+
};
|
|
82
|
+
action: 'display' | 'email';
|
|
83
|
+
}
|
|
84
|
+
export interface JSCalendarRecurrenceRule {
|
|
85
|
+
'@type': 'RecurrenceRule';
|
|
86
|
+
frequency: 'yearly' | 'monthly' | 'weekly' | 'daily' | 'hourly' | 'minutely' | 'secondly';
|
|
87
|
+
interval?: number;
|
|
88
|
+
firstDayOfWeek?: string;
|
|
89
|
+
byDay?: {
|
|
90
|
+
'@type': 'NDay';
|
|
91
|
+
day: string;
|
|
92
|
+
nthOfPeriod?: number;
|
|
93
|
+
}[];
|
|
94
|
+
byMonthDay?: number[];
|
|
95
|
+
byMonth?: string[];
|
|
96
|
+
byYearDay?: number[];
|
|
97
|
+
byWeekNo?: number[];
|
|
98
|
+
byHour?: number[];
|
|
99
|
+
byMinute?: number[];
|
|
100
|
+
bySecond?: number[];
|
|
101
|
+
bySetPosition?: number[];
|
|
102
|
+
count?: number;
|
|
103
|
+
until?: string;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* An RRULE as a JSCalendar RecurrenceRule (RFC 8984 §4.3.3), or null when it holds a part the
|
|
107
|
+
* mapping does not know (the verbatim RRULE is exported beside it either way). A UTC UNTIL becomes
|
|
108
|
+
* the wall time in `timezone`; a date UNTIL the end of that day.
|
|
109
|
+
*/
|
|
110
|
+
export declare function recurrenceRuleFromRRule(rrule: string, timezone: string): JSCalendarRecurrenceRule | null;
|
|
111
|
+
/**
|
|
112
|
+
* A Slotlock calendar event as a JSCalendar Event (RFC 8984): its id as `uid`, its revision as
|
|
113
|
+
* `sequence`, start as a LocalDateTime in its zone with an exact duration, the organizer an
|
|
114
|
+
* `owner` participant, reminders `OffsetTrigger` alerts before the start, and the recurrence as
|
|
115
|
+
* `recurrenceRules` with `recurrenceOverrides` keyed by each exception's original start.
|
|
116
|
+
*/
|
|
117
|
+
export declare function toJSCalendarEvent(event: SlotlockCalendarEvent): JSCalendarEvent;
|