@memberjunction/connector-eventbrite 1.0.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.
@@ -0,0 +1,178 @@
1
+ import { type UserInfo } from '@memberjunction/core';
2
+ import type { MJCompanyIntegrationEntity, MJIntegrationObjectEntity } from '@memberjunction/core-entities';
3
+ import { BaseRESTIntegrationConnector, type RESTAuthContext, type RESTResponse, type PaginationState, type PaginationType, type ConnectionTestResult, type FetchContext, type FetchBatchResult, type RateLimitPolicy } from '@memberjunction/integration-engine';
4
+ /**
5
+ * Per-connection configuration for the Eventbrite Platform REST API v3 connector.
6
+ *
7
+ * Eventbrite has a single shared host (`https://www.eventbriteapi.com/v3`). Auth is
8
+ * a Bearer token — either a long-lived private token (issued from the account API Keys
9
+ * page) or an OAuth2 authorization-code access token. Both are used verbatim as
10
+ * `Authorization: Bearer <token>`; the connector does not perform the token exchange
11
+ * (the resolved token lives in the credential store).
12
+ */
13
+ export interface EventbriteConnectionConfig {
14
+ /**
15
+ * The resolved Bearer token (private token OR OAuth2 access token). From the credential
16
+ * store (keys PrivateToken / Token / AccessToken / apiKey). Secrets never live in code.
17
+ */
18
+ Token?: string;
19
+ /**
20
+ * Non-secret API host override (e.g. a local mock for replay/contract testing). When set,
21
+ * it WINS over the production host. Mirrors the ORCID/Novi `ApiBaseUrl` pattern — required
22
+ * for the mock-floor e2e testability tier.
23
+ */
24
+ ApiBaseUrl?: string;
25
+ /** HTTP request timeout in milliseconds. Default: 30000. */
26
+ RequestTimeoutMs?: number;
27
+ /** Maximum retries for rate-limited / transient failures. Default: 4. */
28
+ MaxRetries?: number;
29
+ /** Minimum interval between outbound requests (ms). Default: 100. */
30
+ MinRequestIntervalMs?: number;
31
+ }
32
+ /**
33
+ * Connector for the Eventbrite Platform REST API v3.
34
+ *
35
+ * Authenticates via a Bearer token (private token or OAuth2 access token, resolved
36
+ * upstream and held in the credential store). Reads ride the base
37
+ * {@link BaseRESTIntegrationConnector} pull path; this class overrides only the
38
+ * genuinely Eventbrite-specific bits:
39
+ * - {@link BuildHeaders}: `Authorization: Bearer <token>` + `Accept: application/json`.
40
+ * - {@link GetBaseURL}: the shared `https://www.eventbriteapi.com/v3` host (or a
41
+ * non-secret `ApiBaseUrl` override for mock testing).
42
+ * - {@link NormalizeResponse}: unwraps the named-key list envelope (the IO's
43
+ * `ResponseDataKey`, e.g. `events`/`attendees`/`orders`) which sits alongside a
44
+ * `pagination` object; a bare object is a one-record detail; null → [].
45
+ * - {@link ExtractPaginationInfo} / {@link BuildPaginatedURL}: Eventbrite continuation-cursor
46
+ * pagination (`?continuation=<token>` + `pagination.has_more_items`/`.continuation`),
47
+ * plus the `changed_since=<watermark>` param for incremental objects (Order/Attendee) —
48
+ * fully metadata-driven (read `obj.IncrementalWatermarkField` + `obj.SupportsIncrementalSync`),
49
+ * NEVER keyed off a hardcoded object name.
50
+ * - {@link FetchChanges}: sets the watermark context, delegates to the base, then advances
51
+ * the watermark from the records' `changed` field on the final batch only (HasMore=false)
52
+ * so a partial-failure mid-pagination leaves the watermark unchanged.
53
+ *
54
+ * Create/Update/Delete use the generic per-operation column path
55
+ * (CreateAPIPath/Method/BodyShape/BodyKey/IDLocation, Update*, Delete*) driven entirely
56
+ * by the IO metadata — no per-verb override. Eventbrite uses POST for update (its
57
+ * convention) and wrapped bodies for most resources (CreateBodyKey =
58
+ * event|ticket_class|venue|discount|question|webhook|...). Parent template vars
59
+ * ({organization_id}/{event_id}) are resolved by the engine's parent-iteration from each
60
+ * IO's `Configuration.parentObjectName`.
61
+ */
62
+ export declare class EventbriteConnector extends BaseRESTIntegrationConnector {
63
+ /** Cached auth context (token + resolved host). */
64
+ private authState;
65
+ /** Timestamp of the last outbound request, used for throttling. */
66
+ private lastRequestTime;
67
+ /** Watermark for the current FetchChanges cycle, emitted as the IO's incremental param. */
68
+ private currentWatermark;
69
+ /** Verbatim from the metadata Integration row — part of the three-way name invariant. */
70
+ get IntegrationName(): string;
71
+ get SupportsCreate(): boolean;
72
+ get SupportsUpdate(): boolean;
73
+ get SupportsDelete(): boolean;
74
+ /**
75
+ * Eventbrite documents a default 2,000 calls/hour per token (HTTP 429 HIT_RATE_LIMIT
76
+ * over it). Run under that ceiling; the engine's AIMD bucket throttles + backs off.
77
+ */
78
+ get RateLimitPolicy(): RateLimitPolicy | null;
79
+ /**
80
+ * Cap how many EVENT/ORG parents a second-layer object (TicketClass, Attendee, Question,
81
+ * EventTeam, InventoryTier, …) iterates per FetchChanges call. At Eventbrite's deliberately
82
+ * conservative 0.27 tok/s (~3.7 s/request once the SHARED burst is spent by earlier objects in
83
+ * the same sync), the base default of 10 parents costs ~37 s and blows the 30 s FetchChanges
84
+ * op-timeout — the batch is then abandoned and the object syncs 0 records for any org with that
85
+ * many events. A batch of 4 costs ~15 s (well under 30 s) and the engine resumes the remaining
86
+ * parents via HasMore/keyset, so a high-event-count org still syncs completely.
87
+ */
88
+ protected TemplateVarParentBatchSize(): number;
89
+ /** Parse Eventbrite's Retry-After header (delta-seconds or HTTP-date) into milliseconds. */
90
+ ExtractRetryAfterMs(error: unknown): number | undefined;
91
+ /**
92
+ * Verifies connectivity via `GET /users/me/`. A 2xx confirms the Bearer token is valid;
93
+ * a 401/403 means the token was rejected (NOT_AUTH / NOT_PERMITTED).
94
+ */
95
+ TestConnection(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<ConnectionTestResult>;
96
+ /**
97
+ * Sets the watermark context that {@link BuildPaginatedURL} emits as the IO's
98
+ * incremental `changed_since` param (for Order/Attendee), delegates the actual fetch +
99
+ * cursor pagination to the base, then advances the watermark from the returned records'
100
+ * `changed` field on the FINAL batch only (HasMore=false) so a partial-failure
101
+ * mid-pagination leaves the watermark unchanged.
102
+ */
103
+ FetchChanges(ctx: FetchContext): Promise<FetchBatchResult>;
104
+ /**
105
+ * Scans a batch for the latest watermark value. Eventbrite's incremental objects
106
+ * (Order, Attendee) carry a `changed` ISO-8601 timestamp per record (the field named by
107
+ * the IO's `IncrementalWatermarkField`); we take the max so the next run's `changed_since`
108
+ * resumes from there.
109
+ */
110
+ private ExtractLatestWatermark;
111
+ protected Authenticate(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<RESTAuthContext>;
112
+ /** Builds the Eventbrite auth header: `Authorization: Bearer <token>` + `Accept: application/json`. */
113
+ protected BuildHeaders(auth: RESTAuthContext): Record<string, string>;
114
+ /**
115
+ * Unwraps Eventbrite's response shapes:
116
+ * - List endpoints: `{ <responseDataKey>: [ ... ], pagination: { ... } }` → the named array.
117
+ * - Single-record detail (no responseDataKey): a bare object → a one-element array.
118
+ * - null → [].
119
+ * The IO metadata's `responseDataKey` (e.g. `events`/`attendees`/`orders`) is the
120
+ * authoritative envelope key; when absent the body is treated as a bare detail object.
121
+ */
122
+ protected NormalizeResponse(rawBody: unknown, responseDataKey: string | null): Record<string, unknown>[];
123
+ private coerceToArray;
124
+ private isRecord;
125
+ /**
126
+ * Continuation-cursor pagination: Eventbrite returns a `pagination` envelope carrying
127
+ * `has_more_items` (boolean) and `continuation` (opaque cursor token). There are more
128
+ * records while `has_more_items` is true AND a continuation token is present. The
129
+ * total record count (`object_count`) is surfaced when available.
130
+ *
131
+ * The `Cursor` pagination type drives this; non-cursor objects (`None`) report no more.
132
+ */
133
+ protected ExtractPaginationInfo(rawBody: unknown, paginationType: PaginationType, currentPage: number, currentOffset: number, _pageSize: number): PaginationState;
134
+ /**
135
+ * Builds the paginated request URL. Eventbrite cursor pagination uses `?continuation=<token>`
136
+ * (the base default emits `?cursor=...&limit=...`), so we override to emit the vendor's
137
+ * param. Also emits the IO's `IncrementalWatermarkField` as `changed_since=<watermark>`
138
+ * when this is an incremental object (Order/Attendee) and a watermark is in context —
139
+ * fully metadata-driven (read `obj.IncrementalWatermarkField` + `obj.SupportsIncrementalSync`),
140
+ * NEVER keyed off a hardcoded object name.
141
+ *
142
+ * Parent template vars ({organization_id}/{event_id}) are NOT substituted here — those are
143
+ * resolved by the engine's parent-iteration from the IO's `Configuration.parentObjectName`.
144
+ */
145
+ protected BuildPaginatedURL(basePath: string, obj: MJIntegrationObjectEntity, _page: number, _offset: number, cursor?: string, _effectivePageSize?: number): string;
146
+ /**
147
+ * Resolves the vendor-side query param name for an incremental object. Eventbrite's
148
+ * incremental filter param is `changed_since` (the IO's `IncrementalWatermarkField` is the
149
+ * RECORD field `changed`). Metadata-driven: only objects whose `SupportsIncrementalSync` is
150
+ * true and whose watermark field is set receive the param.
151
+ */
152
+ private resolveWatermarkParam;
153
+ protected GetBaseURL(_companyIntegration: MJCompanyIntegrationEntity, auth: RESTAuthContext): string;
154
+ protected MakeHTTPRequest(auth: RESTAuthContext, url: string, method: string, headers: Record<string, string>, body?: unknown): Promise<RESTResponse>;
155
+ /** Single fetch() with an AbortController-backed timeout. */
156
+ private doFetch;
157
+ private safeParseJSON;
158
+ private isRetryableError;
159
+ private backoffMs;
160
+ private backoffFromResponse;
161
+ private throttle;
162
+ private sleep;
163
+ private asObject;
164
+ /**
165
+ * Resolves the connection config: the Bearer token from the credential store; the
166
+ * non-secret host override + transport tunables from CompanyIntegration.Configuration.
167
+ * Secrets are NEVER baked into code.
168
+ */
169
+ private parseConfig;
170
+ /** Resolves the API host: the non-secret override wins over the production host. */
171
+ private resolveBaseUrl;
172
+ /** Parses the non-secret host/tunables config from CompanyIntegration.Configuration JSON. */
173
+ private parseConfigurationJson;
174
+ /** Loads the Bearer token from the MJ credential store. */
175
+ private loadFromCredential;
176
+ }
177
+ /** Tree-shaking prevention function — import and call from the package entry point. */
178
+ export declare function LoadEventbriteConnector(): void;
@@ -0,0 +1,488 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { RegisterClass } from '@memberjunction/global';
8
+ import { Metadata } from '@memberjunction/core';
9
+ import { BaseIntegrationConnector, BaseRESTIntegrationConnector, } from '@memberjunction/integration-engine';
10
+ // ─── Constants ────────────────────────────────────────────────────────
11
+ const PROD_API_HOST = 'https://www.eventbriteapi.com/v3';
12
+ const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
13
+ const DEFAULT_MAX_RETRIES = 4;
14
+ const DEFAULT_MIN_REQUEST_INTERVAL_MS = 100;
15
+ /**
16
+ * Eventbrite documents a default rate limit of 2,000 calls per hour per token
17
+ * (≈0.55/s). Run conservatively under that: ~0.27 tokens/s with a small burst so the
18
+ * engine's AIMD bucket throttles + backs off on the 429 HIT_RATE_LIMIT error.
19
+ */
20
+ const RATE_LIMIT_TOKENS_PER_SEC = 0.27;
21
+ const RATE_LIMIT_BURST = 10;
22
+ // ─── Connector implementation ─────────────────────────────────────────
23
+ /**
24
+ * Connector for the Eventbrite Platform REST API v3.
25
+ *
26
+ * Authenticates via a Bearer token (private token or OAuth2 access token, resolved
27
+ * upstream and held in the credential store). Reads ride the base
28
+ * {@link BaseRESTIntegrationConnector} pull path; this class overrides only the
29
+ * genuinely Eventbrite-specific bits:
30
+ * - {@link BuildHeaders}: `Authorization: Bearer <token>` + `Accept: application/json`.
31
+ * - {@link GetBaseURL}: the shared `https://www.eventbriteapi.com/v3` host (or a
32
+ * non-secret `ApiBaseUrl` override for mock testing).
33
+ * - {@link NormalizeResponse}: unwraps the named-key list envelope (the IO's
34
+ * `ResponseDataKey`, e.g. `events`/`attendees`/`orders`) which sits alongside a
35
+ * `pagination` object; a bare object is a one-record detail; null → [].
36
+ * - {@link ExtractPaginationInfo} / {@link BuildPaginatedURL}: Eventbrite continuation-cursor
37
+ * pagination (`?continuation=<token>` + `pagination.has_more_items`/`.continuation`),
38
+ * plus the `changed_since=<watermark>` param for incremental objects (Order/Attendee) —
39
+ * fully metadata-driven (read `obj.IncrementalWatermarkField` + `obj.SupportsIncrementalSync`),
40
+ * NEVER keyed off a hardcoded object name.
41
+ * - {@link FetchChanges}: sets the watermark context, delegates to the base, then advances
42
+ * the watermark from the records' `changed` field on the final batch only (HasMore=false)
43
+ * so a partial-failure mid-pagination leaves the watermark unchanged.
44
+ *
45
+ * Create/Update/Delete use the generic per-operation column path
46
+ * (CreateAPIPath/Method/BodyShape/BodyKey/IDLocation, Update*, Delete*) driven entirely
47
+ * by the IO metadata — no per-verb override. Eventbrite uses POST for update (its
48
+ * convention) and wrapped bodies for most resources (CreateBodyKey =
49
+ * event|ticket_class|venue|discount|question|webhook|...). Parent template vars
50
+ * ({organization_id}/{event_id}) are resolved by the engine's parent-iteration from each
51
+ * IO's `Configuration.parentObjectName`.
52
+ */
53
+ let EventbriteConnector = class EventbriteConnector extends BaseRESTIntegrationConnector {
54
+ constructor() {
55
+ super(...arguments);
56
+ /** Cached auth context (token + resolved host). */
57
+ this.authState = null;
58
+ /** Timestamp of the last outbound request, used for throttling. */
59
+ this.lastRequestTime = 0;
60
+ }
61
+ // ── Identity + capability getters ───────────────────────────────────
62
+ /** Verbatim from the metadata Integration row — part of the three-way name invariant. */
63
+ get IntegrationName() { return 'Eventbrite'; }
64
+ // Eventbrite exposes a documented write API for a subset of objects (Events, Ticket
65
+ // Classes, Venues, Discounts, Questions, Webhooks, Ticket Groups, Inventory Tiers, Event
66
+ // Teams, Media). The generic per-operation path enforces null-capability honesty per IO
67
+ // (an IO with no CreateAPIPath throws on create), so these getters reflect that SOME IOs
68
+ // are writable; the actual writable set is each IO's per-op columns in the metadata.
69
+ get SupportsCreate() { return true; }
70
+ get SupportsUpdate() { return true; }
71
+ get SupportsDelete() { return true; }
72
+ // ── Sync-efficiency hooks ───────────────────────────────────────────
73
+ /**
74
+ * Eventbrite documents a default 2,000 calls/hour per token (HTTP 429 HIT_RATE_LIMIT
75
+ * over it). Run under that ceiling; the engine's AIMD bucket throttles + backs off.
76
+ */
77
+ get RateLimitPolicy() {
78
+ return { TokensPerSec: RATE_LIMIT_TOKENS_PER_SEC, Burst: RATE_LIMIT_BURST, ThrottleBackoffFactor: 0.5 };
79
+ }
80
+ /**
81
+ * Cap how many EVENT/ORG parents a second-layer object (TicketClass, Attendee, Question,
82
+ * EventTeam, InventoryTier, …) iterates per FetchChanges call. At Eventbrite's deliberately
83
+ * conservative 0.27 tok/s (~3.7 s/request once the SHARED burst is spent by earlier objects in
84
+ * the same sync), the base default of 10 parents costs ~37 s and blows the 30 s FetchChanges
85
+ * op-timeout — the batch is then abandoned and the object syncs 0 records for any org with that
86
+ * many events. A batch of 4 costs ~15 s (well under 30 s) and the engine resumes the remaining
87
+ * parents via HasMore/keyset, so a high-event-count org still syncs completely.
88
+ */
89
+ TemplateVarParentBatchSize() {
90
+ return 4;
91
+ }
92
+ /** Parse Eventbrite's Retry-After header (delta-seconds or HTTP-date) into milliseconds. */
93
+ ExtractRetryAfterMs(error) {
94
+ const headers = error?.Headers;
95
+ if (!headers)
96
+ return undefined;
97
+ const retryAfter = headers['retry-after'] ?? headers['Retry-After'];
98
+ if (typeof retryAfter !== 'string' || retryAfter.length === 0)
99
+ return undefined;
100
+ const asSeconds = Number(retryAfter);
101
+ if (!isNaN(asSeconds) && asSeconds >= 0)
102
+ return Math.round(asSeconds * 1000);
103
+ const asDate = Date.parse(retryAfter);
104
+ if (!isNaN(asDate)) {
105
+ const delta = asDate - Date.now();
106
+ if (delta > 0)
107
+ return delta;
108
+ }
109
+ return undefined;
110
+ }
111
+ // ─── TestConnection ──────────────────────────────────────────────
112
+ /**
113
+ * Verifies connectivity via `GET /users/me/`. A 2xx confirms the Bearer token is valid;
114
+ * a 401/403 means the token was rejected (NOT_AUTH / NOT_PERMITTED).
115
+ */
116
+ async TestConnection(companyIntegration, contextUser) {
117
+ try {
118
+ const auth = await this.Authenticate(companyIntegration, contextUser);
119
+ const headers = this.BuildHeaders(auth);
120
+ const probeUrl = `${auth.BaseUrl}/users/me/`;
121
+ const resp = await this.MakeHTTPRequest(auth, probeUrl, 'GET', headers);
122
+ if (resp.Status === 401 || resp.Status === 403) {
123
+ return { Success: false, Message: `Eventbrite TestConnection failed: HTTP ${resp.Status} (token rejected)` };
124
+ }
125
+ if (resp.Status >= 500) {
126
+ return { Success: false, Message: `Eventbrite TestConnection failed: HTTP ${resp.Status} (server error)` };
127
+ }
128
+ if (resp.Status < 200 || resp.Status >= 300) {
129
+ return { Success: false, Message: `Eventbrite returned HTTP ${resp.Status} from ${probeUrl}` };
130
+ }
131
+ return {
132
+ Success: true,
133
+ Message: `Connected to Eventbrite Platform API v3 at ${auth.BaseUrl}`,
134
+ ServerVersion: 'Eventbrite API v3',
135
+ };
136
+ }
137
+ catch (err) {
138
+ const message = err instanceof Error ? err.message : String(err);
139
+ return { Success: false, Message: `Connection failed: ${message}` };
140
+ }
141
+ }
142
+ // ─── FetchChanges (watermark-aware) ───────────────────────────────
143
+ /**
144
+ * Sets the watermark context that {@link BuildPaginatedURL} emits as the IO's
145
+ * incremental `changed_since` param (for Order/Attendee), delegates the actual fetch +
146
+ * cursor pagination to the base, then advances the watermark from the returned records'
147
+ * `changed` field on the FINAL batch only (HasMore=false) so a partial-failure
148
+ * mid-pagination leaves the watermark unchanged.
149
+ */
150
+ async FetchChanges(ctx) {
151
+ this.currentWatermark = ctx.WatermarkValue ?? undefined;
152
+ const result = await super.FetchChanges(ctx);
153
+ const obj = this.GetCachedObject(ctx.CompanyIntegration.IntegrationID, ctx.ObjectName);
154
+ if (obj.SupportsIncrementalSync && obj.IncrementalWatermarkField && !result.HasMore) {
155
+ const advanced = this.ExtractLatestWatermark(result.Records, obj.IncrementalWatermarkField);
156
+ const newWatermark = advanced ?? ctx.WatermarkValue ?? undefined;
157
+ if (newWatermark != null)
158
+ return { ...result, NewWatermarkValue: newWatermark };
159
+ }
160
+ return result;
161
+ }
162
+ /**
163
+ * Scans a batch for the latest watermark value. Eventbrite's incremental objects
164
+ * (Order, Attendee) carry a `changed` ISO-8601 timestamp per record (the field named by
165
+ * the IO's `IncrementalWatermarkField`); we take the max so the next run's `changed_since`
166
+ * resumes from there.
167
+ */
168
+ ExtractLatestWatermark(records, watermarkField) {
169
+ let latest = null;
170
+ for (const rec of records) {
171
+ const raw = rec.Fields?.[watermarkField];
172
+ if (typeof raw !== 'string' || raw.length === 0)
173
+ continue;
174
+ const d = new Date(raw);
175
+ if (!isNaN(d.getTime()) && (latest === null || d > latest))
176
+ latest = d;
177
+ }
178
+ return latest ? latest.toISOString() : null;
179
+ }
180
+ // ─── Auth + transport (abstract base requirements) ────────────────
181
+ async Authenticate(companyIntegration, contextUser) {
182
+ if (this.authState)
183
+ return this.authState;
184
+ const config = await this.parseConfig(companyIntegration, contextUser);
185
+ const state = {
186
+ Token: config.Token ?? '',
187
+ BaseUrl: this.resolveBaseUrl(config),
188
+ Config: config,
189
+ };
190
+ this.authState = state;
191
+ return state;
192
+ }
193
+ /** Builds the Eventbrite auth header: `Authorization: Bearer <token>` + `Accept: application/json`. */
194
+ BuildHeaders(auth) {
195
+ const ebAuth = auth;
196
+ return {
197
+ 'Authorization': `Bearer ${ebAuth.Token}`,
198
+ 'Accept': 'application/json',
199
+ 'Content-Type': 'application/json',
200
+ };
201
+ }
202
+ /**
203
+ * Unwraps Eventbrite's response shapes:
204
+ * - List endpoints: `{ <responseDataKey>: [ ... ], pagination: { ... } }` → the named array.
205
+ * - Single-record detail (no responseDataKey): a bare object → a one-element array.
206
+ * - null → [].
207
+ * The IO metadata's `responseDataKey` (e.g. `events`/`attendees`/`orders`) is the
208
+ * authoritative envelope key; when absent the body is treated as a bare detail object.
209
+ */
210
+ NormalizeResponse(rawBody, responseDataKey) {
211
+ if (rawBody == null)
212
+ return [];
213
+ const asObj = this.asObject(rawBody);
214
+ // Explicit metadata-declared envelope key wins (the list case).
215
+ if (responseDataKey && asObj) {
216
+ if (responseDataKey in asObj)
217
+ return this.coerceToArray(asObj[responseDataKey]);
218
+ // Key declared but absent (e.g. an error or empty envelope) — nothing to emit.
219
+ return [];
220
+ }
221
+ if (asObj) {
222
+ // Bare single-record detail object (no responseDataKey, e.g. User / Media / Organizer).
223
+ return [asObj];
224
+ }
225
+ // Bare array fallback (defensive — Eventbrite list shapes are always keyed).
226
+ if (Array.isArray(rawBody))
227
+ return rawBody.filter(this.isRecord);
228
+ return [];
229
+ }
230
+ coerceToArray(node) {
231
+ if (Array.isArray(node))
232
+ return node.filter(this.isRecord);
233
+ if (node && typeof node === 'object')
234
+ return [node];
235
+ return [];
236
+ }
237
+ isRecord(node) {
238
+ return node != null && typeof node === 'object' && !Array.isArray(node);
239
+ }
240
+ /**
241
+ * Continuation-cursor pagination: Eventbrite returns a `pagination` envelope carrying
242
+ * `has_more_items` (boolean) and `continuation` (opaque cursor token). There are more
243
+ * records while `has_more_items` is true AND a continuation token is present. The
244
+ * total record count (`object_count`) is surfaced when available.
245
+ *
246
+ * The `Cursor` pagination type drives this; non-cursor objects (`None`) report no more.
247
+ */
248
+ ExtractPaginationInfo(rawBody, paginationType, currentPage, currentOffset, _pageSize) {
249
+ if (paginationType !== 'Cursor') {
250
+ return { HasMore: false, NextPage: currentPage, NextOffset: currentOffset };
251
+ }
252
+ const asObj = this.asObject(rawBody);
253
+ const pagination = asObj ? this.asObject(asObj['pagination']) : undefined;
254
+ const hasMore = pagination?.has_more_items === true
255
+ && typeof pagination?.continuation === 'string'
256
+ && pagination.continuation.length > 0;
257
+ const totalRecords = typeof pagination?.object_count === 'number' ? pagination.object_count : undefined;
258
+ return {
259
+ HasMore: hasMore,
260
+ NextPage: currentPage + 1,
261
+ NextOffset: currentOffset,
262
+ NextCursor: hasMore ? pagination?.continuation : undefined,
263
+ TotalRecords: totalRecords,
264
+ };
265
+ }
266
+ /**
267
+ * Builds the paginated request URL. Eventbrite cursor pagination uses `?continuation=<token>`
268
+ * (the base default emits `?cursor=...&limit=...`), so we override to emit the vendor's
269
+ * param. Also emits the IO's `IncrementalWatermarkField` as `changed_since=<watermark>`
270
+ * when this is an incremental object (Order/Attendee) and a watermark is in context —
271
+ * fully metadata-driven (read `obj.IncrementalWatermarkField` + `obj.SupportsIncrementalSync`),
272
+ * NEVER keyed off a hardcoded object name.
273
+ *
274
+ * Parent template vars ({organization_id}/{event_id}) are NOT substituted here — those are
275
+ * resolved by the engine's parent-iteration from the IO's `Configuration.parentObjectName`.
276
+ */
277
+ BuildPaginatedURL(basePath, obj, _page, _offset, cursor, _effectivePageSize) {
278
+ const separator = basePath.includes('?') ? '&' : '?';
279
+ const params = new URLSearchParams();
280
+ // Incremental param (changed_since) for objects that declare a watermark field.
281
+ const watermarkParam = this.resolveWatermarkParam(obj);
282
+ if (obj.SupportsIncrementalSync && watermarkParam && this.currentWatermark) {
283
+ params.set(watermarkParam, this.currentWatermark);
284
+ }
285
+ // Continuation cursor for the Cursor pagination type (after the first page).
286
+ if (obj.PaginationType === 'Cursor' && cursor) {
287
+ params.set('continuation', cursor);
288
+ }
289
+ const qs = params.toString();
290
+ return qs.length > 0 ? `${basePath}${separator}${qs}` : basePath;
291
+ }
292
+ /**
293
+ * Resolves the vendor-side query param name for an incremental object. Eventbrite's
294
+ * incremental filter param is `changed_since` (the IO's `IncrementalWatermarkField` is the
295
+ * RECORD field `changed`). Metadata-driven: only objects whose `SupportsIncrementalSync` is
296
+ * true and whose watermark field is set receive the param.
297
+ */
298
+ resolveWatermarkParam(obj) {
299
+ if (!obj.SupportsIncrementalSync || !obj.IncrementalWatermarkField)
300
+ return undefined;
301
+ return 'changed_since';
302
+ }
303
+ GetBaseURL(_companyIntegration, auth) {
304
+ return auth.BaseUrl;
305
+ }
306
+ // ─── HTTP transport with retry + throttling ───────────────────────
307
+ async MakeHTTPRequest(auth, url, method, headers, body) {
308
+ const ebAuth = auth;
309
+ const cfg = ebAuth.Config;
310
+ const maxRetries = cfg.MaxRetries ?? DEFAULT_MAX_RETRIES;
311
+ const timeoutMs = cfg.RequestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
312
+ const minInterval = cfg.MinRequestIntervalMs ?? DEFAULT_MIN_REQUEST_INTERVAL_MS;
313
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
314
+ await this.throttle(minInterval);
315
+ try {
316
+ const resp = await this.doFetch(url, method, headers, body, timeoutMs);
317
+ this.lastRequestTime = Date.now();
318
+ if ((resp.Status === 429 || resp.Status === 503) && attempt < maxRetries) {
319
+ await this.sleep(this.backoffFromResponse(resp, attempt));
320
+ continue;
321
+ }
322
+ return resp;
323
+ }
324
+ catch (err) {
325
+ if (attempt === maxRetries)
326
+ throw err;
327
+ if (!this.isRetryableError(err))
328
+ throw err;
329
+ await this.sleep(this.backoffMs(attempt));
330
+ }
331
+ }
332
+ throw new Error(`Eventbrite request to ${url} exhausted ${maxRetries + 1} attempts`);
333
+ }
334
+ /** Single fetch() with an AbortController-backed timeout. */
335
+ async doFetch(url, method, headers, body, timeoutMs) {
336
+ const controller = new AbortController();
337
+ const handle = setTimeout(() => controller.abort(), timeoutMs);
338
+ try {
339
+ const resp = await fetch(url, {
340
+ method,
341
+ headers,
342
+ body: body !== undefined && method !== 'GET' ? JSON.stringify(body) : undefined,
343
+ signal: controller.signal,
344
+ });
345
+ const respHeaders = {};
346
+ resp.headers.forEach((value, key) => { respHeaders[key.toLowerCase()] = value; });
347
+ const text = await resp.text();
348
+ const parsed = text.length > 0 ? this.safeParseJSON(text) : null;
349
+ return { Status: resp.status, Body: parsed, Headers: respHeaders };
350
+ }
351
+ finally {
352
+ clearTimeout(handle);
353
+ }
354
+ }
355
+ safeParseJSON(text) {
356
+ try {
357
+ return JSON.parse(text);
358
+ }
359
+ catch {
360
+ return text;
361
+ }
362
+ }
363
+ isRetryableError(err) {
364
+ const msg = err instanceof Error ? err.message : String(err);
365
+ return /abort|timeout|ECONNRESET|ENOTFOUND|ETIMEDOUT|ECONNREFUSED|fetch failed|network/i.test(msg);
366
+ }
367
+ backoffMs(attempt) {
368
+ const base = Math.min(1000 * Math.pow(2, attempt), 20000);
369
+ const jitter = Math.floor(Math.random() * 500);
370
+ return base + jitter;
371
+ }
372
+ backoffFromResponse(resp, attempt) {
373
+ const fromHeader = this.ExtractRetryAfterMs({ Headers: resp.Headers });
374
+ if (fromHeader != null)
375
+ return Math.min(fromHeader, 30000);
376
+ return this.backoffMs(attempt);
377
+ }
378
+ async throttle(minIntervalMs) {
379
+ const elapsed = Date.now() - this.lastRequestTime;
380
+ if (elapsed < minIntervalMs)
381
+ await this.sleep(minIntervalMs - elapsed);
382
+ }
383
+ sleep(ms) {
384
+ return new Promise(resolve => setTimeout(resolve, ms));
385
+ }
386
+ asObject(node) {
387
+ return node && typeof node === 'object' && !Array.isArray(node) ? node : undefined;
388
+ }
389
+ // ─── Config parsing ───────────────────────────────────────────────
390
+ /**
391
+ * Resolves the connection config: the Bearer token from the credential store; the
392
+ * non-secret host override + transport tunables from CompanyIntegration.Configuration.
393
+ * Secrets are NEVER baked into code.
394
+ */
395
+ async parseConfig(companyIntegration, contextUser) {
396
+ const fromCredential = companyIntegration.CredentialID
397
+ ? await this.loadFromCredential(companyIntegration.CredentialID, contextUser)
398
+ : null;
399
+ const fromConfig = this.parseConfigurationJson(companyIntegration.Configuration);
400
+ const merged = { ...fromConfig, ...fromCredential };
401
+ // Credential's Token wins; host override + tunables come from Configuration.
402
+ merged.Token = (fromCredential?.Token ?? fromConfig.Token);
403
+ merged.ApiBaseUrl = merged.ApiBaseUrl ?? fromConfig.ApiBaseUrl;
404
+ merged.RequestTimeoutMs = merged.RequestTimeoutMs ?? fromConfig.RequestTimeoutMs;
405
+ merged.MaxRetries = merged.MaxRetries ?? fromConfig.MaxRetries;
406
+ merged.MinRequestIntervalMs = merged.MinRequestIntervalMs ?? fromConfig.MinRequestIntervalMs;
407
+ if (!merged.Token) {
408
+ throw new Error('EventbriteConnector: a Bearer token (PrivateToken / Token / AccessToken / apiKey) ' +
409
+ 'must be provided via the credential store or CompanyIntegration.Configuration.');
410
+ }
411
+ return merged;
412
+ }
413
+ /** Resolves the API host: the non-secret override wins over the production host. */
414
+ resolveBaseUrl(config) {
415
+ const raw = (config.ApiBaseUrl ?? PROD_API_HOST).trim();
416
+ return raw.replace(/\/+$/, '');
417
+ }
418
+ /** Parses the non-secret host/tunables config from CompanyIntegration.Configuration JSON. */
419
+ parseConfigurationJson(raw) {
420
+ if (!raw || raw.trim().length === 0)
421
+ return {};
422
+ let parsed;
423
+ try {
424
+ parsed = JSON.parse(raw);
425
+ }
426
+ catch {
427
+ throw new Error('EventbriteConnector: CompanyIntegration.Configuration is not valid JSON.');
428
+ }
429
+ const str = (...keys) => {
430
+ for (const k of keys) {
431
+ const hit = Object.entries(parsed).find(([key]) => key.toLowerCase() === k.toLowerCase());
432
+ if (hit && typeof hit[1] === 'string' && hit[1].length > 0)
433
+ return hit[1];
434
+ }
435
+ return undefined;
436
+ };
437
+ const num = (...keys) => {
438
+ for (const k of keys) {
439
+ const hit = Object.entries(parsed).find(([key]) => key.toLowerCase() === k.toLowerCase());
440
+ if (hit && typeof hit[1] === 'number')
441
+ return hit[1];
442
+ }
443
+ return undefined;
444
+ };
445
+ return {
446
+ // A token MAY be carried in Configuration for credential-free replay harnesses;
447
+ // the credential store remains preferred (parseConfig gives fromCredential precedence).
448
+ Token: str('PrivateToken', 'Token', 'AccessToken', 'accessToken', 'apiKey', 'api_key'),
449
+ ApiBaseUrl: str('apiBaseUrl', 'api_base_url', 'APIBaseURL', 'baseUrl', 'base_url'),
450
+ RequestTimeoutMs: num('requestTimeoutMs'),
451
+ MaxRetries: num('maxRetries'),
452
+ MinRequestIntervalMs: num('minRequestIntervalMs'),
453
+ };
454
+ }
455
+ /** Loads the Bearer token from the MJ credential store. */
456
+ async loadFromCredential(credentialID, contextUser, provider) {
457
+ const md = provider ?? new Metadata();
458
+ const credential = await md.GetEntityObject('MJ: Credentials', contextUser);
459
+ const loaded = await credential.Load(credentialID);
460
+ if (!loaded || !credential.Values)
461
+ return null;
462
+ let raw;
463
+ try {
464
+ raw = JSON.parse(credential.Values);
465
+ }
466
+ catch {
467
+ return null;
468
+ }
469
+ const get = (...keys) => {
470
+ for (const k of keys) {
471
+ const hit = Object.entries(raw).find(([key]) => key.toLowerCase() === k.toLowerCase());
472
+ if (hit && typeof hit[1] === 'string')
473
+ return hit[1];
474
+ }
475
+ return undefined;
476
+ };
477
+ return {
478
+ Token: get('PrivateToken', 'Token', 'AccessToken', 'accessToken', 'apiKey', 'api_key', 'key'),
479
+ };
480
+ }
481
+ };
482
+ EventbriteConnector = __decorate([
483
+ RegisterClass(BaseIntegrationConnector, 'EventbriteConnector')
484
+ ], EventbriteConnector);
485
+ export { EventbriteConnector };
486
+ /** Tree-shaking prevention function — import and call from the package entry point. */
487
+ export function LoadEventbriteConnector() { }
488
+ //# sourceMappingURL=EventbriteConnector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventbriteConnector.js","sourceRoot":"","sources":["../src/EventbriteConnector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './EventbriteConnector.js';
2
+ /** Open App bootstrap entry: importing this module ran the connector's @RegisterClass decorator;
3
+ * this no-op satisfies the loader's required startupExport and forces the import at MJAPI boot. */
4
+ export declare function registerConnector(): void;
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './EventbriteConnector.js';
2
+ /** Open App bootstrap entry: importing this module ran the connector's @RegisterClass decorator;
3
+ * this no-op satisfies the loader's required startupExport and forces the import at MJAPI boot. */
4
+ export function registerConnector() { }
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AAEzC;oGACoG;AACpG,MAAM,UAAU,iBAAiB,KAAiD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@memberjunction/connector-eventbrite",
3
+ "version": "1.0.0",
4
+ "description": "MemberJunction Eventbrite connector.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "/dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc && tsc-alias -f",
13
+ "test": "vitest run --passWithNoTests"
14
+ },
15
+ "author": "MemberJunction.com",
16
+ "license": "ISC",
17
+ "peerDependencies": {
18
+ "@memberjunction/core": ">=5.42.0 <6.0.0",
19
+ "@memberjunction/core-entities": ">=5.42.0 <6.0.0",
20
+ "@memberjunction/global": ">=5.42.0 <6.0.0",
21
+ "@memberjunction/integration-engine": ">=5.42.0 <6.0.0",
22
+ "@memberjunction/integration-engine-base": ">=5.42.0 <6.0.0"
23
+ },
24
+ "dependencies": {},
25
+ "devDependencies": {
26
+ "@types/node": "24.10.11",
27
+ "tsc-alias": "^1.8.16",
28
+ "typescript": "^5.9.3",
29
+ "vitest": "^4.0.18",
30
+ "@memberjunction/core": "^5.42.0",
31
+ "@memberjunction/core-entities": "^5.42.0",
32
+ "@memberjunction/global": "^5.42.0",
33
+ "@memberjunction/integration-engine": "^5.42.0",
34
+ "@memberjunction/integration-engine-base": "^5.42.0"
35
+ },
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/MemberJunction/Integrations"
39
+ }
40
+ }