@matech/thebigpos-sdk 3.12.0 → 3.13.0-dev-5466
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 +39 -0
- package/dist/index.d.ts +71 -4
- package/dist/index.js +44 -5
- package/dist/index.js.map +1 -1
- package/docs/sdk_generation.md +149 -0
- package/package.json +16 -6
- package/scripts/apply-json-patch-content-type.js +189 -36
- package/src/index.ts +116 -6
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Publishing the POS Typescript SDK
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
1. Clone the repository (if you haven't already):
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/MortgageAutomationTechnologies/thebigpos-sdk-typescript
|
|
9
|
+
cd thebigpos-sdk-typescript
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
2. Install swagger-typescript-api globally:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm i -g swagger-typescript-api
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
3. Connect to the MAT VPN
|
|
19
|
+
|
|
20
|
+
## Step 1: Create a release branch
|
|
21
|
+
|
|
22
|
+
Create a new branch for the version you're releasing:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
git checkout develop
|
|
26
|
+
git pull origin develop
|
|
27
|
+
git checkout -b release/X.Y.Z
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Step 2: Generate the SDK
|
|
31
|
+
|
|
32
|
+
Replace `{version}` with the target API version (e.g., `v2.31.0`):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx swagger-typescript-api generate -p https://api.thebigpos.dev/swagger/{version}/swagger.json -o ./src -n index.ts -r true --axios --enum-names-as-values --generate-union-enums
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
> **Note:** If generating locally, use `http://localhost:5212/swagger/{version}/swagger.json` due to self-signed cert issues with https.
|
|
39
|
+
|
|
40
|
+
## Step 3: Apply post-generation fixes
|
|
41
|
+
|
|
42
|
+
Run the script to fix PATCH methods content type and Operation interface:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
node scripts/apply-json-patch-content-type.js
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This script:
|
|
49
|
+
- Sets all PATCH methods to use `ContentType.JsonPatch`
|
|
50
|
+
- Adds `JsonPatch` to the `ContentType` enum
|
|
51
|
+
- Fixes the `Operation` interface to allow any value type
|
|
52
|
+
|
|
53
|
+
## Step 4: Update the version
|
|
54
|
+
|
|
55
|
+
Use npm's version command to update the version in `package.json`:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm version X.Y.Z
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Version conventions:**
|
|
62
|
+
|
|
63
|
+
- Match the SDK version to the API version being released
|
|
64
|
+
- For release candidates (pre-release), use: `npm version X.Y.Z-rc.N --preid=rc`
|
|
65
|
+
- For patch increments: `npm version patch`
|
|
66
|
+
- For minor increments: `npm version minor`
|
|
67
|
+
|
|
68
|
+
## Step 5: Build the SDK
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm run build
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Ensure there are no TypeScript compilation errors.
|
|
75
|
+
|
|
76
|
+
## Step 6: Merge develop (if needed)
|
|
77
|
+
|
|
78
|
+
If there are changes in develop that need to be included:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
git fetch origin develop
|
|
82
|
+
git merge origin/develop
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
If there are conflicts in `src/index.ts` or `dist/*`, regenerate the SDK (Step 2), apply fixes (Step 3), and rebuild (Step 5) to resolve them.
|
|
86
|
+
|
|
87
|
+
## Step 7: Commit and push
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
git add .
|
|
91
|
+
git commit -m "X.Y.Z"
|
|
92
|
+
git push -u origin release/X.Y.Z
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Step 8: Publish to NPM
|
|
96
|
+
|
|
97
|
+
### Authentication
|
|
98
|
+
|
|
99
|
+
NPM requires a granular access token with publish permissions and 2FA bypass enabled.
|
|
100
|
+
|
|
101
|
+
1. Go to [npmjs.com](https://www.npmjs.com) > Access Tokens > Generate New Token
|
|
102
|
+
2. Select "Granular Access Token"
|
|
103
|
+
3. Enable "Bypass 2FA for automation"
|
|
104
|
+
4. Set permissions to publish to `@matech/thebigpos-sdk`
|
|
105
|
+
|
|
106
|
+
Configure the token:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npm config set //registry.npmjs.org/:_authToken YOUR_TOKEN
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Publish
|
|
113
|
+
|
|
114
|
+
**To latest (stable release):**
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npm publish --access public
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**To next (pre-release):**
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npm publish --tag next
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**To a feature tag (for testing):**
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
npm publish --tag feature-name
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Installing the SDK
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Latest stable
|
|
136
|
+
yarn add @matech/thebigpos-sdk
|
|
137
|
+
|
|
138
|
+
# Next pre-release
|
|
139
|
+
yarn add @matech/thebigpos-sdk@next
|
|
140
|
+
|
|
141
|
+
# Specific version
|
|
142
|
+
yarn add @matech/thebigpos-sdk@X.Y.Z
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Step 9: Clean up
|
|
146
|
+
|
|
147
|
+
1. **Revoke the NPM token** after publishing for security
|
|
148
|
+
2. **Create a Pull Request** from `release/X.Y.Z` to `develop` and `main`
|
|
149
|
+
3. **Create a GitHub Release** with release notes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matech/thebigpos-sdk",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.13.0-dev-5466",
|
|
4
4
|
"description": "The Big POS Typescript SDK",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,15 +26,25 @@
|
|
|
26
26
|
"url": "https://github.com/MortgageAutomationTechnologies/thebigpos-sdk-typescript/issues"
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://github.com/MortgageAutomationTechnologies/thebigpos-sdk-typescript#readme",
|
|
29
|
-
"
|
|
30
|
-
"
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"axios": "^1"
|
|
31
34
|
},
|
|
32
35
|
"devDependencies": {
|
|
33
|
-
"
|
|
36
|
+
"axios": "^1.16.1",
|
|
37
|
+
"esbuild": "^0.28.1",
|
|
34
38
|
"husky": "^9.1.5",
|
|
35
|
-
"rimraf": "6.1.
|
|
39
|
+
"rimraf": "6.1.3",
|
|
36
40
|
"ts-node": "^10.9.2",
|
|
37
41
|
"typescript": "^5.5.4"
|
|
38
42
|
},
|
|
39
|
-
"
|
|
43
|
+
"resolutions": {
|
|
44
|
+
"diff": "^4.0.4",
|
|
45
|
+
"brace-expansion": "^5.0.8",
|
|
46
|
+
"follow-redirects": "^1.16.0",
|
|
47
|
+
"form-data": "^4.0.6"
|
|
48
|
+
},
|
|
49
|
+
"swaggerSha256": "000116dcb6106671f46d660b838d69cb7c8ba945079ac8971134e4f99e493c87"
|
|
40
50
|
}
|
|
@@ -1,56 +1,209 @@
|
|
|
1
|
-
/*
|
|
2
|
-
|
|
1
|
+
/*
|
|
2
|
+
Post-generation fixup for the generated TypeScript SDK.
|
|
3
3
|
|
|
4
|
-
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
swagger-typescript-api does not propagate the `application/json-patch+json`
|
|
5
|
+
request content type into the generated code, so PATCH methods that use JSON
|
|
6
|
+
Patch would otherwise go out with the wrong Content-Type. This script restores
|
|
7
|
+
it by reading the OpenAPI spec the SDK was generated from and, for every
|
|
8
|
+
generated PATCH method, setting:
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
- ContentType.JsonPatch -> when the spec's requestBody for that path
|
|
11
|
+
advertises application/json-patch+json
|
|
12
|
+
- ContentType.Json -> for every other PATCH method
|
|
13
|
+
(e.g. updateLoan, which the backend declares as
|
|
14
|
+
[Consumes("application/json")])
|
|
15
|
+
|
|
16
|
+
The decision is taken entirely from the spec — there is no hard-coded list of
|
|
17
|
+
endpoints to keep in sync. It also ensures the ContentType enum includes
|
|
18
|
+
JsonPatch and relaxes the Operation interface `value` to accept any value.
|
|
19
|
+
|
|
20
|
+
It additionally teaches `createFormData` to recognise React Native files. The
|
|
21
|
+
generator assumes a browser and detects file parts with `instanceof Blob ||
|
|
22
|
+
instanceof File`; in React Native a file is a plain `{ uri, name, type }`
|
|
23
|
+
object, so without the extra branch every mobile upload is serialised as the
|
|
24
|
+
string "[object Object]". This used to live as a patch-package patch in
|
|
25
|
+
pos-mobile-v2, which had to be re-created on every SDK bump.
|
|
26
|
+
|
|
27
|
+
Usage (pass the SAME spec given to `swagger-typescript-api -p`):
|
|
28
|
+
node scripts/apply-json-patch-content-type.js https://api.thebigpos.dev/swagger/<version>/swagger.json
|
|
29
|
+
node scripts/apply-json-patch-content-type.js ./swagger.json
|
|
30
|
+
SWAGGER_SPEC=<url-or-file> node scripts/apply-json-patch-content-type.js
|
|
31
|
+
|
|
32
|
+
Design notes:
|
|
33
|
+
- The rewrite is scoped to a single generated method block at a time
|
|
34
|
+
(anchored on that method's own `...params,`), so it can never bleed across
|
|
35
|
+
method boundaries.
|
|
36
|
+
- It sets each method's content type to its target value rather than doing a
|
|
37
|
+
conditional replace, so it is idempotent and self-healing (it also repairs
|
|
38
|
+
a previously-seen ContentType.JsonPatchPatch double-application).
|
|
39
|
+
- If no spec is provided (e.g. a plain commit-hook run), the content-type
|
|
40
|
+
rewrite is skipped instead of guessing, so it can never silently corrupt
|
|
41
|
+
the generated output.
|
|
9
42
|
*/
|
|
10
43
|
|
|
11
44
|
const fs = require('fs')
|
|
45
|
+
const nodePath = require('path')
|
|
12
46
|
|
|
13
|
-
const
|
|
47
|
+
const SRC = nodePath.resolve(__dirname, '../src/index.ts')
|
|
14
48
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
49
|
+
async function loadSpec(source) {
|
|
50
|
+
if (!source) return null
|
|
51
|
+
if (/^https?:\/\//i.test(source)) {
|
|
52
|
+
const res = await fetch(source)
|
|
53
|
+
if (!res.ok) throw new Error(`Failed to fetch spec from "${source}": HTTP ${res.status}`)
|
|
54
|
+
return res.json()
|
|
55
|
+
}
|
|
56
|
+
return JSON.parse(fs.readFileSync(nodePath.resolve(source), 'utf8'))
|
|
18
57
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
58
|
+
|
|
59
|
+
// Collapse spec ("{id}") and generated ("${id}") path params to a common token
|
|
60
|
+
// so generated paths can be matched against spec paths regardless of param names.
|
|
61
|
+
function normalizePath(p) {
|
|
62
|
+
return p.replace(/\$\{[^}]+\}/g, '{}').replace(/\{[^}]+\}/g, '{}')
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function jsonPatchPaths(spec) {
|
|
66
|
+
const set = new Set()
|
|
67
|
+
for (const [route, ops] of Object.entries(spec.paths || {})) {
|
|
68
|
+
const content = ops && ops.patch && ops.patch.requestBody && ops.patch.requestBody.content
|
|
69
|
+
if (content && Object.prototype.hasOwnProperty.call(content, 'application/json-patch+json')) {
|
|
70
|
+
set.add(normalizePath(route))
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return set
|
|
25
74
|
}
|
|
26
75
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/
|
|
30
|
-
(
|
|
31
|
-
)
|
|
76
|
+
function setContentType(block, member) {
|
|
77
|
+
const target = `type: ContentType.${member}`
|
|
78
|
+
if (/type:\s*ContentType\.\w+/.test(block)) return block.replace(/type:\s*ContentType\.\w+/, target)
|
|
79
|
+
if (/type:\s*"[^"]*"/.test(block)) return block.replace(/type:\s*"[^"]*"/, target)
|
|
80
|
+
if (/\n(\s*)format:/.test(block)) return block.replace(/\n(\s*)format:/, `\n$1${target},\n$1format:`)
|
|
81
|
+
return block.replace(/\n(\s*)\.\.\.params,/, `\n$1${target},\n$1...params,`)
|
|
82
|
+
}
|
|
32
83
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
/export enum ContentType\s*{([\s\S]*?)}/,
|
|
36
|
-
(match, enumBody) => {
|
|
84
|
+
function ensureJsonPatchEnum(content) {
|
|
85
|
+
return content.replace(/export enum ContentType\s*{([\s\S]*?)}/, (match, enumBody) => {
|
|
37
86
|
if (enumBody.includes('JsonPatch')) return match
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
)
|
|
87
|
+
return `export enum ContentType {\n JsonPatch = "application/json-patch+json",\n ${enumBody.trim()}\n}`
|
|
88
|
+
})
|
|
89
|
+
}
|
|
42
90
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
/export interface Operation\s*{([\s\S]*?)}/,
|
|
46
|
-
(match, body) => {
|
|
91
|
+
function relaxOperationValue(content) {
|
|
92
|
+
return content.replace(/export interface Operation\s*{([\s\S]*?)}/, (match, body) => {
|
|
47
93
|
const updated = body.replace(
|
|
48
94
|
/value\?:\s*object\s*\|?\s*null?;/,
|
|
49
95
|
'value?: string | number | boolean | null | object;'
|
|
50
96
|
)
|
|
51
97
|
return `export interface Operation {\n ${updated.trim()}\n}`
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const RN_FILE_MARKER = 'isReactNativeFile'
|
|
102
|
+
|
|
103
|
+
// swagger-typescript-api assumes a browser: it detects multipart file parts with
|
|
104
|
+
// `instanceof Blob || instanceof File`. React Native has neither in a usable form —
|
|
105
|
+
// a file there is a plain `{ uri, name, type }` object. Without this branch those
|
|
106
|
+
// objects fall through to `stringifyFormItem` and every upload from the mobile app
|
|
107
|
+
// goes out as the string "[object Object]".
|
|
108
|
+
//
|
|
109
|
+
// The React Native check runs first so the `instanceof` operands are never even
|
|
110
|
+
// evaluated on that path.
|
|
111
|
+
//
|
|
112
|
+
// The pattern is deliberately whitespace-tolerant instead of matching one exact
|
|
113
|
+
// line. As generated today that statement is exactly 80 characters wide, which is
|
|
114
|
+
// Prettier's default printWidth — so the moment the generator nests it one level
|
|
115
|
+
// deeper, or renames `formItem`, Prettier reflows it across two lines. Anchoring
|
|
116
|
+
// on the single-line form would then quietly stop matching.
|
|
117
|
+
const GENERATED_FILE_CHECK =
|
|
118
|
+
/^([ \t]*)const isFileType\s*=\s*formItem instanceof Blob\s*\|\|\s*formItem instanceof File;/m
|
|
119
|
+
|
|
120
|
+
function applyReactNativeFileSupport(content) {
|
|
121
|
+
if (content.includes(RN_FILE_MARKER)) return content
|
|
122
|
+
|
|
123
|
+
// Never fail open. A silent no-op here ships an SDK where every React Native
|
|
124
|
+
// upload is serialised as "[object Object]", with nothing in the build to
|
|
125
|
+
// suggest anything went wrong.
|
|
126
|
+
if (!GENERATED_FILE_CHECK.test(content)) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
'applyReactNativeFileSupport: could not find the generated `isFileType` check in ' +
|
|
129
|
+
'createFormData.\n' +
|
|
130
|
+
'swagger-typescript-api has most likely changed its output. Update ' +
|
|
131
|
+
'GENERATED_FILE_CHECK in this script — do not skip this step, or React Native ' +
|
|
132
|
+
'file uploads will break with no visible error.'
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return content.replace(
|
|
137
|
+
GENERATED_FILE_CHECK,
|
|
138
|
+
(match, indent) =>
|
|
139
|
+
[
|
|
140
|
+
`${indent}// React Native files are plain { uri, name, type } objects, not Blob/File.`,
|
|
141
|
+
`${indent}const ${RN_FILE_MARKER} =`,
|
|
142
|
+
`${indent} !!formItem &&`,
|
|
143
|
+
`${indent} typeof formItem === "object" &&`,
|
|
144
|
+
`${indent} "uri" in formItem &&`,
|
|
145
|
+
`${indent} "name" in formItem &&`,
|
|
146
|
+
`${indent} "type" in formItem;`,
|
|
147
|
+
`${indent}const isFileType =`,
|
|
148
|
+
`${indent} ${RN_FILE_MARKER} || formItem instanceof Blob || formItem instanceof File;`,
|
|
149
|
+
].join('\n')
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function applyContentTypes(content, patchPaths) {
|
|
154
|
+
// Heal any earlier double-application (ContentType.JsonPatchPatch...).
|
|
155
|
+
content = content.replace(/ContentType\.JsonPatch(?:Patch)+\b/g, 'ContentType.JsonPatch')
|
|
156
|
+
|
|
157
|
+
const METHOD_BLOCK = /[a-zA-Z0-9_]+:\s*\([\s\S]*?\)\s*=>\s*this\.request<[^>]*>\(\{[\s\S]*?\.\.\.params,/g
|
|
158
|
+
return content.replace(METHOD_BLOCK, (block) => {
|
|
159
|
+
if (!/method:\s*"PATCH"/.test(block)) {
|
|
160
|
+
// Non-PATCH methods must never be JSON Patch.
|
|
161
|
+
return /type:\s*ContentType\.JsonPatch\b/.test(block)
|
|
162
|
+
? block.replace(/type:\s*ContentType\.JsonPatch\b/, 'type: ContentType.Json')
|
|
163
|
+
: block
|
|
164
|
+
}
|
|
165
|
+
const routeMatch = block.match(/path:\s*`([^`]*)`/)
|
|
166
|
+
const route = routeMatch ? normalizePath(routeMatch[1]) : ''
|
|
167
|
+
return setContentType(block, patchPaths.has(route) ? 'JsonPatch' : 'Json')
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
;(async () => {
|
|
172
|
+
if (!fs.existsSync(SRC)) {
|
|
173
|
+
console.error(`Error: File not found at "${SRC}". Generate the SDK first.`)
|
|
174
|
+
process.exit(1)
|
|
52
175
|
}
|
|
53
|
-
)
|
|
54
176
|
|
|
55
|
-
|
|
56
|
-
|
|
177
|
+
const source = process.argv[2] || process.env.SWAGGER_SPEC || process.env.SWAGGER_URL
|
|
178
|
+
let spec
|
|
179
|
+
try {
|
|
180
|
+
spec = await loadSpec(source)
|
|
181
|
+
} catch (err) {
|
|
182
|
+
console.error(`Error loading OpenAPI spec: ${err.message}`)
|
|
183
|
+
process.exit(1)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
let content = fs.readFileSync(SRC, 'utf8')
|
|
187
|
+
content = ensureJsonPatchEnum(content)
|
|
188
|
+
content = relaxOperationValue(content)
|
|
189
|
+
content = applyReactNativeFileSupport(content)
|
|
190
|
+
|
|
191
|
+
if (!spec) {
|
|
192
|
+
console.warn(
|
|
193
|
+
'No OpenAPI spec provided (argument / SWAGGER_SPEC / SWAGGER_URL) — skipping PATCH content-type rewrite.\n' +
|
|
194
|
+
'Re-run with the spec used for generation to apply it, e.g.:\n' +
|
|
195
|
+
' node scripts/apply-json-patch-content-type.js https://api.thebigpos.dev/swagger/<version>/swagger.json'
|
|
196
|
+
)
|
|
197
|
+
fs.writeFileSync(SRC, content)
|
|
198
|
+
return
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const patchPaths = jsonPatchPaths(spec)
|
|
202
|
+
content = applyContentTypes(content, patchPaths)
|
|
203
|
+
|
|
204
|
+
fs.writeFileSync(SRC, content)
|
|
205
|
+
console.log(`SDK patch complete: PATCH content types set from the OpenAPI spec (${patchPaths.size} json-patch endpoint(s)).`)
|
|
206
|
+
})().catch((err) => {
|
|
207
|
+
console.error(err)
|
|
208
|
+
process.exit(1)
|
|
209
|
+
})
|
package/src/index.ts
CHANGED
|
@@ -851,8 +851,10 @@ export interface AdminAccessUser {
|
|
|
851
851
|
preferredLoanOfficer?: PreferredLoanOfficer | null;
|
|
852
852
|
loanIDs: string[];
|
|
853
853
|
drafts: Draft[];
|
|
854
|
+
inProgressLoans?: InProgressLoan[] | null;
|
|
854
855
|
notificationSettings?: UserNotificationSettings | null;
|
|
855
856
|
hasExtendedLoanVisibility: boolean;
|
|
857
|
+
applicationV3Enabled?: boolean | null;
|
|
856
858
|
/** @format uuid */
|
|
857
859
|
accountID?: string | null;
|
|
858
860
|
loans: UserLoan[];
|
|
@@ -1732,8 +1734,10 @@ export interface BranchUser {
|
|
|
1732
1734
|
preferredLoanOfficer?: PreferredLoanOfficer | null;
|
|
1733
1735
|
loanIDs: string[];
|
|
1734
1736
|
drafts: Draft[];
|
|
1737
|
+
inProgressLoans?: InProgressLoan[] | null;
|
|
1735
1738
|
notificationSettings?: UserNotificationSettings | null;
|
|
1736
1739
|
hasExtendedLoanVisibility: boolean;
|
|
1740
|
+
applicationV3Enabled?: boolean | null;
|
|
1737
1741
|
/** @format uuid */
|
|
1738
1742
|
branchID: string;
|
|
1739
1743
|
branchName: string;
|
|
@@ -2354,8 +2358,10 @@ export interface DetailedUser {
|
|
|
2354
2358
|
preferredLoanOfficer?: PreferredLoanOfficer | null;
|
|
2355
2359
|
loanIDs: string[];
|
|
2356
2360
|
drafts: Draft[];
|
|
2361
|
+
inProgressLoans?: InProgressLoan[] | null;
|
|
2357
2362
|
notificationSettings?: UserNotificationSettings | null;
|
|
2358
2363
|
hasExtendedLoanVisibility: boolean;
|
|
2364
|
+
applicationV3Enabled?: boolean | null;
|
|
2359
2365
|
}
|
|
2360
2366
|
|
|
2361
2367
|
export interface DocumentDataRequest {
|
|
@@ -3176,8 +3182,10 @@ export interface ImpersonatedDetailedUser {
|
|
|
3176
3182
|
preferredLoanOfficer?: PreferredLoanOfficer | null;
|
|
3177
3183
|
loanIDs: string[];
|
|
3178
3184
|
drafts: Draft[];
|
|
3185
|
+
inProgressLoans?: InProgressLoan[] | null;
|
|
3179
3186
|
notificationSettings?: UserNotificationSettings | null;
|
|
3180
3187
|
hasExtendedLoanVisibility: boolean;
|
|
3188
|
+
applicationV3Enabled?: boolean | null;
|
|
3181
3189
|
/** @deprecated */
|
|
3182
3190
|
impersonatedBy?: string | null;
|
|
3183
3191
|
impersonatingUser?: User | null;
|
|
@@ -3190,6 +3198,17 @@ export interface ImportUserLoanTaskRequest {
|
|
|
3190
3198
|
userID: string;
|
|
3191
3199
|
}
|
|
3192
3200
|
|
|
3201
|
+
export interface InProgressLoan {
|
|
3202
|
+
/** @format uuid */
|
|
3203
|
+
id: string;
|
|
3204
|
+
/** @format uuid */
|
|
3205
|
+
borrowerId: string;
|
|
3206
|
+
/** @format uuid */
|
|
3207
|
+
siteConfigurationId?: string | null;
|
|
3208
|
+
/** @format date-time */
|
|
3209
|
+
updatedAt?: string | null;
|
|
3210
|
+
}
|
|
3211
|
+
|
|
3193
3212
|
export interface IncompleteApplicationSummary {
|
|
3194
3213
|
/** @format int32 */
|
|
3195
3214
|
total: number;
|
|
@@ -3462,6 +3481,20 @@ export interface LoanApplicationRequest {
|
|
|
3462
3481
|
existingLoanId?: string | null;
|
|
3463
3482
|
}
|
|
3464
3483
|
|
|
3484
|
+
export interface LoanApplicationSession {
|
|
3485
|
+
routeName: string;
|
|
3486
|
+
currentQuestionId?: string | null;
|
|
3487
|
+
questionHistory: string[];
|
|
3488
|
+
/** @format date-time */
|
|
3489
|
+
completedAt?: string | null;
|
|
3490
|
+
}
|
|
3491
|
+
|
|
3492
|
+
export interface LoanApplicationSessionRequest {
|
|
3493
|
+
routeName: string;
|
|
3494
|
+
currentQuestionId?: string | null;
|
|
3495
|
+
questionHistory: string[];
|
|
3496
|
+
}
|
|
3497
|
+
|
|
3465
3498
|
export interface LoanBorrower {
|
|
3466
3499
|
/** @format uuid */
|
|
3467
3500
|
id: string;
|
|
@@ -5144,6 +5177,8 @@ export interface LoanTaskCounts {
|
|
|
5144
5177
|
completed: number;
|
|
5145
5178
|
/** @format int32 */
|
|
5146
5179
|
rejected: number;
|
|
5180
|
+
/** @format int32 */
|
|
5181
|
+
awaitingRegistration: number;
|
|
5147
5182
|
}
|
|
5148
5183
|
|
|
5149
5184
|
export interface LoanTaskSearchRequest {
|
|
@@ -8872,7 +8907,15 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
8872
8907
|
property instanceof Array ? property : [property];
|
|
8873
8908
|
|
|
8874
8909
|
for (const formItem of propertyContent) {
|
|
8875
|
-
|
|
8910
|
+
// React Native files are plain { uri, name, type } objects, not Blob/File.
|
|
8911
|
+
const isReactNativeFile =
|
|
8912
|
+
!!formItem &&
|
|
8913
|
+
typeof formItem === "object" &&
|
|
8914
|
+
"uri" in formItem &&
|
|
8915
|
+
"name" in formItem &&
|
|
8916
|
+
"type" in formItem;
|
|
8917
|
+
const isFileType =
|
|
8918
|
+
isReactNativeFile || formItem instanceof Blob || formItem instanceof File;
|
|
8876
8919
|
formData.append(
|
|
8877
8920
|
key,
|
|
8878
8921
|
isFileType ? formItem : this.stringifyFormItem(formItem),
|
|
@@ -8934,7 +8977,7 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
8934
8977
|
|
|
8935
8978
|
/**
|
|
8936
8979
|
* @title The Big POS API
|
|
8937
|
-
* @version v3.
|
|
8980
|
+
* @version v3.13.0
|
|
8938
8981
|
* @termsOfService https://www.thebigpos.com/terms-of-use/
|
|
8939
8982
|
* @contact Mortgage Automation Technologies <support@thebigpos.com> (https://www.thebigpos.com/terms-of-use/)
|
|
8940
8983
|
*/
|
|
@@ -15298,7 +15341,7 @@ export class Api<
|
|
|
15298
15341
|
}),
|
|
15299
15342
|
|
|
15300
15343
|
/**
|
|
15301
|
-
* @description Returns
|
|
15344
|
+
* @description Returns the folders the caller can access that are relevant to this loan — those holding a document the caller can read, plus those bound to one of the loan's tasks, even when empty — with the caller's effective accessLevel and the count of documents they can read in each. Upload destinations are the active entries with accessLevel at least Write. Documents that are not assigned to a folder are returned as a synthetic 'Unassigned' folder (ID = empty GUID, isUnassigned = true); filter to its documents with searchLoanDocuments folderScope 'Unassigned' rather than by echoing that ID.
|
|
15302
15345
|
*
|
|
15303
15346
|
* @tags LoanDocumentFoldersForSingleLoan
|
|
15304
15347
|
* @name ListLoanDocumentFolders
|
|
@@ -16481,7 +16524,7 @@ export class Api<
|
|
|
16481
16524
|
}),
|
|
16482
16525
|
|
|
16483
16526
|
/**
|
|
16484
|
-
* @description Queues an account template against a borrower slot that has no registered user yet. The row owns a per-loan copy of the template, so editing it never changes the account's catalogue. An optional due date is stored on the row; without one the row has none.
|
|
16527
|
+
* @description Queues an account template against a borrower slot that has no registered user yet. The row owns a per-loan copy of the template, so editing it never changes the account's catalogue. An optional due date is stored on the row; without one the row has none. A template already queued for the slot is refused; one staff removed earlier can be queued again this way.
|
|
16485
16528
|
*
|
|
16486
16529
|
* @tags LoanRoleTasks
|
|
16487
16530
|
* @name CreateLoanRoleTask
|
|
@@ -16681,11 +16724,19 @@ export class Api<
|
|
|
16681
16724
|
* @response `400` `any` Bad Request
|
|
16682
16725
|
* @response `401` `ProblemDetails` Unauthorized
|
|
16683
16726
|
* @response `403` `ProblemDetails` Forbidden
|
|
16727
|
+
* @response `404` `ProblemDetails` Not Found
|
|
16684
16728
|
*/
|
|
16685
|
-
createLoanv3: (
|
|
16729
|
+
createLoanv3: (
|
|
16730
|
+
data: LoanApplicationRequest,
|
|
16731
|
+
query?: {
|
|
16732
|
+
application?: string;
|
|
16733
|
+
},
|
|
16734
|
+
params: RequestParams = {},
|
|
16735
|
+
) =>
|
|
16686
16736
|
this.request<LoanApplication, ProblemDetails>({
|
|
16687
16737
|
path: `/api/loans`,
|
|
16688
16738
|
method: "POST",
|
|
16739
|
+
query: query,
|
|
16689
16740
|
body: data,
|
|
16690
16741
|
secure: true,
|
|
16691
16742
|
type: "application/json",
|
|
@@ -16769,13 +16820,14 @@ export class Api<
|
|
|
16769
16820
|
* @response `400` `ProblemDetails` Bad Request
|
|
16770
16821
|
* @response `404` `ProblemDetails` Not Found
|
|
16771
16822
|
* @response `409` `ProblemDetails` Conflict
|
|
16823
|
+
* @response `422` `UnprocessableEntity` Unprocessable Content
|
|
16772
16824
|
*/
|
|
16773
16825
|
completeBorrowerApplication: (
|
|
16774
16826
|
loanId: string,
|
|
16775
16827
|
borrowerId: string,
|
|
16776
16828
|
params: RequestParams = {},
|
|
16777
16829
|
) =>
|
|
16778
|
-
this.request<void, ProblemDetails>({
|
|
16830
|
+
this.request<void, ProblemDetails | UnprocessableEntity>({
|
|
16779
16831
|
path: `/api/loans/${loanId}/borrowers/${borrowerId}/complete`,
|
|
16780
16832
|
method: "POST",
|
|
16781
16833
|
secure: true,
|
|
@@ -16793,6 +16845,7 @@ export class Api<
|
|
|
16793
16845
|
* @response `200` `LoanBorrowerSsn` OK
|
|
16794
16846
|
* @response `403` `ProblemDetails` Forbidden
|
|
16795
16847
|
* @response `404` `ProblemDetails` Not Found
|
|
16848
|
+
* @response `429` `ProblemDetails` Too Many Requests
|
|
16796
16849
|
*/
|
|
16797
16850
|
getLoanBorrowerSsn: (
|
|
16798
16851
|
loanId: string,
|
|
@@ -16807,6 +16860,63 @@ export class Api<
|
|
|
16807
16860
|
...params,
|
|
16808
16861
|
}),
|
|
16809
16862
|
|
|
16863
|
+
/**
|
|
16864
|
+
* No description
|
|
16865
|
+
*
|
|
16866
|
+
* @tags Loans
|
|
16867
|
+
* @name GetBorrowerApplicationSession
|
|
16868
|
+
* @summary Get borrower application session
|
|
16869
|
+
* @request GET:/api/loans/{loanId}/borrowers/{borrowerId}/application-session
|
|
16870
|
+
* @secure
|
|
16871
|
+
* @response `200` `LoanApplicationSession` OK
|
|
16872
|
+
* @response `400` `any` Bad Request
|
|
16873
|
+
* @response `401` `ProblemDetails` Unauthorized
|
|
16874
|
+
* @response `403` `ProblemDetails` Forbidden
|
|
16875
|
+
* @response `404` `ProblemDetails` Not Found
|
|
16876
|
+
*/
|
|
16877
|
+
getBorrowerApplicationSession: (
|
|
16878
|
+
loanId: string,
|
|
16879
|
+
borrowerId: string,
|
|
16880
|
+
params: RequestParams = {},
|
|
16881
|
+
) =>
|
|
16882
|
+
this.request<LoanApplicationSession, ProblemDetails>({
|
|
16883
|
+
path: `/api/loans/${loanId}/borrowers/${borrowerId}/application-session`,
|
|
16884
|
+
method: "GET",
|
|
16885
|
+
secure: true,
|
|
16886
|
+
format: "json",
|
|
16887
|
+
...params,
|
|
16888
|
+
}),
|
|
16889
|
+
|
|
16890
|
+
/**
|
|
16891
|
+
* No description
|
|
16892
|
+
*
|
|
16893
|
+
* @tags Loans
|
|
16894
|
+
* @name UpdateBorrowerApplicationSession
|
|
16895
|
+
* @summary Update borrower application session
|
|
16896
|
+
* @request PUT:/api/loans/{loanId}/borrowers/{borrowerId}/application-session
|
|
16897
|
+
* @secure
|
|
16898
|
+
* @response `200` `LoanApplicationSession` OK
|
|
16899
|
+
* @response `400` `any` Bad Request
|
|
16900
|
+
* @response `401` `ProblemDetails` Unauthorized
|
|
16901
|
+
* @response `403` `ProblemDetails` Forbidden
|
|
16902
|
+
* @response `404` `ProblemDetails` Not Found
|
|
16903
|
+
*/
|
|
16904
|
+
updateBorrowerApplicationSession: (
|
|
16905
|
+
loanId: string,
|
|
16906
|
+
borrowerId: string,
|
|
16907
|
+
data: LoanApplicationSessionRequest,
|
|
16908
|
+
params: RequestParams = {},
|
|
16909
|
+
) =>
|
|
16910
|
+
this.request<LoanApplicationSession, ProblemDetails>({
|
|
16911
|
+
path: `/api/loans/${loanId}/borrowers/${borrowerId}/application-session`,
|
|
16912
|
+
method: "PUT",
|
|
16913
|
+
body: data,
|
|
16914
|
+
secure: true,
|
|
16915
|
+
type: "application/json",
|
|
16916
|
+
format: "json",
|
|
16917
|
+
...params,
|
|
16918
|
+
}),
|
|
16919
|
+
|
|
16810
16920
|
/**
|
|
16811
16921
|
* No description
|
|
16812
16922
|
*
|