@borrowbetter/arpcsdk 0.5.0 → 0.6.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/README.md +10 -3
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ pnpm add @borrowbetter/arpcsdk
|
|
|
10
10
|
|
|
11
11
|
## Requirements
|
|
12
12
|
|
|
13
|
-
- Node.js >=
|
|
13
|
+
- Node.js >= 22.12
|
|
14
14
|
- FDR ARPC OAuth client credentials (provided by your FDR integration contact)
|
|
15
15
|
|
|
16
16
|
## Quick start
|
|
@@ -295,6 +295,13 @@ Releases are automated via [Changesets](https://github.com/changesets/changesets
|
|
|
295
295
|
pnpm changeset
|
|
296
296
|
```
|
|
297
297
|
Pick the bump (patch/minor/major) and write a summary. Commit the generated `.changeset/*.md` alongside your code.
|
|
298
|
-
2. Merge to `main`. The **Release** workflow (`.github/workflows/release.yml`)
|
|
298
|
+
2. Merge to `main`. The **Release** workflow (`.github/workflows/release.yml`) runs `changeset version` (bumps `package.json` + updates `CHANGELOG.md`, consuming the changeset) on a `changeset-release/main` branch and opens a **chore: version packages** PR.
|
|
299
|
+
3. The same workflow run waits on that PR's checks and squash-merges it as soon as they're all green — no action needed from you. That merge lands on `main`, re-triggers Release with no changesets pending, and *that* run publishes to npm.
|
|
299
300
|
|
|
300
|
-
|
|
301
|
+
Nothing is pushed to `main` directly; the org rulesets don't allow it. Every repo-facing step runs as the `borrowbetter-automation` GitHub App, which is a `pull_request`-mode bypass actor on `org-require-pr-review` — that's what lets it merge a mechanical version bump without a human approval while still forcing the change through a PR. The merge gate is *every* check on the PR, not just the contexts the ruleset marks required, so a red typecheck stops the release even though CI isn't a required context.
|
|
302
|
+
|
|
303
|
+
If a release stalls, look for an open `chore: version packages` PR: a failed check leaves it sitting there and turns the Release run red. Fix forward on `main` and the next push rebuilds the branch from scratch.
|
|
304
|
+
|
|
305
|
+
> **Never write the literal CI-skip token in a commit message or PR body.** GitHub honours it anywhere in the message, not just the first line, and squash merges here inherit the branch's commit messages (`squash_merge_commit_message: COMMIT_MESSAGES`). Mentioning it in prose — even in backticks, even to say you removed it — silently suppresses CI on the PR and Release on the merge, which is exactly the run that publishes. It cost this repo a day of green-looking PRs with no CI on them. Write it as "the skip-ci marker" instead.
|
|
306
|
+
|
|
307
|
+
Publishing uses **npm OIDC trusted publishing** — no `NPM_TOKEN` secret. The trusted-publisher policy on npm is scoped to this repo + the `release.yml` workflow, so don't rename or move that file. `workflow_dispatch` publishes whatever version `package.json` currently holds, for when a bump landed but the publish didn't.
|
package/dist/index.js
CHANGED
|
@@ -110,8 +110,9 @@ var customInstance = async (request, options) => {
|
|
|
110
110
|
// and refreshes once the cached token goes stale. The OAuth exchange
|
|
111
111
|
// itself runs on a bare ky.post (no hook), so there's no recursion.
|
|
112
112
|
beforeRequest: [
|
|
113
|
-
async (
|
|
114
|
-
|
|
113
|
+
async ({ request: request2 }) => {
|
|
114
|
+
const token = await resolveToken();
|
|
115
|
+
request2.headers.set("Authorization", `Bearer ${token}`);
|
|
115
116
|
}
|
|
116
117
|
]
|
|
117
118
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/auth.ts","../src/http/client.ts","../src/generated/arpc.ts","../src/draft-type.ts","../src/index.ts"],"names":["ky"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * SDK configuration.\n *\n * The library never reads the environment itself — a consumer constructs\n * `new ArpcSDK(config)`, which calls `configure()`. Where that config comes\n * from (env vars, a secrets manager, a config service) is the caller's business.\n */\n/**\n * Bearer-token store. The SDK authenticates lazily on the first gateway call:\n * it asks `get()` for a still-valid token and, on `null`, exchanges credentials\n * and hands the fresh token to `set()`. Owning expiry is the cache's job —\n * `get()` returns `null` once the token is stale (or near-stale). The default\n * store is in-memory and per-process; supply one to persist across restarts or\n * share across workers.\n */\nexport interface TokenCache {\n\t/** Return a valid bearer token, or `null` if absent/expired. */\n\tget(): Promise<string | null>;\n\t/** Persist a freshly exchanged token. `expiresAt` already includes the SDK's refresh skew. */\n\tset(token: string, expiresAt: Date): Promise<void>;\n}\n\n/** FDR deployment target. Selects both hosts — see `ARPC_ENDPOINTS`. */\nexport type ArpcEnvironment = \"dev\" | \"stg\" | \"prd\";\n\n/** The host pair a single environment resolves to. */\nexport interface ArpcEndpoint {\n\t/** OAuth host — token exchange only (`POST /v1/token`). */\n\treadonly oauth: string;\n\t/** API gateway host — every non-auth call. */\n\treadonly gateway: string;\n}\n\n/**\n * Per-environment hosts. The two differ by domain, not just subdomain: the\n * OAuth host is `ffngcp.com`, the gateway is `fdrgcp.com`.\n *\n * Frozen: this table backs both host resolution and environment validation, so\n * a consumer mutating it would quietly change SDK behavior.\n */\nexport const ARPC_ENDPOINTS: Readonly<Record<ArpcEnvironment, ArpcEndpoint>> =\n\tObject.freeze({\n\t\tdev: Object.freeze({\n\t\t\toauth: \"https://oauth.dev.ffngcp.com\",\n\t\t\tgateway: \"https://apis-gateway-v2.dev.fdrgcp.com\",\n\t\t}),\n\t\tstg: Object.freeze({\n\t\t\toauth: \"https://oauth.stg.ffngcp.com\",\n\t\t\tgateway: \"https://apis-gateway-v2.stg.fdrgcp.com\",\n\t\t}),\n\t\tprd: Object.freeze({\n\t\t\toauth: \"https://oauth.prd.ffngcp.com\",\n\t\t\tgateway: \"https://apis-gateway-v2.prd.fdrgcp.com\",\n\t\t}),\n\t});\n\n/**\n * Narrow a raw string to an `ArpcEnvironment`. Useful when the value arrives\n * untyped — an env var, a JSON config file, a request payload.\n */\nexport function isArpcEnvironment(value: string): value is ArpcEnvironment {\n\t// Own keys only — `in` would also match inherited members like `toString`.\n\treturn Object.keys(ARPC_ENDPOINTS).includes(value);\n}\n\nexport interface ArpcAuth {\n\t/**\n\t * OAuth client_id (HTTP Basic username). Also used as the lead's\n\t * `seller_agent_email` — the OAuth identity is a registered DRA agent.\n\t */\n\tusername: string;\n\t/** OAuth client_secret (HTTP Basic password). */\n\tpassword: string;\n\t/** Bearer-token store. Defaults to an in-memory, per-process cache. */\n\tcache?: TokenCache;\n}\n\n/**\n * Escape hatch — per-host overrides of the `environment` defaults. Omit a key\n * (or leave it `undefined`) to keep that environment's host.\n */\nexport interface ArpcUrls {\n\t/** OAuth host — token exchange only (`POST /v1/token`). */\n\toauth?: string;\n\t/** API gateway host — every non-auth call. */\n\tgateway?: string;\n}\n\nexport interface ArpcConfig {\n\t/** Selects the FDR environment. Drives both hosts. */\n\tenvironment: ArpcEnvironment;\n\tauth: ArpcAuth;\n\turls?: ArpcUrls;\n}\n\n/** Config as the internals consume it — hosts resolved to concrete strings. */\nexport interface ResolvedArpcConfig extends ArpcConfig {\n\turls: Required<ArpcUrls>;\n}\n\nlet current: ResolvedArpcConfig | null = null;\n\n/**\n * Fold the environment defaults together with any caller overrides. The guard\n * looks unreachable given the types, but `environment` routinely arrives from\n * somewhere untyped (an env var, a JSON config, a JS caller) — catch it here\n * rather than letting `undefined` reach a request URL.\n */\nfunction resolveUrls(config: ArpcConfig): Required<ArpcUrls> {\n\tif (!isArpcEnvironment(config.environment)) {\n\t\tthrow new Error(\n\t\t\t`Unknown environment: ${config.environment} (expected one of ${Object.keys(ARPC_ENDPOINTS).join(\", \")})`,\n\t\t);\n\t}\n\tconst defaults = ARPC_ENDPOINTS[config.environment];\n\treturn {\n\t\toauth: config.urls?.oauth ?? defaults.oauth,\n\t\tgateway: config.urls?.gateway ?? defaults.gateway,\n\t};\n}\n\n/** Set the active config, resolving hosts once. Called by the `ArpcSDK` constructor. */\nexport function configure(config: ArpcConfig): void {\n\tcurrent = { ...config, urls: resolveUrls(config) };\n}\n\n/** Read the active config. Throws if the SDK hasn't been constructed yet. */\nexport function getConfig(): ResolvedArpcConfig {\n\tif (!current) {\n\t\tthrow new Error(\n\t\t\t\"ArpcSDK is not configured — construct `new ArpcSDK(config)` before making calls\",\n\t\t);\n\t}\n\treturn current;\n}\n","import ky from \"ky\";\nimport { getConfig, type TokenCache } from \"./config\";\n\n// Token lifecycle lives in the orchestration layer, not the generated client:\n// the exchange targets the OAuth host (not the gateway), uses HTTP Basic, and is\n// form-encoded. Authentication is lazy — `resolveToken()` runs from the ky\n// beforeRequest hook on the first gateway call (and again once the token goes\n// stale), so callers never manage the token by hand.\nexport interface TokenResponse {\n\taccess_token: string;\n\ttoken_type?: string;\n\texpires_in?: number;\n}\n\n// Refresh this many ms before the server's stated expiry, so a token never\n// lapses mid-flight. Applied once, when we compute the stored `expiresAt`.\nconst TOKEN_SKEW_MS = 30_000;\n// FDR tokens are ~900s; fall back to that if the response omits expires_in.\nconst DEFAULT_TTL_S = 900;\n\n/** Raw credentials → bearer JWT. No storage; `resolveToken()` owns that. */\nexport async function exchangeToken(): Promise<TokenResponse> {\n\tconst { urls, auth } = getConfig();\n\tconst basic = Buffer.from(`${auth.username}:${auth.password}`).toString(\n\t\t\"base64\",\n\t);\n\n\treturn ky\n\t\t.post(`${urls.oauth}/v1/token`, {\n\t\t\theaders: { Authorization: `Basic ${basic}` },\n\t\t\tbody: new URLSearchParams({ grant_type: \"client_credentials\" }),\n\t\t})\n\t\t.json<TokenResponse>();\n}\n\n// Default store: in-memory, per-process. Used when config omits `cache`.\nlet memToken: string | null = null;\nlet memExpiresAt = 0;\nconst defaultCache: TokenCache = {\n\tasync get() {\n\t\treturn memToken && Date.now() < memExpiresAt ? memToken : null;\n\t},\n\tasync set(token, expiresAt) {\n\t\tmemToken = token;\n\t\tmemExpiresAt = expiresAt.getTime();\n\t},\n};\n\n// Single-flight guard: a cold burst of concurrent gateway calls performs one\n// exchange, not one per call.\nlet inflight: Promise<string> | null = null;\n\n/**\n * Return a valid bearer token, exchanging + caching on a miss. Called by the\n * gateway beforeRequest hook; not part of the public surface.\n */\nexport function resolveToken(): Promise<string> {\n\tconst store = getConfig().auth.cache ?? defaultCache;\n\tif (inflight) return inflight;\n\n\tinflight = (async () => {\n\t\tconst cached = await store.get();\n\t\tif (cached) return cached;\n\t\tconst res = await exchangeToken();\n\t\tconst ttl = (res.expires_in ?? DEFAULT_TTL_S) * 1000;\n\t\tawait store.set(\n\t\t\tres.access_token,\n\t\t\tnew Date(Date.now() + ttl - TOKEN_SKEW_MS),\n\t\t);\n\t\treturn res.access_token;\n\t})().finally(() => {\n\t\tinflight = null;\n\t});\n\treturn inflight;\n}\n","import ky from \"ky\";\nimport { resolveToken } from \"../auth\";\nimport { getConfig } from \"../config\";\n\n// ---------------------------------------------------------------------------\n// Orval custom mutator (ky-backed).\n//\n// Every generated operation calls `customInstance<T>(config, options)`. We\n// route all calls to the API gateway, attach the bearer token via a\n// beforeRequest hook (lazy auth — `resolveToken()` exchanges/refreshes as\n// needed), and return a small { status, data, headers } wrapper WITHOUT\n// throwing on non-2xx — the caller inspects status codes itself (202 +\n// Retry-After on program, 400 on a UW/DRA gate, etc.).\n// ---------------------------------------------------------------------------\n\n// Shape Orval passes as the first arg (axios-style request config).\nexport interface RequestConfig {\n\turl: string;\n\tmethod: string;\n\tparams?: Record<string, unknown>;\n\tdata?: unknown;\n\theaders?: Record<string, string>;\n\tsignal?: AbortSignal;\n\tresponseType?: string;\n}\n\nexport interface HttpResponse<T> {\n\tstatus: number;\n\tdata: T;\n\theaders: Headers;\n}\n\nexport const customInstance = async <T>(\n\trequest: RequestConfig,\n\toptions?: Partial<RequestConfig>,\n): Promise<HttpResponse<T>> => {\n\tconst { url, method, params, data, signal } = { ...request, ...options };\n\t// Merge headers from both sides — a per-call override (e.g. an\n\t// x-correlation-id in `options.headers`) must not drop the operation's\n\t// Content-Type. The bearer token is layered on last, below.\n\tconst headers = { ...request.headers, ...options?.headers };\n\n\tconst target = new URL(url, getConfig().urls.gateway);\n\tif (params) {\n\t\tfor (const [key, value] of Object.entries(params)) {\n\t\t\tif (value !== undefined && value !== null)\n\t\t\t\ttarget.searchParams.set(key, String(value));\n\t\t}\n\t}\n\n\tconst response = await ky(target, {\n\t\tmethod,\n\t\theaders,\n\t\thooks: {\n\t\t\t// Lazy bearer injection: resolveToken() exchanges on the first call\n\t\t\t// and refreshes once the cached token goes stale. The OAuth exchange\n\t\t\t// itself runs on a bare ky.post (no hook), so there's no recursion.\n\t\t\tbeforeRequest: [\n\t\t\t\tasync (req) => {\n\t\t\t\t\treq.headers.set(\"Authorization\", `Bearer ${await resolveToken()}`);\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t...(data !== undefined ? { json: data } : {}),\n\t\tsignal,\n\t\tthrowHttpErrors: false,\n\t\tretry: 0,\n\t\t// Some gateway calls (program generation in particular) can take well over ky's\n\t\t// 10s default to respond. Raise the per-request ceiling; the program poll loop\n\t\t// handles 202/Retry-After on top of this.\n\t\ttimeout: 60_000,\n\t});\n\n\tconst text = await response.text();\n\tlet body: T;\n\ttry {\n\t\tbody = (text ? JSON.parse(text) : undefined) as T;\n\t} catch {\n\t\t// Non-JSON body (e.g. a gateway HTML error page on a transient 5xx). Don't throw —\n\t\t// hand back the raw text so callers can inspect status/body and retry as needed.\n\t\tbody = text as unknown as T;\n\t}\n\treturn { status: response.status, data: body, headers: response.headers };\n};\n","/**\n * Generated by orval v7.21.0 🍺\n * Do not edit manually.\n * ARPC — Achieve Resolution Partner Connect API\n * FDR Wholesale API — A Hybrid Integration Model designed to maximise partner velocity without compromising enterprise data standards. DEX (Digital Enrollment Experience) is the partner-facing integration layer that powers the full applicant lifecycle. The `fdr_applicant_id` acts as the applicant's passport across all systems, persisted from first eligibility check through enrollment. All endpoints require a valid Bearer JWT with the `arpc.all` role.\n\n**Published:** 2026-08-18\n * OpenAPI spec version: 2026.16.1\n */\nimport type {\n ARPCErrorResponse,\n ApplicationSendEmailResponse,\n BankUpdateRequest,\n CreateLeadRequest,\n CreateLeadResponse,\n DraRequest,\n DraResponse,\n EligibilityRequest,\n EligibilityResponse,\n LeadPatchRequest,\n LeadResponse,\n LeadTransferRequest,\n LeadTransferResponse,\n ProgramRequest,\n ProgramSelectionRequest,\n ProgramSummaryTaskRequest,\n ProgramSummaryTaskResponse,\n ReadinessResponse,\n RegisterApplicantV2Request,\n RegisterApplicantV2Response,\n SpinwheelNetworkUserRequest,\n SpinwheelNetworkUserResponse,\n StatelessReadinessRequest,\n UwSubmissionV2Response\n} from './model';\n\nimport { customInstance } from '../http/client';\ntype SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];\n\n\n export const getARPCAchieveResolutionPartnerConnectAPI = () => {\n/**\n * Synchronous Orchestration: Handles both lead creation and income/expense data in one step, eliminating the async polling black box. Data authority shifts here — Achieve becomes the Source of Truth once the lead is formally promoted. Returns the full lead creation result including program options.\n * @summary Sync wholesale lead creation\n */\nconst createLeadSync = (\n createLeadRequest: CreateLeadRequest,\n options?: SecondParameter<typeof customInstance<CreateLeadResponse>>,) => {\n return customInstance<CreateLeadResponse>(\n {url: `/v3/application`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: createLeadRequest\n },\n options);\n }\n \n/**\n * Gateway-level endpoint: selects a payment schedule for an existing lead and persists the program offer. After calling generateProgram, choose a schedule from payment_schedule_options and submit its draft_type and estimated_monthly_payment here. The gateway injects request attributes and forwards internally to POST /v3/application/program. Requires a valid Authorization header.\n * @summary Select program schedule for an existing lead\n */\nconst selectProgram = (\n programSelectionRequest: ProgramSelectionRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/program-selection`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: programSelectionRequest\n },\n options);\n }\n \n/**\n * Stateless Readiness Check: Pre-flight validation before initiating program calculations. Catches duplicate SSNs or emails early to prevent downstream failures. Requires a valid Authorization header.\n * @summary Check application readiness\n */\nconst checkApplicationReadiness = (\n statelessReadinessRequest: StatelessReadinessRequest,\n options?: SecondParameter<typeof customInstance<ReadinessResponse>>,) => {\n return customInstance<ReadinessResponse>(\n {url: `/v1/application/readiness`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: statelessReadinessRequest\n },\n options);\n }\n \n/**\n * Recovery endpoint — only required when the async Spinwheel user creation triggered by `POST /v1/applicant/register` fails due to a user error (e.g. invalid SSN or DOB). Not needed in the happy path. Authenticates the seller, resolves the law firm / program, creates an applicant ID when needed, and connects the applicant to the Spinwheel network. Requires a valid Authorization header.\n * @summary Create / connect Spinwheel network user\n */\nconst createSpinwheelNetworkUser = (\n spinwheelNetworkUserRequest: SpinwheelNetworkUserRequest,\n options?: SecondParameter<typeof customInstance<SpinwheelNetworkUserResponse>>,) => {\n return customInstance<SpinwheelNetworkUserResponse>(\n {url: `/v1/application/spinwheel-network-user`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: spinwheelNetworkUserRequest\n },\n options);\n }\n \n/**\n * Authenticates the seller, validates banking disclosure requirements, optionally validates the submitted account and routing numbers, patches the program, and returns the refreshed lead payload. Requires a valid Authorization header.\n * @summary Update applicant bank details\n */\nconst updateApplicationBankDetails = (\n applicantId: string,\n bankUpdateRequest: BankUpdateRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/bank-update/${applicantId}`, method: 'PATCH',\n headers: {'Content-Type': 'application/json', },\n data: bankUpdateRequest\n },\n options);\n }\n \n/**\n * Banking Disclosure: Manually triggers the banking disclosure email. **This endpoint is optional** — it is only needed when the disclosure was not already sent automatically by `POST /v2/application/uw-submission/{fdrApplicantId}` (which auto-sends on full UW approval). Use this endpoint for conditional approvals or when the v1 UW submission path is in use. A critical legal prerequisite that must be completed before enrollment can proceed. Requires a valid Authorization header.\n * @summary Send banking disclosure email (optional — only if not auto-sent by v2 UW submission)\n */\nconst sendEmail = (\n fdrApplicantId: string,\n options?: SecondParameter<typeof customInstance<ApplicationSendEmailResponse>>,) => {\n return customInstance<ApplicationSendEmailResponse>(\n {url: `/v1/application/send-email/${fdrApplicantId}`, method: 'POST'\n },\n options);\n }\n \n/**\n * Submits a lead evaluation request. fdr_applicant_id is required in the request body. Requires a valid Authorization header with the arpc.all role.\n * @summary Transfer a lead to the debt-resolution program\n */\nconst leadTransfer = (\n leadTransferRequest: LeadTransferRequest,\n options?: SecondParameter<typeof customInstance<LeadTransferResponse>>,) => {\n return customInstance<LeadTransferResponse>(\n {url: `/v1/application/lead-transfer`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: leadTransferRequest\n },\n options);\n }\n \n/**\n * Fetches the current state of an application / lead record by FDR applicant ID. Requires a valid Authorization header.\n * @summary Read application / lead details\n */\nconst readLead = (\n fdrApplicantId: string,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/${fdrApplicantId}`, method: 'GET'\n },\n options);\n }\n \n/**\n * Applies a partial update to an existing wholesale lead record. Requires a valid Authorization header and an x-correlation-id header for request tracing. For split drafts, update second_draft_date_split after UW submission and before generating the DRA; the bi-weekly second_draft_date_bi_weekly field is populated automatically during UW approval.\n * @summary Partial update of application / lead record\n */\nconst patchLead = (\n fdrApplicantId: string,\n leadPatchRequest: LeadPatchRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/${fdrApplicantId}`, method: 'PATCH',\n headers: {'Content-Type': 'application/json', },\n data: leadPatchRequest\n },\n options);\n }\n \n/**\n * DRA Readiness Check: Final pre-flight confirming the lead is approved and all prerequisites are met before initiating the embedded signing session. Requires a valid Authorization header.\n * @summary Get application readiness status\n */\nconst getApplicationReadiness = (\n applicantId: string,\n options?: SecondParameter<typeof customInstance<ReadinessResponse>>,) => {\n return customInstance<ReadinessResponse>(\n {url: `/v1/application/${applicantId}/readiness`, method: 'GET'\n },\n options);\n }\n \n/**\n * Embedded DRA Signing: Returns an Embedded Signing URL so the applicant signs the Debt Resolution Agreement via DocuSign directly within the Symple UI, preventing session breakage. Successful legal execution triggers automatic enrollment. Requires a valid Authorization header.\n * @summary Generate Debt Resolution Agreement (DRA)\n */\nconst generateDra = (\n applicantId: string,\n draRequest: DraRequest,\n options?: SecondParameter<typeof customInstance<DraResponse>>,) => {\n return customInstance<DraResponse>(\n {url: `/v2/application/${applicantId}/dra`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: draRequest\n },\n options);\n }\n \n/**\n * **Recommended endpoint.** `POST /v1/applicant/register` is deprecated and will be retired by end of July 2026 (deadline can be extended on request if your team needs more time). Identity Anchoring: Persists applicant PII to Achieve's managed partner CRM and generates the `fdr_applicant_id` — the applicant's passport across all systems. Routes to the correct target system based on seller identity, and triggers the async credit fetch. Requires a valid Authorization header.\n * @summary Seller-aware applicant registration (v2 — unified ARPCErrorResponse envelope) — recommended\n */\nconst registerApplicantV2 = (\n registerApplicantV2Request: RegisterApplicantV2Request,\n options?: SecondParameter<typeof customInstance<RegisterApplicantV2Response>>,) => {\n return customInstance<RegisterApplicantV2Response>(\n {url: `/v2/applicant/register`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: registerApplicantV2Request\n },\n options);\n }\n \n/**\n * Async Polling Loop: Call this single endpoint for both initial generation and refresh. Returns 202 Accepted with a Retry-After header while credit is still pending. Once ready, the Managed Package orchestrates the calculation and persists the program result. Requires a valid Authorization header.\n * @summary Generate application program (v1)\n */\nconst generateProgramV1 = (\n programRequest: ProgramRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/program`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: programRequest\n },\n options);\n }\n \n/**\n * Eligibility Scout: Two operational modes — (1) no PII required: state-based quote using provided debt accounts; (2) credit pull: full applicant PII for a live soft credit report. Returns estimated program options to anchor the conversation before any registration occurs. Requires a valid Authorization header.\n * @summary Check application eligibility\n */\nconst checkEligibility = (\n eligibilityRequest: EligibilityRequest,\n options?: SecondParameter<typeof customInstance<EligibilityResponse>>,) => {\n return customInstance<EligibilityResponse>(\n {url: `/v2/application/eligibility`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: eligibilityRequest\n },\n options);\n }\n \n/**\n * **Recommended endpoint — supersedes v1.** Submits a wholesale application to the underwriting system. On full UW approval (`sub_status = 'UW Approved'`) the banking disclosure email is sent automatically — no separate `send-email` call is needed in this path. Conditional approvals suppress the auto-send; in that case the manual `POST /v1/application/send-email/{fdrApplicantId}` endpoint can be used. Uses the SF Object API directly (no suip-proxy hop). Requires a valid Authorization header.\n * @summary Submit application to underwriting (v2 — auto banking disclosure) — recommended\n */\nconst uwSubmissionV2 = (\n fdrApplicantId: string,\n options?: SecondParameter<typeof customInstance<UwSubmissionV2Response>>,) => {\n return customInstance<UwSubmissionV2Response>(\n {url: `/v2/application/uw-submission/${fdrApplicantId}`, method: 'POST'\n },\n options);\n }\n \n/**\n * Creates a SUIP Salesforce 'Program Summary Recording' task for the applicant identified by the {id} path variable. For DEX (or missing header), the parent SF opportunity is additionally PATCHed with the seller-config partner default PSC. For DC, the task is created and the parent SF opportunity is PATCHed only when ws_psc_code is provided in the request payload.\n * @summary Create program-summary recording task\n */\nconst createProgramSummaryTask = (\n id: string,\n programSummaryTaskRequest: ProgramSummaryTaskRequest,\n options?: SecondParameter<typeof customInstance<ProgramSummaryTaskResponse>>,) => {\n return customInstance<ProgramSummaryTaskResponse>(\n {url: `/v2/application/program-summary-task/${id}`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: programSummaryTaskRequest\n },\n options);\n }\n \nreturn {createLeadSync,selectProgram,checkApplicationReadiness,createSpinwheelNetworkUser,updateApplicationBankDetails,sendEmail,leadTransfer,readLead,patchLead,getApplicationReadiness,generateDra,registerApplicantV2,generateProgramV1,checkEligibility,uwSubmissionV2,createProgramSummaryTask}};\nexport type CreateLeadSyncResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['createLeadSync']>>>\nexport type SelectProgramResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['selectProgram']>>>\nexport type CheckApplicationReadinessResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['checkApplicationReadiness']>>>\nexport type CreateSpinwheelNetworkUserResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['createSpinwheelNetworkUser']>>>\nexport type UpdateApplicationBankDetailsResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['updateApplicationBankDetails']>>>\nexport type SendEmailResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['sendEmail']>>>\nexport type LeadTransferResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['leadTransfer']>>>\nexport type ReadLeadResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['readLead']>>>\nexport type PatchLeadResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['patchLead']>>>\nexport type GetApplicationReadinessResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['getApplicationReadiness']>>>\nexport type GenerateDraResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['generateDra']>>>\nexport type RegisterApplicantV2Result = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['registerApplicantV2']>>>\nexport type GenerateProgramV1Result = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['generateProgramV1']>>>\nexport type CheckEligibilityResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['checkEligibility']>>>\nexport type UwSubmissionV2Result = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['uwSubmissionV2']>>>\nexport type CreateProgramSummaryTaskResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['createProgramSummaryTask']>>>\n","import type {\n\tLeadApplication,\n\tLeadApplicationDraftType,\n\tProgramSelectionRequestDraftType,\n} from \"./generated/model\";\n\n/**\n * FDR's API speaks two vocabularies for the same value. You *send* a lowercase\n * schedule code (`bi-weekly`) to `selectProgram`; the lead *reports* a\n * capitalised label (`Bi-Weekly`) back on `application.draft_type`. Nothing in\n * the spec connects them, and the mismatch is silent — comparing what you sent\n * against what came back always looks like a failure.\n *\n * The labels below were confirmed against live STG by selecting each draft type\n * in turn. Through 2026.16.0 the spec documented `Monthly [Regular]` and\n * `Twice Monthly [Split]` for two of them and the API returned neither; 16.1\n * corrected the response enum, so the generated types now agree with the wire.\n * The two *vocabularies* remain — a corrected enum is not a unified one.\n *\n * Scope is narrow: `LeadApplication.draft_type` is the only label-valued site\n * in the whole spec. `PaymentSchedule` and `ProgramSelectionRequest` are both\n * already lowercase, and `LeadPatchRequest` has no `draft_type` at all, so\n * `selectProgram` is the only write path.\n *\n * These maps are annotated as `Record<>` over the generated enums on purpose:\n * if FDR ever adds a fourth draft type, codegen widens the enum and these fail\n * to compile until someone fills in the new key. The mapping keeps itself\n * honest without any bespoke assertion.\n */\n\n/** Schedule code → the label the lead reports back. */\nexport const DRAFT_TYPE_LABEL: Record<\n\tProgramSelectionRequestDraftType,\n\tLeadApplicationDraftType\n> = {\n\tregular: \"Regular\",\n\tsplit: \"Split\",\n\t\"bi-weekly\": \"Bi-Weekly\",\n};\n\n/** Lead-reported label → the schedule code `selectProgram` accepts. */\nexport const DRAFT_TYPE_CODE: Record<\n\tLeadApplicationDraftType,\n\tProgramSelectionRequestDraftType\n> = {\n\tRegular: \"regular\",\n\tSplit: \"split\",\n\t\"Bi-Weekly\": \"bi-weekly\",\n};\n\n/**\n * Read a lead's current draft type as a value you can hand straight back to\n * `selectProgram` — closing the round-trip FDR's two vocabularies leave open.\n *\n * Returns `undefined` when the lead has no selection yet, and also when the\n * label isn't one we know: the server can start returning a new picklist value\n * before we've regenerated against a newer spec, and guessing would be worse\n * than admitting we don't recognise it.\n */\nexport const draftTypeOf = (\n\tapplication: LeadApplication | undefined | null,\n): ProgramSelectionRequestDraftType | undefined => {\n\tconst label = application?.draft_type;\n\treturn label ? DRAFT_TYPE_CODE[label] : undefined;\n};\n","import { type ArpcConfig, configure } from \"./config\";\nimport { getARPCAchieveResolutionPartnerConnectAPI } from \"./generated/arpc\";\n\nexport type {\n\tArpcAuth,\n\tArpcConfig,\n\tArpcEndpoint,\n\tArpcEnvironment,\n\tArpcUrls,\n\tTokenCache,\n} from \"./config\";\nexport { ARPC_ENDPOINTS, isArpcEnvironment } from \"./config\";\nexport { DRAFT_TYPE_CODE, DRAFT_TYPE_LABEL, draftTypeOf } from \"./draft-type\";\nexport type * from \"./generated/model\";\nexport type { HttpResponse } from \"./http/client\";\n\n/**\n * ARPC SDK — a typed, agnostic client for FDR's ARPC DEX API (Achieve\n * Resolution Partner Connect, Digital Enrollment Experience).\n *\n * Thin by design: it owns the two-host routing (both derived from\n * `environment`), the OAuth token lifecycle, and bearer injection, and exposes\n * the full endpoint surface as typed operations on `sdk.api`. It does not\n * orchestrate the enrollment sequence — the caller\n * assembles payloads and threads the `fdr_applicant_id` between calls. See\n * `scripts/smoke.ts` for a full end-to-end reference sequence (incl. the program\n * poll loop).\n *\n * Auth is lazy: the first `api` call exchanges credentials for a bearer JWT and\n * caches it (~900s TTL), then re-exchanges shortly before it expires. There's no\n * explicit login step. Supply `auth.cache` to persist the token across restarts\n * or share it across workers; otherwise it's held in-process.\n *\n * Operations never throw on a non-2xx: each returns `{ status, data, headers }`,\n * so a business gate (e.g. a UW/DRA readiness failure) comes back as a normal\n * response you inspect via `status`/`data`. Only transport errors throw.\n *\n * Note: config and the default token cache are process-global — construct one\n * `ArpcSDK` per process. A second instance reconfigures the first; instances are\n * not isolated (single-tenant by design).\n *\n * @example\n * ```typescript\n * const sdk = new ArpcSDK({\n * environment: \"stg\",\n * auth: {\n * username: \"borrowbetter@seller.com\",\n * password: process.env.ARPC_OAUTH_PASSWORD!,\n * },\n * });\n *\n * // The first call authenticates automatically and caches the token.\n * const elig = await sdk.api.checkEligibility({ ... });\n * const faid = elig.data.application?.applicant?.fdr_applicant_id;\n * ```\n */\nexport class ArpcSDK {\n\t/** The full typed endpoint surface — one method per gateway operation. */\n\treadonly api = getARPCAchieveResolutionPartnerConnectAPI();\n\n\tconstructor(config: ArpcConfig) {\n\t\tconfigure(config);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/auth.ts","../src/http/client.ts","../src/generated/arpc.ts","../src/draft-type.ts","../src/index.ts"],"names":["ky","request"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * SDK configuration.\n *\n * The library never reads the environment itself — a consumer constructs\n * `new ArpcSDK(config)`, which calls `configure()`. Where that config comes\n * from (env vars, a secrets manager, a config service) is the caller's business.\n */\n/**\n * Bearer-token store. The SDK authenticates lazily on the first gateway call:\n * it asks `get()` for a still-valid token and, on `null`, exchanges credentials\n * and hands the fresh token to `set()`. Owning expiry is the cache's job —\n * `get()` returns `null` once the token is stale (or near-stale). The default\n * store is in-memory and per-process; supply one to persist across restarts or\n * share across workers.\n */\nexport interface TokenCache {\n\t/** Return a valid bearer token, or `null` if absent/expired. */\n\tget(): Promise<string | null>;\n\t/** Persist a freshly exchanged token. `expiresAt` already includes the SDK's refresh skew. */\n\tset(token: string, expiresAt: Date): Promise<void>;\n}\n\n/** FDR deployment target. Selects both hosts — see `ARPC_ENDPOINTS`. */\nexport type ArpcEnvironment = \"dev\" | \"stg\" | \"prd\";\n\n/** The host pair a single environment resolves to. */\nexport interface ArpcEndpoint {\n\t/** OAuth host — token exchange only (`POST /v1/token`). */\n\treadonly oauth: string;\n\t/** API gateway host — every non-auth call. */\n\treadonly gateway: string;\n}\n\n/**\n * Per-environment hosts. The two differ by domain, not just subdomain: the\n * OAuth host is `ffngcp.com`, the gateway is `fdrgcp.com`.\n *\n * Frozen: this table backs both host resolution and environment validation, so\n * a consumer mutating it would quietly change SDK behavior.\n */\nexport const ARPC_ENDPOINTS: Readonly<Record<ArpcEnvironment, ArpcEndpoint>> =\n\tObject.freeze({\n\t\tdev: Object.freeze({\n\t\t\toauth: \"https://oauth.dev.ffngcp.com\",\n\t\t\tgateway: \"https://apis-gateway-v2.dev.fdrgcp.com\",\n\t\t}),\n\t\tstg: Object.freeze({\n\t\t\toauth: \"https://oauth.stg.ffngcp.com\",\n\t\t\tgateway: \"https://apis-gateway-v2.stg.fdrgcp.com\",\n\t\t}),\n\t\tprd: Object.freeze({\n\t\t\toauth: \"https://oauth.prd.ffngcp.com\",\n\t\t\tgateway: \"https://apis-gateway-v2.prd.fdrgcp.com\",\n\t\t}),\n\t});\n\n/**\n * Narrow a raw string to an `ArpcEnvironment`. Useful when the value arrives\n * untyped — an env var, a JSON config file, a request payload.\n */\nexport function isArpcEnvironment(value: string): value is ArpcEnvironment {\n\t// Own keys only — `in` would also match inherited members like `toString`.\n\treturn Object.keys(ARPC_ENDPOINTS).includes(value);\n}\n\nexport interface ArpcAuth {\n\t/**\n\t * OAuth client_id (HTTP Basic username). Also used as the lead's\n\t * `seller_agent_email` — the OAuth identity is a registered DRA agent.\n\t */\n\tusername: string;\n\t/** OAuth client_secret (HTTP Basic password). */\n\tpassword: string;\n\t/** Bearer-token store. Defaults to an in-memory, per-process cache. */\n\tcache?: TokenCache;\n}\n\n/**\n * Escape hatch — per-host overrides of the `environment` defaults. Omit a key\n * (or leave it `undefined`) to keep that environment's host.\n */\nexport interface ArpcUrls {\n\t/** OAuth host — token exchange only (`POST /v1/token`). */\n\toauth?: string;\n\t/** API gateway host — every non-auth call. */\n\tgateway?: string;\n}\n\nexport interface ArpcConfig {\n\t/** Selects the FDR environment. Drives both hosts. */\n\tenvironment: ArpcEnvironment;\n\tauth: ArpcAuth;\n\turls?: ArpcUrls;\n}\n\n/** Config as the internals consume it — hosts resolved to concrete strings. */\nexport interface ResolvedArpcConfig extends ArpcConfig {\n\turls: Required<ArpcUrls>;\n}\n\nlet current: ResolvedArpcConfig | null = null;\n\n/**\n * Fold the environment defaults together with any caller overrides. The guard\n * looks unreachable given the types, but `environment` routinely arrives from\n * somewhere untyped (an env var, a JSON config, a JS caller) — catch it here\n * rather than letting `undefined` reach a request URL.\n */\nfunction resolveUrls(config: ArpcConfig): Required<ArpcUrls> {\n\tif (!isArpcEnvironment(config.environment)) {\n\t\tthrow new Error(\n\t\t\t`Unknown environment: ${config.environment} (expected one of ${Object.keys(ARPC_ENDPOINTS).join(\", \")})`,\n\t\t);\n\t}\n\tconst defaults = ARPC_ENDPOINTS[config.environment];\n\treturn {\n\t\toauth: config.urls?.oauth ?? defaults.oauth,\n\t\tgateway: config.urls?.gateway ?? defaults.gateway,\n\t};\n}\n\n/** Set the active config, resolving hosts once. Called by the `ArpcSDK` constructor. */\nexport function configure(config: ArpcConfig): void {\n\tcurrent = { ...config, urls: resolveUrls(config) };\n}\n\n/** Read the active config. Throws if the SDK hasn't been constructed yet. */\nexport function getConfig(): ResolvedArpcConfig {\n\tif (!current) {\n\t\tthrow new Error(\n\t\t\t\"ArpcSDK is not configured — construct `new ArpcSDK(config)` before making calls\",\n\t\t);\n\t}\n\treturn current;\n}\n","import ky from \"ky\";\nimport { getConfig, type TokenCache } from \"./config\";\n\n// Token lifecycle lives in the orchestration layer, not the generated client:\n// the exchange targets the OAuth host (not the gateway), uses HTTP Basic, and is\n// form-encoded. Authentication is lazy — `resolveToken()` runs from the ky\n// beforeRequest hook on the first gateway call (and again once the token goes\n// stale), so callers never manage the token by hand.\nexport interface TokenResponse {\n\taccess_token: string;\n\ttoken_type?: string;\n\texpires_in?: number;\n}\n\n// Refresh this many ms before the server's stated expiry, so a token never\n// lapses mid-flight. Applied once, when we compute the stored `expiresAt`.\nconst TOKEN_SKEW_MS = 30_000;\n// FDR tokens are ~900s; fall back to that if the response omits expires_in.\nconst DEFAULT_TTL_S = 900;\n\n/** Raw credentials → bearer JWT. No storage; `resolveToken()` owns that. */\nexport async function exchangeToken(): Promise<TokenResponse> {\n\tconst { urls, auth } = getConfig();\n\tconst basic = Buffer.from(`${auth.username}:${auth.password}`).toString(\n\t\t\"base64\",\n\t);\n\n\treturn ky\n\t\t.post(`${urls.oauth}/v1/token`, {\n\t\t\theaders: { Authorization: `Basic ${basic}` },\n\t\t\tbody: new URLSearchParams({ grant_type: \"client_credentials\" }),\n\t\t})\n\t\t.json<TokenResponse>();\n}\n\n// Default store: in-memory, per-process. Used when config omits `cache`.\nlet memToken: string | null = null;\nlet memExpiresAt = 0;\nconst defaultCache: TokenCache = {\n\tasync get() {\n\t\treturn memToken && Date.now() < memExpiresAt ? memToken : null;\n\t},\n\tasync set(token, expiresAt) {\n\t\tmemToken = token;\n\t\tmemExpiresAt = expiresAt.getTime();\n\t},\n};\n\n// Single-flight guard: a cold burst of concurrent gateway calls performs one\n// exchange, not one per call.\nlet inflight: Promise<string> | null = null;\n\n/**\n * Return a valid bearer token, exchanging + caching on a miss. Called by the\n * gateway beforeRequest hook; not part of the public surface.\n */\nexport function resolveToken(): Promise<string> {\n\tconst store = getConfig().auth.cache ?? defaultCache;\n\tif (inflight) return inflight;\n\n\tinflight = (async () => {\n\t\tconst cached = await store.get();\n\t\tif (cached) return cached;\n\t\tconst res = await exchangeToken();\n\t\tconst ttl = (res.expires_in ?? DEFAULT_TTL_S) * 1000;\n\t\tawait store.set(\n\t\t\tres.access_token,\n\t\t\tnew Date(Date.now() + ttl - TOKEN_SKEW_MS),\n\t\t);\n\t\treturn res.access_token;\n\t})().finally(() => {\n\t\tinflight = null;\n\t});\n\treturn inflight;\n}\n","import ky from \"ky\";\nimport { resolveToken } from \"../auth\";\nimport { getConfig } from \"../config\";\n\n// ---------------------------------------------------------------------------\n// Orval custom mutator (ky-backed).\n//\n// Every generated operation calls `customInstance<T>(config, options)`. We\n// route all calls to the API gateway, attach the bearer token via a\n// beforeRequest hook (lazy auth — `resolveToken()` exchanges/refreshes as\n// needed), and return a small { status, data, headers } wrapper WITHOUT\n// throwing on non-2xx — the caller inspects status codes itself (202 +\n// Retry-After on program, 400 on a UW/DRA gate, etc.).\n// ---------------------------------------------------------------------------\n\n// Shape Orval passes as the first arg (axios-style request config).\nexport interface RequestConfig {\n\turl: string;\n\tmethod: string;\n\tparams?: Record<string, unknown>;\n\tdata?: unknown;\n\theaders?: Record<string, string>;\n\tsignal?: AbortSignal;\n\tresponseType?: string;\n}\n\nexport interface HttpResponse<T> {\n\tstatus: number;\n\tdata: T;\n\theaders: Headers;\n}\n\nexport const customInstance = async <T>(\n\trequest: RequestConfig,\n\toptions?: Partial<RequestConfig>,\n): Promise<HttpResponse<T>> => {\n\tconst { url, method, params, data, signal } = { ...request, ...options };\n\t// Merge headers from both sides — a per-call override (e.g. an\n\t// x-correlation-id in `options.headers`) must not drop the operation's\n\t// Content-Type. The bearer token is layered on last, below.\n\tconst headers = { ...request.headers, ...options?.headers };\n\n\tconst target = new URL(url, getConfig().urls.gateway);\n\tif (params) {\n\t\tfor (const [key, value] of Object.entries(params)) {\n\t\t\tif (value !== undefined && value !== null)\n\t\t\t\ttarget.searchParams.set(key, String(value));\n\t\t}\n\t}\n\n\tconst response = await ky(target, {\n\t\tmethod,\n\t\theaders,\n\t\thooks: {\n\t\t\t// Lazy bearer injection: resolveToken() exchanges on the first call\n\t\t\t// and refreshes once the cached token goes stale. The OAuth exchange\n\t\t\t// itself runs on a bare ky.post (no hook), so there's no recursion.\n\t\t\tbeforeRequest: [\n\t\t\t\tasync ({ request }) => {\n\t\t\t\t\tconst token = await resolveToken();\n\t\t\t\t\trequest.headers.set(\"Authorization\", `Bearer ${token}`);\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t...(data !== undefined ? { json: data } : {}),\n\t\tsignal,\n\t\tthrowHttpErrors: false,\n\t\tretry: 0,\n\t\t// Some gateway calls (program generation in particular) can take well over ky's\n\t\t// 10s default to respond. Raise the per-request ceiling; the program poll loop\n\t\t// handles 202/Retry-After on top of this.\n\t\ttimeout: 60_000,\n\t});\n\n\tconst text = await response.text();\n\tlet body: T;\n\ttry {\n\t\tbody = (text ? JSON.parse(text) : undefined) as T;\n\t} catch {\n\t\t// Non-JSON body (e.g. a gateway HTML error page on a transient 5xx). Don't throw —\n\t\t// hand back the raw text so callers can inspect status/body and retry as needed.\n\t\tbody = text as unknown as T;\n\t}\n\treturn { status: response.status, data: body, headers: response.headers };\n};\n","/**\n * Generated by orval v7.21.0 🍺\n * Do not edit manually.\n * ARPC — Achieve Resolution Partner Connect API\n * FDR Wholesale API — A Hybrid Integration Model designed to maximise partner velocity without compromising enterprise data standards. DEX (Digital Enrollment Experience) is the partner-facing integration layer that powers the full applicant lifecycle. The `fdr_applicant_id` acts as the applicant's passport across all systems, persisted from first eligibility check through enrollment. All endpoints require a valid Bearer JWT with the `arpc.all` role.\n\n**Published:** 2026-08-18\n * OpenAPI spec version: 2026.16.1\n */\nimport type {\n ARPCErrorResponse,\n ApplicationSendEmailResponse,\n BankUpdateRequest,\n CreateLeadRequest,\n CreateLeadResponse,\n DraRequest,\n DraResponse,\n EligibilityRequest,\n EligibilityResponse,\n LeadPatchRequest,\n LeadResponse,\n LeadTransferRequest,\n LeadTransferResponse,\n ProgramRequest,\n ProgramSelectionRequest,\n ProgramSummaryTaskRequest,\n ProgramSummaryTaskResponse,\n ReadinessResponse,\n RegisterApplicantV2Request,\n RegisterApplicantV2Response,\n SpinwheelNetworkUserRequest,\n SpinwheelNetworkUserResponse,\n StatelessReadinessRequest,\n UwSubmissionV2Response\n} from './model';\n\nimport { customInstance } from '../http/client';\ntype SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];\n\n\n export const getARPCAchieveResolutionPartnerConnectAPI = () => {\n/**\n * Synchronous Orchestration: Handles both lead creation and income/expense data in one step, eliminating the async polling black box. Data authority shifts here — Achieve becomes the Source of Truth once the lead is formally promoted. Returns the full lead creation result including program options.\n * @summary Sync wholesale lead creation\n */\nconst createLeadSync = (\n createLeadRequest: CreateLeadRequest,\n options?: SecondParameter<typeof customInstance<CreateLeadResponse>>,) => {\n return customInstance<CreateLeadResponse>(\n {url: `/v3/application`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: createLeadRequest\n },\n options);\n }\n \n/**\n * Gateway-level endpoint: selects a payment schedule for an existing lead and persists the program offer. After calling generateProgram, choose a schedule from payment_schedule_options and submit its draft_type and estimated_monthly_payment here. The gateway injects request attributes and forwards internally to POST /v3/application/program. Requires a valid Authorization header.\n * @summary Select program schedule for an existing lead\n */\nconst selectProgram = (\n programSelectionRequest: ProgramSelectionRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/program-selection`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: programSelectionRequest\n },\n options);\n }\n \n/**\n * Stateless Readiness Check: Pre-flight validation before initiating program calculations. Catches duplicate SSNs or emails early to prevent downstream failures. Requires a valid Authorization header.\n * @summary Check application readiness\n */\nconst checkApplicationReadiness = (\n statelessReadinessRequest: StatelessReadinessRequest,\n options?: SecondParameter<typeof customInstance<ReadinessResponse>>,) => {\n return customInstance<ReadinessResponse>(\n {url: `/v1/application/readiness`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: statelessReadinessRequest\n },\n options);\n }\n \n/**\n * Recovery endpoint — only required when the async Spinwheel user creation triggered by `POST /v1/applicant/register` fails due to a user error (e.g. invalid SSN or DOB). Not needed in the happy path. Authenticates the seller, resolves the law firm / program, creates an applicant ID when needed, and connects the applicant to the Spinwheel network. Requires a valid Authorization header.\n * @summary Create / connect Spinwheel network user\n */\nconst createSpinwheelNetworkUser = (\n spinwheelNetworkUserRequest: SpinwheelNetworkUserRequest,\n options?: SecondParameter<typeof customInstance<SpinwheelNetworkUserResponse>>,) => {\n return customInstance<SpinwheelNetworkUserResponse>(\n {url: `/v1/application/spinwheel-network-user`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: spinwheelNetworkUserRequest\n },\n options);\n }\n \n/**\n * Authenticates the seller, validates banking disclosure requirements, optionally validates the submitted account and routing numbers, patches the program, and returns the refreshed lead payload. Requires a valid Authorization header.\n * @summary Update applicant bank details\n */\nconst updateApplicationBankDetails = (\n applicantId: string,\n bankUpdateRequest: BankUpdateRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/bank-update/${applicantId}`, method: 'PATCH',\n headers: {'Content-Type': 'application/json', },\n data: bankUpdateRequest\n },\n options);\n }\n \n/**\n * Banking Disclosure: Manually triggers the banking disclosure email. **This endpoint is optional** — it is only needed when the disclosure was not already sent automatically by `POST /v2/application/uw-submission/{fdrApplicantId}` (which auto-sends on full UW approval). Use this endpoint for conditional approvals or when the v1 UW submission path is in use. A critical legal prerequisite that must be completed before enrollment can proceed. Requires a valid Authorization header.\n * @summary Send banking disclosure email (optional — only if not auto-sent by v2 UW submission)\n */\nconst sendEmail = (\n fdrApplicantId: string,\n options?: SecondParameter<typeof customInstance<ApplicationSendEmailResponse>>,) => {\n return customInstance<ApplicationSendEmailResponse>(\n {url: `/v1/application/send-email/${fdrApplicantId}`, method: 'POST'\n },\n options);\n }\n \n/**\n * Submits a lead evaluation request. fdr_applicant_id is required in the request body. Requires a valid Authorization header with the arpc.all role.\n * @summary Transfer a lead to the debt-resolution program\n */\nconst leadTransfer = (\n leadTransferRequest: LeadTransferRequest,\n options?: SecondParameter<typeof customInstance<LeadTransferResponse>>,) => {\n return customInstance<LeadTransferResponse>(\n {url: `/v1/application/lead-transfer`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: leadTransferRequest\n },\n options);\n }\n \n/**\n * Fetches the current state of an application / lead record by FDR applicant ID. Requires a valid Authorization header.\n * @summary Read application / lead details\n */\nconst readLead = (\n fdrApplicantId: string,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/${fdrApplicantId}`, method: 'GET'\n },\n options);\n }\n \n/**\n * Applies a partial update to an existing wholesale lead record. Requires a valid Authorization header and an x-correlation-id header for request tracing. For split drafts, update second_draft_date_split after UW submission and before generating the DRA; the bi-weekly second_draft_date_bi_weekly field is populated automatically during UW approval.\n * @summary Partial update of application / lead record\n */\nconst patchLead = (\n fdrApplicantId: string,\n leadPatchRequest: LeadPatchRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/${fdrApplicantId}`, method: 'PATCH',\n headers: {'Content-Type': 'application/json', },\n data: leadPatchRequest\n },\n options);\n }\n \n/**\n * DRA Readiness Check: Final pre-flight confirming the lead is approved and all prerequisites are met before initiating the embedded signing session. Requires a valid Authorization header.\n * @summary Get application readiness status\n */\nconst getApplicationReadiness = (\n applicantId: string,\n options?: SecondParameter<typeof customInstance<ReadinessResponse>>,) => {\n return customInstance<ReadinessResponse>(\n {url: `/v1/application/${applicantId}/readiness`, method: 'GET'\n },\n options);\n }\n \n/**\n * Embedded DRA Signing: Returns an Embedded Signing URL so the applicant signs the Debt Resolution Agreement via DocuSign directly within the Symple UI, preventing session breakage. Successful legal execution triggers automatic enrollment. Requires a valid Authorization header.\n * @summary Generate Debt Resolution Agreement (DRA)\n */\nconst generateDra = (\n applicantId: string,\n draRequest: DraRequest,\n options?: SecondParameter<typeof customInstance<DraResponse>>,) => {\n return customInstance<DraResponse>(\n {url: `/v2/application/${applicantId}/dra`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: draRequest\n },\n options);\n }\n \n/**\n * **Recommended endpoint.** `POST /v1/applicant/register` is deprecated and will be retired by end of July 2026 (deadline can be extended on request if your team needs more time). Identity Anchoring: Persists applicant PII to Achieve's managed partner CRM and generates the `fdr_applicant_id` — the applicant's passport across all systems. Routes to the correct target system based on seller identity, and triggers the async credit fetch. Requires a valid Authorization header.\n * @summary Seller-aware applicant registration (v2 — unified ARPCErrorResponse envelope) — recommended\n */\nconst registerApplicantV2 = (\n registerApplicantV2Request: RegisterApplicantV2Request,\n options?: SecondParameter<typeof customInstance<RegisterApplicantV2Response>>,) => {\n return customInstance<RegisterApplicantV2Response>(\n {url: `/v2/applicant/register`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: registerApplicantV2Request\n },\n options);\n }\n \n/**\n * Async Polling Loop: Call this single endpoint for both initial generation and refresh. Returns 202 Accepted with a Retry-After header while credit is still pending. Once ready, the Managed Package orchestrates the calculation and persists the program result. Requires a valid Authorization header.\n * @summary Generate application program (v1)\n */\nconst generateProgramV1 = (\n programRequest: ProgramRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/program`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: programRequest\n },\n options);\n }\n \n/**\n * Eligibility Scout: Two operational modes — (1) no PII required: state-based quote using provided debt accounts; (2) credit pull: full applicant PII for a live soft credit report. Returns estimated program options to anchor the conversation before any registration occurs. Requires a valid Authorization header.\n * @summary Check application eligibility\n */\nconst checkEligibility = (\n eligibilityRequest: EligibilityRequest,\n options?: SecondParameter<typeof customInstance<EligibilityResponse>>,) => {\n return customInstance<EligibilityResponse>(\n {url: `/v2/application/eligibility`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: eligibilityRequest\n },\n options);\n }\n \n/**\n * **Recommended endpoint — supersedes v1.** Submits a wholesale application to the underwriting system. On full UW approval (`sub_status = 'UW Approved'`) the banking disclosure email is sent automatically — no separate `send-email` call is needed in this path. Conditional approvals suppress the auto-send; in that case the manual `POST /v1/application/send-email/{fdrApplicantId}` endpoint can be used. Uses the SF Object API directly (no suip-proxy hop). Requires a valid Authorization header.\n * @summary Submit application to underwriting (v2 — auto banking disclosure) — recommended\n */\nconst uwSubmissionV2 = (\n fdrApplicantId: string,\n options?: SecondParameter<typeof customInstance<UwSubmissionV2Response>>,) => {\n return customInstance<UwSubmissionV2Response>(\n {url: `/v2/application/uw-submission/${fdrApplicantId}`, method: 'POST'\n },\n options);\n }\n \n/**\n * Creates a SUIP Salesforce 'Program Summary Recording' task for the applicant identified by the {id} path variable. For DEX (or missing header), the parent SF opportunity is additionally PATCHed with the seller-config partner default PSC. For DC, the task is created and the parent SF opportunity is PATCHed only when ws_psc_code is provided in the request payload.\n * @summary Create program-summary recording task\n */\nconst createProgramSummaryTask = (\n id: string,\n programSummaryTaskRequest: ProgramSummaryTaskRequest,\n options?: SecondParameter<typeof customInstance<ProgramSummaryTaskResponse>>,) => {\n return customInstance<ProgramSummaryTaskResponse>(\n {url: `/v2/application/program-summary-task/${id}`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: programSummaryTaskRequest\n },\n options);\n }\n \nreturn {createLeadSync,selectProgram,checkApplicationReadiness,createSpinwheelNetworkUser,updateApplicationBankDetails,sendEmail,leadTransfer,readLead,patchLead,getApplicationReadiness,generateDra,registerApplicantV2,generateProgramV1,checkEligibility,uwSubmissionV2,createProgramSummaryTask}};\nexport type CreateLeadSyncResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['createLeadSync']>>>\nexport type SelectProgramResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['selectProgram']>>>\nexport type CheckApplicationReadinessResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['checkApplicationReadiness']>>>\nexport type CreateSpinwheelNetworkUserResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['createSpinwheelNetworkUser']>>>\nexport type UpdateApplicationBankDetailsResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['updateApplicationBankDetails']>>>\nexport type SendEmailResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['sendEmail']>>>\nexport type LeadTransferResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['leadTransfer']>>>\nexport type ReadLeadResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['readLead']>>>\nexport type PatchLeadResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['patchLead']>>>\nexport type GetApplicationReadinessResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['getApplicationReadiness']>>>\nexport type GenerateDraResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['generateDra']>>>\nexport type RegisterApplicantV2Result = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['registerApplicantV2']>>>\nexport type GenerateProgramV1Result = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['generateProgramV1']>>>\nexport type CheckEligibilityResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['checkEligibility']>>>\nexport type UwSubmissionV2Result = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['uwSubmissionV2']>>>\nexport type CreateProgramSummaryTaskResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['createProgramSummaryTask']>>>\n","import type {\n\tLeadApplication,\n\tLeadApplicationDraftType,\n\tProgramSelectionRequestDraftType,\n} from \"./generated/model\";\n\n/**\n * FDR's API speaks two vocabularies for the same value. You *send* a lowercase\n * schedule code (`bi-weekly`) to `selectProgram`; the lead *reports* a\n * capitalised label (`Bi-Weekly`) back on `application.draft_type`. Nothing in\n * the spec connects them, and the mismatch is silent — comparing what you sent\n * against what came back always looks like a failure.\n *\n * The labels below were confirmed against live STG by selecting each draft type\n * in turn. Through 2026.16.0 the spec documented `Monthly [Regular]` and\n * `Twice Monthly [Split]` for two of them and the API returned neither; 16.1\n * corrected the response enum, so the generated types now agree with the wire.\n * The two *vocabularies* remain — a corrected enum is not a unified one.\n *\n * Scope is narrow: `LeadApplication.draft_type` is the only label-valued site\n * in the whole spec. `PaymentSchedule` and `ProgramSelectionRequest` are both\n * already lowercase, and `LeadPatchRequest` has no `draft_type` at all, so\n * `selectProgram` is the only write path.\n *\n * These maps are annotated as `Record<>` over the generated enums on purpose:\n * if FDR ever adds a fourth draft type, codegen widens the enum and these fail\n * to compile until someone fills in the new key. The mapping keeps itself\n * honest without any bespoke assertion.\n */\n\n/** Schedule code → the label the lead reports back. */\nexport const DRAFT_TYPE_LABEL: Record<\n\tProgramSelectionRequestDraftType,\n\tLeadApplicationDraftType\n> = {\n\tregular: \"Regular\",\n\tsplit: \"Split\",\n\t\"bi-weekly\": \"Bi-Weekly\",\n};\n\n/** Lead-reported label → the schedule code `selectProgram` accepts. */\nexport const DRAFT_TYPE_CODE: Record<\n\tLeadApplicationDraftType,\n\tProgramSelectionRequestDraftType\n> = {\n\tRegular: \"regular\",\n\tSplit: \"split\",\n\t\"Bi-Weekly\": \"bi-weekly\",\n};\n\n/**\n * Read a lead's current draft type as a value you can hand straight back to\n * `selectProgram` — closing the round-trip FDR's two vocabularies leave open.\n *\n * Returns `undefined` when the lead has no selection yet, and also when the\n * label isn't one we know: the server can start returning a new picklist value\n * before we've regenerated against a newer spec, and guessing would be worse\n * than admitting we don't recognise it.\n */\nexport const draftTypeOf = (\n\tapplication: LeadApplication | undefined | null,\n): ProgramSelectionRequestDraftType | undefined => {\n\tconst label = application?.draft_type;\n\treturn label ? DRAFT_TYPE_CODE[label] : undefined;\n};\n","import { type ArpcConfig, configure } from \"./config\";\nimport { getARPCAchieveResolutionPartnerConnectAPI } from \"./generated/arpc\";\n\nexport type {\n\tArpcAuth,\n\tArpcConfig,\n\tArpcEndpoint,\n\tArpcEnvironment,\n\tArpcUrls,\n\tTokenCache,\n} from \"./config\";\nexport { ARPC_ENDPOINTS, isArpcEnvironment } from \"./config\";\nexport { DRAFT_TYPE_CODE, DRAFT_TYPE_LABEL, draftTypeOf } from \"./draft-type\";\nexport type * from \"./generated/model\";\nexport type { HttpResponse } from \"./http/client\";\n\n/**\n * ARPC SDK — a typed, agnostic client for FDR's ARPC DEX API (Achieve\n * Resolution Partner Connect, Digital Enrollment Experience).\n *\n * Thin by design: it owns the two-host routing (both derived from\n * `environment`), the OAuth token lifecycle, and bearer injection, and exposes\n * the full endpoint surface as typed operations on `sdk.api`. It does not\n * orchestrate the enrollment sequence — the caller\n * assembles payloads and threads the `fdr_applicant_id` between calls. See\n * `scripts/smoke.ts` for a full end-to-end reference sequence (incl. the program\n * poll loop).\n *\n * Auth is lazy: the first `api` call exchanges credentials for a bearer JWT and\n * caches it (~900s TTL), then re-exchanges shortly before it expires. There's no\n * explicit login step. Supply `auth.cache` to persist the token across restarts\n * or share it across workers; otherwise it's held in-process.\n *\n * Operations never throw on a non-2xx: each returns `{ status, data, headers }`,\n * so a business gate (e.g. a UW/DRA readiness failure) comes back as a normal\n * response you inspect via `status`/`data`. Only transport errors throw.\n *\n * Note: config and the default token cache are process-global — construct one\n * `ArpcSDK` per process. A second instance reconfigures the first; instances are\n * not isolated (single-tenant by design).\n *\n * @example\n * ```typescript\n * const sdk = new ArpcSDK({\n * environment: \"stg\",\n * auth: {\n * username: \"borrowbetter@seller.com\",\n * password: process.env.ARPC_OAUTH_PASSWORD!,\n * },\n * });\n *\n * // The first call authenticates automatically and caches the token.\n * const elig = await sdk.api.checkEligibility({ ... });\n * const faid = elig.data.application?.applicant?.fdr_applicant_id;\n * ```\n */\nexport class ArpcSDK {\n\t/** The full typed endpoint surface — one method per gateway operation. */\n\treadonly api = getARPCAchieveResolutionPartnerConnectAPI();\n\n\tconstructor(config: ArpcConfig) {\n\t\tconfigure(config);\n\t}\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -104,8 +104,9 @@ var customInstance = async (request, options) => {
|
|
|
104
104
|
// and refreshes once the cached token goes stale. The OAuth exchange
|
|
105
105
|
// itself runs on a bare ky.post (no hook), so there's no recursion.
|
|
106
106
|
beforeRequest: [
|
|
107
|
-
async (
|
|
108
|
-
|
|
107
|
+
async ({ request: request2 }) => {
|
|
108
|
+
const token = await resolveToken();
|
|
109
|
+
request2.headers.set("Authorization", `Bearer ${token}`);
|
|
109
110
|
}
|
|
110
111
|
]
|
|
111
112
|
},
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/auth.ts","../src/http/client.ts","../src/generated/arpc.ts","../src/draft-type.ts","../src/index.ts"],"names":["ky"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * SDK configuration.\n *\n * The library never reads the environment itself — a consumer constructs\n * `new ArpcSDK(config)`, which calls `configure()`. Where that config comes\n * from (env vars, a secrets manager, a config service) is the caller's business.\n */\n/**\n * Bearer-token store. The SDK authenticates lazily on the first gateway call:\n * it asks `get()` for a still-valid token and, on `null`, exchanges credentials\n * and hands the fresh token to `set()`. Owning expiry is the cache's job —\n * `get()` returns `null` once the token is stale (or near-stale). The default\n * store is in-memory and per-process; supply one to persist across restarts or\n * share across workers.\n */\nexport interface TokenCache {\n\t/** Return a valid bearer token, or `null` if absent/expired. */\n\tget(): Promise<string | null>;\n\t/** Persist a freshly exchanged token. `expiresAt` already includes the SDK's refresh skew. */\n\tset(token: string, expiresAt: Date): Promise<void>;\n}\n\n/** FDR deployment target. Selects both hosts — see `ARPC_ENDPOINTS`. */\nexport type ArpcEnvironment = \"dev\" | \"stg\" | \"prd\";\n\n/** The host pair a single environment resolves to. */\nexport interface ArpcEndpoint {\n\t/** OAuth host — token exchange only (`POST /v1/token`). */\n\treadonly oauth: string;\n\t/** API gateway host — every non-auth call. */\n\treadonly gateway: string;\n}\n\n/**\n * Per-environment hosts. The two differ by domain, not just subdomain: the\n * OAuth host is `ffngcp.com`, the gateway is `fdrgcp.com`.\n *\n * Frozen: this table backs both host resolution and environment validation, so\n * a consumer mutating it would quietly change SDK behavior.\n */\nexport const ARPC_ENDPOINTS: Readonly<Record<ArpcEnvironment, ArpcEndpoint>> =\n\tObject.freeze({\n\t\tdev: Object.freeze({\n\t\t\toauth: \"https://oauth.dev.ffngcp.com\",\n\t\t\tgateway: \"https://apis-gateway-v2.dev.fdrgcp.com\",\n\t\t}),\n\t\tstg: Object.freeze({\n\t\t\toauth: \"https://oauth.stg.ffngcp.com\",\n\t\t\tgateway: \"https://apis-gateway-v2.stg.fdrgcp.com\",\n\t\t}),\n\t\tprd: Object.freeze({\n\t\t\toauth: \"https://oauth.prd.ffngcp.com\",\n\t\t\tgateway: \"https://apis-gateway-v2.prd.fdrgcp.com\",\n\t\t}),\n\t});\n\n/**\n * Narrow a raw string to an `ArpcEnvironment`. Useful when the value arrives\n * untyped — an env var, a JSON config file, a request payload.\n */\nexport function isArpcEnvironment(value: string): value is ArpcEnvironment {\n\t// Own keys only — `in` would also match inherited members like `toString`.\n\treturn Object.keys(ARPC_ENDPOINTS).includes(value);\n}\n\nexport interface ArpcAuth {\n\t/**\n\t * OAuth client_id (HTTP Basic username). Also used as the lead's\n\t * `seller_agent_email` — the OAuth identity is a registered DRA agent.\n\t */\n\tusername: string;\n\t/** OAuth client_secret (HTTP Basic password). */\n\tpassword: string;\n\t/** Bearer-token store. Defaults to an in-memory, per-process cache. */\n\tcache?: TokenCache;\n}\n\n/**\n * Escape hatch — per-host overrides of the `environment` defaults. Omit a key\n * (or leave it `undefined`) to keep that environment's host.\n */\nexport interface ArpcUrls {\n\t/** OAuth host — token exchange only (`POST /v1/token`). */\n\toauth?: string;\n\t/** API gateway host — every non-auth call. */\n\tgateway?: string;\n}\n\nexport interface ArpcConfig {\n\t/** Selects the FDR environment. Drives both hosts. */\n\tenvironment: ArpcEnvironment;\n\tauth: ArpcAuth;\n\turls?: ArpcUrls;\n}\n\n/** Config as the internals consume it — hosts resolved to concrete strings. */\nexport interface ResolvedArpcConfig extends ArpcConfig {\n\turls: Required<ArpcUrls>;\n}\n\nlet current: ResolvedArpcConfig | null = null;\n\n/**\n * Fold the environment defaults together with any caller overrides. The guard\n * looks unreachable given the types, but `environment` routinely arrives from\n * somewhere untyped (an env var, a JSON config, a JS caller) — catch it here\n * rather than letting `undefined` reach a request URL.\n */\nfunction resolveUrls(config: ArpcConfig): Required<ArpcUrls> {\n\tif (!isArpcEnvironment(config.environment)) {\n\t\tthrow new Error(\n\t\t\t`Unknown environment: ${config.environment} (expected one of ${Object.keys(ARPC_ENDPOINTS).join(\", \")})`,\n\t\t);\n\t}\n\tconst defaults = ARPC_ENDPOINTS[config.environment];\n\treturn {\n\t\toauth: config.urls?.oauth ?? defaults.oauth,\n\t\tgateway: config.urls?.gateway ?? defaults.gateway,\n\t};\n}\n\n/** Set the active config, resolving hosts once. Called by the `ArpcSDK` constructor. */\nexport function configure(config: ArpcConfig): void {\n\tcurrent = { ...config, urls: resolveUrls(config) };\n}\n\n/** Read the active config. Throws if the SDK hasn't been constructed yet. */\nexport function getConfig(): ResolvedArpcConfig {\n\tif (!current) {\n\t\tthrow new Error(\n\t\t\t\"ArpcSDK is not configured — construct `new ArpcSDK(config)` before making calls\",\n\t\t);\n\t}\n\treturn current;\n}\n","import ky from \"ky\";\nimport { getConfig, type TokenCache } from \"./config\";\n\n// Token lifecycle lives in the orchestration layer, not the generated client:\n// the exchange targets the OAuth host (not the gateway), uses HTTP Basic, and is\n// form-encoded. Authentication is lazy — `resolveToken()` runs from the ky\n// beforeRequest hook on the first gateway call (and again once the token goes\n// stale), so callers never manage the token by hand.\nexport interface TokenResponse {\n\taccess_token: string;\n\ttoken_type?: string;\n\texpires_in?: number;\n}\n\n// Refresh this many ms before the server's stated expiry, so a token never\n// lapses mid-flight. Applied once, when we compute the stored `expiresAt`.\nconst TOKEN_SKEW_MS = 30_000;\n// FDR tokens are ~900s; fall back to that if the response omits expires_in.\nconst DEFAULT_TTL_S = 900;\n\n/** Raw credentials → bearer JWT. No storage; `resolveToken()` owns that. */\nexport async function exchangeToken(): Promise<TokenResponse> {\n\tconst { urls, auth } = getConfig();\n\tconst basic = Buffer.from(`${auth.username}:${auth.password}`).toString(\n\t\t\"base64\",\n\t);\n\n\treturn ky\n\t\t.post(`${urls.oauth}/v1/token`, {\n\t\t\theaders: { Authorization: `Basic ${basic}` },\n\t\t\tbody: new URLSearchParams({ grant_type: \"client_credentials\" }),\n\t\t})\n\t\t.json<TokenResponse>();\n}\n\n// Default store: in-memory, per-process. Used when config omits `cache`.\nlet memToken: string | null = null;\nlet memExpiresAt = 0;\nconst defaultCache: TokenCache = {\n\tasync get() {\n\t\treturn memToken && Date.now() < memExpiresAt ? memToken : null;\n\t},\n\tasync set(token, expiresAt) {\n\t\tmemToken = token;\n\t\tmemExpiresAt = expiresAt.getTime();\n\t},\n};\n\n// Single-flight guard: a cold burst of concurrent gateway calls performs one\n// exchange, not one per call.\nlet inflight: Promise<string> | null = null;\n\n/**\n * Return a valid bearer token, exchanging + caching on a miss. Called by the\n * gateway beforeRequest hook; not part of the public surface.\n */\nexport function resolveToken(): Promise<string> {\n\tconst store = getConfig().auth.cache ?? defaultCache;\n\tif (inflight) return inflight;\n\n\tinflight = (async () => {\n\t\tconst cached = await store.get();\n\t\tif (cached) return cached;\n\t\tconst res = await exchangeToken();\n\t\tconst ttl = (res.expires_in ?? DEFAULT_TTL_S) * 1000;\n\t\tawait store.set(\n\t\t\tres.access_token,\n\t\t\tnew Date(Date.now() + ttl - TOKEN_SKEW_MS),\n\t\t);\n\t\treturn res.access_token;\n\t})().finally(() => {\n\t\tinflight = null;\n\t});\n\treturn inflight;\n}\n","import ky from \"ky\";\nimport { resolveToken } from \"../auth\";\nimport { getConfig } from \"../config\";\n\n// ---------------------------------------------------------------------------\n// Orval custom mutator (ky-backed).\n//\n// Every generated operation calls `customInstance<T>(config, options)`. We\n// route all calls to the API gateway, attach the bearer token via a\n// beforeRequest hook (lazy auth — `resolveToken()` exchanges/refreshes as\n// needed), and return a small { status, data, headers } wrapper WITHOUT\n// throwing on non-2xx — the caller inspects status codes itself (202 +\n// Retry-After on program, 400 on a UW/DRA gate, etc.).\n// ---------------------------------------------------------------------------\n\n// Shape Orval passes as the first arg (axios-style request config).\nexport interface RequestConfig {\n\turl: string;\n\tmethod: string;\n\tparams?: Record<string, unknown>;\n\tdata?: unknown;\n\theaders?: Record<string, string>;\n\tsignal?: AbortSignal;\n\tresponseType?: string;\n}\n\nexport interface HttpResponse<T> {\n\tstatus: number;\n\tdata: T;\n\theaders: Headers;\n}\n\nexport const customInstance = async <T>(\n\trequest: RequestConfig,\n\toptions?: Partial<RequestConfig>,\n): Promise<HttpResponse<T>> => {\n\tconst { url, method, params, data, signal } = { ...request, ...options };\n\t// Merge headers from both sides — a per-call override (e.g. an\n\t// x-correlation-id in `options.headers`) must not drop the operation's\n\t// Content-Type. The bearer token is layered on last, below.\n\tconst headers = { ...request.headers, ...options?.headers };\n\n\tconst target = new URL(url, getConfig().urls.gateway);\n\tif (params) {\n\t\tfor (const [key, value] of Object.entries(params)) {\n\t\t\tif (value !== undefined && value !== null)\n\t\t\t\ttarget.searchParams.set(key, String(value));\n\t\t}\n\t}\n\n\tconst response = await ky(target, {\n\t\tmethod,\n\t\theaders,\n\t\thooks: {\n\t\t\t// Lazy bearer injection: resolveToken() exchanges on the first call\n\t\t\t// and refreshes once the cached token goes stale. The OAuth exchange\n\t\t\t// itself runs on a bare ky.post (no hook), so there's no recursion.\n\t\t\tbeforeRequest: [\n\t\t\t\tasync (req) => {\n\t\t\t\t\treq.headers.set(\"Authorization\", `Bearer ${await resolveToken()}`);\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t...(data !== undefined ? { json: data } : {}),\n\t\tsignal,\n\t\tthrowHttpErrors: false,\n\t\tretry: 0,\n\t\t// Some gateway calls (program generation in particular) can take well over ky's\n\t\t// 10s default to respond. Raise the per-request ceiling; the program poll loop\n\t\t// handles 202/Retry-After on top of this.\n\t\ttimeout: 60_000,\n\t});\n\n\tconst text = await response.text();\n\tlet body: T;\n\ttry {\n\t\tbody = (text ? JSON.parse(text) : undefined) as T;\n\t} catch {\n\t\t// Non-JSON body (e.g. a gateway HTML error page on a transient 5xx). Don't throw —\n\t\t// hand back the raw text so callers can inspect status/body and retry as needed.\n\t\tbody = text as unknown as T;\n\t}\n\treturn { status: response.status, data: body, headers: response.headers };\n};\n","/**\n * Generated by orval v7.21.0 🍺\n * Do not edit manually.\n * ARPC — Achieve Resolution Partner Connect API\n * FDR Wholesale API — A Hybrid Integration Model designed to maximise partner velocity without compromising enterprise data standards. DEX (Digital Enrollment Experience) is the partner-facing integration layer that powers the full applicant lifecycle. The `fdr_applicant_id` acts as the applicant's passport across all systems, persisted from first eligibility check through enrollment. All endpoints require a valid Bearer JWT with the `arpc.all` role.\n\n**Published:** 2026-08-18\n * OpenAPI spec version: 2026.16.1\n */\nimport type {\n ARPCErrorResponse,\n ApplicationSendEmailResponse,\n BankUpdateRequest,\n CreateLeadRequest,\n CreateLeadResponse,\n DraRequest,\n DraResponse,\n EligibilityRequest,\n EligibilityResponse,\n LeadPatchRequest,\n LeadResponse,\n LeadTransferRequest,\n LeadTransferResponse,\n ProgramRequest,\n ProgramSelectionRequest,\n ProgramSummaryTaskRequest,\n ProgramSummaryTaskResponse,\n ReadinessResponse,\n RegisterApplicantV2Request,\n RegisterApplicantV2Response,\n SpinwheelNetworkUserRequest,\n SpinwheelNetworkUserResponse,\n StatelessReadinessRequest,\n UwSubmissionV2Response\n} from './model';\n\nimport { customInstance } from '../http/client';\ntype SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];\n\n\n export const getARPCAchieveResolutionPartnerConnectAPI = () => {\n/**\n * Synchronous Orchestration: Handles both lead creation and income/expense data in one step, eliminating the async polling black box. Data authority shifts here — Achieve becomes the Source of Truth once the lead is formally promoted. Returns the full lead creation result including program options.\n * @summary Sync wholesale lead creation\n */\nconst createLeadSync = (\n createLeadRequest: CreateLeadRequest,\n options?: SecondParameter<typeof customInstance<CreateLeadResponse>>,) => {\n return customInstance<CreateLeadResponse>(\n {url: `/v3/application`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: createLeadRequest\n },\n options);\n }\n \n/**\n * Gateway-level endpoint: selects a payment schedule for an existing lead and persists the program offer. After calling generateProgram, choose a schedule from payment_schedule_options and submit its draft_type and estimated_monthly_payment here. The gateway injects request attributes and forwards internally to POST /v3/application/program. Requires a valid Authorization header.\n * @summary Select program schedule for an existing lead\n */\nconst selectProgram = (\n programSelectionRequest: ProgramSelectionRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/program-selection`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: programSelectionRequest\n },\n options);\n }\n \n/**\n * Stateless Readiness Check: Pre-flight validation before initiating program calculations. Catches duplicate SSNs or emails early to prevent downstream failures. Requires a valid Authorization header.\n * @summary Check application readiness\n */\nconst checkApplicationReadiness = (\n statelessReadinessRequest: StatelessReadinessRequest,\n options?: SecondParameter<typeof customInstance<ReadinessResponse>>,) => {\n return customInstance<ReadinessResponse>(\n {url: `/v1/application/readiness`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: statelessReadinessRequest\n },\n options);\n }\n \n/**\n * Recovery endpoint — only required when the async Spinwheel user creation triggered by `POST /v1/applicant/register` fails due to a user error (e.g. invalid SSN or DOB). Not needed in the happy path. Authenticates the seller, resolves the law firm / program, creates an applicant ID when needed, and connects the applicant to the Spinwheel network. Requires a valid Authorization header.\n * @summary Create / connect Spinwheel network user\n */\nconst createSpinwheelNetworkUser = (\n spinwheelNetworkUserRequest: SpinwheelNetworkUserRequest,\n options?: SecondParameter<typeof customInstance<SpinwheelNetworkUserResponse>>,) => {\n return customInstance<SpinwheelNetworkUserResponse>(\n {url: `/v1/application/spinwheel-network-user`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: spinwheelNetworkUserRequest\n },\n options);\n }\n \n/**\n * Authenticates the seller, validates banking disclosure requirements, optionally validates the submitted account and routing numbers, patches the program, and returns the refreshed lead payload. Requires a valid Authorization header.\n * @summary Update applicant bank details\n */\nconst updateApplicationBankDetails = (\n applicantId: string,\n bankUpdateRequest: BankUpdateRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/bank-update/${applicantId}`, method: 'PATCH',\n headers: {'Content-Type': 'application/json', },\n data: bankUpdateRequest\n },\n options);\n }\n \n/**\n * Banking Disclosure: Manually triggers the banking disclosure email. **This endpoint is optional** — it is only needed when the disclosure was not already sent automatically by `POST /v2/application/uw-submission/{fdrApplicantId}` (which auto-sends on full UW approval). Use this endpoint for conditional approvals or when the v1 UW submission path is in use. A critical legal prerequisite that must be completed before enrollment can proceed. Requires a valid Authorization header.\n * @summary Send banking disclosure email (optional — only if not auto-sent by v2 UW submission)\n */\nconst sendEmail = (\n fdrApplicantId: string,\n options?: SecondParameter<typeof customInstance<ApplicationSendEmailResponse>>,) => {\n return customInstance<ApplicationSendEmailResponse>(\n {url: `/v1/application/send-email/${fdrApplicantId}`, method: 'POST'\n },\n options);\n }\n \n/**\n * Submits a lead evaluation request. fdr_applicant_id is required in the request body. Requires a valid Authorization header with the arpc.all role.\n * @summary Transfer a lead to the debt-resolution program\n */\nconst leadTransfer = (\n leadTransferRequest: LeadTransferRequest,\n options?: SecondParameter<typeof customInstance<LeadTransferResponse>>,) => {\n return customInstance<LeadTransferResponse>(\n {url: `/v1/application/lead-transfer`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: leadTransferRequest\n },\n options);\n }\n \n/**\n * Fetches the current state of an application / lead record by FDR applicant ID. Requires a valid Authorization header.\n * @summary Read application / lead details\n */\nconst readLead = (\n fdrApplicantId: string,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/${fdrApplicantId}`, method: 'GET'\n },\n options);\n }\n \n/**\n * Applies a partial update to an existing wholesale lead record. Requires a valid Authorization header and an x-correlation-id header for request tracing. For split drafts, update second_draft_date_split after UW submission and before generating the DRA; the bi-weekly second_draft_date_bi_weekly field is populated automatically during UW approval.\n * @summary Partial update of application / lead record\n */\nconst patchLead = (\n fdrApplicantId: string,\n leadPatchRequest: LeadPatchRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/${fdrApplicantId}`, method: 'PATCH',\n headers: {'Content-Type': 'application/json', },\n data: leadPatchRequest\n },\n options);\n }\n \n/**\n * DRA Readiness Check: Final pre-flight confirming the lead is approved and all prerequisites are met before initiating the embedded signing session. Requires a valid Authorization header.\n * @summary Get application readiness status\n */\nconst getApplicationReadiness = (\n applicantId: string,\n options?: SecondParameter<typeof customInstance<ReadinessResponse>>,) => {\n return customInstance<ReadinessResponse>(\n {url: `/v1/application/${applicantId}/readiness`, method: 'GET'\n },\n options);\n }\n \n/**\n * Embedded DRA Signing: Returns an Embedded Signing URL so the applicant signs the Debt Resolution Agreement via DocuSign directly within the Symple UI, preventing session breakage. Successful legal execution triggers automatic enrollment. Requires a valid Authorization header.\n * @summary Generate Debt Resolution Agreement (DRA)\n */\nconst generateDra = (\n applicantId: string,\n draRequest: DraRequest,\n options?: SecondParameter<typeof customInstance<DraResponse>>,) => {\n return customInstance<DraResponse>(\n {url: `/v2/application/${applicantId}/dra`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: draRequest\n },\n options);\n }\n \n/**\n * **Recommended endpoint.** `POST /v1/applicant/register` is deprecated and will be retired by end of July 2026 (deadline can be extended on request if your team needs more time). Identity Anchoring: Persists applicant PII to Achieve's managed partner CRM and generates the `fdr_applicant_id` — the applicant's passport across all systems. Routes to the correct target system based on seller identity, and triggers the async credit fetch. Requires a valid Authorization header.\n * @summary Seller-aware applicant registration (v2 — unified ARPCErrorResponse envelope) — recommended\n */\nconst registerApplicantV2 = (\n registerApplicantV2Request: RegisterApplicantV2Request,\n options?: SecondParameter<typeof customInstance<RegisterApplicantV2Response>>,) => {\n return customInstance<RegisterApplicantV2Response>(\n {url: `/v2/applicant/register`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: registerApplicantV2Request\n },\n options);\n }\n \n/**\n * Async Polling Loop: Call this single endpoint for both initial generation and refresh. Returns 202 Accepted with a Retry-After header while credit is still pending. Once ready, the Managed Package orchestrates the calculation and persists the program result. Requires a valid Authorization header.\n * @summary Generate application program (v1)\n */\nconst generateProgramV1 = (\n programRequest: ProgramRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/program`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: programRequest\n },\n options);\n }\n \n/**\n * Eligibility Scout: Two operational modes — (1) no PII required: state-based quote using provided debt accounts; (2) credit pull: full applicant PII for a live soft credit report. Returns estimated program options to anchor the conversation before any registration occurs. Requires a valid Authorization header.\n * @summary Check application eligibility\n */\nconst checkEligibility = (\n eligibilityRequest: EligibilityRequest,\n options?: SecondParameter<typeof customInstance<EligibilityResponse>>,) => {\n return customInstance<EligibilityResponse>(\n {url: `/v2/application/eligibility`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: eligibilityRequest\n },\n options);\n }\n \n/**\n * **Recommended endpoint — supersedes v1.** Submits a wholesale application to the underwriting system. On full UW approval (`sub_status = 'UW Approved'`) the banking disclosure email is sent automatically — no separate `send-email` call is needed in this path. Conditional approvals suppress the auto-send; in that case the manual `POST /v1/application/send-email/{fdrApplicantId}` endpoint can be used. Uses the SF Object API directly (no suip-proxy hop). Requires a valid Authorization header.\n * @summary Submit application to underwriting (v2 — auto banking disclosure) — recommended\n */\nconst uwSubmissionV2 = (\n fdrApplicantId: string,\n options?: SecondParameter<typeof customInstance<UwSubmissionV2Response>>,) => {\n return customInstance<UwSubmissionV2Response>(\n {url: `/v2/application/uw-submission/${fdrApplicantId}`, method: 'POST'\n },\n options);\n }\n \n/**\n * Creates a SUIP Salesforce 'Program Summary Recording' task for the applicant identified by the {id} path variable. For DEX (or missing header), the parent SF opportunity is additionally PATCHed with the seller-config partner default PSC. For DC, the task is created and the parent SF opportunity is PATCHed only when ws_psc_code is provided in the request payload.\n * @summary Create program-summary recording task\n */\nconst createProgramSummaryTask = (\n id: string,\n programSummaryTaskRequest: ProgramSummaryTaskRequest,\n options?: SecondParameter<typeof customInstance<ProgramSummaryTaskResponse>>,) => {\n return customInstance<ProgramSummaryTaskResponse>(\n {url: `/v2/application/program-summary-task/${id}`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: programSummaryTaskRequest\n },\n options);\n }\n \nreturn {createLeadSync,selectProgram,checkApplicationReadiness,createSpinwheelNetworkUser,updateApplicationBankDetails,sendEmail,leadTransfer,readLead,patchLead,getApplicationReadiness,generateDra,registerApplicantV2,generateProgramV1,checkEligibility,uwSubmissionV2,createProgramSummaryTask}};\nexport type CreateLeadSyncResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['createLeadSync']>>>\nexport type SelectProgramResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['selectProgram']>>>\nexport type CheckApplicationReadinessResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['checkApplicationReadiness']>>>\nexport type CreateSpinwheelNetworkUserResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['createSpinwheelNetworkUser']>>>\nexport type UpdateApplicationBankDetailsResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['updateApplicationBankDetails']>>>\nexport type SendEmailResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['sendEmail']>>>\nexport type LeadTransferResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['leadTransfer']>>>\nexport type ReadLeadResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['readLead']>>>\nexport type PatchLeadResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['patchLead']>>>\nexport type GetApplicationReadinessResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['getApplicationReadiness']>>>\nexport type GenerateDraResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['generateDra']>>>\nexport type RegisterApplicantV2Result = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['registerApplicantV2']>>>\nexport type GenerateProgramV1Result = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['generateProgramV1']>>>\nexport type CheckEligibilityResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['checkEligibility']>>>\nexport type UwSubmissionV2Result = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['uwSubmissionV2']>>>\nexport type CreateProgramSummaryTaskResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['createProgramSummaryTask']>>>\n","import type {\n\tLeadApplication,\n\tLeadApplicationDraftType,\n\tProgramSelectionRequestDraftType,\n} from \"./generated/model\";\n\n/**\n * FDR's API speaks two vocabularies for the same value. You *send* a lowercase\n * schedule code (`bi-weekly`) to `selectProgram`; the lead *reports* a\n * capitalised label (`Bi-Weekly`) back on `application.draft_type`. Nothing in\n * the spec connects them, and the mismatch is silent — comparing what you sent\n * against what came back always looks like a failure.\n *\n * The labels below were confirmed against live STG by selecting each draft type\n * in turn. Through 2026.16.0 the spec documented `Monthly [Regular]` and\n * `Twice Monthly [Split]` for two of them and the API returned neither; 16.1\n * corrected the response enum, so the generated types now agree with the wire.\n * The two *vocabularies* remain — a corrected enum is not a unified one.\n *\n * Scope is narrow: `LeadApplication.draft_type` is the only label-valued site\n * in the whole spec. `PaymentSchedule` and `ProgramSelectionRequest` are both\n * already lowercase, and `LeadPatchRequest` has no `draft_type` at all, so\n * `selectProgram` is the only write path.\n *\n * These maps are annotated as `Record<>` over the generated enums on purpose:\n * if FDR ever adds a fourth draft type, codegen widens the enum and these fail\n * to compile until someone fills in the new key. The mapping keeps itself\n * honest without any bespoke assertion.\n */\n\n/** Schedule code → the label the lead reports back. */\nexport const DRAFT_TYPE_LABEL: Record<\n\tProgramSelectionRequestDraftType,\n\tLeadApplicationDraftType\n> = {\n\tregular: \"Regular\",\n\tsplit: \"Split\",\n\t\"bi-weekly\": \"Bi-Weekly\",\n};\n\n/** Lead-reported label → the schedule code `selectProgram` accepts. */\nexport const DRAFT_TYPE_CODE: Record<\n\tLeadApplicationDraftType,\n\tProgramSelectionRequestDraftType\n> = {\n\tRegular: \"regular\",\n\tSplit: \"split\",\n\t\"Bi-Weekly\": \"bi-weekly\",\n};\n\n/**\n * Read a lead's current draft type as a value you can hand straight back to\n * `selectProgram` — closing the round-trip FDR's two vocabularies leave open.\n *\n * Returns `undefined` when the lead has no selection yet, and also when the\n * label isn't one we know: the server can start returning a new picklist value\n * before we've regenerated against a newer spec, and guessing would be worse\n * than admitting we don't recognise it.\n */\nexport const draftTypeOf = (\n\tapplication: LeadApplication | undefined | null,\n): ProgramSelectionRequestDraftType | undefined => {\n\tconst label = application?.draft_type;\n\treturn label ? DRAFT_TYPE_CODE[label] : undefined;\n};\n","import { type ArpcConfig, configure } from \"./config\";\nimport { getARPCAchieveResolutionPartnerConnectAPI } from \"./generated/arpc\";\n\nexport type {\n\tArpcAuth,\n\tArpcConfig,\n\tArpcEndpoint,\n\tArpcEnvironment,\n\tArpcUrls,\n\tTokenCache,\n} from \"./config\";\nexport { ARPC_ENDPOINTS, isArpcEnvironment } from \"./config\";\nexport { DRAFT_TYPE_CODE, DRAFT_TYPE_LABEL, draftTypeOf } from \"./draft-type\";\nexport type * from \"./generated/model\";\nexport type { HttpResponse } from \"./http/client\";\n\n/**\n * ARPC SDK — a typed, agnostic client for FDR's ARPC DEX API (Achieve\n * Resolution Partner Connect, Digital Enrollment Experience).\n *\n * Thin by design: it owns the two-host routing (both derived from\n * `environment`), the OAuth token lifecycle, and bearer injection, and exposes\n * the full endpoint surface as typed operations on `sdk.api`. It does not\n * orchestrate the enrollment sequence — the caller\n * assembles payloads and threads the `fdr_applicant_id` between calls. See\n * `scripts/smoke.ts` for a full end-to-end reference sequence (incl. the program\n * poll loop).\n *\n * Auth is lazy: the first `api` call exchanges credentials for a bearer JWT and\n * caches it (~900s TTL), then re-exchanges shortly before it expires. There's no\n * explicit login step. Supply `auth.cache` to persist the token across restarts\n * or share it across workers; otherwise it's held in-process.\n *\n * Operations never throw on a non-2xx: each returns `{ status, data, headers }`,\n * so a business gate (e.g. a UW/DRA readiness failure) comes back as a normal\n * response you inspect via `status`/`data`. Only transport errors throw.\n *\n * Note: config and the default token cache are process-global — construct one\n * `ArpcSDK` per process. A second instance reconfigures the first; instances are\n * not isolated (single-tenant by design).\n *\n * @example\n * ```typescript\n * const sdk = new ArpcSDK({\n * environment: \"stg\",\n * auth: {\n * username: \"borrowbetter@seller.com\",\n * password: process.env.ARPC_OAUTH_PASSWORD!,\n * },\n * });\n *\n * // The first call authenticates automatically and caches the token.\n * const elig = await sdk.api.checkEligibility({ ... });\n * const faid = elig.data.application?.applicant?.fdr_applicant_id;\n * ```\n */\nexport class ArpcSDK {\n\t/** The full typed endpoint surface — one method per gateway operation. */\n\treadonly api = getARPCAchieveResolutionPartnerConnectAPI();\n\n\tconstructor(config: ArpcConfig) {\n\t\tconfigure(config);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/auth.ts","../src/http/client.ts","../src/generated/arpc.ts","../src/draft-type.ts","../src/index.ts"],"names":["ky","request"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * SDK configuration.\n *\n * The library never reads the environment itself — a consumer constructs\n * `new ArpcSDK(config)`, which calls `configure()`. Where that config comes\n * from (env vars, a secrets manager, a config service) is the caller's business.\n */\n/**\n * Bearer-token store. The SDK authenticates lazily on the first gateway call:\n * it asks `get()` for a still-valid token and, on `null`, exchanges credentials\n * and hands the fresh token to `set()`. Owning expiry is the cache's job —\n * `get()` returns `null` once the token is stale (or near-stale). The default\n * store is in-memory and per-process; supply one to persist across restarts or\n * share across workers.\n */\nexport interface TokenCache {\n\t/** Return a valid bearer token, or `null` if absent/expired. */\n\tget(): Promise<string | null>;\n\t/** Persist a freshly exchanged token. `expiresAt` already includes the SDK's refresh skew. */\n\tset(token: string, expiresAt: Date): Promise<void>;\n}\n\n/** FDR deployment target. Selects both hosts — see `ARPC_ENDPOINTS`. */\nexport type ArpcEnvironment = \"dev\" | \"stg\" | \"prd\";\n\n/** The host pair a single environment resolves to. */\nexport interface ArpcEndpoint {\n\t/** OAuth host — token exchange only (`POST /v1/token`). */\n\treadonly oauth: string;\n\t/** API gateway host — every non-auth call. */\n\treadonly gateway: string;\n}\n\n/**\n * Per-environment hosts. The two differ by domain, not just subdomain: the\n * OAuth host is `ffngcp.com`, the gateway is `fdrgcp.com`.\n *\n * Frozen: this table backs both host resolution and environment validation, so\n * a consumer mutating it would quietly change SDK behavior.\n */\nexport const ARPC_ENDPOINTS: Readonly<Record<ArpcEnvironment, ArpcEndpoint>> =\n\tObject.freeze({\n\t\tdev: Object.freeze({\n\t\t\toauth: \"https://oauth.dev.ffngcp.com\",\n\t\t\tgateway: \"https://apis-gateway-v2.dev.fdrgcp.com\",\n\t\t}),\n\t\tstg: Object.freeze({\n\t\t\toauth: \"https://oauth.stg.ffngcp.com\",\n\t\t\tgateway: \"https://apis-gateway-v2.stg.fdrgcp.com\",\n\t\t}),\n\t\tprd: Object.freeze({\n\t\t\toauth: \"https://oauth.prd.ffngcp.com\",\n\t\t\tgateway: \"https://apis-gateway-v2.prd.fdrgcp.com\",\n\t\t}),\n\t});\n\n/**\n * Narrow a raw string to an `ArpcEnvironment`. Useful when the value arrives\n * untyped — an env var, a JSON config file, a request payload.\n */\nexport function isArpcEnvironment(value: string): value is ArpcEnvironment {\n\t// Own keys only — `in` would also match inherited members like `toString`.\n\treturn Object.keys(ARPC_ENDPOINTS).includes(value);\n}\n\nexport interface ArpcAuth {\n\t/**\n\t * OAuth client_id (HTTP Basic username). Also used as the lead's\n\t * `seller_agent_email` — the OAuth identity is a registered DRA agent.\n\t */\n\tusername: string;\n\t/** OAuth client_secret (HTTP Basic password). */\n\tpassword: string;\n\t/** Bearer-token store. Defaults to an in-memory, per-process cache. */\n\tcache?: TokenCache;\n}\n\n/**\n * Escape hatch — per-host overrides of the `environment` defaults. Omit a key\n * (or leave it `undefined`) to keep that environment's host.\n */\nexport interface ArpcUrls {\n\t/** OAuth host — token exchange only (`POST /v1/token`). */\n\toauth?: string;\n\t/** API gateway host — every non-auth call. */\n\tgateway?: string;\n}\n\nexport interface ArpcConfig {\n\t/** Selects the FDR environment. Drives both hosts. */\n\tenvironment: ArpcEnvironment;\n\tauth: ArpcAuth;\n\turls?: ArpcUrls;\n}\n\n/** Config as the internals consume it — hosts resolved to concrete strings. */\nexport interface ResolvedArpcConfig extends ArpcConfig {\n\turls: Required<ArpcUrls>;\n}\n\nlet current: ResolvedArpcConfig | null = null;\n\n/**\n * Fold the environment defaults together with any caller overrides. The guard\n * looks unreachable given the types, but `environment` routinely arrives from\n * somewhere untyped (an env var, a JSON config, a JS caller) — catch it here\n * rather than letting `undefined` reach a request URL.\n */\nfunction resolveUrls(config: ArpcConfig): Required<ArpcUrls> {\n\tif (!isArpcEnvironment(config.environment)) {\n\t\tthrow new Error(\n\t\t\t`Unknown environment: ${config.environment} (expected one of ${Object.keys(ARPC_ENDPOINTS).join(\", \")})`,\n\t\t);\n\t}\n\tconst defaults = ARPC_ENDPOINTS[config.environment];\n\treturn {\n\t\toauth: config.urls?.oauth ?? defaults.oauth,\n\t\tgateway: config.urls?.gateway ?? defaults.gateway,\n\t};\n}\n\n/** Set the active config, resolving hosts once. Called by the `ArpcSDK` constructor. */\nexport function configure(config: ArpcConfig): void {\n\tcurrent = { ...config, urls: resolveUrls(config) };\n}\n\n/** Read the active config. Throws if the SDK hasn't been constructed yet. */\nexport function getConfig(): ResolvedArpcConfig {\n\tif (!current) {\n\t\tthrow new Error(\n\t\t\t\"ArpcSDK is not configured — construct `new ArpcSDK(config)` before making calls\",\n\t\t);\n\t}\n\treturn current;\n}\n","import ky from \"ky\";\nimport { getConfig, type TokenCache } from \"./config\";\n\n// Token lifecycle lives in the orchestration layer, not the generated client:\n// the exchange targets the OAuth host (not the gateway), uses HTTP Basic, and is\n// form-encoded. Authentication is lazy — `resolveToken()` runs from the ky\n// beforeRequest hook on the first gateway call (and again once the token goes\n// stale), so callers never manage the token by hand.\nexport interface TokenResponse {\n\taccess_token: string;\n\ttoken_type?: string;\n\texpires_in?: number;\n}\n\n// Refresh this many ms before the server's stated expiry, so a token never\n// lapses mid-flight. Applied once, when we compute the stored `expiresAt`.\nconst TOKEN_SKEW_MS = 30_000;\n// FDR tokens are ~900s; fall back to that if the response omits expires_in.\nconst DEFAULT_TTL_S = 900;\n\n/** Raw credentials → bearer JWT. No storage; `resolveToken()` owns that. */\nexport async function exchangeToken(): Promise<TokenResponse> {\n\tconst { urls, auth } = getConfig();\n\tconst basic = Buffer.from(`${auth.username}:${auth.password}`).toString(\n\t\t\"base64\",\n\t);\n\n\treturn ky\n\t\t.post(`${urls.oauth}/v1/token`, {\n\t\t\theaders: { Authorization: `Basic ${basic}` },\n\t\t\tbody: new URLSearchParams({ grant_type: \"client_credentials\" }),\n\t\t})\n\t\t.json<TokenResponse>();\n}\n\n// Default store: in-memory, per-process. Used when config omits `cache`.\nlet memToken: string | null = null;\nlet memExpiresAt = 0;\nconst defaultCache: TokenCache = {\n\tasync get() {\n\t\treturn memToken && Date.now() < memExpiresAt ? memToken : null;\n\t},\n\tasync set(token, expiresAt) {\n\t\tmemToken = token;\n\t\tmemExpiresAt = expiresAt.getTime();\n\t},\n};\n\n// Single-flight guard: a cold burst of concurrent gateway calls performs one\n// exchange, not one per call.\nlet inflight: Promise<string> | null = null;\n\n/**\n * Return a valid bearer token, exchanging + caching on a miss. Called by the\n * gateway beforeRequest hook; not part of the public surface.\n */\nexport function resolveToken(): Promise<string> {\n\tconst store = getConfig().auth.cache ?? defaultCache;\n\tif (inflight) return inflight;\n\n\tinflight = (async () => {\n\t\tconst cached = await store.get();\n\t\tif (cached) return cached;\n\t\tconst res = await exchangeToken();\n\t\tconst ttl = (res.expires_in ?? DEFAULT_TTL_S) * 1000;\n\t\tawait store.set(\n\t\t\tres.access_token,\n\t\t\tnew Date(Date.now() + ttl - TOKEN_SKEW_MS),\n\t\t);\n\t\treturn res.access_token;\n\t})().finally(() => {\n\t\tinflight = null;\n\t});\n\treturn inflight;\n}\n","import ky from \"ky\";\nimport { resolveToken } from \"../auth\";\nimport { getConfig } from \"../config\";\n\n// ---------------------------------------------------------------------------\n// Orval custom mutator (ky-backed).\n//\n// Every generated operation calls `customInstance<T>(config, options)`. We\n// route all calls to the API gateway, attach the bearer token via a\n// beforeRequest hook (lazy auth — `resolveToken()` exchanges/refreshes as\n// needed), and return a small { status, data, headers } wrapper WITHOUT\n// throwing on non-2xx — the caller inspects status codes itself (202 +\n// Retry-After on program, 400 on a UW/DRA gate, etc.).\n// ---------------------------------------------------------------------------\n\n// Shape Orval passes as the first arg (axios-style request config).\nexport interface RequestConfig {\n\turl: string;\n\tmethod: string;\n\tparams?: Record<string, unknown>;\n\tdata?: unknown;\n\theaders?: Record<string, string>;\n\tsignal?: AbortSignal;\n\tresponseType?: string;\n}\n\nexport interface HttpResponse<T> {\n\tstatus: number;\n\tdata: T;\n\theaders: Headers;\n}\n\nexport const customInstance = async <T>(\n\trequest: RequestConfig,\n\toptions?: Partial<RequestConfig>,\n): Promise<HttpResponse<T>> => {\n\tconst { url, method, params, data, signal } = { ...request, ...options };\n\t// Merge headers from both sides — a per-call override (e.g. an\n\t// x-correlation-id in `options.headers`) must not drop the operation's\n\t// Content-Type. The bearer token is layered on last, below.\n\tconst headers = { ...request.headers, ...options?.headers };\n\n\tconst target = new URL(url, getConfig().urls.gateway);\n\tif (params) {\n\t\tfor (const [key, value] of Object.entries(params)) {\n\t\t\tif (value !== undefined && value !== null)\n\t\t\t\ttarget.searchParams.set(key, String(value));\n\t\t}\n\t}\n\n\tconst response = await ky(target, {\n\t\tmethod,\n\t\theaders,\n\t\thooks: {\n\t\t\t// Lazy bearer injection: resolveToken() exchanges on the first call\n\t\t\t// and refreshes once the cached token goes stale. The OAuth exchange\n\t\t\t// itself runs on a bare ky.post (no hook), so there's no recursion.\n\t\t\tbeforeRequest: [\n\t\t\t\tasync ({ request }) => {\n\t\t\t\t\tconst token = await resolveToken();\n\t\t\t\t\trequest.headers.set(\"Authorization\", `Bearer ${token}`);\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t...(data !== undefined ? { json: data } : {}),\n\t\tsignal,\n\t\tthrowHttpErrors: false,\n\t\tretry: 0,\n\t\t// Some gateway calls (program generation in particular) can take well over ky's\n\t\t// 10s default to respond. Raise the per-request ceiling; the program poll loop\n\t\t// handles 202/Retry-After on top of this.\n\t\ttimeout: 60_000,\n\t});\n\n\tconst text = await response.text();\n\tlet body: T;\n\ttry {\n\t\tbody = (text ? JSON.parse(text) : undefined) as T;\n\t} catch {\n\t\t// Non-JSON body (e.g. a gateway HTML error page on a transient 5xx). Don't throw —\n\t\t// hand back the raw text so callers can inspect status/body and retry as needed.\n\t\tbody = text as unknown as T;\n\t}\n\treturn { status: response.status, data: body, headers: response.headers };\n};\n","/**\n * Generated by orval v7.21.0 🍺\n * Do not edit manually.\n * ARPC — Achieve Resolution Partner Connect API\n * FDR Wholesale API — A Hybrid Integration Model designed to maximise partner velocity without compromising enterprise data standards. DEX (Digital Enrollment Experience) is the partner-facing integration layer that powers the full applicant lifecycle. The `fdr_applicant_id` acts as the applicant's passport across all systems, persisted from first eligibility check through enrollment. All endpoints require a valid Bearer JWT with the `arpc.all` role.\n\n**Published:** 2026-08-18\n * OpenAPI spec version: 2026.16.1\n */\nimport type {\n ARPCErrorResponse,\n ApplicationSendEmailResponse,\n BankUpdateRequest,\n CreateLeadRequest,\n CreateLeadResponse,\n DraRequest,\n DraResponse,\n EligibilityRequest,\n EligibilityResponse,\n LeadPatchRequest,\n LeadResponse,\n LeadTransferRequest,\n LeadTransferResponse,\n ProgramRequest,\n ProgramSelectionRequest,\n ProgramSummaryTaskRequest,\n ProgramSummaryTaskResponse,\n ReadinessResponse,\n RegisterApplicantV2Request,\n RegisterApplicantV2Response,\n SpinwheelNetworkUserRequest,\n SpinwheelNetworkUserResponse,\n StatelessReadinessRequest,\n UwSubmissionV2Response\n} from './model';\n\nimport { customInstance } from '../http/client';\ntype SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];\n\n\n export const getARPCAchieveResolutionPartnerConnectAPI = () => {\n/**\n * Synchronous Orchestration: Handles both lead creation and income/expense data in one step, eliminating the async polling black box. Data authority shifts here — Achieve becomes the Source of Truth once the lead is formally promoted. Returns the full lead creation result including program options.\n * @summary Sync wholesale lead creation\n */\nconst createLeadSync = (\n createLeadRequest: CreateLeadRequest,\n options?: SecondParameter<typeof customInstance<CreateLeadResponse>>,) => {\n return customInstance<CreateLeadResponse>(\n {url: `/v3/application`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: createLeadRequest\n },\n options);\n }\n \n/**\n * Gateway-level endpoint: selects a payment schedule for an existing lead and persists the program offer. After calling generateProgram, choose a schedule from payment_schedule_options and submit its draft_type and estimated_monthly_payment here. The gateway injects request attributes and forwards internally to POST /v3/application/program. Requires a valid Authorization header.\n * @summary Select program schedule for an existing lead\n */\nconst selectProgram = (\n programSelectionRequest: ProgramSelectionRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/program-selection`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: programSelectionRequest\n },\n options);\n }\n \n/**\n * Stateless Readiness Check: Pre-flight validation before initiating program calculations. Catches duplicate SSNs or emails early to prevent downstream failures. Requires a valid Authorization header.\n * @summary Check application readiness\n */\nconst checkApplicationReadiness = (\n statelessReadinessRequest: StatelessReadinessRequest,\n options?: SecondParameter<typeof customInstance<ReadinessResponse>>,) => {\n return customInstance<ReadinessResponse>(\n {url: `/v1/application/readiness`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: statelessReadinessRequest\n },\n options);\n }\n \n/**\n * Recovery endpoint — only required when the async Spinwheel user creation triggered by `POST /v1/applicant/register` fails due to a user error (e.g. invalid SSN or DOB). Not needed in the happy path. Authenticates the seller, resolves the law firm / program, creates an applicant ID when needed, and connects the applicant to the Spinwheel network. Requires a valid Authorization header.\n * @summary Create / connect Spinwheel network user\n */\nconst createSpinwheelNetworkUser = (\n spinwheelNetworkUserRequest: SpinwheelNetworkUserRequest,\n options?: SecondParameter<typeof customInstance<SpinwheelNetworkUserResponse>>,) => {\n return customInstance<SpinwheelNetworkUserResponse>(\n {url: `/v1/application/spinwheel-network-user`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: spinwheelNetworkUserRequest\n },\n options);\n }\n \n/**\n * Authenticates the seller, validates banking disclosure requirements, optionally validates the submitted account and routing numbers, patches the program, and returns the refreshed lead payload. Requires a valid Authorization header.\n * @summary Update applicant bank details\n */\nconst updateApplicationBankDetails = (\n applicantId: string,\n bankUpdateRequest: BankUpdateRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/bank-update/${applicantId}`, method: 'PATCH',\n headers: {'Content-Type': 'application/json', },\n data: bankUpdateRequest\n },\n options);\n }\n \n/**\n * Banking Disclosure: Manually triggers the banking disclosure email. **This endpoint is optional** — it is only needed when the disclosure was not already sent automatically by `POST /v2/application/uw-submission/{fdrApplicantId}` (which auto-sends on full UW approval). Use this endpoint for conditional approvals or when the v1 UW submission path is in use. A critical legal prerequisite that must be completed before enrollment can proceed. Requires a valid Authorization header.\n * @summary Send banking disclosure email (optional — only if not auto-sent by v2 UW submission)\n */\nconst sendEmail = (\n fdrApplicantId: string,\n options?: SecondParameter<typeof customInstance<ApplicationSendEmailResponse>>,) => {\n return customInstance<ApplicationSendEmailResponse>(\n {url: `/v1/application/send-email/${fdrApplicantId}`, method: 'POST'\n },\n options);\n }\n \n/**\n * Submits a lead evaluation request. fdr_applicant_id is required in the request body. Requires a valid Authorization header with the arpc.all role.\n * @summary Transfer a lead to the debt-resolution program\n */\nconst leadTransfer = (\n leadTransferRequest: LeadTransferRequest,\n options?: SecondParameter<typeof customInstance<LeadTransferResponse>>,) => {\n return customInstance<LeadTransferResponse>(\n {url: `/v1/application/lead-transfer`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: leadTransferRequest\n },\n options);\n }\n \n/**\n * Fetches the current state of an application / lead record by FDR applicant ID. Requires a valid Authorization header.\n * @summary Read application / lead details\n */\nconst readLead = (\n fdrApplicantId: string,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/${fdrApplicantId}`, method: 'GET'\n },\n options);\n }\n \n/**\n * Applies a partial update to an existing wholesale lead record. Requires a valid Authorization header and an x-correlation-id header for request tracing. For split drafts, update second_draft_date_split after UW submission and before generating the DRA; the bi-weekly second_draft_date_bi_weekly field is populated automatically during UW approval.\n * @summary Partial update of application / lead record\n */\nconst patchLead = (\n fdrApplicantId: string,\n leadPatchRequest: LeadPatchRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/${fdrApplicantId}`, method: 'PATCH',\n headers: {'Content-Type': 'application/json', },\n data: leadPatchRequest\n },\n options);\n }\n \n/**\n * DRA Readiness Check: Final pre-flight confirming the lead is approved and all prerequisites are met before initiating the embedded signing session. Requires a valid Authorization header.\n * @summary Get application readiness status\n */\nconst getApplicationReadiness = (\n applicantId: string,\n options?: SecondParameter<typeof customInstance<ReadinessResponse>>,) => {\n return customInstance<ReadinessResponse>(\n {url: `/v1/application/${applicantId}/readiness`, method: 'GET'\n },\n options);\n }\n \n/**\n * Embedded DRA Signing: Returns an Embedded Signing URL so the applicant signs the Debt Resolution Agreement via DocuSign directly within the Symple UI, preventing session breakage. Successful legal execution triggers automatic enrollment. Requires a valid Authorization header.\n * @summary Generate Debt Resolution Agreement (DRA)\n */\nconst generateDra = (\n applicantId: string,\n draRequest: DraRequest,\n options?: SecondParameter<typeof customInstance<DraResponse>>,) => {\n return customInstance<DraResponse>(\n {url: `/v2/application/${applicantId}/dra`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: draRequest\n },\n options);\n }\n \n/**\n * **Recommended endpoint.** `POST /v1/applicant/register` is deprecated and will be retired by end of July 2026 (deadline can be extended on request if your team needs more time). Identity Anchoring: Persists applicant PII to Achieve's managed partner CRM and generates the `fdr_applicant_id` — the applicant's passport across all systems. Routes to the correct target system based on seller identity, and triggers the async credit fetch. Requires a valid Authorization header.\n * @summary Seller-aware applicant registration (v2 — unified ARPCErrorResponse envelope) — recommended\n */\nconst registerApplicantV2 = (\n registerApplicantV2Request: RegisterApplicantV2Request,\n options?: SecondParameter<typeof customInstance<RegisterApplicantV2Response>>,) => {\n return customInstance<RegisterApplicantV2Response>(\n {url: `/v2/applicant/register`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: registerApplicantV2Request\n },\n options);\n }\n \n/**\n * Async Polling Loop: Call this single endpoint for both initial generation and refresh. Returns 202 Accepted with a Retry-After header while credit is still pending. Once ready, the Managed Package orchestrates the calculation and persists the program result. Requires a valid Authorization header.\n * @summary Generate application program (v1)\n */\nconst generateProgramV1 = (\n programRequest: ProgramRequest,\n options?: SecondParameter<typeof customInstance<LeadResponse>>,) => {\n return customInstance<LeadResponse>(\n {url: `/v1/application/program`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: programRequest\n },\n options);\n }\n \n/**\n * Eligibility Scout: Two operational modes — (1) no PII required: state-based quote using provided debt accounts; (2) credit pull: full applicant PII for a live soft credit report. Returns estimated program options to anchor the conversation before any registration occurs. Requires a valid Authorization header.\n * @summary Check application eligibility\n */\nconst checkEligibility = (\n eligibilityRequest: EligibilityRequest,\n options?: SecondParameter<typeof customInstance<EligibilityResponse>>,) => {\n return customInstance<EligibilityResponse>(\n {url: `/v2/application/eligibility`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: eligibilityRequest\n },\n options);\n }\n \n/**\n * **Recommended endpoint — supersedes v1.** Submits a wholesale application to the underwriting system. On full UW approval (`sub_status = 'UW Approved'`) the banking disclosure email is sent automatically — no separate `send-email` call is needed in this path. Conditional approvals suppress the auto-send; in that case the manual `POST /v1/application/send-email/{fdrApplicantId}` endpoint can be used. Uses the SF Object API directly (no suip-proxy hop). Requires a valid Authorization header.\n * @summary Submit application to underwriting (v2 — auto banking disclosure) — recommended\n */\nconst uwSubmissionV2 = (\n fdrApplicantId: string,\n options?: SecondParameter<typeof customInstance<UwSubmissionV2Response>>,) => {\n return customInstance<UwSubmissionV2Response>(\n {url: `/v2/application/uw-submission/${fdrApplicantId}`, method: 'POST'\n },\n options);\n }\n \n/**\n * Creates a SUIP Salesforce 'Program Summary Recording' task for the applicant identified by the {id} path variable. For DEX (or missing header), the parent SF opportunity is additionally PATCHed with the seller-config partner default PSC. For DC, the task is created and the parent SF opportunity is PATCHed only when ws_psc_code is provided in the request payload.\n * @summary Create program-summary recording task\n */\nconst createProgramSummaryTask = (\n id: string,\n programSummaryTaskRequest: ProgramSummaryTaskRequest,\n options?: SecondParameter<typeof customInstance<ProgramSummaryTaskResponse>>,) => {\n return customInstance<ProgramSummaryTaskResponse>(\n {url: `/v2/application/program-summary-task/${id}`, method: 'POST',\n headers: {'Content-Type': 'application/json', },\n data: programSummaryTaskRequest\n },\n options);\n }\n \nreturn {createLeadSync,selectProgram,checkApplicationReadiness,createSpinwheelNetworkUser,updateApplicationBankDetails,sendEmail,leadTransfer,readLead,patchLead,getApplicationReadiness,generateDra,registerApplicantV2,generateProgramV1,checkEligibility,uwSubmissionV2,createProgramSummaryTask}};\nexport type CreateLeadSyncResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['createLeadSync']>>>\nexport type SelectProgramResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['selectProgram']>>>\nexport type CheckApplicationReadinessResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['checkApplicationReadiness']>>>\nexport type CreateSpinwheelNetworkUserResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['createSpinwheelNetworkUser']>>>\nexport type UpdateApplicationBankDetailsResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['updateApplicationBankDetails']>>>\nexport type SendEmailResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['sendEmail']>>>\nexport type LeadTransferResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['leadTransfer']>>>\nexport type ReadLeadResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['readLead']>>>\nexport type PatchLeadResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['patchLead']>>>\nexport type GetApplicationReadinessResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['getApplicationReadiness']>>>\nexport type GenerateDraResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['generateDra']>>>\nexport type RegisterApplicantV2Result = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['registerApplicantV2']>>>\nexport type GenerateProgramV1Result = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['generateProgramV1']>>>\nexport type CheckEligibilityResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['checkEligibility']>>>\nexport type UwSubmissionV2Result = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['uwSubmissionV2']>>>\nexport type CreateProgramSummaryTaskResult = NonNullable<Awaited<ReturnType<ReturnType<typeof getARPCAchieveResolutionPartnerConnectAPI>['createProgramSummaryTask']>>>\n","import type {\n\tLeadApplication,\n\tLeadApplicationDraftType,\n\tProgramSelectionRequestDraftType,\n} from \"./generated/model\";\n\n/**\n * FDR's API speaks two vocabularies for the same value. You *send* a lowercase\n * schedule code (`bi-weekly`) to `selectProgram`; the lead *reports* a\n * capitalised label (`Bi-Weekly`) back on `application.draft_type`. Nothing in\n * the spec connects them, and the mismatch is silent — comparing what you sent\n * against what came back always looks like a failure.\n *\n * The labels below were confirmed against live STG by selecting each draft type\n * in turn. Through 2026.16.0 the spec documented `Monthly [Regular]` and\n * `Twice Monthly [Split]` for two of them and the API returned neither; 16.1\n * corrected the response enum, so the generated types now agree with the wire.\n * The two *vocabularies* remain — a corrected enum is not a unified one.\n *\n * Scope is narrow: `LeadApplication.draft_type` is the only label-valued site\n * in the whole spec. `PaymentSchedule` and `ProgramSelectionRequest` are both\n * already lowercase, and `LeadPatchRequest` has no `draft_type` at all, so\n * `selectProgram` is the only write path.\n *\n * These maps are annotated as `Record<>` over the generated enums on purpose:\n * if FDR ever adds a fourth draft type, codegen widens the enum and these fail\n * to compile until someone fills in the new key. The mapping keeps itself\n * honest without any bespoke assertion.\n */\n\n/** Schedule code → the label the lead reports back. */\nexport const DRAFT_TYPE_LABEL: Record<\n\tProgramSelectionRequestDraftType,\n\tLeadApplicationDraftType\n> = {\n\tregular: \"Regular\",\n\tsplit: \"Split\",\n\t\"bi-weekly\": \"Bi-Weekly\",\n};\n\n/** Lead-reported label → the schedule code `selectProgram` accepts. */\nexport const DRAFT_TYPE_CODE: Record<\n\tLeadApplicationDraftType,\n\tProgramSelectionRequestDraftType\n> = {\n\tRegular: \"regular\",\n\tSplit: \"split\",\n\t\"Bi-Weekly\": \"bi-weekly\",\n};\n\n/**\n * Read a lead's current draft type as a value you can hand straight back to\n * `selectProgram` — closing the round-trip FDR's two vocabularies leave open.\n *\n * Returns `undefined` when the lead has no selection yet, and also when the\n * label isn't one we know: the server can start returning a new picklist value\n * before we've regenerated against a newer spec, and guessing would be worse\n * than admitting we don't recognise it.\n */\nexport const draftTypeOf = (\n\tapplication: LeadApplication | undefined | null,\n): ProgramSelectionRequestDraftType | undefined => {\n\tconst label = application?.draft_type;\n\treturn label ? DRAFT_TYPE_CODE[label] : undefined;\n};\n","import { type ArpcConfig, configure } from \"./config\";\nimport { getARPCAchieveResolutionPartnerConnectAPI } from \"./generated/arpc\";\n\nexport type {\n\tArpcAuth,\n\tArpcConfig,\n\tArpcEndpoint,\n\tArpcEnvironment,\n\tArpcUrls,\n\tTokenCache,\n} from \"./config\";\nexport { ARPC_ENDPOINTS, isArpcEnvironment } from \"./config\";\nexport { DRAFT_TYPE_CODE, DRAFT_TYPE_LABEL, draftTypeOf } from \"./draft-type\";\nexport type * from \"./generated/model\";\nexport type { HttpResponse } from \"./http/client\";\n\n/**\n * ARPC SDK — a typed, agnostic client for FDR's ARPC DEX API (Achieve\n * Resolution Partner Connect, Digital Enrollment Experience).\n *\n * Thin by design: it owns the two-host routing (both derived from\n * `environment`), the OAuth token lifecycle, and bearer injection, and exposes\n * the full endpoint surface as typed operations on `sdk.api`. It does not\n * orchestrate the enrollment sequence — the caller\n * assembles payloads and threads the `fdr_applicant_id` between calls. See\n * `scripts/smoke.ts` for a full end-to-end reference sequence (incl. the program\n * poll loop).\n *\n * Auth is lazy: the first `api` call exchanges credentials for a bearer JWT and\n * caches it (~900s TTL), then re-exchanges shortly before it expires. There's no\n * explicit login step. Supply `auth.cache` to persist the token across restarts\n * or share it across workers; otherwise it's held in-process.\n *\n * Operations never throw on a non-2xx: each returns `{ status, data, headers }`,\n * so a business gate (e.g. a UW/DRA readiness failure) comes back as a normal\n * response you inspect via `status`/`data`. Only transport errors throw.\n *\n * Note: config and the default token cache are process-global — construct one\n * `ArpcSDK` per process. A second instance reconfigures the first; instances are\n * not isolated (single-tenant by design).\n *\n * @example\n * ```typescript\n * const sdk = new ArpcSDK({\n * environment: \"stg\",\n * auth: {\n * username: \"borrowbetter@seller.com\",\n * password: process.env.ARPC_OAUTH_PASSWORD!,\n * },\n * });\n *\n * // The first call authenticates automatically and caches the token.\n * const elig = await sdk.api.checkEligibility({ ... });\n * const faid = elig.data.application?.applicant?.fdr_applicant_id;\n * ```\n */\nexport class ArpcSDK {\n\t/** The full typed endpoint surface — one method per gateway operation. */\n\treadonly api = getARPCAchieveResolutionPartnerConnectAPI();\n\n\tconstructor(config: ArpcConfig) {\n\t\tconfigure(config);\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@borrowbetter/arpcsdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Typed, agnostic client for FDR's ARPC DEX API — Achieve Resolution Partner Connect (Digital Enrollment Experience)",
|
|
5
5
|
"author": "BorrowBetter",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"release": "pnpm build && changeset publish"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"ky": "^1.
|
|
48
|
+
"ky": "^2.1.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@biomejs/biome": "^2.4.4",
|
|
@@ -60,6 +60,6 @@
|
|
|
60
60
|
"typescript": "^5.7.3"
|
|
61
61
|
},
|
|
62
62
|
"engines": {
|
|
63
|
-
"node": ">=
|
|
63
|
+
"node": ">=22.12"
|
|
64
64
|
}
|
|
65
65
|
}
|