@memberjunction/connector-cvent 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,145 @@
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 RateLimitPolicy, type ConnectionTestResult, type ExternalObjectSchema, type ExternalFieldSchema, type FetchContext, type FetchBatchResult } from '@memberjunction/integration-engine';
4
+ /**
5
+ * OAuth2 client-credentials connection config for Cvent, parsed from the attached MJ
6
+ * Credential (preferred) or the CompanyIntegration.Configuration JSON. Field names are read
7
+ * case-insensitively. None of these values are read at build time — they are resolved from
8
+ * the bound credential at runtime.
9
+ */
10
+ export interface CventConnectionConfig {
11
+ /** OAuth2 client identifier (Cvent API application key). */
12
+ ClientId: string;
13
+ /** OAuth2 client secret (Cvent API application secret). */
14
+ ClientSecret: string;
15
+ /** Optional token-endpoint override; defaults to the documented Cvent token URL. */
16
+ TokenURL?: string;
17
+ /** Optional REST base host override (e.g. the EUR host). Defaults to the US platform host. */
18
+ BaseURL?: string;
19
+ /** Optional space-delimited OAuth2 scopes ({domain}/{resource}:{action}). */
20
+ Scope?: string;
21
+ /** Maximum retries for rate-limited / transient failures. Default 4. */
22
+ MaxRetries?: number;
23
+ /** HTTP request timeout in ms. Default 30000. */
24
+ RequestTimeoutMs?: number;
25
+ }
26
+ export declare class CventConnector extends BaseRESTIntegrationConnector {
27
+ /** Cached auth context for the current sync run. */
28
+ private authCache;
29
+ /** Shared OAuth2 token manager — owns the token round-trip + cache (no inline crypto). */
30
+ private readonly tokenManager;
31
+ /** Current watermark value, emitted as the IO's IncrementalWatermarkField on the request. */
32
+ private currentWatermark;
33
+ get IntegrationName(): string;
34
+ get SupportsCreate(): boolean;
35
+ get SupportsUpdate(): boolean;
36
+ get SupportsDelete(): boolean;
37
+ /** True when any cached IntegrationObject satisfies the predicate. []→false when the engine
38
+ * cache is unavailable (capability probed before configuration) — fail-safe read-only. */
39
+ private anyObjectDeclares;
40
+ /**
41
+ * Conservative seed rate; the engine's AIMD token bucket auto-tunes from the observed
42
+ * X-RateLimit / 429 / Retry-After signal. ThrottleBackoffFactor halves the rate on a throttle.
43
+ */
44
+ get RateLimitPolicy(): RateLimitPolicy;
45
+ /**
46
+ * Parses a `Retry-After` header (seconds or http-date) or an `X-RateLimit-Reset` epoch into ms.
47
+ * Cvent returns `429` + `Retry-After` and `X-RateLimit-*` headers per the frozen contract.
48
+ */
49
+ ExtractRetryAfterMs(error: unknown): number | undefined;
50
+ /**
51
+ * OAuth2 client-credentials authentication. Mints/caches the access token via the shared
52
+ * {@link OAuth2TokenManager} (Basic-auth client credentials, grant_type=client_credentials).
53
+ */
54
+ protected Authenticate(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<RESTAuthContext>;
55
+ /**
56
+ * Resolves the token endpoint. An absolute `TokenURL` is used verbatim; a relative one is
57
+ * resolved against the configured `BaseURL`'s origin (Cvent's token + API share a host, so a
58
+ * region/base-URL override — or a test origin — carries the token endpoint with it).
59
+ */
60
+ private resolveTokenURL;
61
+ /** Runs the client_credentials token round-trip through OAuth2TokenManager (Basic auth). */
62
+ private MintToken;
63
+ /** Sends the OAuth2 bearer token on every request. */
64
+ protected BuildHeaders(auth: RESTAuthContext): Record<string, string>;
65
+ protected GetBaseURL(_companyIntegration: MJCompanyIntegrationEntity, auth: RESTAuthContext): string;
66
+ /**
67
+ * Normalizes Cvent responses. Cvent list endpoints return `{ data: [...], paging: {...} }`;
68
+ * detail (GET /resource/{id}) endpoints return a single object. An IO may declare its own
69
+ * ResponseDataKey; otherwise the connector reads the standard `data[]` envelope. Empty strings
70
+ * are coerced to null so date/optional columns persist cleanly. The FULL source record passes
71
+ * through (no field filtering) so the framework's custom-column capture sees everything returned.
72
+ */
73
+ protected NormalizeResponse(rawBody: unknown, responseDataKey: string | null): Record<string, unknown>[];
74
+ /**
75
+ * Derives Cursor pagination state from the response `paging.nextToken` field. A non-empty
76
+ * nextToken means another page exists; null/absent means this was the last page. The base
77
+ * pagination loop carries the cursor internally (NextCursor → next BuildPaginatedURL `token`).
78
+ */
79
+ protected ExtractPaginationInfo(rawBody: unknown, _paginationType: PaginationType, _currentPage: number, _currentOffset: number, _pageSize: number): PaginationState;
80
+ /**
81
+ * Emits Cvent cursor params (`token`/`limit`) plus, for an incremental IO, the vendor watermark
82
+ * param. The watermark behaviour is fully METADATA-DRIVEN: the param NAME comes from the IO's
83
+ * `IncrementalWatermarkField` and is emitted only when `SupportsIncrementalSync=true` AND a
84
+ * watermark value is in context. `limit` is clamped to the server cap (200).
85
+ */
86
+ protected BuildPaginatedURL(basePath: string, obj: MJIntegrationObjectEntity, _page: number, _offset: number, cursor?: string, effectivePageSize?: number): string;
87
+ /** Executes an HTTP request with retry/backoff for 429/503 + transient network errors. */
88
+ protected MakeHTTPRequest(auth: RESTAuthContext, url: string, method: string, headers: Record<string, string>, body?: unknown): Promise<RESTResponse>;
89
+ /**
90
+ * Tests connectivity by minting a client_credentials token and listing one Event record.
91
+ * A 2xx confirms the OAuth2 credentials + base URL are valid against the live API.
92
+ */
93
+ TestConnection(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<ConnectionTestResult>;
94
+ /**
95
+ * Discovers the full object universe from the IntegrationEngineBase cache (the Declared
96
+ * metadata). Cvent publishes its catalog credential-free (OpenAPI spec), so the baseline is
97
+ * Declared metadata — never hardcoded here, never sampled at build. A live credential is
98
+ * ADDITIVE (tenant-specific custom fields surfaced at sync via the framework's custom-column
99
+ * capture), never the baseline — so credential-free discovery re-yields the standard universe.
100
+ */
101
+ DiscoverObjects(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<ExternalObjectSchema[]>;
102
+ /** Discovers fields for an object from the cached Declared metadata. */
103
+ DiscoverFields(companyIntegration: MJCompanyIntegrationEntity, objectName: string, contextUser: UserInfo): Promise<ExternalFieldSchema[]>;
104
+ /**
105
+ * Sets the watermark context the page URL builder needs, delegates the cursor walk to the base
106
+ * (which descends nested template-var paths via FK metadata so nested IOs never silently return
107
+ * 0 rows), then advances the watermark from the returned records on the final batch only
108
+ * (partial-failure-safe — the watermark stays unchanged if the batch did not fully drain).
109
+ */
110
+ FetchChanges(ctx: FetchContext): Promise<FetchBatchResult>;
111
+ /**
112
+ * Parses the OAuth2 connection config, preferring the attached MJ Credential over the raw
113
+ * Configuration JSON. Credential bytes are resolved at runtime — never at build.
114
+ */
115
+ private ParseConfig;
116
+ /** Loads the OAuth2 config from the MJ: Credentials entity Values JSON. */
117
+ private ParseConfigFromCredential;
118
+ /** Validates the parsed config + applies defaults. Field names are case-insensitive. */
119
+ private ValidateConfig;
120
+ /** Resolves the REST base URL from the credential override (e.g. EUR host), else the US default. Strips a trailing slash. */
121
+ private ResolveBaseUrl;
122
+ /** Normalizes a raw record's top-level values (empty-string → null). */
123
+ private NormalizeRecord;
124
+ /** Reads the `paging.nextToken` dot-path cursor from a response body, if present. */
125
+ private ReadNextCursor;
126
+ /**
127
+ * Extracts the latest watermark value across a batch for incremental advancement. Uses the IO's
128
+ * declared IncrementalWatermarkField when resolvable, falling back to common timestamp keys.
129
+ */
130
+ private ExtractLatestWatermark;
131
+ /** Resolves the IncrementalWatermarkField for an object from the engine cache. */
132
+ private ResolveWatermarkField;
133
+ /** Parses a Retry-After header (seconds or http-date) into ms, if present. */
134
+ private RetryAfterMs;
135
+ /** Exponential backoff delay for retry attempts (initial 2000ms, exponent 2, capped at 16000ms). */
136
+ private BackoffDelay;
137
+ /** Checks whether an error is transient (network/timeout). */
138
+ private IsTransientNetworkError;
139
+ /** Builds the normalized RESTResponse from a fetch Response. */
140
+ private BuildRESTResponse;
141
+ /** Promise-wrapped setTimeout. */
142
+ private Sleep;
143
+ }
144
+ /** Tree-shaking prevention — import and call from the package entry point. */
145
+ export declare function LoadCventConnector(): void;
@@ -0,0 +1,540 @@
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
+ /**
8
+ * CventConnector — Integration connector for the Cvent event-management platform via
9
+ * the Cvent Platform REST API (the `/ea` namespace on `api-platform.cvent.com`).
10
+ *
11
+ * API docs: https://developer.cvent.com/ (OpenAPI spec, published credential-free).
12
+ *
13
+ * ── Auth: OAuth2 client_credentials ──────────────────────────────────────────
14
+ * Mints/caches a bearer ACCESS TOKEN via the shared {@link OAuth2TokenManager}
15
+ * (no inlined token/crypto). Cvent runs a 2-legged client-credentials flow:
16
+ * POST {tokenURL} body: grant_type=client_credentials
17
+ * Authorization: Basic base64(client_id:client_secret)
18
+ * Token lifetime ≈ 60 min; the manager re-acquires via client credentials when the
19
+ * cached token is near expiry. Every API request sends `Authorization: Bearer {token}`.
20
+ *
21
+ * ── Base URL (region-aware) ──────────────────────────────────────────────────
22
+ * Default REST host `https://api-platform.cvent.com` (the `/ea` version segment is
23
+ * carried on the IO APIPaths). An EUR tenant uses `https://api-platform-eur.cvent.com/ea`.
24
+ * The region/base-URL override is read from the credential/config — never hardcoded.
25
+ *
26
+ * ── Catalog (metadata-driven, NOT hardcoded) ─────────────────────────────────
27
+ * The 179-object / 2192-field universe comes from the Declared metadata seeded in
28
+ * `metadata/integrations/cvent/.cvent.integration.json` (case 1 — Cvent publishes its
29
+ * OpenAPI spec credential-free). The connector NEVER bakes an object/field catalog into
30
+ * code; DiscoverObjects/DiscoverFields read the engine cache.
31
+ *
32
+ * ── Pagination & incremental ─────────────────────────────────────────────────
33
+ * Cursor pagination: request `limit` (default 100, max 200) + an opaque `token`; the
34
+ * next cursor is read from the response body field `paging.nextToken` (null/absent ⇒
35
+ * last page). Records arrive under `data[]`. Incremental sync is metadata-driven: an IO
36
+ * with `SupportsIncrementalSync=true` emits its `IncrementalWatermarkField` (a documented
37
+ * timestamp filter, e.g. `lastModified`/`modified`) carrying the watermark.
38
+ *
39
+ * ── Write ─────────────────────────────────────────────────────────────────────
40
+ * The generic per-operation CRUD path on the base reads each IO's Create/Update/Delete
41
+ * columns (BodyShape=flat; Create ID from response body; Update/Delete ID in the path).
42
+ * Write capability is METADATA-DRIVEN. Create routes through the base's BuildCreatedResult.
43
+ */
44
+ import { RegisterClass } from '@memberjunction/global';
45
+ import { Metadata } from '@memberjunction/core';
46
+ import { BaseIntegrationConnector, BaseRESTIntegrationConnector, OAuth2TokenManager, } from '@memberjunction/integration-engine';
47
+ import { IntegrationEngineBase } from '@memberjunction/integration-engine-base';
48
+ // ─── Constants ───────────────────────────────────────────────────────
49
+ /** Documented Cvent token endpoint (client_credentials grant). */
50
+ const DEFAULT_TOKEN_URL = 'https://api-platform.cvent.com/ea/oauth2/token';
51
+ /** Default REST host (US platform). The `/ea` version segment lives on the IO APIPaths. */
52
+ const DEFAULT_BASE_URL = 'https://api-platform.cvent.com/ea';
53
+ /** Cursor pagination params (from Configuration.PaginationDefaults). */
54
+ const CURSOR_PARAM = 'token';
55
+ const PAGE_SIZE_PARAM = 'limit';
56
+ /** Server-side max page size; default 100. */
57
+ const CVENT_MAX_PAGE_SIZE = 200;
58
+ const DEFAULT_PAGE_SIZE = 100;
59
+ /** Response field carrying the next cursor (dot-path `paging.nextToken`). */
60
+ const NEXT_CURSOR_PATH = ['paging', 'nextToken'];
61
+ /** Response field carrying the record array. */
62
+ const DATA_KEY = 'data';
63
+ const DEFAULT_MAX_RETRIES = 4;
64
+ const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
65
+ /** Retry backoff (Configuration.RetryBackoff*): initial 2000ms, exponent 2, max 16000ms. */
66
+ const RETRY_BACKOFF_INITIAL_MS = 2_000;
67
+ const RETRY_BACKOFF_MAX_MS = 16_000;
68
+ const RETRY_BACKOFF_EXPONENT = 2;
69
+ /**
70
+ * Conservative sustained rate. Cvent surfaces X-RateLimit-* headers + 429 + Retry-After but
71
+ * does not publish a fixed numeric ceiling for the Platform API; the engine's AIMD token
72
+ * bucket auto-tunes from the observed 429/Retry-After signal off this conservative seed.
73
+ */
74
+ const CVENT_TOKENS_PER_SEC = 5;
75
+ const CVENT_BURST = 10;
76
+ // ─── Connector Implementation ────────────────────────────────────────
77
+ let CventConnector = class CventConnector extends BaseRESTIntegrationConnector {
78
+ constructor() {
79
+ super(...arguments);
80
+ /** Cached auth context for the current sync run. */
81
+ this.authCache = null;
82
+ /** Shared OAuth2 token manager — owns the token round-trip + cache (no inline crypto). */
83
+ this.tokenManager = new OAuth2TokenManager();
84
+ }
85
+ // Returns the EXACT MJ: Integrations.Name string LITERAL so the T1 ThreeWayName invariant can
86
+ // statically parse the getter's returned value. Verbatim from the identity-establisher handoff
87
+ // (metadata.fields.Name === 'Cvent').
88
+ get IntegrationName() { return 'Cvent'; }
89
+ // ── Capability getters: METADATA-DRIVEN (no hardcoded answer) ─────
90
+ //
91
+ // Write capability FOLLOWS the per-operation CRUD columns on the cached IntegrationObjects
92
+ // (Declared metadata). An object is create-capable when it declares CreateAPIPath + CreateMethod;
93
+ // same for update/delete. The base BaseRESTIntegrationConnector generic CRUD path executes the
94
+ // verb off those columns (BodyShape=flat, Create ID from response body, Update/Delete ID in path);
95
+ // Cvent's writes are standard flat-body REST that the generic per-operation path handles, so this
96
+ // connector wires no idiosyncratic write override.
97
+ get SupportsCreate() {
98
+ return this.anyObjectDeclares(o => !!o.CreateAPIPath && !!o.CreateMethod);
99
+ }
100
+ get SupportsUpdate() {
101
+ return this.anyObjectDeclares(o => !!o.UpdateAPIPath && !!o.UpdateMethod);
102
+ }
103
+ get SupportsDelete() {
104
+ return this.anyObjectDeclares(o => !!o.DeleteAPIPath && !!o.DeleteMethod);
105
+ }
106
+ /** True when any cached IntegrationObject satisfies the predicate. []→false when the engine
107
+ * cache is unavailable (capability probed before configuration) — fail-safe read-only. */
108
+ anyObjectDeclares(pred) {
109
+ const integration = IntegrationEngineBase.Instance.GetIntegrationByName('Cvent');
110
+ if (!integration)
111
+ return false;
112
+ return IntegrationEngineBase.Instance.GetActiveIntegrationObjects(integration.ID).some(pred);
113
+ }
114
+ // ── Sync-efficiency hooks (evidence from the frozen contract) ─────
115
+ /**
116
+ * Conservative seed rate; the engine's AIMD token bucket auto-tunes from the observed
117
+ * X-RateLimit / 429 / Retry-After signal. ThrottleBackoffFactor halves the rate on a throttle.
118
+ */
119
+ get RateLimitPolicy() {
120
+ return {
121
+ TokensPerSec: CVENT_TOKENS_PER_SEC,
122
+ Burst: CVENT_BURST,
123
+ ThrottleBackoffFactor: 0.5,
124
+ };
125
+ }
126
+ /**
127
+ * Parses a `Retry-After` header (seconds or http-date) or an `X-RateLimit-Reset` epoch into ms.
128
+ * Cvent returns `429` + `Retry-After` and `X-RateLimit-*` headers per the frozen contract.
129
+ */
130
+ ExtractRetryAfterMs(error) {
131
+ if (!error || typeof error !== 'object')
132
+ return undefined;
133
+ const headers = error.Headers;
134
+ if (!headers)
135
+ return undefined;
136
+ const retryAfter = headers['retry-after'];
137
+ if (retryAfter) {
138
+ const asSeconds = Number(retryAfter);
139
+ if (!Number.isNaN(asSeconds))
140
+ return Math.max(0, asSeconds * 1_000);
141
+ const asDate = new Date(retryAfter).getTime();
142
+ if (!Number.isNaN(asDate))
143
+ return Math.max(0, asDate - Date.now());
144
+ }
145
+ // X-RateLimit-Reset is an epoch-seconds instant in Cvent's headers.
146
+ const reset = headers['x-ratelimit-reset'];
147
+ if (reset) {
148
+ const resetEpoch = Number(reset);
149
+ if (!Number.isNaN(resetEpoch))
150
+ return Math.max(0, resetEpoch * 1_000 - Date.now());
151
+ }
152
+ return undefined;
153
+ }
154
+ // ─── BaseRESTIntegrationConnector abstract methods ──────────────
155
+ /**
156
+ * OAuth2 client-credentials authentication. Mints/caches the access token via the shared
157
+ * {@link OAuth2TokenManager} (Basic-auth client credentials, grant_type=client_credentials).
158
+ */
159
+ async Authenticate(companyIntegration, contextUser) {
160
+ if (this.authCache)
161
+ return this.authCache;
162
+ const config = await this.ParseConfig(companyIntegration, contextUser);
163
+ const baseUrl = this.ResolveBaseUrl(config);
164
+ const token = await this.MintToken(config);
165
+ const auth = { Token: token, BaseUrl: baseUrl, Config: config };
166
+ this.authCache = auth;
167
+ return auth;
168
+ }
169
+ /**
170
+ * Resolves the token endpoint. An absolute `TokenURL` is used verbatim; a relative one is
171
+ * resolved against the configured `BaseURL`'s origin (Cvent's token + API share a host, so a
172
+ * region/base-URL override — or a test origin — carries the token endpoint with it).
173
+ */
174
+ resolveTokenURL(config) {
175
+ const raw = config.TokenURL ?? DEFAULT_TOKEN_URL;
176
+ try {
177
+ return new URL(raw).toString();
178
+ }
179
+ catch {
180
+ const base = config.BaseURL && config.BaseURL.length > 0 ? config.BaseURL : DEFAULT_BASE_URL;
181
+ return new URL(raw, base).toString();
182
+ }
183
+ }
184
+ /** Runs the client_credentials token round-trip through OAuth2TokenManager (Basic auth). */
185
+ async MintToken(config) {
186
+ const req = {
187
+ TokenURL: this.resolveTokenURL(config),
188
+ ClientId: config.ClientId,
189
+ ClientSecret: config.ClientSecret,
190
+ // Cvent expects base64(client_id:client_secret) in a Basic Authorization header on
191
+ // the token request (client creds NOT in the form body).
192
+ UseBasicAuth: true,
193
+ Scopes: config.Scope,
194
+ ScopeParam: 'scope',
195
+ TimeoutMs: config.RequestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,
196
+ };
197
+ const token = await this.tokenManager.GetAccessToken(req, 'client_credentials');
198
+ return token.AccessToken;
199
+ }
200
+ /** Sends the OAuth2 bearer token on every request. */
201
+ BuildHeaders(auth) {
202
+ const token = auth.Token ?? auth.Token ?? '';
203
+ return {
204
+ 'Authorization': `Bearer ${token}`,
205
+ 'Accept': 'application/json',
206
+ 'Content-Type': 'application/json',
207
+ };
208
+ }
209
+ GetBaseURL(_companyIntegration, auth) {
210
+ // The /ea version segment is part of the resolved base URL; IO APIPaths are relative to it.
211
+ return auth.BaseUrl;
212
+ }
213
+ /**
214
+ * Normalizes Cvent responses. Cvent list endpoints return `{ data: [...], paging: {...} }`;
215
+ * detail (GET /resource/{id}) endpoints return a single object. An IO may declare its own
216
+ * ResponseDataKey; otherwise the connector reads the standard `data[]` envelope. Empty strings
217
+ * are coerced to null so date/optional columns persist cleanly. The FULL source record passes
218
+ * through (no field filtering) so the framework's custom-column capture sees everything returned.
219
+ */
220
+ NormalizeResponse(rawBody, responseDataKey) {
221
+ if (rawBody == null)
222
+ return [];
223
+ if (Array.isArray(rawBody)) {
224
+ return rawBody.map(r => this.NormalizeRecord(r));
225
+ }
226
+ if (typeof rawBody === 'object') {
227
+ const body = rawBody;
228
+ const key = responseDataKey ?? DATA_KEY;
229
+ if (Array.isArray(body[key])) {
230
+ return body[key].map(r => this.NormalizeRecord(r));
231
+ }
232
+ // Genuine single-object detail record (no data[] envelope).
233
+ return [this.NormalizeRecord(body)];
234
+ }
235
+ return [];
236
+ }
237
+ /**
238
+ * Derives Cursor pagination state from the response `paging.nextToken` field. A non-empty
239
+ * nextToken means another page exists; null/absent means this was the last page. The base
240
+ * pagination loop carries the cursor internally (NextCursor → next BuildPaginatedURL `token`).
241
+ */
242
+ ExtractPaginationInfo(rawBody, _paginationType, _currentPage, _currentOffset, _pageSize) {
243
+ const nextToken = this.ReadNextCursor(rawBody);
244
+ if (nextToken && nextToken.length > 0) {
245
+ return { HasMore: true, NextCursor: nextToken };
246
+ }
247
+ return { HasMore: false };
248
+ }
249
+ /**
250
+ * Emits Cvent cursor params (`token`/`limit`) plus, for an incremental IO, the vendor watermark
251
+ * param. The watermark behaviour is fully METADATA-DRIVEN: the param NAME comes from the IO's
252
+ * `IncrementalWatermarkField` and is emitted only when `SupportsIncrementalSync=true` AND a
253
+ * watermark value is in context. `limit` is clamped to the server cap (200).
254
+ */
255
+ BuildPaginatedURL(basePath, obj, _page, _offset, cursor, effectivePageSize) {
256
+ const requested = effectivePageSize ?? obj.DefaultPageSize ?? DEFAULT_PAGE_SIZE;
257
+ const limit = Math.min(Math.max(requested, 1), CVENT_MAX_PAGE_SIZE);
258
+ const separator = basePath.includes('?') ? '&' : '?';
259
+ const params = new URLSearchParams();
260
+ const watermarkField = obj.IncrementalWatermarkField;
261
+ // Only send the watermark on the FIRST page (no cursor yet); subsequent pages ride the cursor.
262
+ // Cvent's incremental filter is the `filter` DSL param (spec: `filter='field' comparisonType
263
+ // 'value'`, comparison types eq/le/ge/gt/lt) — NOT a bare `<field>=` query key (Cvent exposes
264
+ // none). Use `ge` for an inclusive server-side watermark on the record's last-modified field.
265
+ if (!cursor && obj.SupportsIncrementalSync && watermarkField && this.currentWatermark) {
266
+ params.set('filter', `${watermarkField} ge '${this.currentWatermark}'`);
267
+ }
268
+ if (cursor) {
269
+ params.set(CURSOR_PARAM, cursor);
270
+ }
271
+ params.set(PAGE_SIZE_PARAM, String(limit));
272
+ return `${basePath}${separator}${params.toString()}`;
273
+ }
274
+ /** Executes an HTTP request with retry/backoff for 429/503 + transient network errors. */
275
+ async MakeHTTPRequest(auth, url, method, headers, body) {
276
+ const cvAuth = auth;
277
+ const maxRetries = cvAuth.Config?.MaxRetries ?? DEFAULT_MAX_RETRIES;
278
+ const timeoutMs = cvAuth.Config?.RequestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
279
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
280
+ const fetchOptions = {
281
+ method,
282
+ headers,
283
+ signal: AbortSignal.timeout(timeoutMs),
284
+ };
285
+ if (body !== undefined && method !== 'GET') {
286
+ fetchOptions.body = typeof body === 'string' ? body : JSON.stringify(body);
287
+ }
288
+ let response;
289
+ try {
290
+ response = await fetch(url, fetchOptions);
291
+ }
292
+ catch (err) {
293
+ if (attempt < maxRetries && this.IsTransientNetworkError(err)) {
294
+ await this.Sleep(this.BackoffDelay(attempt));
295
+ continue;
296
+ }
297
+ throw err;
298
+ }
299
+ if ((response.status === 429 || response.status === 503) && attempt < maxRetries) {
300
+ console.warn(`[Cvent] HTTP ${response.status} from ${url} — backing off`);
301
+ await this.Sleep(this.RetryAfterMs(response) ?? this.BackoffDelay(attempt));
302
+ continue;
303
+ }
304
+ return this.BuildRESTResponse(response);
305
+ }
306
+ throw new Error(`Cvent request failed after ${maxRetries + 1} attempts: ${url}`);
307
+ }
308
+ // ─── TestConnection ──────────────────────────────────────────────
309
+ /**
310
+ * Tests connectivity by minting a client_credentials token and listing one Event record.
311
+ * A 2xx confirms the OAuth2 credentials + base URL are valid against the live API.
312
+ */
313
+ async TestConnection(companyIntegration, contextUser) {
314
+ try {
315
+ const auth = (await this.Authenticate(companyIntegration, contextUser));
316
+ const headers = this.BuildHeaders(auth);
317
+ const url = `${this.GetBaseURL(companyIntegration, auth)}/events?${PAGE_SIZE_PARAM}=1`;
318
+ const response = await this.MakeHTTPRequest(auth, url, 'GET', headers);
319
+ if (response.Status < 200 || response.Status >= 300) {
320
+ return {
321
+ Success: false,
322
+ Message: `Cvent returned HTTP ${response.Status} from ${url}`,
323
+ };
324
+ }
325
+ return {
326
+ Success: true,
327
+ Message: `Connected to Cvent at ${auth.BaseUrl}`,
328
+ ServerVersion: 'Cvent Platform REST API',
329
+ };
330
+ }
331
+ catch (err) {
332
+ const message = err instanceof Error ? err.message : String(err);
333
+ return { Success: false, Message: `Connection failed: ${message}` };
334
+ }
335
+ }
336
+ // ─── Discovery (metadata-driven, no hardcoded catalog) ───────────
337
+ /**
338
+ * Discovers the full object universe from the IntegrationEngineBase cache (the Declared
339
+ * metadata). Cvent publishes its catalog credential-free (OpenAPI spec), so the baseline is
340
+ * Declared metadata — never hardcoded here, never sampled at build. A live credential is
341
+ * ADDITIVE (tenant-specific custom fields surfaced at sync via the framework's custom-column
342
+ * capture), never the baseline — so credential-free discovery re-yields the standard universe.
343
+ */
344
+ async DiscoverObjects(companyIntegration, contextUser) {
345
+ return super.DiscoverObjects(companyIntegration, contextUser);
346
+ }
347
+ /** Discovers fields for an object from the cached Declared metadata. */
348
+ async DiscoverFields(companyIntegration, objectName, contextUser) {
349
+ return super.DiscoverFields(companyIntegration, objectName, contextUser);
350
+ }
351
+ // ─── FetchChanges override ──────────────────────────────────────
352
+ /**
353
+ * Sets the watermark context the page URL builder needs, delegates the cursor walk to the base
354
+ * (which descends nested template-var paths via FK metadata so nested IOs never silently return
355
+ * 0 rows), then advances the watermark from the returned records on the final batch only
356
+ * (partial-failure-safe — the watermark stays unchanged if the batch did not fully drain).
357
+ */
358
+ async FetchChanges(ctx) {
359
+ this.currentWatermark = ctx.WatermarkValue ?? undefined;
360
+ const result = await super.FetchChanges(ctx);
361
+ const isFinal = !result.HasMore;
362
+ const newWatermark = isFinal
363
+ ? (this.ExtractLatestWatermark(result.Records, ctx) ?? ctx.WatermarkValue ?? undefined)
364
+ : undefined;
365
+ return { ...result, NewWatermarkValue: newWatermark };
366
+ }
367
+ // ─── Config parsing ──────────────────────────────────────────────
368
+ /**
369
+ * Parses the OAuth2 connection config, preferring the attached MJ Credential over the raw
370
+ * Configuration JSON. Credential bytes are resolved at runtime — never at build.
371
+ */
372
+ async ParseConfig(companyIntegration, contextUser) {
373
+ if (companyIntegration.CredentialID) {
374
+ return this.ParseConfigFromCredential(companyIntegration.CredentialID, contextUser);
375
+ }
376
+ if (companyIntegration.Configuration) {
377
+ return this.ValidateConfig(JSON.parse(companyIntegration.Configuration));
378
+ }
379
+ throw new Error('Cvent connector requires either CredentialID or Configuration JSON');
380
+ }
381
+ /** Loads the OAuth2 config from the MJ: Credentials entity Values JSON. */
382
+ async ParseConfigFromCredential(credentialID, contextUser, provider) {
383
+ const md = provider ?? new Metadata();
384
+ const cred = await md.GetEntityObject('MJ: Credentials', contextUser);
385
+ const loaded = await cred.Load(credentialID);
386
+ if (!loaded || !cred.Values) {
387
+ throw new Error('Cvent credential could not be loaded or has no Values JSON');
388
+ }
389
+ return this.ValidateConfig(JSON.parse(cred.Values));
390
+ }
391
+ /** Validates the parsed config + applies defaults. Field names are case-insensitive. */
392
+ ValidateConfig(raw) {
393
+ if (!raw || typeof raw !== 'object') {
394
+ throw new Error('Cvent configuration is not a valid object');
395
+ }
396
+ const obj = raw;
397
+ const getStr = (...keys) => {
398
+ for (const key of keys) {
399
+ const lower = key.toLowerCase();
400
+ for (const [k, v] of Object.entries(obj)) {
401
+ if (k.toLowerCase() === lower && typeof v === 'string' && v.length > 0)
402
+ return v;
403
+ }
404
+ }
405
+ return undefined;
406
+ };
407
+ const getNum = (...keys) => {
408
+ for (const key of keys) {
409
+ const lower = key.toLowerCase();
410
+ for (const [k, v] of Object.entries(obj)) {
411
+ if (k.toLowerCase() === lower && typeof v === 'number')
412
+ return v;
413
+ }
414
+ }
415
+ return undefined;
416
+ };
417
+ const clientId = getStr('clientid', 'client_id', 'apikey', 'api_key');
418
+ const clientSecret = getStr('clientsecret', 'client_secret', 'apisecret', 'api_secret');
419
+ if (!clientId || !clientSecret) {
420
+ throw new Error('Cvent OAuth2 configuration missing required field: ClientId / ClientSecret');
421
+ }
422
+ return {
423
+ ClientId: clientId,
424
+ ClientSecret: clientSecret,
425
+ TokenURL: getStr('tokenurl', 'token_url'),
426
+ BaseURL: getStr('baseurl', 'base_url', 'resthost', 'rest_host'),
427
+ Scope: getStr('scope', 'scopes'),
428
+ MaxRetries: getNum('maxretries') ?? DEFAULT_MAX_RETRIES,
429
+ RequestTimeoutMs: getNum('requesttimeoutms') ?? DEFAULT_REQUEST_TIMEOUT_MS,
430
+ };
431
+ }
432
+ /** Resolves the REST base URL from the credential override (e.g. EUR host), else the US default. Strips a trailing slash. */
433
+ ResolveBaseUrl(config) {
434
+ const base = config.BaseURL && config.BaseURL.length > 0 ? config.BaseURL : DEFAULT_BASE_URL;
435
+ return base.replace(/\/+$/, '');
436
+ }
437
+ // ─── Normalization helpers ───────────────────────────────────────
438
+ /** Normalizes a raw record's top-level values (empty-string → null). */
439
+ NormalizeRecord(record) {
440
+ const out = {};
441
+ for (const [key, value] of Object.entries(record)) {
442
+ out[key] = value === '' ? null : value;
443
+ }
444
+ return out;
445
+ }
446
+ /** Reads the `paging.nextToken` dot-path cursor from a response body, if present. */
447
+ ReadNextCursor(rawBody) {
448
+ if (!rawBody || typeof rawBody !== 'object')
449
+ return undefined;
450
+ let node = rawBody;
451
+ for (const seg of NEXT_CURSOR_PATH) {
452
+ if (!node || typeof node !== 'object')
453
+ return undefined;
454
+ node = node[seg];
455
+ }
456
+ return typeof node === 'string' && node.length > 0 ? node : undefined;
457
+ }
458
+ /**
459
+ * Extracts the latest watermark value across a batch for incremental advancement. Uses the IO's
460
+ * declared IncrementalWatermarkField when resolvable, falling back to common timestamp keys.
461
+ */
462
+ ExtractLatestWatermark(records, ctx) {
463
+ const fieldName = this.ResolveWatermarkField(ctx.ObjectName);
464
+ let latest = null;
465
+ for (const rec of records) {
466
+ const raw = (fieldName && rec.Fields?.[fieldName])
467
+ ?? rec.Fields?.lastModified ?? rec.Fields?.modified ?? rec.Fields?.updatedAt;
468
+ if (typeof raw !== 'string' || raw.length === 0)
469
+ continue;
470
+ const d = new Date(raw);
471
+ if (!Number.isNaN(d.getTime()) && (latest === null || d > latest))
472
+ latest = d;
473
+ }
474
+ return latest ? latest.toISOString() : null;
475
+ }
476
+ /** Resolves the IncrementalWatermarkField for an object from the engine cache. */
477
+ ResolveWatermarkField(objectName) {
478
+ const integration = IntegrationEngineBase.Instance.GetIntegrationByName('Cvent');
479
+ if (!integration)
480
+ return undefined;
481
+ const io = IntegrationEngineBase.Instance
482
+ .GetActiveIntegrationObjects(integration.ID)
483
+ .find(o => o.Name === objectName);
484
+ return io?.IncrementalWatermarkField ?? undefined;
485
+ }
486
+ // ─── HTTP helpers ────────────────────────────────────────────────
487
+ /** Parses a Retry-After header (seconds or http-date) into ms, if present. */
488
+ RetryAfterMs(response) {
489
+ const header = response.headers.get('retry-after');
490
+ if (!header)
491
+ return undefined;
492
+ const asSeconds = Number(header);
493
+ if (!Number.isNaN(asSeconds))
494
+ return Math.max(0, asSeconds * 1_000);
495
+ const asDate = new Date(header).getTime();
496
+ if (!Number.isNaN(asDate))
497
+ return Math.max(0, asDate - Date.now());
498
+ return undefined;
499
+ }
500
+ /** Exponential backoff delay for retry attempts (initial 2000ms, exponent 2, capped at 16000ms). */
501
+ BackoffDelay(attempt) {
502
+ return Math.min(RETRY_BACKOFF_INITIAL_MS * Math.pow(RETRY_BACKOFF_EXPONENT, attempt), RETRY_BACKOFF_MAX_MS);
503
+ }
504
+ /** Checks whether an error is transient (network/timeout). */
505
+ IsTransientNetworkError(err) {
506
+ if (!(err instanceof Error))
507
+ return false;
508
+ const msg = err.message.toLowerCase();
509
+ return msg.includes('timeout') || msg.includes('abort') ||
510
+ msg.includes('econnreset') || msg.includes('econnrefused') ||
511
+ msg.includes('fetch failed');
512
+ }
513
+ /** Builds the normalized RESTResponse from a fetch Response. */
514
+ async BuildRESTResponse(response) {
515
+ const headers = {};
516
+ response.headers.forEach((v, k) => { headers[k.toLowerCase()] = v; });
517
+ const text = await response.text();
518
+ let body = null;
519
+ if (text.length > 0) {
520
+ try {
521
+ body = JSON.parse(text);
522
+ }
523
+ catch {
524
+ body = text;
525
+ }
526
+ }
527
+ return { Status: response.status, Body: body, Headers: headers };
528
+ }
529
+ /** Promise-wrapped setTimeout. */
530
+ Sleep(ms) {
531
+ return new Promise(resolve => setTimeout(resolve, ms));
532
+ }
533
+ };
534
+ CventConnector = __decorate([
535
+ RegisterClass(BaseIntegrationConnector, '@memberjunction/connector-cvent')
536
+ ], CventConnector);
537
+ export { CventConnector };
538
+ /** Tree-shaking prevention — import and call from the package entry point. */
539
+ export function LoadCventConnector() { }
540
+ //# sourceMappingURL=CventConnector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CventConnector.js","sourceRoot":"","sources":["../src/CventConnector.ts"],"names":[],"mappings":";;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAyC,MAAM,sBAAsB,CAAC;AAEvF,OAAO,EACH,wBAAwB,EACxB,4BAA4B,EAC5B,kBAAkB,GAYrB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAuChF,wEAAwE;AAExE,kEAAkE;AAClE,MAAM,iBAAiB,GAAG,gDAAgD,CAAC;AAE3E,2FAA2F;AAC3F,MAAM,gBAAgB,GAAG,mCAAmC,CAAC;AAE7D,wEAAwE;AACxE,MAAM,YAAY,GAAG,OAAO,CAAC;AAC7B,MAAM,eAAe,GAAG,OAAO,CAAC;AAChC,8CAA8C;AAC9C,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAE9B,6EAA6E;AAC7E,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AACjD,gDAAgD;AAChD,MAAM,QAAQ,GAAG,MAAM,CAAC;AAExB,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAE1C,4FAA4F;AAC5F,MAAM,wBAAwB,GAAG,KAAK,CAAC;AACvC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AACpC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAEjC;;;;GAIG;AACH,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB,wEAAwE;AAGjE,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,4BAA4B;IAAzD;;QAEH,oDAAoD;QAC5C,cAAS,GAA4B,IAAI,CAAC;QAElD,0FAA0F;QACzE,iBAAY,GAAG,IAAI,kBAAkB,EAAE,CAAC;IA2hB7D,CAAC;IAthBG,8FAA8F;IAC9F,+FAA+F;IAC/F,sCAAsC;IACtC,IAAoB,eAAe,KAAa,OAAO,OAAO,CAAC,CAAC,CAAC;IAEjE,qEAAqE;IACrE,EAAE;IACF,2FAA2F;IAC3F,kGAAkG;IAClG,+FAA+F;IAC/F,mGAAmG;IACnG,kGAAkG;IAClG,mDAAmD;IAEnD,IAAoB,cAAc;QAC9B,OAAO,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAC9E,CAAC;IACD,IAAoB,cAAc;QAC9B,OAAO,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAC9E,CAAC;IACD,IAAoB,cAAc;QAC9B,OAAO,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAC9E,CAAC;IAED;+FAC2F;IACnF,iBAAiB,CAAC,IAA+C;QACrE,MAAM,WAAW,GAAG,qBAAqB,CAAC,QAAQ,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACjF,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC;QAC/B,OAAO,qBAAqB,CAAC,QAAQ,CAAC,2BAA2B,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjG,CAAC;IAED,qEAAqE;IAErE;;;OAGG;IACH,IAAoB,eAAe;QAC/B,OAAO;YACH,YAAY,EAAE,oBAAoB;YAClC,KAAK,EAAE,WAAW;YAClB,qBAAqB,EAAE,GAAG;SAC7B,CAAC;IACN,CAAC;IAED;;;OAGG;IACa,mBAAmB,CAAC,KAAc;QAC9C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QAC1D,MAAM,OAAO,GAAI,KAA8C,CAAC,OAAO,CAAC;QACxE,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QAE/B,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;QAC1C,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;YACrC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;gBAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC;YACpE,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;gBAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,oEAAoE;QACpE,MAAM,KAAK,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAC3C,IAAI,KAAK,EAAE,CAAC;YACR,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;gBAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,mEAAmE;IAEnE;;;OAGG;IACO,KAAK,CAAC,YAAY,CACxB,kBAA8C,EAC9C,WAAqB;QAErB,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC;QAE1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;QACvE,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAE3C,MAAM,IAAI,GAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAClF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACK,eAAe,CAAC,MAA6B;QACjD,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,IAAI,iBAAiB,CAAC;QACjD,IAAI,CAAC;YACD,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACL,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;YAC7F,OAAO,IAAI,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QACzC,CAAC;IACL,CAAC;IAED,4FAA4F;IACpF,KAAK,CAAC,SAAS,CAAC,MAA6B;QACjD,MAAM,GAAG,GAAuB;YAC5B,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;YACtC,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,mFAAmF;YACnF,yDAAyD;YACzD,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,MAAM,CAAC,KAAK;YACpB,UAAU,EAAE,OAAO;YACnB,SAAS,EAAE,MAAM,CAAC,gBAAgB,IAAI,0BAA0B;SACnE,CAAC;QACF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;QAChF,OAAO,KAAK,CAAC,WAAW,CAAC;IAC7B,CAAC;IAED,sDAAsD;IAC5C,YAAY,CAAC,IAAqB;QACxC,MAAM,KAAK,GAAI,IAAyB,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QACnE,OAAO;YACH,eAAe,EAAE,UAAU,KAAK,EAAE;YAClC,QAAQ,EAAE,kBAAkB;YAC5B,cAAc,EAAE,kBAAkB;SACrC,CAAC;IACN,CAAC;IAES,UAAU,CAChB,mBAA+C,EAC/C,IAAqB;QAErB,4FAA4F;QAC5F,OAAQ,IAAyB,CAAC,OAAO,CAAC;IAC9C,CAAC;IAED;;;;;;OAMG;IACO,iBAAiB,CACvB,OAAgB,EAChB,eAA8B;QAE9B,IAAI,OAAO,IAAI,IAAI;YAAE,OAAO,EAAE,CAAC;QAE/B,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,OAAQ,OAAqC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;QACpF,CAAC;QAED,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,OAAkC,CAAC;YAEhD,MAAM,GAAG,GAAG,eAAe,IAAI,QAAQ,CAAC;YACxC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC3B,OAAQ,IAAI,CAAC,GAAG,CAA+B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;YACtF,CAAC;YAED,4DAA4D;YAC5D,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,EAAE,CAAC;IACd,CAAC;IAED;;;;OAIG;IACO,qBAAqB,CAC3B,OAAgB,EAChB,eAA+B,EAC/B,YAAoB,EACpB,cAAsB,EACtB,SAAiB;QAEjB,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;QACpD,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACgB,iBAAiB,CAChC,QAAgB,EAChB,GAA8B,EAC9B,KAAa,EACb,OAAe,EACf,MAAe,EACf,iBAA0B;QAE1B,MAAM,SAAS,GAAG,iBAAiB,IAAI,GAAG,CAAC,eAAe,IAAI,iBAAiB,CAAC;QAChF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;QACpE,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QAErC,MAAM,cAAc,GAAG,GAAG,CAAC,yBAAyB,CAAC;QACrD,+FAA+F;QAC/F,6FAA6F;QAC7F,8FAA8F;QAC9F,8FAA8F;QAC9F,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,uBAAuB,IAAI,cAAc,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACpF,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,cAAc,QAAQ,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,MAAM,EAAE,CAAC;YACT,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAE3C,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IACzD,CAAC;IAED,0FAA0F;IAChF,KAAK,CAAC,eAAe,CAC3B,IAAqB,EACrB,GAAW,EACX,MAAc,EACd,OAA+B,EAC/B,IAAc;QAEd,MAAM,MAAM,GAAG,IAAwB,CAAC;QACxC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,IAAI,mBAAmB,CAAC;QACpE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,IAAI,0BAA0B,CAAC;QAEhF,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;YACrD,MAAM,YAAY,GAAgB;gBAC9B,MAAM;gBACN,OAAO;gBACP,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC;aACzC,CAAC;YACF,IAAI,IAAI,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;gBACzC,YAAY,CAAC,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/E,CAAC;YAED,IAAI,QAAkB,CAAC;YACvB,IAAI,CAAC;gBACD,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;YAC9C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,IAAI,OAAO,GAAG,UAAU,IAAI,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC5D,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC7C,SAAS;gBACb,CAAC;gBACD,MAAM,GAAG,CAAC;YACd,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;gBAC/E,OAAO,CAAC,IAAI,CAAC,gBAAgB,QAAQ,CAAC,MAAM,SAAS,GAAG,gBAAgB,CAAC,CAAC;gBAC1E,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC5E,SAAS;YACb,CAAC;YAED,OAAO,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC5C,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,8BAA8B,UAAU,GAAG,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,oEAAoE;IAEpE;;;OAGG;IACI,KAAK,CAAC,cAAc,CACvB,kBAA8C,EAC9C,WAAqB;QAErB,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAqB,CAAC;YAC5F,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YACxC,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE,IAAI,CAAC,WAAW,eAAe,IAAI,CAAC;YACvF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAEvE,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;gBAClD,OAAO;oBACH,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,uBAAuB,QAAQ,CAAC,MAAM,SAAS,GAAG,EAAE;iBAChE,CAAC;YACN,CAAC;YACD,OAAO;gBACH,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,yBAAyB,IAAI,CAAC,OAAO,EAAE;gBAChD,aAAa,EAAE,yBAAyB;aAC3C,CAAC;QACN,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,sBAAsB,OAAO,EAAE,EAAE,CAAC;QACxE,CAAC;IACL,CAAC;IAED,oEAAoE;IAEpE;;;;;;OAMG;IACa,KAAK,CAAC,eAAe,CACjC,kBAA8C,EAC9C,WAAqB;QAErB,OAAO,KAAK,CAAC,eAAe,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;IAClE,CAAC;IAED,wEAAwE;IACxD,KAAK,CAAC,cAAc,CAChC,kBAA8C,EAC9C,UAAkB,EAClB,WAAqB;QAErB,OAAO,KAAK,CAAC,cAAc,CAAC,kBAAkB,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IAC7E,CAAC;IAED,mEAAmE;IAEnE;;;;;OAKG;IACa,KAAK,CAAC,YAAY,CAAC,GAAiB;QAChD,IAAI,CAAC,gBAAgB,GAAG,GAAG,CAAC,cAAc,IAAI,SAAS,CAAC;QAExD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAE7C,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;QAChC,MAAM,YAAY,GAAG,OAAO;YACxB,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,cAAc,IAAI,SAAS,CAAC;YACvF,CAAC,CAAC,SAAS,CAAC;QAEhB,OAAO,EAAE,GAAG,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,CAAC;IAC1D,CAAC;IAED,oEAAoE;IAEpE;;;OAGG;IACK,KAAK,CAAC,WAAW,CACrB,kBAA8C,EAC9C,WAAsB;QAEtB,IAAI,kBAAkB,CAAC,YAAY,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,yBAAyB,CAAC,kBAAkB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,kBAAkB,CAAC,aAAa,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IAC1F,CAAC;IAED,2EAA2E;IACnE,KAAK,CAAC,yBAAyB,CACnC,YAAoB,EACpB,WAAsB,EACtB,QAA4B;QAE5B,MAAM,EAAE,GAAG,QAAQ,IAAI,IAAI,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,eAAe,CAAqB,iBAAiB,EAAE,WAAW,CAAC,CAAC;QAC1F,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,wFAAwF;IAChF,cAAc,CAAC,GAAY;QAC/B,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACjE,CAAC;QACD,MAAM,GAAG,GAAG,GAA8B,CAAC;QAC3C,MAAM,MAAM,GAAG,CAAC,GAAG,IAAc,EAAsB,EAAE;YACrD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACrB,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;gBAChC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;oBACvC,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;wBAAE,OAAO,CAAC,CAAC;gBACrF,CAAC;YACL,CAAC;YACD,OAAO,SAAS,CAAC;QACrB,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,GAAG,IAAc,EAAsB,EAAE;YACrD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACrB,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;gBAChC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;oBACvC,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,IAAI,OAAO,CAAC,KAAK,QAAQ;wBAAE,OAAO,CAAC,CAAC;gBACrE,CAAC;YACL,CAAC;YACD,OAAO,SAAS,CAAC;QACrB,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QACtE,MAAM,YAAY,GAAG,MAAM,CAAC,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;QACxF,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;QAClG,CAAC;QAED,OAAO;YACH,QAAQ,EAAE,QAAQ;YAClB,YAAY,EAAE,YAAY;YAC1B,QAAQ,EAAE,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC;YACzC,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,CAAC;YAC/D,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC;YAChC,UAAU,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,mBAAmB;YACvD,gBAAgB,EAAE,MAAM,CAAC,kBAAkB,CAAC,IAAI,0BAA0B;SAC7E,CAAC;IACN,CAAC;IAED,6HAA6H;IACrH,cAAc,CAAC,MAA6B;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAC7F,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,oEAAoE;IAEpE,wEAAwE;IAChE,eAAe,CAAC,MAA+B;QACnD,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAC3C,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED,qFAAqF;IAC7E,cAAc,CAAC,OAAgB;QACnC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QAC9D,IAAI,IAAI,GAAY,OAAO,CAAC;QAC5B,KAAK,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAC;YACxD,IAAI,GAAI,IAAgC,CAAC,GAAG,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1E,CAAC;IAED;;;OAGG;IACK,sBAAsB,CAC1B,OAA8C,EAC9C,GAAiB;QAEjB,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7D,IAAI,MAAM,GAAgB,IAAI,CAAC;QAC/B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC;mBAC3C,GAAG,CAAC,MAAM,EAAE,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC;YACjF,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAC1D,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,GAAG,MAAM,CAAC;gBAAE,MAAM,GAAG,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAChD,CAAC;IAED,kFAAkF;IAC1E,qBAAqB,CAAC,UAAkB;QAC5C,MAAM,WAAW,GAAG,qBAAqB,CAAC,QAAQ,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACjF,IAAI,CAAC,WAAW;YAAE,OAAO,SAAS,CAAC;QACnC,MAAM,EAAE,GAAG,qBAAqB,CAAC,QAAQ;aACpC,2BAA2B,CAAC,WAAW,CAAC,EAAE,CAAC;aAC3C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QACtC,OAAO,EAAE,EAAE,yBAAyB,IAAI,SAAS,CAAC;IACtD,CAAC;IAED,oEAAoE;IAEpE,8EAA8E;IACtE,YAAY,CAAC,QAAkB;QACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAC9B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACnE,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,oGAAoG;IAC5F,YAAY,CAAC,OAAe;QAChC,OAAO,IAAI,CAAC,GAAG,CACX,wBAAwB,GAAG,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,OAAO,CAAC,EACpE,oBAAoB,CACvB,CAAC;IACN,CAAC;IAED,8DAA8D;IACtD,uBAAuB,CAAC,GAAY;QACxC,IAAI,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAC1C,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QACtC,OAAO,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;YAChD,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC1D,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC;IAED,gEAAgE;IACxD,KAAK,CAAC,iBAAiB,CAAC,QAAkB;QAC9C,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEtE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,IAAI,GAAY,IAAI,CAAC;QACzB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClB,IAAI,CAAC;gBAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,IAAI,GAAG,IAAI,CAAC;YAAC,CAAC;QAC3D,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IACrE,CAAC;IAED,kCAAkC;IAC1B,KAAK,CAAC,EAAU;QACpB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;CACJ,CAAA;AAjiBY,cAAc;IAD1B,aAAa,CAAC,wBAAwB,EAAE,iCAAiC,CAAC;GAC9D,cAAc,CAiiB1B;;AAED,8EAA8E;AAC9E,MAAM,UAAU,kBAAkB,KAAuB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './CventConnector.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 './CventConnector.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,qBAAqB,CAAC;AAEpC;oGACoG;AACpG,MAAM,UAAU,iBAAiB,KAAiD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@memberjunction/connector-cvent",
3
+ "version": "1.0.0",
4
+ "private": false,
5
+ "description": "MemberJunction Cvent connector.",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "/dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc && tsc-alias -f",
14
+ "test": "vitest run --passWithNoTests"
15
+ },
16
+ "author": "MemberJunction.com",
17
+ "license": "ISC",
18
+ "peerDependencies": {
19
+ "@memberjunction/core": ">=5.42.0 <6.0.0",
20
+ "@memberjunction/core-entities": ">=5.42.0 <6.0.0",
21
+ "@memberjunction/global": ">=5.42.0 <6.0.0",
22
+ "@memberjunction/integration-engine": ">=5.42.0 <6.0.0",
23
+ "@memberjunction/integration-engine-base": ">=5.42.0 <6.0.0"
24
+ },
25
+ "dependencies": {},
26
+ "devDependencies": {
27
+ "@types/node": "24.10.11",
28
+ "tsc-alias": "^1.8.16",
29
+ "typescript": "^5.9.3",
30
+ "vitest": "^4.0.18",
31
+ "@memberjunction/core": "^5.42.0",
32
+ "@memberjunction/core-entities": "^5.42.0",
33
+ "@memberjunction/global": "^5.42.0",
34
+ "@memberjunction/integration-engine": "^5.42.0",
35
+ "@memberjunction/integration-engine-base": "^5.42.0"
36
+ },
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/MemberJunction/Integrations"
40
+ }
41
+ }