onboardconnect-agent 1.2.11 → 1.3.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,222 @@
1
+ import { OcLogger } from "../logger.js";
2
+ // ─── Oracle PeopleSoft Campus Solutions (Track A — real implementation) ─────────
3
+ //
4
+ // On-prem / LAN, behind Integration Broker (IB). The profile carries the IB base
5
+ // URL (e.g. https://ps.campus.edu/PSIGW/RESTListeningConnector/<node>/), the ISU
6
+ // user/password for Basic auth, and the node name. Service operations are named
7
+ // per campus, so the service-op name is driven entirely by `payload.resource`.
8
+ //
9
+ // Auth model (driven by profile.authType):
10
+ // "basic" → HTTP Basic with the ISU username/password (default IB pattern).
11
+ // "bearer" → a pre-issued bearer/OAuth token on the profile (profile.bearerToken).
12
+ // "soap" → WS-Security UsernameToken against the SOAP listening connector;
13
+ // the request is built as a SOAP envelope instead of REST.
14
+ //
15
+ // test → ping a documented service op / the IB ping listener.
16
+ // read → GET the REST service op, filtered by `match` (or SOAP get request).
17
+ // upsert → POST/PUT the Constituent/person service op with the mapped record;
18
+ // idempotency rides on the natural key in `payload.match` (EMPLID /
19
+ // sisStudentId).
20
+ //
21
+ // Plan / runbook: docs/runbooks/sis-writeback.md (PeopleSoft section).
22
+ const ocLogger = new OcLogger("sis-peoplesoft");
23
+ function ocTrimSlash(url) {
24
+ return url.replace(/\/+$/, "");
25
+ }
26
+ async function ocSafeText(res) {
27
+ try {
28
+ return (await res.text()).slice(0, 500);
29
+ }
30
+ catch {
31
+ return "<no body>";
32
+ }
33
+ }
34
+ /** Auth header for the IB REST listener. */
35
+ function ocPsAuthHeader(ctx) {
36
+ const { profile } = ctx;
37
+ if (profile.authType === "bearer") {
38
+ if (!profile.bearerToken) {
39
+ throw new Error(`PeopleSoft profile "${profile.id}" uses bearer auth but has no bearerToken`);
40
+ }
41
+ return { Authorization: `Bearer ${profile.bearerToken}` };
42
+ }
43
+ // Default + SOAP path use the ISU username/password (Basic / WS-Security).
44
+ if (!profile.username || !profile.password) {
45
+ throw new Error(`PeopleSoft profile "${profile.id}" is missing username/password`);
46
+ }
47
+ const basic = Buffer.from(`${profile.username}:${profile.password}`).toString("base64");
48
+ return { Authorization: `Basic ${basic}` };
49
+ }
50
+ /**
51
+ * REST URL for a service operation. The IB REST listening connector path already
52
+ * includes the node; we trust profile.baseUrl to carry it (…/RESTListeningConnector/<node>/).
53
+ * The service-op name (and optional REST resource segments) comes from
54
+ * payload.resource. The natural keys in `match` become trailing path segments,
55
+ * which is how IB CI-based REST handlers usually receive their keys (e.g.
56
+ * .../EMPLID/123). Any unmatched filtering is also mirrored onto the query string.
57
+ */
58
+ function ocPsRestUrl(ctx, base) {
59
+ const resource = ctx.payload.resource.replace(/^\/+|\/+$/g, "");
60
+ if (!resource) {
61
+ throw new Error("PeopleSoft call requires payload.resource to name the IB service operation");
62
+ }
63
+ const match = ctx.payload.match ?? {};
64
+ const keyValues = Object.values(match).map((v) => encodeURIComponent(String(v)));
65
+ const keyed = keyValues.length > 0;
66
+ let url = `${base}/${resource}`;
67
+ if (keyed)
68
+ url += `/${keyValues.join("/")}`;
69
+ return { url, keyed };
70
+ }
71
+ /** Coerce a vendor JSON object into a flat string row for the cloud. */
72
+ function ocFlattenRow(obj) {
73
+ const row = {};
74
+ for (const [k, v] of Object.entries(obj ?? {})) {
75
+ if (v == null)
76
+ continue;
77
+ row[k] = typeof v === "object" ? JSON.stringify(v) : String(v);
78
+ }
79
+ return row;
80
+ }
81
+ /** XML-escape a value for inclusion in a SOAP envelope. */
82
+ function ocXmlEscape(value) {
83
+ return value
84
+ .replace(/&/g, "&amp;")
85
+ .replace(/</g, "&lt;")
86
+ .replace(/>/g, "&gt;")
87
+ .replace(/"/g, "&quot;")
88
+ .replace(/'/g, "&apos;");
89
+ }
90
+ /**
91
+ * WS-Security SOAP request against the SOAP listening connector. The service-op
92
+ * name comes from payload.resource; the natural keys (match) and mapped record
93
+ * fields are emitted as child elements verbatim (names are campus/service
94
+ * specific). UsernameToken carries the ISU credentials.
95
+ */
96
+ async function ocPsSoapCall(ctx, base) {
97
+ const { profile, payload } = ctx;
98
+ if (!profile.username || !profile.password) {
99
+ throw new Error(`PeopleSoft profile "${profile.id}" is missing username/password for WS-Security`);
100
+ }
101
+ const operation = payload.resource.replace(/[^A-Za-z0-9_.]/g, "");
102
+ if (!operation) {
103
+ throw new Error("PeopleSoft SOAP call requires payload.resource to name the service operation");
104
+ }
105
+ const match = payload.match ?? {};
106
+ const record = (payload.record ?? {});
107
+ const fields = { ...match, ...record };
108
+ const dataFields = Object.entries(fields)
109
+ .map(([k, v]) => {
110
+ const tag = ocXmlEscape(k);
111
+ return `<${tag}>${ocXmlEscape(typeof v === "object" ? JSON.stringify(v) : String(v))}</${tag}>`;
112
+ })
113
+ .join("");
114
+ const wsse = `<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">` +
115
+ `<wsse:UsernameToken>` +
116
+ `<wsse:Username>${ocXmlEscape(profile.username)}</wsse:Username>` +
117
+ `<wsse:Password>${ocXmlEscape(profile.password)}</wsse:Password>` +
118
+ `</wsse:UsernameToken>` +
119
+ `</wsse:Security>`;
120
+ const envelope = `<?xml version="1.0" encoding="UTF-8"?>` +
121
+ `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">` +
122
+ `<soapenv:Header>${wsse}</soapenv:Header>` +
123
+ `<soapenv:Body><${operation}>${dataFields}</${operation}></soapenv:Body>` +
124
+ `</soapenv:Envelope>`;
125
+ const res = await fetch(ocTrimSlash(base), {
126
+ method: "POST",
127
+ headers: {
128
+ "Content-Type": "text/xml; charset=utf-8",
129
+ SOAPAction: operation,
130
+ },
131
+ body: envelope,
132
+ });
133
+ const text = await res.text();
134
+ if (!res.ok || /<(soapenv:|SOAP-ENV:)?Fault>/i.test(text)) {
135
+ throw new Error(`PeopleSoft SOAP ${operation} failed (${res.status}): ${text.slice(0, 500)}`);
136
+ }
137
+ const sisId = Object.values(match)[0];
138
+ ocLogger.info("peoplesoft soap call", { operation, sisId });
139
+ return { ...(sisId ? { sisId: String(sisId) } : {}), raw: text };
140
+ }
141
+ export async function ocPeoplesoftCall(ctx) {
142
+ const { payload, profile } = ctx;
143
+ const base = ocTrimSlash(profile.baseUrl);
144
+ // SOAP variant: routed entirely through the WS-Security envelope builder.
145
+ if (profile.authType === "soap") {
146
+ if (payload.operation === "test") {
147
+ // A SOAP "test" still exercises the listener + WS-Security credentials.
148
+ return ocPsSoapCall(ctx, base);
149
+ }
150
+ return ocPsSoapCall(ctx, base);
151
+ }
152
+ const authHeaders = ocPsAuthHeader(ctx);
153
+ const jsonHeaders = { ...authHeaders, Accept: "application/json" };
154
+ if (payload.operation === "test") {
155
+ // Ping the IB REST listener. Many sites expose a lightweight ping service op;
156
+ // when payload.resource is provided we hit it (HEAD-like GET), otherwise we
157
+ // probe the configured base. A 2xx/3xx/401-free response means the listener
158
+ // is reachable and the credentials were accepted.
159
+ const probe = payload.resource ? ocPsRestUrl(ctx, base).url : base;
160
+ const res = await fetch(probe, { headers: jsonHeaders });
161
+ if (!res.ok) {
162
+ throw new Error(`PeopleSoft test probe failed (${res.status}): ${await ocSafeText(res)}`);
163
+ }
164
+ return { raw: { ok: true, vendor: "peoplesoft", resource: payload.resource } };
165
+ }
166
+ if (payload.operation === "read") {
167
+ const { url } = ocPsRestUrl(ctx, base);
168
+ // Also mirror match keys onto the query string for service ops that filter by
169
+ // query rather than path segments.
170
+ const params = new URLSearchParams();
171
+ for (const [k, v] of Object.entries(payload.match ?? {}))
172
+ params.set(k, v);
173
+ const finalUrl = params.toString() ? `${url}?${params.toString()}` : url;
174
+ const res = await fetch(finalUrl, { headers: jsonHeaders });
175
+ if (!res.ok) {
176
+ throw new Error(`PeopleSoft read failed (${res.status}): ${await ocSafeText(res)}`);
177
+ }
178
+ const body = (await res.json());
179
+ // IB REST responses vary: a bare array, a single object, or a wrapper with a
180
+ // collection property. Normalise the common shapes.
181
+ let arr;
182
+ if (Array.isArray(body)) {
183
+ arr = body;
184
+ }
185
+ else if (body && typeof body === "object") {
186
+ const data = body.data ?? body.rows;
187
+ arr = Array.isArray(data) ? data : [body];
188
+ }
189
+ else {
190
+ arr = [body];
191
+ }
192
+ const rows = arr.map((r) => ocFlattenRow(r));
193
+ ocLogger.info("peoplesoft read", { resource: payload.resource, rows: rows.length });
194
+ return { rows, raw: body };
195
+ }
196
+ if (payload.operation === "upsert") {
197
+ const record = payload.record ?? {};
198
+ const { url, keyed } = ocPsRestUrl(ctx, base);
199
+ // When the natural key is present we PUT to the keyed instance URL (update);
200
+ // otherwise POST to the service op to create. This matches CI-based REST
201
+ // handlers that key updates on EMPLID / sisStudentId in the path.
202
+ const method = keyed ? "PUT" : "POST";
203
+ const res = await fetch(url, {
204
+ method,
205
+ headers: { ...jsonHeaders, "Content-Type": "application/json" },
206
+ body: JSON.stringify(record),
207
+ });
208
+ if (!res.ok) {
209
+ throw new Error(`PeopleSoft ${method} ${payload.resource} failed (${res.status}): ${await ocSafeText(res)}`);
210
+ }
211
+ const respBody = (await res.json().catch(() => ({})));
212
+ // Prefer an id the service op echoes back; fall back to the supplied natural
213
+ // key (the stable, caller-known handle for the record).
214
+ const matchVal = Object.values(payload.match ?? {})[0];
215
+ const echoed = respBody["EMPLID"] ?? respBody["id"] ?? respBody["sisStudentId"];
216
+ const sisId = echoed != null ? String(echoed) : matchVal != null ? String(matchVal) : undefined;
217
+ ocLogger.info("peoplesoft upsert", { resource: payload.resource, method, sisId });
218
+ return { ...(sisId ? { sisId } : {}), raw: respBody };
219
+ }
220
+ throw new Error(`Unsupported PeopleSoft operation: ${String(payload.operation)}`);
221
+ }
222
+ //# sourceMappingURL=peoplesoft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peoplesoft.js","sourceRoot":"","sources":["../../src/sis/peoplesoft.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { OcSisCallResult } from "@oc/types";
2
+ import type { OcSisVendorContext } from "../sis.js";
3
+ export declare function ocWorkdayCall(ctx: OcSisVendorContext): Promise<OcSisCallResult>;
4
+ //# sourceMappingURL=workday.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workday.d.ts","sourceRoot":"","sources":["../../src/sis/workday.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAqQpD,wBAAsB,aAAa,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC,CAuFrF"}
@@ -0,0 +1,303 @@
1
+ import { OcLogger } from "../logger.js";
2
+ // ─── Workday Student (Track A — real implementation) ────────────────────────────
3
+ //
4
+ // SaaS, tenant-scoped host. The profile carries the tenant-scoped base URL
5
+ // (e.g. https://wd2-impl-services1.workday.com), the Workday tenant name, the
6
+ // registered API Client credentials, and the web-service / REST API version.
7
+ //
8
+ // Auth model: OAuth 2.0 against the tenant token endpoint
9
+ // (POST /ccx/oauth2/<tenant>/token). Two grants are supported:
10
+ // - client_credentials (authType "oauth_client_credentials")
11
+ // - refresh_token (authType "oauth_refresh_token", profile.refreshToken)
12
+ // The bearer token is cached per profile id until shortly before expiry, then
13
+ // re-fetched — mirroring the Ethos JWT cache.
14
+ //
15
+ // test → obtain a token + a cheap authenticated GET to validate creds.
16
+ // read → GET the REST resource, optionally filtered by `match`.
17
+ // upsert → person/student write. REST where the resource is exposed as REST
18
+ // (/ccx/api/.../<tenant>/...); for writes that require the SOAP Web
19
+ // Service (WWS), build a SOAP envelope and POST it to
20
+ // /ccx/service/<tenant>/... . Idempotency rides on Workday Reference
21
+ // IDs (Student_ID / Applicant_ID) carried in `payload.match`.
22
+ //
23
+ // Plan / runbook: docs/runbooks/sis-writeback.md (Workday section).
24
+ const ocLogger = new OcLogger("sis-workday");
25
+ // Refresh the bearer this many ms before its nominal expiry to avoid edge races.
26
+ const OC_WD_TOKEN_SKEW_MS = 60_000;
27
+ // Workday access tokens default to ~1h. Cache conservatively when the token
28
+ // response omits expires_in.
29
+ const OC_WD_DEFAULT_TTL_MS = 50 * 60_000;
30
+ // Per-profile token cache (process-lifetime). Keyed by profile id so multiple
31
+ // Workday profiles on one agent never share a bearer.
32
+ const ocWorkdayTokenCache = new Map();
33
+ function ocTrimSlash(url) {
34
+ return url.replace(/\/+$/, "");
35
+ }
36
+ async function ocSafeText(res) {
37
+ try {
38
+ return (await res.text()).slice(0, 500);
39
+ }
40
+ catch {
41
+ return "<no body>";
42
+ }
43
+ }
44
+ /** Tenant name from the profile — required for every endpoint path. */
45
+ function ocWorkdayTenant(ctx) {
46
+ const tenant = ctx.profile.tenant?.trim();
47
+ if (!tenant) {
48
+ throw new Error(`Workday profile "${ctx.profile.id}" has no tenant configured`);
49
+ }
50
+ return tenant;
51
+ }
52
+ /** Token endpoint: explicit profile.tokenUrl wins, else derived from base + tenant. */
53
+ function ocWorkdayTokenUrl(ctx, base, tenant) {
54
+ const explicit = ctx.profile.tokenUrl?.trim();
55
+ return explicit ? ocTrimSlash(explicit) : `${base}/ccx/oauth2/${tenant}/token`;
56
+ }
57
+ /** Obtain (and cache) an OAuth2 bearer token for the tenant. */
58
+ async function ocWorkdayGetToken(ctx) {
59
+ const { profile } = ctx;
60
+ if (!profile.clientId || !profile.clientSecret) {
61
+ throw new Error(`Workday profile "${profile.id}" is missing clientId/clientSecret`);
62
+ }
63
+ const cached = ocWorkdayTokenCache.get(profile.id);
64
+ if (cached && cached.expiresAt - OC_WD_TOKEN_SKEW_MS > Date.now()) {
65
+ return cached.accessToken;
66
+ }
67
+ const base = ocTrimSlash(profile.baseUrl);
68
+ const tenant = ocWorkdayTenant(ctx);
69
+ const tokenUrl = ocWorkdayTokenUrl(ctx, base, tenant);
70
+ // Workday registers the API Client with either grant. refresh_token is the
71
+ // common ISU pattern; client_credentials is used for service-to-service ISUs.
72
+ const form = new URLSearchParams();
73
+ if (profile.authType === "oauth_refresh_token") {
74
+ if (!profile.refreshToken) {
75
+ throw new Error(`Workday profile "${profile.id}" uses refresh_token grant but has no refreshToken`);
76
+ }
77
+ form.set("grant_type", "refresh_token");
78
+ form.set("refresh_token", profile.refreshToken);
79
+ }
80
+ else {
81
+ form.set("grant_type", "client_credentials");
82
+ }
83
+ // Client auth via HTTP Basic (client_id:client_secret) — Workday's documented
84
+ // form for the token endpoint.
85
+ const basic = Buffer.from(`${profile.clientId}:${profile.clientSecret}`).toString("base64");
86
+ const res = await fetch(tokenUrl, {
87
+ method: "POST",
88
+ headers: {
89
+ Authorization: `Basic ${basic}`,
90
+ "Content-Type": "application/x-www-form-urlencoded",
91
+ Accept: "application/json",
92
+ },
93
+ body: form.toString(),
94
+ });
95
+ if (!res.ok) {
96
+ throw new Error(`Workday auth failed (${res.status}): ${await ocSafeText(res)}`);
97
+ }
98
+ const body = (await res.json().catch(() => ({})));
99
+ if (!body.access_token) {
100
+ throw new Error("Workday auth returned no access_token");
101
+ }
102
+ const ttl = typeof body.expires_in === "number" ? body.expires_in * 1000 : OC_WD_DEFAULT_TTL_MS;
103
+ ocWorkdayTokenCache.set(profile.id, {
104
+ accessToken: body.access_token,
105
+ expiresAt: Date.now() + ttl,
106
+ });
107
+ return body.access_token;
108
+ }
109
+ function ocWorkdayJsonHeaders(token) {
110
+ return {
111
+ Authorization: `Bearer ${token}`,
112
+ Accept: "application/json",
113
+ "Content-Type": "application/json",
114
+ };
115
+ }
116
+ /** REST API version segment, defaulting to "v1" when the profile omits it. */
117
+ function ocWorkdayVersion(ctx) {
118
+ return ctx.profile.version?.trim() || "v1";
119
+ }
120
+ /**
121
+ * Build the REST URL for a resource. The profile's `resource` is the API
122
+ * service + path tail (e.g. "studentRecords/v1/<tenant>/students" is too brittle
123
+ * to hardcode, so we accept either a fully-formed tail or a bare resource and
124
+ * assemble /ccx/api/<resource-or-version>/<tenant>/...). Campus-specific service
125
+ * names are driven entirely from payload.resource rather than hardcoded here.
126
+ */
127
+ function ocWorkdayRestUrl(ctx, base, tenant) {
128
+ const version = ocWorkdayVersion(ctx);
129
+ // A resource that already contains a slash is treated as a full service path
130
+ // tail "<service>/<version?>/<path>"; otherwise we frame it as
131
+ // "<resource>/<version>". Either way the tenant is injected before the path.
132
+ const resource = ctx.payload.resource.replace(/^\/+/, "");
133
+ return `${base}/ccx/api/${resource}/${tenant}`.replace(/\/+$/, "") + `?version=${encodeURIComponent(version)}`;
134
+ }
135
+ /** Coerce a vendor JSON object into a flat string row for the cloud. */
136
+ function ocFlattenRow(obj) {
137
+ const row = {};
138
+ for (const [k, v] of Object.entries(obj ?? {})) {
139
+ if (v == null)
140
+ continue;
141
+ row[k] = typeof v === "object" ? JSON.stringify(v) : String(v);
142
+ }
143
+ return row;
144
+ }
145
+ /** XML-escape a value for inclusion in a SOAP envelope. */
146
+ function ocXmlEscape(value) {
147
+ return value
148
+ .replace(/&/g, "&amp;")
149
+ .replace(/</g, "&lt;")
150
+ .replace(/>/g, "&gt;")
151
+ .replace(/"/g, "&quot;")
152
+ .replace(/'/g, "&apos;");
153
+ }
154
+ /**
155
+ * Does this upsert require the SOAP Web Service (WWS) rather than REST?
156
+ * Driven by the profile authType ("soap") or an explicit hint on the record
157
+ * (record.__transport === "soap") so a single profile can mix REST reads with a
158
+ * SOAP student write without code changes.
159
+ */
160
+ function ocWorkdayWantsSoap(ctx) {
161
+ if (ctx.profile.authType === "soap")
162
+ return true;
163
+ const record = ctx.payload.record ?? {};
164
+ return record["__transport"] === "soap";
165
+ }
166
+ /**
167
+ * SOAP WWS upsert. Builds a generic Workday-style envelope: the operation name
168
+ * comes from payload.resource (e.g. "Put_Student"), the OAuth bearer is carried
169
+ * in the HTTP Authorization header, the Reference ID(s) from payload.match seed
170
+ * idempotency, and the mapped record fields become child elements. Exact field
171
+ * element names are campus/service specific, so they are emitted verbatim from
172
+ * payload.record rather than hardcoded.
173
+ */
174
+ async function ocWorkdaySoapUpsert(ctx, base, tenant, token) {
175
+ const operation = ctx.payload.resource.replace(/[^A-Za-z0-9_]/g, "");
176
+ if (!operation) {
177
+ throw new Error("Workday SOAP upsert requires payload.resource to name the WWS operation");
178
+ }
179
+ const match = ctx.payload.match ?? {};
180
+ const record = (ctx.payload.record ?? {});
181
+ // Reference IDs (Student_ID / Applicant_ID etc.) carry idempotency. Each match
182
+ // key becomes a typed Workday Reference ID element.
183
+ const referenceIds = Object.entries(match)
184
+ .map(([type, value]) => `<wd:ID wd:type="${ocXmlEscape(type)}">${ocXmlEscape(String(value))}</wd:ID>`)
185
+ .join("");
186
+ // Mapped record fields → child elements (names emitted verbatim; values escaped).
187
+ const dataFields = Object.entries(record)
188
+ .filter(([k]) => k !== "__transport")
189
+ .map(([k, v]) => {
190
+ const tag = ocXmlEscape(k);
191
+ return `<wd:${tag}>${ocXmlEscape(typeof v === "object" ? JSON.stringify(v) : String(v))}</wd:${tag}>`;
192
+ })
193
+ .join("");
194
+ const envelope = `<?xml version="1.0" encoding="UTF-8"?>` +
195
+ `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wd="urn:com.workday/bsvc">` +
196
+ `<soapenv:Body>` +
197
+ `<wd:${operation}_Request>` +
198
+ (referenceIds ? `<wd:Reference>${referenceIds}</wd:Reference>` : "") +
199
+ `<wd:Data>${dataFields}</wd:Data>` +
200
+ `</wd:${operation}_Request>` +
201
+ `</soapenv:Body>` +
202
+ `</soapenv:Envelope>`;
203
+ const url = `${base}/ccx/service/${tenant}/${ocWorkdayVersion(ctx)}`;
204
+ const res = await fetch(url, {
205
+ method: "POST",
206
+ headers: {
207
+ Authorization: `Bearer ${token}`,
208
+ "Content-Type": "text/xml; charset=utf-8",
209
+ SOAPAction: operation,
210
+ },
211
+ body: envelope,
212
+ });
213
+ const text = await res.text();
214
+ if (!res.ok || /<(soapenv:)?Fault>/i.test(text)) {
215
+ throw new Error(`Workday SOAP ${operation} failed (${res.status}): ${text.slice(0, 500)}`);
216
+ }
217
+ // Surface the first match value (the Workday Reference ID) as the sisId — it is
218
+ // the stable, caller-supplied handle for the upserted record.
219
+ const sisId = Object.values(match)[0];
220
+ ocLogger.info("workday soap upsert", { operation, sisId });
221
+ return { ...(sisId ? { sisId: String(sisId) } : {}), raw: text };
222
+ }
223
+ export async function ocWorkdayCall(ctx) {
224
+ const { payload, profile } = ctx;
225
+ const base = ocTrimSlash(profile.baseUrl);
226
+ const tenant = ocWorkdayTenant(ctx);
227
+ const token = await ocWorkdayGetToken(ctx);
228
+ if (payload.operation === "test") {
229
+ // Token already exercised the client creds. Add a cheap authenticated GET so
230
+ // a misconfigured base URL / tenant is caught too. The Workday common API
231
+ // "workers" endpoint is a safe, universally-present probe.
232
+ const probe = `${base}/ccx/api/v1/${tenant}/workers?limit=1`;
233
+ const res = await fetch(probe, { headers: ocWorkdayJsonHeaders(token) });
234
+ if (!res.ok) {
235
+ throw new Error(`Workday test probe failed (${res.status}): ${await ocSafeText(res)}`);
236
+ }
237
+ return { raw: { ok: true, vendor: "workday", tenant } };
238
+ }
239
+ if (payload.operation === "read") {
240
+ const match = payload.match ?? {};
241
+ const url = ocWorkdayRestUrl(ctx, base, tenant);
242
+ // Append match keys as query filters (Workday REST collections accept field
243
+ // filters; exact param names are service-specific so we pass them through).
244
+ const params = new URLSearchParams();
245
+ for (const [k, v] of Object.entries(match))
246
+ params.set(k, v);
247
+ const sep = url.includes("?") ? "&" : "?";
248
+ const finalUrl = params.toString() ? `${url}${sep}${params.toString()}` : url;
249
+ const res = await fetch(finalUrl, { headers: ocWorkdayJsonHeaders(token) });
250
+ if (!res.ok) {
251
+ throw new Error(`Workday read failed (${res.status}): ${await ocSafeText(res)}`);
252
+ }
253
+ const body = (await res.json());
254
+ // Workday REST collections wrap rows in { data: [...] }; tolerate a bare array
255
+ // or a single object too.
256
+ const arr = Array.isArray(body)
257
+ ? body
258
+ : Array.isArray(body?.data)
259
+ ? body.data
260
+ : [body];
261
+ const rows = arr.map((r) => ocFlattenRow(r));
262
+ ocLogger.info("workday read", { resource: payload.resource, rows: rows.length });
263
+ return { rows, raw: body };
264
+ }
265
+ if (payload.operation === "upsert") {
266
+ if (ocWorkdayWantsSoap(ctx)) {
267
+ return ocWorkdaySoapUpsert(ctx, base, tenant, token);
268
+ }
269
+ // REST upsert. Idempotency rides on the Workday Reference ID in `match`: when
270
+ // present we target the instance directly with a PUT; otherwise POST to the
271
+ // collection to create. The first match value is the instance reference id.
272
+ const record = payload.record ?? {};
273
+ const match = payload.match ?? {};
274
+ const refId = Object.values(match)[0];
275
+ const collectionUrl = ocWorkdayRestUrl(ctx, base, tenant);
276
+ let url;
277
+ let method;
278
+ if (refId) {
279
+ // Insert the reference id as a path segment before the ?version query.
280
+ const [path, query] = collectionUrl.split("?");
281
+ url = `${path}/${encodeURIComponent(String(refId))}${query ? `?${query}` : ""}`;
282
+ method = "PUT";
283
+ }
284
+ else {
285
+ url = collectionUrl;
286
+ method = "POST";
287
+ }
288
+ const res = await fetch(url, {
289
+ method,
290
+ headers: ocWorkdayJsonHeaders(token),
291
+ body: JSON.stringify(record),
292
+ });
293
+ if (!res.ok) {
294
+ throw new Error(`Workday ${method} ${payload.resource} failed (${res.status}): ${await ocSafeText(res)}`);
295
+ }
296
+ const respBody = (await res.json().catch(() => ({})));
297
+ const sisId = respBody.id ?? (refId != null ? String(refId) : undefined);
298
+ ocLogger.info("workday upsert", { resource: payload.resource, method, sisId });
299
+ return { ...(sisId ? { sisId } : {}), raw: respBody };
300
+ }
301
+ throw new Error(`Unsupported Workday operation: ${String(payload.operation)}`);
302
+ }
303
+ //# sourceMappingURL=workday.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workday.js","sourceRoot":"","sources":["../../src/sis/workday.ts"],"names":[],"mappings":"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"}
package/dist/sis.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import type { OcSisCallPayload, OcSisCallResult } from "@oc/types";
2
+ import type { OcStore, OcSisProfile } from "./store.js";
3
+ /** A resolved vendor call: the validated payload + the profile's credentials. */
4
+ export interface OcSisVendorContext {
5
+ payload: OcSisCallPayload;
6
+ profile: OcSisProfile;
7
+ }
8
+ export declare function executeSisCall(payload: OcSisCallPayload, store: OcStore): Promise<OcSisCallResult>;
9
+ //# sourceMappingURL=sis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sis.d.ts","sourceRoot":"","sources":["../src/sis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAcxD,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,eAAe,CAAC,CAgC1B"}
package/dist/sis.js ADDED
@@ -0,0 +1,30 @@
1
+ import { ocEthosCall } from "./sis/ethos.js";
2
+ import { ocPeoplesoftCall } from "./sis/peoplesoft.js";
3
+ import { ocWorkdayCall } from "./sis/workday.js";
4
+ export async function executeSisCall(payload, store) {
5
+ if (!payload || typeof payload !== "object") {
6
+ throw new Error("Invalid SIS call payload");
7
+ }
8
+ if (!payload.profileId) {
9
+ throw new Error("SIS call is missing profileId");
10
+ }
11
+ const profile = await store.loadSisCredentials(payload.profileId);
12
+ if (!profile) {
13
+ throw new Error(`SIS profile "${payload.profileId}" is not configured on this agent — add it under Settings → SIS Profiles`);
14
+ }
15
+ if (profile.vendor !== payload.vendor) {
16
+ throw new Error(`SIS profile "${payload.profileId}" is a ${profile.vendor} profile but the step requested ${payload.vendor}`);
17
+ }
18
+ const ctx = { payload, profile };
19
+ switch (payload.vendor) {
20
+ case "ethos":
21
+ return ocEthosCall(ctx);
22
+ case "peoplesoft":
23
+ return ocPeoplesoftCall(ctx);
24
+ case "workday":
25
+ return ocWorkdayCall(ctx);
26
+ default:
27
+ throw new Error(`Unsupported SIS vendor: ${String(payload.vendor)}`);
28
+ }
29
+ }
30
+ //# sourceMappingURL=sis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sis.js","sourceRoot":"","sources":["../src/sis.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAiBjD,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAyB,EACzB,KAAc;IAEd,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,gBAAgB,OAAO,CAAC,SAAS,0EAA0E,CAC5G,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CACb,gBAAgB,OAAO,CAAC,SAAS,UAAU,OAAO,CAAC,MAAM,mCAAmC,OAAO,CAAC,MAAM,EAAE,CAC7G,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAuB,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IAErD,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;QACvB,KAAK,OAAO;YACV,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,KAAK,YAAY;YACf,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAC/B,KAAK,SAAS;YACZ,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;QAC5B;YACE,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAE,OAAgC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACnG,CAAC;AACH,CAAC"}