@memberjunction/connector-orcid 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,206 @@
1
+ import { type UserInfo } from '@memberjunction/core';
2
+ import type { MJCompanyIntegrationEntity, MJIntegrationObjectEntity, MJIntegrationObjectFieldEntity } 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 ORCID connector.
6
+ *
7
+ * The ORCID Public API has NO list-all-records endpoint — the iD universe is
8
+ * not enumerable. Instead the universe is SCOPED PER CONNECTION via
9
+ * CompanyIntegration.Configuration. At least one of `searchQuery` / `orcidIds`
10
+ * must be provided.
11
+ */
12
+ export interface ORCIDConnectionConfig {
13
+ /** OAuth2 client_credentials grant — client identifier. From the credential store. */
14
+ ClientID?: string;
15
+ /** OAuth2 client_credentials grant — client secret. From the credential store. */
16
+ ClientSecret?: string;
17
+ /** OAuth2 token endpoint. Defaults to the production/sandbox host based on UseSandbox. */
18
+ TokenURL?: string;
19
+ /** OAuth2 scope. Defaults to '/read-public'. */
20
+ Scope?: string;
21
+ /** When true, use the ORCID sandbox hosts (sandbox.orcid.org / pub.sandbox.orcid.org). */
22
+ UseSandbox?: boolean;
23
+ /**
24
+ * Lucene query string for GET /search or /expanded-search resolving the iD universe at runtime.
25
+ * Examples: 'affiliation-org-name:"Harvard University"', 'given-names:Albert family-name:Einstein'.
26
+ */
27
+ SearchQuery?: string;
28
+ /** Whether to use /expanded-search instead of /search. Default: false (plain /search). */
29
+ UseExpandedSearch?: boolean;
30
+ /** Explicit list of ORCID iDs to sync directly (in addition to / instead of searchQuery). */
31
+ OrcidIds?: string[];
32
+ /**
33
+ * Upper bound on the number of iDs resolved from a search per sync ("Goldilocks" — do NOT drain
34
+ * the ~10k ORCID cap). Default: 1000. Explicit OrcidIds are always synced and are not bounded.
35
+ */
36
+ MaxSearchResults?: number;
37
+ /** HTTP request timeout in milliseconds. Default: 30000. */
38
+ RequestTimeoutMs?: number;
39
+ /** Maximum retries for rate-limited / transient failures. Default: 4. */
40
+ MaxRetries?: number;
41
+ /** Minimum interval between outbound requests (ms). Default: 100 (~10 req/s, well under the 40/s burst cap). */
42
+ MinRequestIntervalMs?: number;
43
+ /**
44
+ * Non-secret API host override (e.g. a local mock for replay testing). When unset, the
45
+ * production/sandbox host is selected by UseSandbox. Same pattern as Path LMS / GrowthZone —
46
+ * required for mock-floor e2e testability.
47
+ */
48
+ ApiBaseUrl?: string;
49
+ }
50
+ /**
51
+ * Connector for the ORCID Public API v3.0 (read-only).
52
+ *
53
+ * Authenticates via OAuth2 2-legged client_credentials (scope `/read-public`)
54
+ * to obtain a bearer token. ORCID is NOT enumerable — there is no
55
+ * "list all records" endpoint — so every sync is SCOPED per connection via
56
+ * `CompanyIntegration.Configuration` (`searchQuery` Lucene query and/or an
57
+ * explicit `orcidIds` array). FetchChanges resolves the in-scope iD set, then
58
+ * fetches `GET /{iD}/record` (root IO) or `GET /{iD}/<section>` (child IOs)
59
+ * per resolved iD.
60
+ *
61
+ * Pull-only: SupportsCreate/Update/Delete are false (the Public API is
62
+ * read-only; writes require the Member API which is out of scope). Incremental
63
+ * sync narrows client-side on each section's `last-modified-date`; the
64
+ * search-scoped universe has no cursor so it re-resolves each run and dedup
65
+ * rides content-hash idempotency in the base ToExternalRecord path.
66
+ *
67
+ * Rides BaseRESTIntegrationConnector (JSON over HTTP via Accept:
68
+ * application/json). The standard FetchChanges template-var mechanism resolves
69
+ * child sections off ALREADY-SYNCED parent iDs; we override FetchChanges so the
70
+ * ROOT (record) iD set is sourced from the Configuration universe rather than a
71
+ * parent table, then delegate child sections to the same per-iD fan-out.
72
+ */
73
+ export declare class ORCIDConnector extends BaseRESTIntegrationConnector {
74
+ /** Cached auth context (token + resolved host). Invalidated on token expiry or 401. */
75
+ private authState;
76
+ /** Timestamp of the last outbound request, used for throttling. */
77
+ private lastRequestTime;
78
+ get SupportsCreate(): boolean;
79
+ get SupportsUpdate(): boolean;
80
+ get SupportsDelete(): boolean;
81
+ get IntegrationName(): string;
82
+ /**
83
+ * ORCID documents a 40 req/s burst ceiling (HTTP 503 over it) and a daily quota
84
+ * (HTTP 429 with X-Rate-Limit-* + Retry-After). Run conservatively under the burst cap.
85
+ */
86
+ get RateLimitPolicy(): RateLimitPolicy | null;
87
+ /** Parse ORCID's Retry-After (delta-seconds or HTTP-date) into milliseconds. */
88
+ ExtractRetryAfterMs(error: unknown): number | undefined;
89
+ /**
90
+ * The search-scoped iD universe has no stable, monotonic ordering key — it is
91
+ * re-resolved from the Lucene query each run (insert/delete-volatile), so keyset
92
+ * resume is N/A. Dedup rides content-hash idempotency. Returns null for every object.
93
+ */
94
+ StableOrderingKey(_objectName: string): string | null;
95
+ /**
96
+ * Verifies connectivity by obtaining a client_credentials token, then issuing a
97
+ * lightweight authenticated probe against a well-known public iD's /record.
98
+ */
99
+ TestConnection(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<ConnectionTestResult>;
100
+ /**
101
+ * Fetches records for the given object, sourcing the iD universe from
102
+ * CompanyIntegration.Configuration (search query and/or explicit list).
103
+ *
104
+ * - ROOT IO ('record'): fetch GET /{iD}/record for each resolved iD.
105
+ * - CHILD section IOs ('works', 'employments', ...): fetch GET /{iD}/<section>
106
+ * for each resolved iD and expand the group envelope into individual items.
107
+ *
108
+ * Incremental: for sections that carry `last-modified-date`, narrow client-side
109
+ * to records strictly newer than ctx.WatermarkValue, and return the max-seen
110
+ * watermark as NewWatermarkValue (persisted by the engine on full-batch success
111
+ * only). The iD universe itself has no cursor (search is re-resolved each run);
112
+ * dedup rides content-hash idempotency in ToExternalRecord.
113
+ */
114
+ FetchChanges(ctx: FetchContext): Promise<FetchBatchResult>;
115
+ /**
116
+ * Fetches the raw item array for a single iD + object. For the root record IO this is
117
+ * a single-element array (the record itself); for a section it is the expanded group items.
118
+ */
119
+ private FetchForId;
120
+ /**
121
+ * Expands an ORCID activity-section group envelope into individual item objects.
122
+ *
123
+ * ORCID groups items under section-specific wrappers (e.g. works →
124
+ * `group[].work-summary[]`, employments → `affiliation-group[].summaries[]`).
125
+ * We walk the generic shape: any array whose elements carry a `put-code` is a
126
+ * leaf item; we flatten all such arrays found anywhere in the envelope. Each
127
+ * item is tagged with the parent `orcid-id` (the FK to record).
128
+ */
129
+ private expandSection;
130
+ /**
131
+ * Resolves the in-scope ORCID iD universe from CompanyIntegration.Configuration:
132
+ * the explicit `orcidIds` list (always included) plus the result of running the
133
+ * Lucene `searchQuery` against /search (or /expanded-search), bounded by
134
+ * MaxSearchResults to avoid draining the ~10k cap. Returns a de-duplicated set.
135
+ */
136
+ private ResolveOrcidIdUniverse;
137
+ /**
138
+ * Runs the Lucene query against ORCID /search (or /expanded-search) with offset
139
+ * pagination (start/rows), accumulating iDs up to maxResults ("Goldilocks" bound).
140
+ * Search is unordered and may return duplicates across pages — de-duplicated by the caller.
141
+ */
142
+ private RunSearch;
143
+ /** Normalizes a raw iD string to the canonical 0000-0000-0000-0000 form, or null if unusable. */
144
+ private normalizeOrcidId;
145
+ /**
146
+ * Builds the ExternalRecord, preserving the FULL raw source record in Fields
147
+ * (full-record pass-through) while flattening the declared scalar fields out of
148
+ * ORCID's nested JSON via TransformRecord/applyTransformPreservingKeys. PK identity
149
+ * (orcid-id for record, put-code for sections) drives the ExternalID; partial keys
150
+ * fall back to the base content-hash identity.
151
+ */
152
+ private toRecord;
153
+ /**
154
+ * Per-record reshaping: ORCID returns deeply-nested JSON; pull the declared scalar
155
+ * convenience fields up to the top level so the generated columns are populated, while
156
+ * the full raw record (every nested blob) is preserved by applyTransformPreservingKeys.
157
+ */
158
+ protected TransformRecord(raw: Record<string, unknown>, obj: MJIntegrationObjectEntity, _fields: MJIntegrationObjectFieldEntity[]): Record<string, unknown>;
159
+ /** Flattens the record IO's person/history-derived convenience scalars. */
160
+ private flattenRecordScalars;
161
+ /** ORCID scalar wrapper: { value: <x> } → <x>; otherwise returns the value as-is. */
162
+ private valueOf;
163
+ /** ORCID date wrapper: { value: <millis> } → ISO string; passthrough on already-scalar/empty. */
164
+ private coerceDate;
165
+ /** Extracts the last-modified-date millis from a record (for watermark comparison). */
166
+ private extractLastModifiedMs;
167
+ /** Pulls a millisecond epoch out of an ORCID timestamp wrapper or a scalar number/ISO string. */
168
+ private extractMs;
169
+ private asObject;
170
+ private parseWatermark;
171
+ protected Authenticate(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<RESTAuthContext>;
172
+ protected BuildHeaders(auth: RESTAuthContext): Record<string, string>;
173
+ /** Not used by the overridden FetchChanges; retained for any base-pipeline callers (GetRecord). */
174
+ protected NormalizeResponse(rawBody: unknown, responseDataKey: string | null): Record<string, unknown>[];
175
+ /** ORCID per-iD endpoints are not paginated — every object declares PaginationType=None. */
176
+ protected ExtractPaginationInfo(_rawBody: unknown, _paginationType: PaginationType, currentPage: number, currentOffset: number, _pageSize: number): PaginationState;
177
+ protected GetBaseURL(_companyIntegration: MJCompanyIntegrationEntity, auth: RESTAuthContext): string;
178
+ private isTokenValid;
179
+ /**
180
+ * Exchanges the client_credentials grant for a bearer token at the ORCID token
181
+ * endpoint. POST form: grant_type=client_credentials, client_id, client_secret,
182
+ * scope=/read-public.
183
+ */
184
+ private obtainAccessToken;
185
+ protected MakeHTTPRequest(auth: RESTAuthContext, url: string, method: string, headers: Record<string, string>, body?: unknown): Promise<RESTResponse>;
186
+ /** Single fetch() with an AbortController-backed timeout. */
187
+ private doFetch;
188
+ private safeParseJSON;
189
+ private isRetryableError;
190
+ private backoffMs;
191
+ private backoffFromResponse;
192
+ private throttle;
193
+ private sleep;
194
+ /**
195
+ * Resolves the connection config: OAuth2 secrets (ClientID/ClientSecret/TokenURL/Scope) from the
196
+ * credential store; the iD-universe scope (searchQuery/orcidIds) + host selection (useSandbox)
197
+ * from CompanyIntegration.Configuration. Secrets are NEVER baked into code.
198
+ */
199
+ private parseConfig;
200
+ /** Parses the non-secret scope/host config from CompanyIntegration.Configuration JSON. */
201
+ private parseConfigurationJson;
202
+ /** Loads OAuth2 secrets from the MJ credential store (generic OAuth2 client-credentials schema). */
203
+ private loadFromCredential;
204
+ }
205
+ /** Tree-shaking prevention function — import and call from the module entry point. */
206
+ export declare function LoadORCIDConnector(): void;
@@ -0,0 +1,708 @@
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_TOKEN_URL = 'https://orcid.org/oauth/token';
12
+ const SANDBOX_TOKEN_URL = 'https://sandbox.orcid.org/oauth/token';
13
+ const PROD_API_HOST = 'https://pub.orcid.org/v3.0';
14
+ const SANDBOX_API_HOST = 'https://pub.sandbox.orcid.org/v3.0';
15
+ const DEFAULT_SCOPE = '/read-public';
16
+ /** Refresh the access token 60s before hard expiry. */
17
+ const TOKEN_REFRESH_BUFFER_MS = 60 * 1000;
18
+ const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
19
+ const DEFAULT_MAX_RETRIES = 4;
20
+ const DEFAULT_MIN_REQUEST_INTERVAL_MS = 100;
21
+ const DEFAULT_MAX_SEARCH_RESULTS = 1000;
22
+ /** ORCID search caps a single page at 1000 rows. */
23
+ const SEARCH_PAGE_ROWS = 1000;
24
+ /** ORCID documented burst limit is 40 req/s; stay comfortably under it. */
25
+ const RATE_LIMIT_TOKENS_PER_SEC = 10;
26
+ /** The root IO whose template var {iD} is satisfied directly from the Configuration-scoped universe. */
27
+ const ROOT_OBJECT_NAME = 'record';
28
+ // ─── Connector implementation ─────────────────────────────────────────
29
+ /**
30
+ * Connector for the ORCID Public API v3.0 (read-only).
31
+ *
32
+ * Authenticates via OAuth2 2-legged client_credentials (scope `/read-public`)
33
+ * to obtain a bearer token. ORCID is NOT enumerable — there is no
34
+ * "list all records" endpoint — so every sync is SCOPED per connection via
35
+ * `CompanyIntegration.Configuration` (`searchQuery` Lucene query and/or an
36
+ * explicit `orcidIds` array). FetchChanges resolves the in-scope iD set, then
37
+ * fetches `GET /{iD}/record` (root IO) or `GET /{iD}/<section>` (child IOs)
38
+ * per resolved iD.
39
+ *
40
+ * Pull-only: SupportsCreate/Update/Delete are false (the Public API is
41
+ * read-only; writes require the Member API which is out of scope). Incremental
42
+ * sync narrows client-side on each section's `last-modified-date`; the
43
+ * search-scoped universe has no cursor so it re-resolves each run and dedup
44
+ * rides content-hash idempotency in the base ToExternalRecord path.
45
+ *
46
+ * Rides BaseRESTIntegrationConnector (JSON over HTTP via Accept:
47
+ * application/json). The standard FetchChanges template-var mechanism resolves
48
+ * child sections off ALREADY-SYNCED parent iDs; we override FetchChanges so the
49
+ * ROOT (record) iD set is sourced from the Configuration universe rather than a
50
+ * parent table, then delegate child sections to the same per-iD fan-out.
51
+ */
52
+ let ORCIDConnector = class ORCIDConnector extends BaseRESTIntegrationConnector {
53
+ constructor() {
54
+ super(...arguments);
55
+ /** Cached auth context (token + resolved host). Invalidated on token expiry or 401. */
56
+ this.authState = null;
57
+ /** Timestamp of the last outbound request, used for throttling. */
58
+ this.lastRequestTime = 0;
59
+ }
60
+ // ── Capability getters (PULL-ONLY) ──────────────────────────────────
61
+ get SupportsCreate() { return false; }
62
+ get SupportsUpdate() { return false; }
63
+ get SupportsDelete() { return false; }
64
+ get IntegrationName() { return 'ORCID'; }
65
+ // ── Sync-efficiency hooks ───────────────────────────────────────────
66
+ /**
67
+ * ORCID documents a 40 req/s burst ceiling (HTTP 503 over it) and a daily quota
68
+ * (HTTP 429 with X-Rate-Limit-* + Retry-After). Run conservatively under the burst cap.
69
+ */
70
+ get RateLimitPolicy() {
71
+ return { TokensPerSec: RATE_LIMIT_TOKENS_PER_SEC, Burst: 40, ThrottleBackoffFactor: 0.5 };
72
+ }
73
+ /** Parse ORCID's Retry-After (delta-seconds or HTTP-date) into milliseconds. */
74
+ ExtractRetryAfterMs(error) {
75
+ const headers = error?.Headers;
76
+ if (!headers)
77
+ return undefined;
78
+ const retryAfter = headers['retry-after'] ?? headers['Retry-After'];
79
+ if (typeof retryAfter !== 'string' || retryAfter.length === 0)
80
+ return undefined;
81
+ const asSeconds = Number(retryAfter);
82
+ if (!isNaN(asSeconds) && asSeconds >= 0)
83
+ return Math.round(asSeconds * 1000);
84
+ const asDate = Date.parse(retryAfter);
85
+ if (!isNaN(asDate)) {
86
+ const delta = asDate - Date.now();
87
+ if (delta > 0)
88
+ return delta;
89
+ }
90
+ return undefined;
91
+ }
92
+ /**
93
+ * The search-scoped iD universe has no stable, monotonic ordering key — it is
94
+ * re-resolved from the Lucene query each run (insert/delete-volatile), so keyset
95
+ * resume is N/A. Dedup rides content-hash idempotency. Returns null for every object.
96
+ */
97
+ StableOrderingKey(_objectName) { return null; }
98
+ // ─── TestConnection ──────────────────────────────────────────────
99
+ /**
100
+ * Verifies connectivity by obtaining a client_credentials token, then issuing a
101
+ * lightweight authenticated probe against a well-known public iD's /record.
102
+ */
103
+ async TestConnection(companyIntegration, contextUser) {
104
+ try {
105
+ const auth = await this.Authenticate(companyIntegration, contextUser);
106
+ // ORCID's canonical sample public record (Sofia Garcia / Josiah Carberry-style); a 200 or 404
107
+ // both prove the token + host are valid (the probe iD may differ between prod and sandbox).
108
+ const probeUrl = `${auth.BaseUrl}/0000-0002-1825-0097/record`;
109
+ const headers = this.BuildHeaders(auth);
110
+ const resp = await this.MakeHTTPRequest(auth, probeUrl, 'GET', headers);
111
+ if (resp.Status === 401 || resp.Status === 403) {
112
+ return { Success: false, Message: `ORCID TestConnection failed: HTTP ${resp.Status} (auth rejected)` };
113
+ }
114
+ if (resp.Status >= 500) {
115
+ return { Success: false, Message: `ORCID TestConnection failed: HTTP ${resp.Status} (server error)` };
116
+ }
117
+ return {
118
+ Success: true,
119
+ Message: `Successfully authenticated against ORCID Public API (${auth.Config.UseSandbox ? 'sandbox' : 'production'}).`,
120
+ ServerVersion: 'ORCID Public API v3.0',
121
+ };
122
+ }
123
+ catch (err) {
124
+ const message = err instanceof Error ? err.message : String(err);
125
+ return { Success: false, Message: `Connection failed: ${message}` };
126
+ }
127
+ }
128
+ // ─── FetchChanges (Configuration-scoped iD universe) ──────────────
129
+ /**
130
+ * Fetches records for the given object, sourcing the iD universe from
131
+ * CompanyIntegration.Configuration (search query and/or explicit list).
132
+ *
133
+ * - ROOT IO ('record'): fetch GET /{iD}/record for each resolved iD.
134
+ * - CHILD section IOs ('works', 'employments', ...): fetch GET /{iD}/<section>
135
+ * for each resolved iD and expand the group envelope into individual items.
136
+ *
137
+ * Incremental: for sections that carry `last-modified-date`, narrow client-side
138
+ * to records strictly newer than ctx.WatermarkValue, and return the max-seen
139
+ * watermark as NewWatermarkValue (persisted by the engine on full-batch success
140
+ * only). The iD universe itself has no cursor (search is re-resolved each run);
141
+ * dedup rides content-hash idempotency in ToExternalRecord.
142
+ */
143
+ async FetchChanges(ctx) {
144
+ const obj = this.GetCachedObject(ctx.CompanyIntegration.IntegrationID, ctx.ObjectName);
145
+ const fields = this.GetCachedFields(obj.ID);
146
+ const auth = await this.Authenticate(ctx.CompanyIntegration, ctx.ContextUser);
147
+ const orcidIds = await this.ResolveOrcidIdUniverse(auth, ctx);
148
+ const warnings = [];
149
+ if (orcidIds.length === 0) {
150
+ warnings.push({
151
+ Code: 'ZERO_SCOPE',
152
+ Message: `ORCID "${ctx.ObjectName}": no iDs resolved from CompanyIntegration.Configuration. ` +
153
+ `Set "searchQuery" (Lucene) and/or "orcidIds" to scope the sync.`,
154
+ });
155
+ return { Records: [], HasMore: false, Warnings: warnings };
156
+ }
157
+ const section = ctx.ObjectName === ROOT_OBJECT_NAME ? null : ctx.ObjectName;
158
+ const watermark = this.parseWatermark(ctx.WatermarkValue);
159
+ const pkFieldNames = fields.filter(f => f.IsPrimaryKey).map(f => f.Name);
160
+ const out = [];
161
+ let maxSeen = watermark;
162
+ for (const iD of orcidIds) {
163
+ const items = await this.FetchForId(auth, obj, iD, section);
164
+ for (const raw of items) {
165
+ const lmd = this.extractLastModifiedMs(raw);
166
+ // Incremental narrowing: skip records not newer than the watermark.
167
+ if (watermark != null && lmd != null && lmd <= watermark)
168
+ continue;
169
+ if (lmd != null && (maxSeen == null || lmd > maxSeen))
170
+ maxSeen = lmd;
171
+ out.push(this.toRecord(raw, obj, fields, pkFieldNames));
172
+ }
173
+ }
174
+ const result = { Records: out, HasMore: false };
175
+ if (maxSeen != null && maxSeen !== watermark) {
176
+ result.NewWatermarkValue = String(maxSeen);
177
+ }
178
+ if (warnings.length > 0)
179
+ result.Warnings = warnings;
180
+ return result;
181
+ }
182
+ /**
183
+ * Fetches the raw item array for a single iD + object. For the root record IO this is
184
+ * a single-element array (the record itself); for a section it is the expanded group items.
185
+ */
186
+ async FetchForId(auth, obj, iD, section) {
187
+ const path = section == null ? `/${encodeURIComponent(iD)}/record` : `/${encodeURIComponent(iD)}/${section}`;
188
+ const url = `${auth.BaseUrl}${path}`;
189
+ const headers = this.BuildHeaders(auth);
190
+ const resp = await this.MakeHTTPRequest(auth, url, 'GET', headers);
191
+ if (resp.Status === 404)
192
+ return [];
193
+ if (resp.Status === 403) {
194
+ console.warn(`[ORCID] HTTP 403 for "${obj.Name}" iD ${iD} — skipping (insufficient scope/visibility).`);
195
+ return [];
196
+ }
197
+ if (resp.Status < 200 || resp.Status >= 300) {
198
+ throw Object.assign(new Error(`ORCID fetch failed for "${obj.Name}" iD ${iD}: HTTP ${resp.Status}`), { Status: resp.Status, Headers: resp.Headers });
199
+ }
200
+ const body = resp.Body;
201
+ if (!body)
202
+ return [];
203
+ if (section == null) {
204
+ // The full record — tag with the iD so the PK (orcid-id) is always present.
205
+ body['orcid-id'] = iD;
206
+ return [body];
207
+ }
208
+ return this.expandSection(body, section, iD);
209
+ }
210
+ /**
211
+ * Expands an ORCID activity-section group envelope into individual item objects.
212
+ *
213
+ * ORCID groups items under section-specific wrappers (e.g. works →
214
+ * `group[].work-summary[]`, employments → `affiliation-group[].summaries[]`).
215
+ * We walk the generic shape: any array whose elements carry a `put-code` is a
216
+ * leaf item; we flatten all such arrays found anywhere in the envelope. Each
217
+ * item is tagged with the parent `orcid-id` (the FK to record).
218
+ */
219
+ expandSection(body, _section, iD) {
220
+ const items = [];
221
+ const visit = (node) => {
222
+ if (Array.isArray(node)) {
223
+ for (const el of node)
224
+ visit(el);
225
+ return;
226
+ }
227
+ if (node && typeof node === 'object') {
228
+ const obj = node;
229
+ if ('put-code' in obj && obj['put-code'] != null) {
230
+ items.push({ ...obj, 'orcid-id': iD });
231
+ return; // a leaf item — do not descend further into its own children
232
+ }
233
+ for (const v of Object.values(obj))
234
+ visit(v);
235
+ }
236
+ };
237
+ visit(body);
238
+ return items;
239
+ }
240
+ // ─── iD universe resolution ──────────────────────────────────────
241
+ /**
242
+ * Resolves the in-scope ORCID iD universe from CompanyIntegration.Configuration:
243
+ * the explicit `orcidIds` list (always included) plus the result of running the
244
+ * Lucene `searchQuery` against /search (or /expanded-search), bounded by
245
+ * MaxSearchResults to avoid draining the ~10k cap. Returns a de-duplicated set.
246
+ */
247
+ async ResolveOrcidIdUniverse(auth, ctx) {
248
+ const cfg = auth.Config;
249
+ const ids = new Set();
250
+ for (const explicit of cfg.OrcidIds ?? []) {
251
+ const normalized = this.normalizeOrcidId(explicit);
252
+ if (normalized)
253
+ ids.add(normalized);
254
+ }
255
+ if (cfg.SearchQuery && cfg.SearchQuery.trim().length > 0) {
256
+ const fromSearch = await this.RunSearch(auth, cfg.SearchQuery, cfg.MaxSearchResults ?? DEFAULT_MAX_SEARCH_RESULTS);
257
+ for (const id of fromSearch)
258
+ ids.add(id);
259
+ }
260
+ // Honor the engine's per-batch ceiling so a huge universe streams across calls (defensive —
261
+ // typical scoped universes are well under BatchSize).
262
+ const all = Array.from(ids);
263
+ const limit = ctx.BatchSize && ctx.BatchSize > 0 ? ctx.BatchSize : all.length;
264
+ return all.slice(0, limit);
265
+ }
266
+ /**
267
+ * Runs the Lucene query against ORCID /search (or /expanded-search) with offset
268
+ * pagination (start/rows), accumulating iDs up to maxResults ("Goldilocks" bound).
269
+ * Search is unordered and may return duplicates across pages — de-duplicated by the caller.
270
+ */
271
+ async RunSearch(auth, query, maxResults) {
272
+ const path = auth.Config.UseExpandedSearch ? '/expanded-search' : '/search';
273
+ const headers = this.BuildHeaders(auth);
274
+ const collected = [];
275
+ let start = 0;
276
+ while (collected.length < maxResults) {
277
+ const rows = Math.min(SEARCH_PAGE_ROWS, maxResults - collected.length);
278
+ const url = `${auth.BaseUrl}${path}?q=${encodeURIComponent(query)}&start=${start}&rows=${rows}`;
279
+ const resp = await this.MakeHTTPRequest(auth, url, 'GET', headers);
280
+ if (resp.Status < 200 || resp.Status >= 300) {
281
+ throw Object.assign(new Error(`ORCID search failed (HTTP ${resp.Status}) for query "${query}"`), { Status: resp.Status, Headers: resp.Headers });
282
+ }
283
+ const body = resp.Body;
284
+ const results = body?.result ?? [];
285
+ if (results.length === 0)
286
+ break;
287
+ for (const r of results) {
288
+ const id = this.normalizeOrcidId(r['orcid-identifier']?.path);
289
+ if (id)
290
+ collected.push(id);
291
+ }
292
+ start += rows;
293
+ // Stop when the API has returned fewer than a full page (exhausted).
294
+ if (results.length < rows)
295
+ break;
296
+ }
297
+ return collected;
298
+ }
299
+ /** Normalizes a raw iD string to the canonical 0000-0000-0000-0000 form, or null if unusable. */
300
+ normalizeOrcidId(raw) {
301
+ if (typeof raw !== 'string')
302
+ return null;
303
+ const trimmed = raw.trim();
304
+ if (trimmed.length === 0)
305
+ return null;
306
+ // Accept a bare iD or a full URI; take the trailing path segment.
307
+ const seg = trimmed.replace(/\/+$/, '').split('/').pop() ?? trimmed;
308
+ return /^[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{3}[0-9X]$/i.test(seg) ? seg.toUpperCase() : null;
309
+ }
310
+ // ─── Record transformation ────────────────────────────────────────
311
+ /**
312
+ * Builds the ExternalRecord, preserving the FULL raw source record in Fields
313
+ * (full-record pass-through) while flattening the declared scalar fields out of
314
+ * ORCID's nested JSON via TransformRecord/applyTransformPreservingKeys. PK identity
315
+ * (orcid-id for record, put-code for sections) drives the ExternalID; partial keys
316
+ * fall back to the base content-hash identity.
317
+ */
318
+ toRecord(raw, obj, fields, pkFieldNames) {
319
+ const flattened = this.applyTransformPreservingKeys(raw, obj, fields);
320
+ const usablePk = pkFieldNames.length > 0
321
+ && pkFieldNames.every(name => flattened[name] != null && String(flattened[name]).length > 0);
322
+ const externalID = usablePk
323
+ ? pkFieldNames.map(name => String(flattened[name])).join('|')
324
+ : '';
325
+ return {
326
+ ExternalID: externalID, // empty → engine treats as content-hash identity downstream
327
+ ObjectType: obj.Name,
328
+ Fields: flattened,
329
+ };
330
+ }
331
+ /**
332
+ * Per-record reshaping: ORCID returns deeply-nested JSON; pull the declared scalar
333
+ * convenience fields up to the top level so the generated columns are populated, while
334
+ * the full raw record (every nested blob) is preserved by applyTransformPreservingKeys.
335
+ */
336
+ TransformRecord(raw, obj, _fields) {
337
+ const out = { ...raw };
338
+ // Common to record + sections: ORCID wraps a millis timestamp as { value: <ms> }.
339
+ out['last-modified-date'] = this.coerceDate(raw['last-modified-date']);
340
+ if ('created-date' in raw)
341
+ out['created-date'] = this.coerceDate(raw['created-date']);
342
+ if (obj.Name === ROOT_OBJECT_NAME) {
343
+ this.flattenRecordScalars(raw, out);
344
+ }
345
+ return out;
346
+ }
347
+ /** Flattens the record IO's person/history-derived convenience scalars. */
348
+ flattenRecordScalars(raw, out) {
349
+ const person = this.asObject(raw['person']);
350
+ const name = person ? this.asObject(person['name']) : undefined;
351
+ if (name) {
352
+ out['given-names'] = this.valueOf(name['given-names']);
353
+ out['family-name'] = this.valueOf(name['family-name']);
354
+ out['credit-name'] = this.valueOf(name['credit-name']);
355
+ }
356
+ const biography = person ? this.asObject(person['biography']) : undefined;
357
+ if (biography)
358
+ out['biography'] = this.valueOf(biography['content']) ?? biography['content'];
359
+ const history = this.asObject(raw['history']);
360
+ if (history) {
361
+ out['submission-date'] = this.coerceDate(history['submission-date']);
362
+ if (typeof history['claimed'] === 'boolean')
363
+ out['claimed'] = history['claimed'];
364
+ if (typeof history['verified-email'] === 'boolean')
365
+ out['verified-email'] = history['verified-email'];
366
+ }
367
+ // Convenience JSON sections (kept as-is; full blobs preserved via pass-through).
368
+ const p = person ?? {};
369
+ if (person) {
370
+ out['emails'] = p['emails'];
371
+ out['researcher-urls'] = p['researcher-urls'];
372
+ out['keywords'] = p['keywords'];
373
+ out['other-names'] = p['other-names'];
374
+ out['addresses'] = p['addresses'];
375
+ out['external-identifiers'] = p['external-identifiers'];
376
+ }
377
+ }
378
+ // ── Value coercion helpers ──────────────────────────────────────────
379
+ /** ORCID scalar wrapper: { value: <x> } → <x>; otherwise returns the value as-is. */
380
+ valueOf(node) {
381
+ const obj = this.asObject(node);
382
+ if (obj && 'value' in obj)
383
+ return obj['value'];
384
+ return node;
385
+ }
386
+ /** ORCID date wrapper: { value: <millis> } → ISO string; passthrough on already-scalar/empty. */
387
+ coerceDate(node) {
388
+ const ms = this.extractMs(node);
389
+ if (ms == null)
390
+ return null;
391
+ return new Date(ms).toISOString();
392
+ }
393
+ /** Extracts the last-modified-date millis from a record (for watermark comparison). */
394
+ extractLastModifiedMs(raw) {
395
+ return this.extractMs(raw['last-modified-date']);
396
+ }
397
+ /** Pulls a millisecond epoch out of an ORCID timestamp wrapper or a scalar number/ISO string. */
398
+ extractMs(node) {
399
+ const obj = this.asObject(node);
400
+ const value = obj && 'value' in obj ? obj['value'] : node;
401
+ if (value == null)
402
+ return null;
403
+ if (typeof value === 'number' && Number.isFinite(value))
404
+ return value;
405
+ if (typeof value === 'string') {
406
+ const asNum = Number(value);
407
+ if (Number.isFinite(asNum) && value.trim() !== '')
408
+ return asNum;
409
+ const parsed = Date.parse(value);
410
+ return Number.isNaN(parsed) ? null : parsed;
411
+ }
412
+ return null;
413
+ }
414
+ asObject(node) {
415
+ return node && typeof node === 'object' && !Array.isArray(node) ? node : undefined;
416
+ }
417
+ parseWatermark(value) {
418
+ if (value == null)
419
+ return null;
420
+ const ms = this.extractMs(value);
421
+ return ms;
422
+ }
423
+ // ─── Auth + transport (abstract base requirements) ────────────────
424
+ async Authenticate(companyIntegration, contextUser) {
425
+ if (this.authState && this.isTokenValid(this.authState)) {
426
+ return this.authState;
427
+ }
428
+ const config = await this.parseConfig(companyIntegration, contextUser);
429
+ const token = await this.obtainAccessToken(config);
430
+ const state = {
431
+ Token: token.access_token,
432
+ ExpiresAt: new Date(Date.now() + (token.expires_in * 1000)),
433
+ BaseUrl: config.ApiBaseUrl ?? (config.UseSandbox ? SANDBOX_API_HOST : PROD_API_HOST),
434
+ Config: config,
435
+ };
436
+ this.authState = state;
437
+ return state;
438
+ }
439
+ BuildHeaders(auth) {
440
+ const orcidAuth = auth;
441
+ return {
442
+ 'Authorization': `Bearer ${orcidAuth.Token}`,
443
+ 'Accept': 'application/json',
444
+ };
445
+ }
446
+ /** Not used by the overridden FetchChanges; retained for any base-pipeline callers (GetRecord). */
447
+ NormalizeResponse(rawBody, responseDataKey) {
448
+ if (rawBody == null)
449
+ return [];
450
+ if (responseDataKey) {
451
+ const obj = this.asObject(rawBody);
452
+ const inner = obj ? obj[responseDataKey] : undefined;
453
+ if (Array.isArray(inner))
454
+ return inner;
455
+ if (inner && typeof inner === 'object')
456
+ return [inner];
457
+ return [];
458
+ }
459
+ if (Array.isArray(rawBody))
460
+ return rawBody;
461
+ if (typeof rawBody === 'object')
462
+ return [rawBody];
463
+ return [];
464
+ }
465
+ /** ORCID per-iD endpoints are not paginated — every object declares PaginationType=None. */
466
+ ExtractPaginationInfo(_rawBody, _paginationType, currentPage, currentOffset, _pageSize) {
467
+ return { HasMore: false, NextPage: currentPage, NextOffset: currentOffset };
468
+ }
469
+ GetBaseURL(_companyIntegration, auth) {
470
+ return auth.BaseUrl;
471
+ }
472
+ // ─── Token lifecycle ──────────────────────────────────────────────
473
+ isTokenValid(state) {
474
+ return state.ExpiresAt.getTime() - Date.now() > TOKEN_REFRESH_BUFFER_MS;
475
+ }
476
+ /**
477
+ * Exchanges the client_credentials grant for a bearer token at the ORCID token
478
+ * endpoint. POST form: grant_type=client_credentials, client_id, client_secret,
479
+ * scope=/read-public.
480
+ */
481
+ async obtainAccessToken(config) {
482
+ if (!config.ClientID || !config.ClientSecret) {
483
+ throw new Error('ORCIDConnector: ClientID and ClientSecret are required for the client_credentials grant.');
484
+ }
485
+ const tokenUrl = config.TokenURL ?? (config.UseSandbox ? SANDBOX_TOKEN_URL : PROD_TOKEN_URL);
486
+ const params = new URLSearchParams({
487
+ grant_type: 'client_credentials',
488
+ client_id: config.ClientID,
489
+ client_secret: config.ClientSecret,
490
+ scope: config.Scope ?? DEFAULT_SCOPE,
491
+ });
492
+ const resp = await fetch(tokenUrl, {
493
+ method: 'POST',
494
+ headers: {
495
+ 'Content-Type': 'application/x-www-form-urlencoded',
496
+ 'Accept': 'application/json',
497
+ },
498
+ body: params.toString(),
499
+ });
500
+ if (!resp.ok) {
501
+ const text = await resp.text();
502
+ throw new Error(`ORCID OAuth token request failed (HTTP ${resp.status}): ${text.slice(0, 500)}`);
503
+ }
504
+ const payload = await resp.json();
505
+ if (!payload.access_token || typeof payload.access_token !== 'string') {
506
+ throw new Error('ORCID OAuth token response missing access_token');
507
+ }
508
+ return payload;
509
+ }
510
+ // ─── HTTP transport with retry + throttling ───────────────────────
511
+ async MakeHTTPRequest(auth, url, method, headers, body) {
512
+ const orcidAuth = auth;
513
+ const cfg = orcidAuth.Config;
514
+ const maxRetries = cfg.MaxRetries ?? DEFAULT_MAX_RETRIES;
515
+ const timeoutMs = cfg.RequestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
516
+ const minInterval = cfg.MinRequestIntervalMs ?? DEFAULT_MIN_REQUEST_INTERVAL_MS;
517
+ let currentHeaders = headers;
518
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
519
+ await this.throttle(minInterval);
520
+ try {
521
+ const resp = await this.doFetch(url, method, currentHeaders, body, timeoutMs);
522
+ this.lastRequestTime = Date.now();
523
+ if (resp.Status === 401 && attempt < maxRetries) {
524
+ // Token expired/revoked — drop the cache, refresh against the held credentials, retry.
525
+ this.authState = null;
526
+ const refreshed = await this.obtainAccessToken(cfg);
527
+ const refreshedState = {
528
+ Token: refreshed.access_token,
529
+ ExpiresAt: new Date(Date.now() + (refreshed.expires_in * 1000)),
530
+ BaseUrl: cfg.ApiBaseUrl ?? (cfg.UseSandbox ? SANDBOX_API_HOST : PROD_API_HOST),
531
+ Config: cfg,
532
+ };
533
+ this.authState = refreshedState;
534
+ currentHeaders = this.BuildHeaders(refreshedState);
535
+ continue;
536
+ }
537
+ if ((resp.Status === 429 || resp.Status === 503) && attempt < maxRetries) {
538
+ await this.sleep(this.backoffFromResponse(resp, attempt));
539
+ continue;
540
+ }
541
+ return resp;
542
+ }
543
+ catch (err) {
544
+ if (attempt === maxRetries)
545
+ throw err;
546
+ if (!this.isRetryableError(err))
547
+ throw err;
548
+ await this.sleep(this.backoffMs(attempt));
549
+ }
550
+ }
551
+ throw new Error(`ORCID request to ${url} exhausted ${maxRetries + 1} attempts`);
552
+ }
553
+ /** Single fetch() with an AbortController-backed timeout. */
554
+ async doFetch(url, method, headers, body, timeoutMs) {
555
+ const controller = new AbortController();
556
+ const handle = setTimeout(() => controller.abort(), timeoutMs);
557
+ try {
558
+ const resp = await fetch(url, {
559
+ method,
560
+ headers,
561
+ body: body !== undefined ? JSON.stringify(body) : undefined,
562
+ signal: controller.signal,
563
+ });
564
+ const respHeaders = {};
565
+ resp.headers.forEach((value, key) => { respHeaders[key.toLowerCase()] = value; });
566
+ const text = await resp.text();
567
+ const parsed = text.length > 0 ? this.safeParseJSON(text) : null;
568
+ return { Status: resp.status, Body: parsed, Headers: respHeaders };
569
+ }
570
+ finally {
571
+ clearTimeout(handle);
572
+ }
573
+ }
574
+ safeParseJSON(text) {
575
+ try {
576
+ return JSON.parse(text);
577
+ }
578
+ catch {
579
+ return text;
580
+ }
581
+ }
582
+ isRetryableError(err) {
583
+ const msg = err instanceof Error ? err.message : String(err);
584
+ return /abort|timeout|ECONNRESET|ENOTFOUND|ETIMEDOUT|network/i.test(msg);
585
+ }
586
+ backoffMs(attempt) {
587
+ const base = Math.min(1000 * Math.pow(2, attempt), 20000);
588
+ const jitter = Math.floor(Math.random() * 500);
589
+ return base + jitter;
590
+ }
591
+ backoffFromResponse(resp, attempt) {
592
+ const fromHeader = this.ExtractRetryAfterMs({ Headers: resp.Headers });
593
+ if (fromHeader != null)
594
+ return Math.min(fromHeader, 30000);
595
+ return this.backoffMs(attempt);
596
+ }
597
+ async throttle(minIntervalMs) {
598
+ const elapsed = Date.now() - this.lastRequestTime;
599
+ if (elapsed < minIntervalMs)
600
+ await this.sleep(minIntervalMs - elapsed);
601
+ }
602
+ sleep(ms) {
603
+ return new Promise(resolve => setTimeout(resolve, ms));
604
+ }
605
+ // ─── Config parsing ───────────────────────────────────────────────
606
+ /**
607
+ * Resolves the connection config: OAuth2 secrets (ClientID/ClientSecret/TokenURL/Scope) from the
608
+ * credential store; the iD-universe scope (searchQuery/orcidIds) + host selection (useSandbox)
609
+ * from CompanyIntegration.Configuration. Secrets are NEVER baked into code.
610
+ */
611
+ async parseConfig(companyIntegration, contextUser) {
612
+ const fromCredential = companyIntegration.CredentialID
613
+ ? await this.loadFromCredential(companyIntegration.CredentialID, contextUser)
614
+ : null;
615
+ const fromConfig = this.parseConfigurationJson(companyIntegration.Configuration);
616
+ const merged = { ...fromCredential, ...fromConfig };
617
+ // Credential secrets win over any duplicate in Configuration; scope/host win from Configuration.
618
+ if (fromCredential) {
619
+ merged.ClientID = fromCredential.ClientID ?? merged.ClientID;
620
+ merged.ClientSecret = fromCredential.ClientSecret ?? merged.ClientSecret;
621
+ merged.TokenURL = fromCredential.TokenURL ?? merged.TokenURL;
622
+ merged.Scope = merged.Scope ?? fromCredential.Scope;
623
+ }
624
+ if (!merged.ClientID || !merged.ClientSecret) {
625
+ throw new Error('ORCIDConnector: ClientID and ClientSecret must be provided via the credential store ' +
626
+ '(OAuth2 client_credentials).');
627
+ }
628
+ if ((!merged.SearchQuery || merged.SearchQuery.trim().length === 0) && (!merged.OrcidIds || merged.OrcidIds.length === 0)) {
629
+ // Not fatal at auth time — surfaced as a ZERO_SCOPE warning per object in FetchChanges.
630
+ merged.OrcidIds = [];
631
+ }
632
+ return merged;
633
+ }
634
+ /** Parses the non-secret scope/host config from CompanyIntegration.Configuration JSON. */
635
+ parseConfigurationJson(raw) {
636
+ if (!raw || raw.trim().length === 0)
637
+ return {};
638
+ let parsed;
639
+ try {
640
+ parsed = JSON.parse(raw);
641
+ }
642
+ catch {
643
+ throw new Error('ORCIDConnector: CompanyIntegration.Configuration is not valid JSON.');
644
+ }
645
+ const out = {};
646
+ const str = (v) => (typeof v === 'string' ? v : undefined);
647
+ out.SearchQuery = str(parsed['searchQuery']);
648
+ out.UseExpandedSearch = parsed['useExpandedSearch'] === true;
649
+ out.UseSandbox = parsed['useSandbox'] === true;
650
+ if (Array.isArray(parsed['orcidIds'])) {
651
+ out.OrcidIds = parsed['orcidIds'].filter(x => typeof x === 'string');
652
+ }
653
+ if (typeof parsed['maxSearchResults'] === 'number')
654
+ out.MaxSearchResults = parsed['maxSearchResults'];
655
+ // Allow non-secret OAuth host overrides from Configuration (secrets never live here).
656
+ out.TokenURL = str(parsed['tokenUrl']);
657
+ out.ApiBaseUrl = str(parsed['apiBaseUrl'] ?? parsed['BaseURL']);
658
+ // Fallback client credentials from Configuration — the credential store remains preferred
659
+ // (the parseConfig merge gives fromCredential precedence). This matches the GrowthZone /
660
+ // Path LMS pattern and is what makes credential-free replay harnesses possible.
661
+ out.ClientID = str(parsed['ClientID'] ?? parsed['clientId']);
662
+ out.ClientSecret = str(parsed['ClientSecret'] ?? parsed['clientSecret']);
663
+ out.Scope = str(parsed['scope']);
664
+ if (typeof parsed['requestTimeoutMs'] === 'number')
665
+ out.RequestTimeoutMs = parsed['requestTimeoutMs'];
666
+ if (typeof parsed['maxRetries'] === 'number')
667
+ out.MaxRetries = parsed['maxRetries'];
668
+ if (typeof parsed['minRequestIntervalMs'] === 'number')
669
+ out.MinRequestIntervalMs = parsed['minRequestIntervalMs'];
670
+ return out;
671
+ }
672
+ /** Loads OAuth2 secrets from the MJ credential store (generic OAuth2 client-credentials schema). */
673
+ async loadFromCredential(credentialID, contextUser, provider) {
674
+ const md = provider ?? new Metadata();
675
+ const credential = await md.GetEntityObject('MJ: Credentials', contextUser);
676
+ const loaded = await credential.Load(credentialID);
677
+ if (!loaded || !credential.Values)
678
+ return null;
679
+ let raw;
680
+ try {
681
+ raw = JSON.parse(credential.Values);
682
+ }
683
+ catch {
684
+ return null;
685
+ }
686
+ const get = (...keys) => {
687
+ for (const k of keys) {
688
+ const hit = Object.entries(raw).find(([key]) => key.toLowerCase() === k.toLowerCase());
689
+ if (hit && typeof hit[1] === 'string')
690
+ return hit[1];
691
+ }
692
+ return undefined;
693
+ };
694
+ return {
695
+ ClientID: get('ClientID', 'clientId', 'client_id'),
696
+ ClientSecret: get('ClientSecret', 'clientSecret', 'client_secret'),
697
+ TokenURL: get('TokenURL', 'tokenUrl', 'token_url'),
698
+ Scope: get('Scope', 'scope'),
699
+ };
700
+ }
701
+ };
702
+ ORCIDConnector = __decorate([
703
+ RegisterClass(BaseIntegrationConnector, '@memberjunction/connector-orcid')
704
+ ], ORCIDConnector);
705
+ export { ORCIDConnector };
706
+ /** Tree-shaking prevention function — import and call from the module entry point. */
707
+ export function LoadORCIDConnector() { }
708
+ //# sourceMappingURL=ORCIDConnector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ORCIDConnector.js","sourceRoot":"","sources":["../src/ORCIDConnector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './ORCIDConnector.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 './ORCIDConnector.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,38 @@
1
+ {
2
+ "name": "@memberjunction/connector-orcid",
3
+ "version": "1.0.0",
4
+ "description": "MemberJunction ORCID 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
+ },
23
+ "dependencies": {},
24
+ "devDependencies": {
25
+ "@types/node": "24.10.11",
26
+ "tsc-alias": "^1.8.16",
27
+ "typescript": "^5.9.3",
28
+ "vitest": "^4.0.18",
29
+ "@memberjunction/core": "^5.42.0",
30
+ "@memberjunction/core-entities": "^5.42.0",
31
+ "@memberjunction/global": "^5.42.0",
32
+ "@memberjunction/integration-engine": "^5.42.0"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/MemberJunction/Integrations"
37
+ }
38
+ }