@memberjunction/connector-rasa-io 2.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.
- package/dist/RasaConnector.d.ts +306 -0
- package/dist/RasaConnector.js +1029 -0
- package/dist/RasaConnector.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { type UserInfo } from '@memberjunction/core';
|
|
2
|
+
import type { MJCompanyIntegrationEntity, MJIntegrationObjectEntity } from '@memberjunction/core-entities';
|
|
3
|
+
import { BaseRESTIntegrationConnector, type ConnectionTestResult, type ExternalFieldSchema, type ExternalObjectSchema, type ExternalRecord, type FetchBatchResult, type FetchContext, type GetRecordContext, type PaginationState, type PaginationType, type RESTAuthContext, type RESTResponse, type SourceSchemaInfo } from '@memberjunction/integration-engine';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
declare const RasaConnectionConfigSchema: z.ZodObject<{
|
|
6
|
+
/** rasa.io API key presented in the token-exchange body. */
|
|
7
|
+
APIKey: z.ZodString;
|
|
8
|
+
/** Account username (email) for the token-exchange HTTP Basic header. */
|
|
9
|
+
Username: z.ZodString;
|
|
10
|
+
/** Account password for the token-exchange HTTP Basic header. */
|
|
11
|
+
Password: z.ZodString;
|
|
12
|
+
/** Optional host override (self-hosted / proxy / test double). Defaults to the vendor host root. */
|
|
13
|
+
BaseURL: z.ZodOptional<z.ZodString>;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
APIKey: string;
|
|
16
|
+
Username: string;
|
|
17
|
+
Password: string;
|
|
18
|
+
BaseURL?: string | undefined;
|
|
19
|
+
}, {
|
|
20
|
+
APIKey: string;
|
|
21
|
+
Username: string;
|
|
22
|
+
Password: string;
|
|
23
|
+
BaseURL?: string | undefined;
|
|
24
|
+
}>;
|
|
25
|
+
/** Connection configuration parsed from the MJ Credential (or CompanyIntegration.Configuration). */
|
|
26
|
+
export type RasaConnectionConfig = z.infer<typeof RasaConnectionConfigSchema>;
|
|
27
|
+
/**
|
|
28
|
+
* rasa.io connector (v1 + v2 REST, single host).
|
|
29
|
+
*
|
|
30
|
+
* Everything routine rides `BaseRESTIntegrationConnector`'s metadata-driven machinery — generic
|
|
31
|
+
* per-operation CRUD, pagination loop, template-var/parent iteration, record→ExternalRecord
|
|
32
|
+
* conversion. Four things are genuinely idiosyncratic and are the ONLY behavioural overrides:
|
|
33
|
+
*
|
|
34
|
+
* 1. **Two-step auth** — `POST /v1/tokens` (HTTP Basic + `{key}` body) mints a JWT that every
|
|
35
|
+
* subsequent request presents in a CUSTOM `rasa-token` header, not `Authorization: Bearer`.
|
|
36
|
+
* 2. **`skip`/`limit` + response-metadata paging** — the base emits `offset`/`limit`; rasa.io uses
|
|
37
|
+
* `skip`/`limit` (RealityProbe: "'skip' advanced past page 1 via offset") and drives the loop from
|
|
38
|
+
* `metadata.next_link`, whose own `skip` value is numeric for offset endpoints and an opaque token
|
|
39
|
+
* for others.
|
|
40
|
+
* 3. **`*_since` watermarks** — the incremental filter is a per-object query param
|
|
41
|
+
* (`updated_since` / `created_since` / `archived_since`) read from the frozen contract.
|
|
42
|
+
* 4. **Conditional per-record envelope unwrapping** — rasa.io wraps each record JSON:API-style as
|
|
43
|
+
* `{data, links}` on SOME objects. Driven strictly by the per-object `recordUnwrapPath` verdict;
|
|
44
|
+
* never guessed (see {@link NormalizeResponse}).
|
|
45
|
+
*/
|
|
46
|
+
/** CANONICAL registration key — the repo's catalog convention is `ClassName` == the npm package name, so
|
|
47
|
+
* instance discovery matches. `Integration.ClassName` is seeded to this value.
|
|
48
|
+
* The short `RasaConnector` key below stays registered for continuity: `ConnectorFactory.Resolve` looks the
|
|
49
|
+
* Integration row's ClassName up verbatim in the ClassFactory, so any tenant row still carrying the legacy
|
|
50
|
+
* short name resolves rather than failing with "No connector registered". Zero cost to keep; removing it
|
|
51
|
+
* would be a breaking change independent of this release's rename. */
|
|
52
|
+
export declare class RasaConnector extends BaseRESTIntegrationConnector {
|
|
53
|
+
/** Cached JWT + mint time (idiosyncrasy #1). */
|
|
54
|
+
private cachedToken;
|
|
55
|
+
private tokenObtainedAt;
|
|
56
|
+
/** Response context for the in-flight fetch (see {@link RasaResponseContext}). */
|
|
57
|
+
private responseCtx;
|
|
58
|
+
/** Watermark value for the in-flight fetch — consumed by {@link AppendDefaultQueryParams}. */
|
|
59
|
+
private currentWatermark;
|
|
60
|
+
/** Non-fatal diagnostics raised during the in-flight fetch, drained into the FetchBatchResult. */
|
|
61
|
+
private pendingWarnings;
|
|
62
|
+
/** Running max of the watermark FIELD across the batches of one object's sync pass. */
|
|
63
|
+
private readonly watermarkHighWater;
|
|
64
|
+
/** Integration ID observed on the last operation — lets `StableOrderingKey(name)` reach the cache. */
|
|
65
|
+
private lastIntegrationID;
|
|
66
|
+
/** Merged public-spec cache (credential-free); populated lazily by discovery. */
|
|
67
|
+
private specCache;
|
|
68
|
+
/** Verbatim from the identity handoff / `MJ: Integrations.Name`. */
|
|
69
|
+
get IntegrationName(): string;
|
|
70
|
+
/** v1 `POST /persons|/posts|/lead-posts`, v2 `POST /lists|/contacts|/subscriptions` — all metadata-driven. */
|
|
71
|
+
get SupportsCreate(): boolean;
|
|
72
|
+
/** v1 `PUT /persons/{id}|/posts/{id}|/lead-posts`, v2 `PUT /contacts/{id}|/subscriptions/{id}`. */
|
|
73
|
+
get SupportsUpdate(): boolean;
|
|
74
|
+
/** v1 `DELETE /persons/{id}` (GDPR hard delete), v2 `DELETE /contacts/{id}` (archive). */
|
|
75
|
+
get SupportsDelete(): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* `updated_since` / `created_since` are inclusive server-side filters over a monotonically
|
|
78
|
+
* advancing timestamp column, so the highest value seen is a safe resume point.
|
|
79
|
+
*/
|
|
80
|
+
get MonotonicWatermark(): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Keyset hint the extractor emitted per object (`IntegrationObject.StableOrderingKey`). Returns the
|
|
83
|
+
* declared key, or null when the object has none — never a guess.
|
|
84
|
+
*/
|
|
85
|
+
StableOrderingKey(objectName: string): string | null;
|
|
86
|
+
/**
|
|
87
|
+
* Step 1 of the vendor's documented flow: `POST {host}/v1/tokens` with an HTTP Basic
|
|
88
|
+
* `Authorization` header AND a `{ key: <apiKey> }` body; the JWT comes back at
|
|
89
|
+
* `results[0]['rasa-token']`. Step 2 (the custom header) is {@link BuildHeaders}.
|
|
90
|
+
*/
|
|
91
|
+
protected Authenticate(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<RESTAuthContext>;
|
|
92
|
+
/** Mints (or reuses) the session JWT. Never logs any credential-derived value. */
|
|
93
|
+
private MintToken;
|
|
94
|
+
/**
|
|
95
|
+
* Reads the JWT out of the token envelope. Primary shape is the documented
|
|
96
|
+
* `ApiResonseTokenCreated` → `results[0]['rasa-token']` (`definitions.RasaToken`); the `data`-wrapped
|
|
97
|
+
* and v2 `access_token` shapes are accepted as transport tolerance, not as a schema claim.
|
|
98
|
+
*/
|
|
99
|
+
private ReadTokenFromBody;
|
|
100
|
+
/** Step 2: the JWT rides a CUSTOM header (`securityDefinitions.authorizer`), not `Authorization`. */
|
|
101
|
+
protected BuildHeaders(auth: RESTAuthContext): Record<string, string>;
|
|
102
|
+
/** Host root for every request; APIPath supplies its own `/v1` or `/v2` segment. */
|
|
103
|
+
protected GetBaseURL(_companyIntegration: MJCompanyIntegrationEntity, auth: RESTAuthContext): string;
|
|
104
|
+
private HostOf;
|
|
105
|
+
/**
|
|
106
|
+
* HTTP transport with bounded retry: network blips, a 401 (mint a fresh JWT and replay once the
|
|
107
|
+
* cached one has aged out), and 429 honouring `Retry-After` when the vendor sends one.
|
|
108
|
+
*/
|
|
109
|
+
protected MakeHTTPRequest(auth: RESTAuthContext, url: string, method: string, headers: Record<string, string>, body?: unknown): Promise<RESTResponse>;
|
|
110
|
+
private BuildRequestInit;
|
|
111
|
+
/** Normalizes a fetch Response, tolerating empty/non-JSON bodies (e.g. a 204 from DELETE). */
|
|
112
|
+
private ToRESTResponse;
|
|
113
|
+
/** `Retry-After` in seconds or as an HTTP-date; null when the vendor sent neither. */
|
|
114
|
+
private RetryAfterMs;
|
|
115
|
+
private IsRetriableNetworkError;
|
|
116
|
+
private Sleep;
|
|
117
|
+
/**
|
|
118
|
+
* Strips the rasa.io response envelope. TWO layers, both metadata-driven:
|
|
119
|
+
*
|
|
120
|
+
* 1. the LIST envelope — `{ code, event, metadata, results, status_code }` — via the object's
|
|
121
|
+
* `ResponseDataKey` (`results`, `results[].data`, `results[].lists`, …);
|
|
122
|
+
* 2. the PER-RECORD envelope — rasa.io wraps some records JSON:API-style as `{ data, links }` —
|
|
123
|
+
* via the object's `Configuration.recordUnwrapPath`, which materializes the RealityProbe's
|
|
124
|
+
* `recordEnvelopeShape` verdict. Present ⇒ verdict was `nested` ⇒ unwrap. **Absent ⇒ we do NOT
|
|
125
|
+
* unwrap** — a missing verdict is DEFERRED, never resolved as "flat" by assumption. When an
|
|
126
|
+
* un-verdicted object nonetheless arrives looking exactly like the vendor's envelope
|
|
127
|
+
* (`{data, links}` and nothing else), we emit a `RECORD_ENVELOPE_UNVERIFIED` warning naming the
|
|
128
|
+
* object so the gap is loud in the run artifact rather than silently mis-mapped.
|
|
129
|
+
*/
|
|
130
|
+
protected NormalizeResponse(rawBody: unknown, responseDataKey: string | null): Record<string, unknown>[];
|
|
131
|
+
/**
|
|
132
|
+
* Evaluates a dotted extraction path against a response body. A segment may be a plain key or a
|
|
133
|
+
* `key[]` list segment; arrays are flattened either way, so `results`, `results[].data` and
|
|
134
|
+
* `results[].data.topics` all resolve uniformly. A null path returns the body itself (array or object).
|
|
135
|
+
*/
|
|
136
|
+
private ExtractByPath;
|
|
137
|
+
/** Raises a one-per-fetch diagnostic when an un-verdicted object arrives inside the vendor envelope. */
|
|
138
|
+
private FlagUndeclaredEnvelope;
|
|
139
|
+
/**
|
|
140
|
+
* rasa.io pages with `skip` + `limit` (NOT the base's `offset`/`limit`). The `skip` value is a
|
|
141
|
+
* numeric offset on offset endpoints and an opaque token on the endpoints whose `next_link` carries
|
|
142
|
+
* a non-numeric `skip` — {@link ExtractPaginationInfo} classifies it, we replay whichever it gave us.
|
|
143
|
+
* `limit` is capped by the object's declared `DefaultPageSize` (the v1 spec's hard `maximum: 50`).
|
|
144
|
+
*/
|
|
145
|
+
protected BuildPaginatedURL(basePath: string, obj: MJIntegrationObjectEntity, _page: number, offset: number, cursor?: string, effectivePageSize?: number): string;
|
|
146
|
+
/**
|
|
147
|
+
* Drives the loop from the response-metadata envelope
|
|
148
|
+
* (`PersonsApiResponseMetadata` / `InsightApiResponseMetadata` / v2 `ResponseMetadata`):
|
|
149
|
+
* `next_link` is the vendor's own next-page URL. A short page (fewer records than requested) always
|
|
150
|
+
* terminates — the vendor emits `next_link` past the end of the dataset, so it is not a sufficient
|
|
151
|
+
* stop signal on its own.
|
|
152
|
+
*/
|
|
153
|
+
protected ExtractPaginationInfo(rawBody: unknown, _paginationType: PaginationType, _currentPage: number, currentOffset: number, pageSize: number): PaginationState;
|
|
154
|
+
/** Reads the `skip` query param out of a vendor `next_link`, tolerating a relative URL. */
|
|
155
|
+
private ReadSkipParam;
|
|
156
|
+
/**
|
|
157
|
+
* Appends the object's declared incremental filter — `Configuration.watermarkParam`
|
|
158
|
+
* (`updated_since` / `created_since` / `archived_since`) — to every request of a watermarked
|
|
159
|
+
* object. Applied HERE rather than in {@link BuildPaginatedURL} so it also reaches non-paginated
|
|
160
|
+
* single-page fetches. Never invents a param name: silent metadata ⇒ full pull.
|
|
161
|
+
*/
|
|
162
|
+
protected AppendDefaultQueryParams(url: string, obj: MJIntegrationObjectEntity): string;
|
|
163
|
+
/**
|
|
164
|
+
* Thin wrapper around the base's metadata-driven fetch. It (a) publishes the per-object response
|
|
165
|
+
* context the base's object-less `NormalizeResponse` signature can't carry, (b) bridges the frozen
|
|
166
|
+
* contract's `accessPath.parentObject` onto the key the base's parent resolver reads, (c) tracks the
|
|
167
|
+
* watermark high-water mark across the object's batches and emits it ONLY on the terminal batch, so
|
|
168
|
+
* a mid-pass failure (which throws before we return) leaves the stored watermark untouched.
|
|
169
|
+
*/
|
|
170
|
+
FetchChanges(ctx: FetchContext): Promise<FetchBatchResult>;
|
|
171
|
+
/**
|
|
172
|
+
* Refuses a read against an object that declares NO read door, instead of letting the base compose a
|
|
173
|
+
* request against the API ROOT. rasa.io has one such object — `Lead Post` is write-only (`APIPath`
|
|
174
|
+
* empty, `CreateAPIPath: /v1/lead-posts`, Create+Update only) — and a caller that syncs "all objects"
|
|
175
|
+
* will ask it to read. Without this guard the empty path resolves to `GET {baseURL}/`, whose failure
|
|
176
|
+
* mode is worse than an error: if the vendor root ever answers 200 (a status/banner document), the
|
|
177
|
+
* envelope reader would treat that payload as this object's record set. Fail precisely and name the
|
|
178
|
+
* cause instead.
|
|
179
|
+
*/
|
|
180
|
+
private AssertReadable;
|
|
181
|
+
/** GetRecord also runs NormalizeResponse — publish the same response context first. */
|
|
182
|
+
GetRecord(ctx: GetRecordContext): Promise<ExternalRecord | null>;
|
|
183
|
+
private IsFirstBatch;
|
|
184
|
+
/** Resolves and stores the extraction path + unwrap-verdict state for the object being fetched. */
|
|
185
|
+
private PublishResponseContext;
|
|
186
|
+
/**
|
|
187
|
+
* Composes the LIST path (`ResponseDataKey`) with the verdicted PER-RECORD unwrap path. The unwrap
|
|
188
|
+
* verdict is anchored at the list root, so `results` + `data` → `results[].data`, and
|
|
189
|
+
* `results[].topics` + `data.topics` → `results[].data.topics` (the probe's re-point: the declared
|
|
190
|
+
* fields live under `data`, not at the record root). No verdict ⇒ the declared key verbatim.
|
|
191
|
+
*/
|
|
192
|
+
private EffectiveDataPath;
|
|
193
|
+
/**
|
|
194
|
+
* The frozen contract expresses an object's owner as `Configuration.accessPath.parentObject`; the
|
|
195
|
+
* base's template-var resolver reads `Configuration.parentObjectName`. Same declared fact, two
|
|
196
|
+
* spellings — bridged here (in memory only, never persisted) so a `{var}` path resolves its parent
|
|
197
|
+
* instead of returning PARENT_UNRESOLVED. Additive: an existing `parentObjectName` always wins.
|
|
198
|
+
*/
|
|
199
|
+
private BridgeAccessPathToParentConfig;
|
|
200
|
+
/** Folds this batch's watermark-field values into the object's running high-water mark. */
|
|
201
|
+
private AdvanceWatermarkHighWater;
|
|
202
|
+
/** Terminal-batch watermark: the run's high-water mark, else the caller's value unchanged. */
|
|
203
|
+
private FinalWatermark;
|
|
204
|
+
/**
|
|
205
|
+
* The generic `CreateRecord` is used as-is; only ID extraction is vendor-shaped. rasa.io returns the
|
|
206
|
+
* new record inside the standard envelope — `PersonApiPostResponse.example` is
|
|
207
|
+
* `{ code, metadata, results: [ { id } ] }` — so the base's root-level `body.id` probe finds nothing.
|
|
208
|
+
* We look at `results[0]` and, when the per-record envelope is in play, `results[0].data`.
|
|
209
|
+
*/
|
|
210
|
+
protected ExtractIDFromResponse(response: RESTResponse, idLocation: string | null): string | undefined;
|
|
211
|
+
/** Vendor error envelope: `metadata.errors` alongside the standard `code` / `status_code`. */
|
|
212
|
+
protected ExtractErrorMessage(response: RESTResponse): string | undefined;
|
|
213
|
+
/**
|
|
214
|
+
* Enumerates the object universe from rasa.io's PUBLICLY-PUBLISHED OpenAPI documents (both API
|
|
215
|
+
* generations), unioned with the persisted Declared metadata. Deliberately credential-free: the
|
|
216
|
+
* runtime structure self-check runs without a token, so standard objects MUST re-yield without one.
|
|
217
|
+
* A live credential is additive only (see {@link IntrospectSchema}). If the specs are unreachable the
|
|
218
|
+
* method degrades to the persisted set rather than failing the sync.
|
|
219
|
+
*/
|
|
220
|
+
DiscoverObjects(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<ExternalObjectSchema[]>;
|
|
221
|
+
/**
|
|
222
|
+
* Fields for one object: the persisted Declared set, unioned with every property the PUBLIC spec
|
|
223
|
+
* declares on the object's backing definitions (`Configuration.recordSchemas`). Credential-free —
|
|
224
|
+
* a token contributes nothing here. Declared entries win on collision; spec-only properties are
|
|
225
|
+
* appended so a vendor schema addition surfaces without a metadata re-extract.
|
|
226
|
+
*/
|
|
227
|
+
DiscoverFields(companyIntegration: MJCompanyIntegrationEntity, objectName: string, contextUser: UserInfo): Promise<ExternalFieldSchema[]>;
|
|
228
|
+
/**
|
|
229
|
+
* Sample-union enrichment (MJ connector standard): after the cache-driven introspection, sample each
|
|
230
|
+
* object's LIVE read shape and union it into the declared field set — this is where a tenant's own
|
|
231
|
+
* custom person attributes reach the schema. Best-effort; a sample failure leaves the declared set
|
|
232
|
+
* untouched. Overrides `IntrospectSchema`, NOT `DiscoverFields` (which would recurse into
|
|
233
|
+
* `DiscoverFieldsViaFetch`'s own fallback).
|
|
234
|
+
*
|
|
235
|
+
* SEQUENTIAL, and that is load-bearing. {@link FetchChanges} publishes its per-object response
|
|
236
|
+
* context onto INSTANCE state (`responseCtx`/`currentWatermark`/`pendingWarnings`) which is read
|
|
237
|
+
* back AFTER the HTTP round-trip. Sampling the catalog with `Promise.all` therefore raced: every
|
|
238
|
+
* concurrent call overwrote `responseCtx`, so a response was normalized against some OTHER object's
|
|
239
|
+
* `DataPath`, matched nothing, and yielded ZERO records — cleanly, with no throw and no warning.
|
|
240
|
+
* Observed live: 17 of 18 objects that reached the sampler logged `rows=0 | cols: []`, the sole
|
|
241
|
+
* survivor being the one that happened to win the race, and the resulting all-null field widths
|
|
242
|
+
* were what made the framework's unknown-width defect drop 8,841 records. The sync engine iterates
|
|
243
|
+
* objects sequentially, which is why the identical read path works there. Do not re-parallelize
|
|
244
|
+
* this without first threading the response context through the call instead of the instance.
|
|
245
|
+
*/
|
|
246
|
+
IntrospectSchema(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<SourceSchemaInfo>;
|
|
247
|
+
/** Declared fields, tolerating an object the cache doesn't carry (a spec-only discovery). */
|
|
248
|
+
private SafeDeclaredFields;
|
|
249
|
+
/** The Swagger definition name(s) backing an object, per its declared `Configuration.recordSchemas`. */
|
|
250
|
+
private RecordSchemaNamesFor;
|
|
251
|
+
/** Reverse index: Swagger definition name → the Declared object that claims it. */
|
|
252
|
+
private IndexDeclaredObjectsByRecordSchema;
|
|
253
|
+
/**
|
|
254
|
+
* The set of doors (normalized endpoint paths) already served by a Declared object. Used to suppress
|
|
255
|
+
* spec-only "objects" that are really an alias of a Declared resource — see the door test in
|
|
256
|
+
* {@link DiscoverObjects}. Both the frozen contract's `accessPath.door` and the row's own `APIPath`
|
|
257
|
+
* are indexed, since either may carry the endpoint for a given object.
|
|
258
|
+
*/
|
|
259
|
+
private IndexDeclaredDoors;
|
|
260
|
+
/**
|
|
261
|
+
* Canonical form of an endpoint path for identity comparison: version segment dropped (a Declared
|
|
262
|
+
* `APIPath` carries `/v1`|`/v2`; a Swagger 2.0 path key does not — the prefix lives in `basePath`),
|
|
263
|
+
* path parameters collapsed to `{}` (`/persons/{id}/topics` ≡ `/persons/{person_id}/topics`), and
|
|
264
|
+
* casing/trailing slashes normalized.
|
|
265
|
+
*/
|
|
266
|
+
private NormalizeDoor;
|
|
267
|
+
/**
|
|
268
|
+
* Every ACTIVE IntegrationObject for this integration, read from the same engine cache the base
|
|
269
|
+
* class reads (`IntegrationEngineBase.GetActiveIntegrationObjects`). Empty when the engine has not
|
|
270
|
+
* been configured yet — discovery then degrades to the spec-only naming, never throws.
|
|
271
|
+
*/
|
|
272
|
+
private ActiveObjects;
|
|
273
|
+
/**
|
|
274
|
+
* Fetches + merges rasa.io's public Swagger documents (v1 and v2) with NO credential, and walks
|
|
275
|
+
* every readable operation to enumerate RECORD TYPES (not entry points): each GET's success schema
|
|
276
|
+
* is resolved through the `{code, metadata, results[]}` envelope down to the item definition. Only
|
|
277
|
+
* the item type itself is yielded — nested `$ref`'d sub-objects are NOT promoted to record types
|
|
278
|
+
* (see {@link EnumerateRecordTypes}). Cached for the process lifetime.
|
|
279
|
+
*/
|
|
280
|
+
private LoadPublicSpecs;
|
|
281
|
+
private FetchSpec;
|
|
282
|
+
/** Walks every readable operation in one document, yielding the record types it exposes. */
|
|
283
|
+
private EnumerateRecordTypes;
|
|
284
|
+
/** Descends the `{code, metadata, results[]}` envelope to the item definition name. */
|
|
285
|
+
private ResolveRecordDefinitionName;
|
|
286
|
+
private RefName;
|
|
287
|
+
/** Maps a Swagger definition's properties onto ExternalFieldSchema. Constraints come from the spec only. */
|
|
288
|
+
private FieldsFromDefinition;
|
|
289
|
+
/** Human-readable object name for a spec-only record type (`PersonsApiGetResponseItem` → `Persons`). */
|
|
290
|
+
private DeriveObjectName;
|
|
291
|
+
/**
|
|
292
|
+
* Proves the whole auth chain end-to-end: mint the JWT (step 1) and spend it on a read (step 2).
|
|
293
|
+
* Uses `/v1/communities` — the smallest documented readable surface every v1 credential can reach.
|
|
294
|
+
*/
|
|
295
|
+
TestConnection(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<ConnectionTestResult>;
|
|
296
|
+
/** Credential record first (the supported path), CompanyIntegration.Configuration as the fallback. */
|
|
297
|
+
private ParseConfig;
|
|
298
|
+
private ParseConfigFromCredential;
|
|
299
|
+
/** Case-insensitive key matching over the credential payload, then strict Zod validation. */
|
|
300
|
+
private NormalizeConfigValues;
|
|
301
|
+
/** Parses an IntegrationObject's Configuration JSON into the typed per-object shape. */
|
|
302
|
+
private ObjectConfig;
|
|
303
|
+
/** Narrows an unknown to a plain object record, or null. */
|
|
304
|
+
private AsRecord;
|
|
305
|
+
}
|
|
306
|
+
export {};
|