@matech/thebigpos-sdk 3.5.0-stag-2100 → 3.5.1-dev-2413
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 +23 -5
- package/dist/index.js +17 -6
- package/dist/index.js.map +1 -1
- package/docs/sdk_generation.md +149 -0
- package/package.json +15 -5
- package/scripts/apply-json-patch-content-type.js +189 -36
- package/src/index.ts +39 -11
|
@@ -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.5.
|
|
3
|
+
"version": "3.5.1-dev-2413",
|
|
4
4
|
"description": "The Big POS Typescript SDK",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,14 +26,24 @@
|
|
|
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"
|
|
42
|
+
},
|
|
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"
|
|
38
48
|
}
|
|
39
49
|
}
|
|
@@ -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
|
@@ -402,6 +402,8 @@ export type LoanDocumentType =
|
|
|
402
402
|
| "AiGeneratedDocument"
|
|
403
403
|
| "Unidentified";
|
|
404
404
|
|
|
405
|
+
export type LoanDocumentFolderScope = "Any" | "Assigned" | "Unassigned";
|
|
406
|
+
|
|
405
407
|
export type LoanDocumentFolderPermissionLevel =
|
|
406
408
|
| "None"
|
|
407
409
|
| "Read"
|
|
@@ -3139,6 +3141,13 @@ export interface GuidPatchOperation {
|
|
|
3139
3141
|
from?: string | null;
|
|
3140
3142
|
}
|
|
3141
3143
|
|
|
3144
|
+
export interface HttpError {
|
|
3145
|
+
logId?: string | null;
|
|
3146
|
+
message?: string | null;
|
|
3147
|
+
errorCode?: string | null;
|
|
3148
|
+
errors?: string[] | null;
|
|
3149
|
+
}
|
|
3150
|
+
|
|
3142
3151
|
export interface IPAddress {
|
|
3143
3152
|
addressFamily: IpAddressAddressFamilyEnum;
|
|
3144
3153
|
/** @format int64 */
|
|
@@ -3762,6 +3771,8 @@ export interface LoanBorrowerEmploymentCurrentGrossIncome {
|
|
|
3762
3771
|
/** @format double */
|
|
3763
3772
|
hourlyRate?: number | null;
|
|
3764
3773
|
/** @format double */
|
|
3774
|
+
annualBasePay?: number | null;
|
|
3775
|
+
/** @format double */
|
|
3765
3776
|
other?: number | null;
|
|
3766
3777
|
/** @format double */
|
|
3767
3778
|
bonus?: number | null;
|
|
@@ -4361,6 +4372,8 @@ export interface LoanDocument {
|
|
|
4361
4372
|
losStatus: string;
|
|
4362
4373
|
contents?: string | null;
|
|
4363
4374
|
failoverDocumentPath?: string | null;
|
|
4375
|
+
/** @format int64 */
|
|
4376
|
+
fileSizeBytes?: number | null;
|
|
4364
4377
|
/** @format date-time */
|
|
4365
4378
|
sensitiveDataPurgedOn?: string | null;
|
|
4366
4379
|
observedDocumentType?: LoanDocumentType | null;
|
|
@@ -4437,6 +4450,7 @@ export interface LoanDocumentFolderWithCount {
|
|
|
4437
4450
|
isActive: boolean;
|
|
4438
4451
|
/** @format int32 */
|
|
4439
4452
|
documentCount: number;
|
|
4453
|
+
isUnassigned: boolean;
|
|
4440
4454
|
}
|
|
4441
4455
|
|
|
4442
4456
|
export interface LoanDocumentPreviewsRequest {
|
|
@@ -4477,6 +4491,7 @@ export interface LoanDocumentSearchCriteria {
|
|
|
4477
4491
|
bucket?: string | null;
|
|
4478
4492
|
/** @format uuid */
|
|
4479
4493
|
folderID?: string | null;
|
|
4494
|
+
folderScope?: LoanDocumentFolderScope | null;
|
|
4480
4495
|
/** @format uuid */
|
|
4481
4496
|
userID?: string | null;
|
|
4482
4497
|
documentIDs?: string[] | null;
|
|
@@ -8580,7 +8595,15 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
8580
8595
|
property instanceof Array ? property : [property];
|
|
8581
8596
|
|
|
8582
8597
|
for (const formItem of propertyContent) {
|
|
8583
|
-
|
|
8598
|
+
// React Native files are plain { uri, name, type } objects, not Blob/File.
|
|
8599
|
+
const isReactNativeFile =
|
|
8600
|
+
!!formItem &&
|
|
8601
|
+
typeof formItem === "object" &&
|
|
8602
|
+
"uri" in formItem &&
|
|
8603
|
+
"name" in formItem &&
|
|
8604
|
+
"type" in formItem;
|
|
8605
|
+
const isFileType =
|
|
8606
|
+
isReactNativeFile || formItem instanceof Blob || formItem instanceof File;
|
|
8584
8607
|
formData.append(
|
|
8585
8608
|
key,
|
|
8586
8609
|
isFileType ? formItem : this.stringifyFormItem(formItem),
|
|
@@ -8642,7 +8665,7 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
8642
8665
|
|
|
8643
8666
|
/**
|
|
8644
8667
|
* @title The Big POS API
|
|
8645
|
-
* @version v3.5.
|
|
8668
|
+
* @version v3.5.1
|
|
8646
8669
|
* @termsOfService https://www.thebigpos.com/terms-of-use/
|
|
8647
8670
|
* @contact Mortgage Automation Technologies <support@thebigpos.com> (https://www.thebigpos.com/terms-of-use/)
|
|
8648
8671
|
*/
|
|
@@ -14388,10 +14411,11 @@ export class Api<
|
|
|
14388
14411
|
* @request POST:/api/listings
|
|
14389
14412
|
* @secure
|
|
14390
14413
|
* @response `201` `Listing` Created
|
|
14391
|
-
* @response `
|
|
14414
|
+
* @response `401` `HttpError` Unauthorized
|
|
14415
|
+
* @response `403` `HttpError` Forbidden
|
|
14392
14416
|
*/
|
|
14393
14417
|
createListing: (data: ListingRequest, params: RequestParams = {}) =>
|
|
14394
|
-
this.request<Listing,
|
|
14418
|
+
this.request<Listing, HttpError>({
|
|
14395
14419
|
path: `/api/listings`,
|
|
14396
14420
|
method: "POST",
|
|
14397
14421
|
body: data,
|
|
@@ -14448,14 +14472,15 @@ export class Api<
|
|
|
14448
14472
|
* @request PUT:/api/listings/{id}
|
|
14449
14473
|
* @secure
|
|
14450
14474
|
* @response `200` `Listing` OK
|
|
14451
|
-
* @response `
|
|
14475
|
+
* @response `401` `HttpError` Unauthorized
|
|
14476
|
+
* @response `403` `HttpError` Forbidden
|
|
14452
14477
|
*/
|
|
14453
14478
|
replaceListing: (
|
|
14454
14479
|
id: string,
|
|
14455
14480
|
data: ListingRequest,
|
|
14456
14481
|
params: RequestParams = {},
|
|
14457
14482
|
) =>
|
|
14458
|
-
this.request<Listing,
|
|
14483
|
+
this.request<Listing, HttpError>({
|
|
14459
14484
|
path: `/api/listings/${id}`,
|
|
14460
14485
|
method: "PUT",
|
|
14461
14486
|
body: data,
|
|
@@ -15046,7 +15071,7 @@ export class Api<
|
|
|
15046
15071
|
}),
|
|
15047
15072
|
|
|
15048
15073
|
/**
|
|
15049
|
-
* @description Returns each folder that holds at least one document the caller can read, with the document count per folder. Documents that are not assigned to a folder are returned as a synthetic 'Unassigned' folder (ID = empty GUID).
|
|
15074
|
+
* @description Returns each folder that holds at least one document the caller can read, with the document count per folder. 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.
|
|
15050
15075
|
*
|
|
15051
15076
|
* @tags LoanDocumentFoldersForSingleLoan
|
|
15052
15077
|
* @name ListLoanDocumentFolders
|
|
@@ -15151,7 +15176,7 @@ export class Api<
|
|
|
15151
15176
|
}),
|
|
15152
15177
|
|
|
15153
15178
|
/**
|
|
15154
|
-
*
|
|
15179
|
+
* @description Filters the loan's readable documents. Pass folderID to filter to one folder, or folderScope 'Unassigned' for the documents that have no folder (the synthetic folder listLoanDocumentFolders reports with isUnassigned true); the two cannot be combined.
|
|
15155
15180
|
*
|
|
15156
15181
|
* @tags LoanDocuments
|
|
15157
15182
|
* @name SearchLoanDocuments
|
|
@@ -15159,6 +15184,7 @@ export class Api<
|
|
|
15159
15184
|
* @request POST:/api/loans/{loanId}/documents/search
|
|
15160
15185
|
* @secure
|
|
15161
15186
|
* @response `200` `LoanDocumentSearchPaginated` OK
|
|
15187
|
+
* @response `422` `UnprocessableEntity` Unprocessable Content
|
|
15162
15188
|
*/
|
|
15163
15189
|
searchLoanDocuments: (
|
|
15164
15190
|
loanId: string,
|
|
@@ -15173,7 +15199,7 @@ export class Api<
|
|
|
15173
15199
|
},
|
|
15174
15200
|
params: RequestParams = {},
|
|
15175
15201
|
) =>
|
|
15176
|
-
this.request<LoanDocumentSearchPaginated,
|
|
15202
|
+
this.request<LoanDocumentSearchPaginated, UnprocessableEntity>({
|
|
15177
15203
|
path: `/api/loans/${loanId}/documents/search`,
|
|
15178
15204
|
method: "POST",
|
|
15179
15205
|
query: query,
|
|
@@ -16462,6 +16488,7 @@ export class Api<
|
|
|
16462
16488
|
* @secure
|
|
16463
16489
|
* @response `201` `TaskComment` Created
|
|
16464
16490
|
* @response `404` `ProblemDetails` Not Found
|
|
16491
|
+
* @response `422` `UnprocessableEntity` Unprocessable Content
|
|
16465
16492
|
*/
|
|
16466
16493
|
createLoanTaskComment: (
|
|
16467
16494
|
loanId: string,
|
|
@@ -16469,7 +16496,7 @@ export class Api<
|
|
|
16469
16496
|
data: TaskCommentRequest,
|
|
16470
16497
|
params: RequestParams = {},
|
|
16471
16498
|
) =>
|
|
16472
|
-
this.request<TaskComment, ProblemDetails>({
|
|
16499
|
+
this.request<TaskComment, ProblemDetails | UnprocessableEntity>({
|
|
16473
16500
|
path: `/api/loans/${loanId}/tasks/${userLoanTaskId}/comments`,
|
|
16474
16501
|
method: "POST",
|
|
16475
16502
|
body: data,
|
|
@@ -16489,6 +16516,7 @@ export class Api<
|
|
|
16489
16516
|
* @secure
|
|
16490
16517
|
* @response `200` `TaskComment` OK
|
|
16491
16518
|
* @response `404` `ProblemDetails` Not Found
|
|
16519
|
+
* @response `422` `UnprocessableEntity` Unprocessable Content
|
|
16492
16520
|
*/
|
|
16493
16521
|
replaceLoanTaskComment: (
|
|
16494
16522
|
loanId: string,
|
|
@@ -16497,7 +16525,7 @@ export class Api<
|
|
|
16497
16525
|
data: TaskCommentRequest,
|
|
16498
16526
|
params: RequestParams = {},
|
|
16499
16527
|
) =>
|
|
16500
|
-
this.request<TaskComment, ProblemDetails>({
|
|
16528
|
+
this.request<TaskComment, ProblemDetails | UnprocessableEntity>({
|
|
16501
16529
|
path: `/api/loans/${loanId}/tasks/${userLoanTaskId}/comments/${commentId}`,
|
|
16502
16530
|
method: "PUT",
|
|
16503
16531
|
body: data,
|