@volter/twin-calcom 0.1.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/LICENSE +202 -0
- package/README.md +90 -0
- package/client/calcom-mirror.css +29 -0
- package/client/calcom-mirror.tsx +125 -0
- package/dist/client/calcom-mirror.bundle.js +321 -0
- package/dist/client/calcom-mirror.css +29 -0
- package/dist/client/calcom-mirror.d.ts +13 -0
- package/dist/client/calcom-mirror.js +61 -0
- package/dist/client/calcom-mirror.tsx +125 -0
- package/dist/src/calcom-budget.d.ts +52 -0
- package/dist/src/calcom-budget.js +145 -0
- package/dist/src/calcom-capabilities.d.ts +3 -0
- package/dist/src/calcom-capabilities.js +521 -0
- package/dist/src/calcom-conformance.d.ts +15 -0
- package/dist/src/calcom-conformance.js +86 -0
- package/dist/src/calcom-connector.d.ts +90 -0
- package/dist/src/calcom-connector.js +229 -0
- package/dist/src/calcom-mirror-ui.d.ts +23 -0
- package/dist/src/calcom-mirror-ui.js +100 -0
- package/dist/src/calcom-perform-harness.d.ts +5 -0
- package/dist/src/calcom-perform-harness.js +29 -0
- package/dist/src/calcom-server.d.ts +14 -0
- package/dist/src/calcom-server.js +31 -0
- package/dist/src/calcom-twin.d.ts +16 -0
- package/dist/src/calcom-twin.js +718 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +31 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.js +69 -0
- package/package.json +72 -0
- package/src/calcom-budget.ts +171 -0
- package/src/calcom-capabilities.ts +529 -0
- package/src/calcom-conformance.ts +92 -0
- package/src/calcom-connector.ts +258 -0
- package/src/calcom-mirror-ui.ts +110 -0
- package/src/calcom-perform-harness.ts +24 -0
- package/src/calcom-server.ts +39 -0
- package/src/calcom-twin.ts +675 -0
- package/src/cli.ts +29 -0
- package/src/index.ts +101 -0
package/src/cli.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { keepProcessAlive } from '@volter/world-core/lifecycle';
|
|
3
|
+
// world-calcom CLI: serve the Cal.com v2 API twin, the mirror UI, or run conformance.
|
|
4
|
+
import { hasFlag, optionValue } from '@volter/world-core/args';
|
|
5
|
+
import { createCalcomTwinServer } from './calcom-server.ts';
|
|
6
|
+
import { createCalcomMirrorServer } from './calcom-mirror-ui.ts';
|
|
7
|
+
|
|
8
|
+
const [cmd, ...rest] = process.argv.slice(2);
|
|
9
|
+
const port = Number(optionValue(rest, '--port', '0')) || undefined;
|
|
10
|
+
const root = optionValue(rest, '--root') || undefined;
|
|
11
|
+
const readOnly = hasFlag(rest, '--read-only'); // a twin accepts writes unless started read-only
|
|
12
|
+
|
|
13
|
+
if (cmd === 'serve') {
|
|
14
|
+
const s = await createCalcomTwinServer({ readOnly, ...(root ? { root } : {}), ...(port ? { port } : {}) });
|
|
15
|
+
process.stdout.write(`calcom twin (v2 API)${readOnly ? ' [read-only]' : ''} at http://127.0.0.1:${s.port}\n`);
|
|
16
|
+
await keepProcessAlive();
|
|
17
|
+
} else if (cmd === 'mirror') {
|
|
18
|
+
const s = await createCalcomMirrorServer({ ...(root ? { root } : {}), ...(port ? { port } : {}) });
|
|
19
|
+
process.stdout.write(`calcom mirror UI (dashboard) at http://127.0.0.1:${s.port}\n`);
|
|
20
|
+
await keepProcessAlive();
|
|
21
|
+
} else if (cmd === 'conformance') {
|
|
22
|
+
// dev-only; lazy so the bin runs without @volter/world-tooling in the runtime graph
|
|
23
|
+
const { checkCalcomConformance } = await import('./calcom-conformance.ts');
|
|
24
|
+
const report = checkCalcomConformance({ ...(root ? { root } : {}) });
|
|
25
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
26
|
+
if (!report.ok) process.exitCode = 1;
|
|
27
|
+
} else {
|
|
28
|
+
process.stdout.write('Usage: world-calcom serve|mirror|conformance [--port N] [--root DIR] [--read-only]\n');
|
|
29
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// @volter/twin-calcom — the Cal.com twin (one vendor, one package), built on the shared
|
|
2
|
+
// @volter/world-core kernel. REST (v2) transport, spec-faithful `{ status, data }` envelope,
|
|
3
|
+
// stateful bookings/event-types/schedules/teams/webhooks, and a React dashboard mirror.
|
|
4
|
+
// Auth is a faked-locally Bearer API key — there is NO JWT / JWKS / webhook signing
|
|
5
|
+
// (Cal.com's API auth is a plain bearer `cal_…` key). Conformance tooling lives in
|
|
6
|
+
// @volter/world-tooling (a dev dependency) — not shipped in the runtime API.
|
|
7
|
+
export { handleCalcomTwinRequest, TWIN_API_VERSION, RESOURCE_TYPES } from './calcom-twin.ts';
|
|
8
|
+
export type { CalcomRequest, CalcomResponse } from './calcom-twin.ts';
|
|
9
|
+
export { createCalcomTwinFetch, createCalcomTwinServer, type CalcomTwinFetchOptions } from './calcom-server.ts';
|
|
10
|
+
export {
|
|
11
|
+
calcomRequestForAction,
|
|
12
|
+
liveCalcomExecute,
|
|
13
|
+
mapBooking,
|
|
14
|
+
mapEventType,
|
|
15
|
+
pullCalcomAll,
|
|
16
|
+
pullCalcomBookings,
|
|
17
|
+
pullCalcomEventTypes,
|
|
18
|
+
syncCalcomFromReal,
|
|
19
|
+
} from './calcom-connector.ts';
|
|
20
|
+
export type { CalcomExecute, LiveCalcomOptions } from './calcom-connector.ts';
|
|
21
|
+
// The client-side rate budget — the fail-closed backstop `liveCalcomExecute` routes every live
|
|
22
|
+
// request through. The MECHANISM is the kernel's shared, vendor-agnostic `RateBudget`; what lives
|
|
23
|
+
// here is Cal.com's DECLARATION (window/ceiling/per-endpoint weights) plus the vendor-bound
|
|
24
|
+
// bindings. Exported so an operator can inspect spend (`snapshot`) and so a caller can catch
|
|
25
|
+
// `CalcomBudgetError` by type; there is deliberately no export that disables the guard.
|
|
26
|
+
export {
|
|
27
|
+
CALCOM_BUDGET_CEILING,
|
|
28
|
+
CALCOM_BUDGET_MAX_RETRY_AFTER_S,
|
|
29
|
+
CALCOM_BUDGET_WINDOW_MS,
|
|
30
|
+
CALCOM_CALL_WEIGHTS,
|
|
31
|
+
CALCOM_RATE_BUDGET,
|
|
32
|
+
CalcomBudget,
|
|
33
|
+
CalcomBudgetError,
|
|
34
|
+
calcomBudgetPath,
|
|
35
|
+
calcomCallWeight,
|
|
36
|
+
} from './calcom-budget.ts';
|
|
37
|
+
export type { CalcomBudgetErrorKind, CalcomBudgetOptions, CalcomBudgetReservation, CalcomBudgetSnapshot } from './calcom-budget.ts';
|
|
38
|
+
export {
|
|
39
|
+
attendeeLabel,
|
|
40
|
+
bookingTone,
|
|
41
|
+
buildCalcomMirrorClient,
|
|
42
|
+
calcomMirrorHtml,
|
|
43
|
+
createCalcomMirrorServer,
|
|
44
|
+
formatWindow,
|
|
45
|
+
} from './calcom-mirror-ui.ts';
|
|
46
|
+
export type { CalcomRow } from './calcom-mirror-ui.ts';
|
|
47
|
+
|
|
48
|
+
// Registry descriptor: the pack self-describes so tooling can discover it.
|
|
49
|
+
import { registerPack, type TwinPack } from '@volter/world-core';
|
|
50
|
+
import { CALCOM_RATE_BUDGET as RATE_BUDGET } from './calcom-budget.ts';
|
|
51
|
+
import { performCalcomAction, syncCalcomFromRemote } from './calcom-connector.ts';
|
|
52
|
+
|
|
53
|
+
export const pack: TwinPack = {
|
|
54
|
+
vendor: 'calcom',
|
|
55
|
+
// PROTOCOL 2 (docs/contributing/architecture.md#protocol-2-the-pack-is-a-plugin): the pack is a plugin — its wire, its tree, and its half of the real
|
|
56
|
+
// state system: perform one entry against Cal.com v2, refresh the root from it. Moved 2026-09-08.
|
|
57
|
+
protocol: '2',
|
|
58
|
+
refresh: { every: '5m', webhook: true, onDemand: { atMost: '30s' } },
|
|
59
|
+
stateSystem: { perform: performCalcomAction, refresh: syncCalcomFromRemote },
|
|
60
|
+
// the round trip: an event type, then a booking of it — the two things a scheduling account is made of
|
|
61
|
+
// the round trip is ONE write — an event type. A booking would have to name an event type, and the only
|
|
62
|
+
// one it could name statically is the twin's implicit default (7001), which is not the subject the kernel
|
|
63
|
+
// adopts; the reference trip below is where a booking gets made, against the event type this created.
|
|
64
|
+
roundTrip: { method: 'POST', path: '/v2/event-types', body: { title: 'Round trip', slug: 'round-trip', lengthInMinutes: 30 }, headers: { authorization: 'Bearer round-trip', 'cal-api-version': '2024-06-14' } },
|
|
65
|
+
// rule 5: a booking names the event type it is a booking OF; when the head adopts Cal.com's id for the
|
|
66
|
+
// event type, the kernel resolves the booking's field first
|
|
67
|
+
referenceTrip: { method: 'POST', path: '/v2/bookings', body: { start: '2026-09-09T11:00:00.000Z', eventTypeId: '{{evtId}}', attendee: { name: 'Round Trip', email: 'round@trip.test', timeZone: 'UTC' } }, headers: { authorization: 'Bearer round-trip', 'cal-api-version': '2024-08-13' } },
|
|
68
|
+
references: [{
|
|
69
|
+
type: 'booking', to: 'event_type',
|
|
70
|
+
key: (f: Record<string, unknown>) => (f.eventTypeId === undefined || f.eventTypeId === null ? undefined : `evt_${String(f.eventTypeId)}`),
|
|
71
|
+
adopt: (_f: Record<string, unknown>, vendorId: string) => ({ eventTypeId: vendorId.replace(/^evt_/, '') }),
|
|
72
|
+
}],
|
|
73
|
+
parityOrigin: 'http://twin',
|
|
74
|
+
shapeParity: 'held',
|
|
75
|
+
// The SAME object calcom-budget.ts declares at module load — one source of truth, so registering
|
|
76
|
+
// the pack and importing the connector can never arm two different ceilings.
|
|
77
|
+
rateBudget: RATE_BUDGET,
|
|
78
|
+
transport: 'rest',
|
|
79
|
+
archetype: 'crud',
|
|
80
|
+
bin: 'world-calcom',
|
|
81
|
+
resources: ['booking', 'event_type', 'schedule', 'team', 'membership', 'webhook', 'slot'],
|
|
82
|
+
specSource: 'cal.com/docs/api-reference/v2 (hand-authored from the published v2 reference)',
|
|
83
|
+
description: 'Cal.com v2 REST twin — { status, data } envelope, stateful bookings/event-types/schedules/teams/webhooks, dashboard mirror.',
|
|
84
|
+
// Adoption + interception, moved off the central maps unchanged (descriptor-first back-migration, adding-a-twin.md §3,
|
|
85
|
+
// 2026-08-31). Both credential-env spellings the vendor uses — CALCOM_* and the
|
|
86
|
+
// shorter CAL_* — stem here; there is no npm client to claim (Cal.com integrations call the v2
|
|
87
|
+
// REST surface directly), so `sdks` is deliberately absent rather than invented.
|
|
88
|
+
adoption: {
|
|
89
|
+
// Cal.com ships no Python SDK and no community client exists. The `Calcom` distribution on
|
|
90
|
+
// PyPI is an unrelated mathematics package - claiming it would map a maths dependency onto a
|
|
91
|
+
// scheduling twin.
|
|
92
|
+
pypi: [],
|
|
93
|
+
envStems: ['CALCOM', 'CAL'],
|
|
94
|
+
},
|
|
95
|
+
hosts: [{ host: 'api.cal.com' }],
|
|
96
|
+
// A scheduling client calls api.cal.com/v2/… — the dev proxy forwards '/v2/' to the twin
|
|
97
|
+
// and strips the absolute host so calls come back same-origin.
|
|
98
|
+
browserRouting: { apiPathPrefix: '/v2/', loaderHost: 'https://api.cal.com' },
|
|
99
|
+
};
|
|
100
|
+
// registered at import: the kernel learns the pack's state system (protocol 2)
|
|
101
|
+
registerPack(pack);
|