@matech/thebigpos-sdk 3.8.0-stag-3544 → 3.9.0-dev-3835
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 +38 -8
- package/dist/index.js +25 -5
- 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 +64 -9
|
@@ -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.9.0-dev-3835",
|
|
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
|
@@ -2150,6 +2150,8 @@ export interface CreateLoanRoleTaskRequest {
|
|
|
2150
2150
|
borrowerPair: number;
|
|
2151
2151
|
/** @format int32 */
|
|
2152
2152
|
borrowerPosition: number;
|
|
2153
|
+
/** @format date */
|
|
2154
|
+
dueDate?: string | null;
|
|
2153
2155
|
}
|
|
2154
2156
|
|
|
2155
2157
|
export interface CreateSession {
|
|
@@ -2866,8 +2868,6 @@ export interface File {
|
|
|
2866
2868
|
fileName: string;
|
|
2867
2869
|
name: string;
|
|
2868
2870
|
s3FilePath: string;
|
|
2869
|
-
user?: User | null;
|
|
2870
|
-
account?: Account | null;
|
|
2871
2871
|
url: string;
|
|
2872
2872
|
}
|
|
2873
2873
|
|
|
@@ -3290,7 +3290,6 @@ export interface Invite {
|
|
|
3290
3290
|
/** @format date-time */
|
|
3291
3291
|
expiresAt?: string | null;
|
|
3292
3292
|
status: string;
|
|
3293
|
-
invitedBy?: User | null;
|
|
3294
3293
|
loan: LoanIdentifier;
|
|
3295
3294
|
url: string;
|
|
3296
3295
|
}
|
|
@@ -4421,7 +4420,7 @@ export interface LoanDocument {
|
|
|
4421
4420
|
/** @format uuid */
|
|
4422
4421
|
id: string;
|
|
4423
4422
|
name: string;
|
|
4424
|
-
loan:
|
|
4423
|
+
loan: LoanIdentifier;
|
|
4425
4424
|
user?: UserSummary | null;
|
|
4426
4425
|
/** @deprecated */
|
|
4427
4426
|
initialBucket?: string | null;
|
|
@@ -4598,6 +4597,7 @@ export interface LoanFinancialRequest {
|
|
|
4598
4597
|
cashToClose?: number | null;
|
|
4599
4598
|
/** @format double */
|
|
4600
4599
|
cashDownPayment?: number | null;
|
|
4600
|
+
downPaymentPercent?: string | null;
|
|
4601
4601
|
/** @format double */
|
|
4602
4602
|
maximumPurchasePrice?: number | null;
|
|
4603
4603
|
isDownPaymentGift?: boolean | null;
|
|
@@ -5041,6 +5041,7 @@ export interface LoanRecommendation {
|
|
|
5041
5041
|
canonicalName: string;
|
|
5042
5042
|
displayName: string;
|
|
5043
5043
|
extractedValue: string;
|
|
5044
|
+
mintable: boolean;
|
|
5044
5045
|
currentLoanValue?: any | null;
|
|
5045
5046
|
/** @format uuid */
|
|
5046
5047
|
sourceDocumentId: string;
|
|
@@ -5072,6 +5073,8 @@ export interface LoanRefinance {
|
|
|
5072
5073
|
existingLiens?: number | null;
|
|
5073
5074
|
/** @format double */
|
|
5074
5075
|
costOfImprovements?: number | null;
|
|
5076
|
+
/** @format double */
|
|
5077
|
+
cashOutAmount?: number | null;
|
|
5075
5078
|
purpose?: LoanRefinancePurpose | null;
|
|
5076
5079
|
currentLoan?: LoanRefinanceCurrentLoan | null;
|
|
5077
5080
|
}
|
|
@@ -5104,6 +5107,8 @@ export interface LoanRefinanceRequest {
|
|
|
5104
5107
|
/** @format int32 */
|
|
5105
5108
|
yearAcquired?: number | null;
|
|
5106
5109
|
purpose?: LoanRefinancePurpose | null;
|
|
5110
|
+
/** @format double */
|
|
5111
|
+
cashOutAmount?: number | null;
|
|
5107
5112
|
currentLoan?: LoanRefinanceCurrentLoanRequest | null;
|
|
5108
5113
|
}
|
|
5109
5114
|
|
|
@@ -5560,6 +5565,15 @@ export interface MilestoneConfigurationRequest {
|
|
|
5560
5565
|
notificationsEnabled: boolean;
|
|
5561
5566
|
}
|
|
5562
5567
|
|
|
5568
|
+
export interface MintedProposal {
|
|
5569
|
+
/** @format uuid */
|
|
5570
|
+
id: string;
|
|
5571
|
+
/** @format date-time */
|
|
5572
|
+
expiresAt: string;
|
|
5573
|
+
columns: string[];
|
|
5574
|
+
rows: string[][];
|
|
5575
|
+
}
|
|
5576
|
+
|
|
5563
5577
|
export interface MobileAppReviewSeed {
|
|
5564
5578
|
/** @format uuid */
|
|
5565
5579
|
userID: string;
|
|
@@ -8883,7 +8897,15 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
8883
8897
|
property instanceof Array ? property : [property];
|
|
8884
8898
|
|
|
8885
8899
|
for (const formItem of propertyContent) {
|
|
8886
|
-
|
|
8900
|
+
// React Native files are plain { uri, name, type } objects, not Blob/File.
|
|
8901
|
+
const isReactNativeFile =
|
|
8902
|
+
!!formItem &&
|
|
8903
|
+
typeof formItem === "object" &&
|
|
8904
|
+
"uri" in formItem &&
|
|
8905
|
+
"name" in formItem &&
|
|
8906
|
+
"type" in formItem;
|
|
8907
|
+
const isFileType =
|
|
8908
|
+
isReactNativeFile || formItem instanceof Blob || formItem instanceof File;
|
|
8887
8909
|
formData.append(
|
|
8888
8910
|
key,
|
|
8889
8911
|
isFileType ? formItem : this.stringifyFormItem(formItem),
|
|
@@ -8945,7 +8967,7 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
8945
8967
|
|
|
8946
8968
|
/**
|
|
8947
8969
|
* @title The Big POS API
|
|
8948
|
-
* @version v3.
|
|
8970
|
+
* @version v3.9.0
|
|
8949
8971
|
* @termsOfService https://www.thebigpos.com/terms-of-use/
|
|
8950
8972
|
* @contact Mortgage Automation Technologies <support@thebigpos.com> (https://www.thebigpos.com/terms-of-use/)
|
|
8951
8973
|
*/
|
|
@@ -11115,16 +11137,23 @@ export class Api<
|
|
|
11115
11137
|
*
|
|
11116
11138
|
* @tags Authentication
|
|
11117
11139
|
* @name LogOut
|
|
11118
|
-
* @summary Sign out (clear auth cookies)
|
|
11140
|
+
* @summary Sign out (revoke the session and clear auth cookies)
|
|
11119
11141
|
* @request POST:/api/logout
|
|
11120
11142
|
* @secure
|
|
11121
11143
|
* @response `204` `NoContentResult` No Content
|
|
11122
11144
|
* @response `422` `UnprocessableEntity` Unprocessable Content
|
|
11123
11145
|
*/
|
|
11124
|
-
logOut: (
|
|
11146
|
+
logOut: (
|
|
11147
|
+
query?: {
|
|
11148
|
+
/** @default true */
|
|
11149
|
+
revokeSessions?: boolean;
|
|
11150
|
+
},
|
|
11151
|
+
params: RequestParams = {},
|
|
11152
|
+
) =>
|
|
11125
11153
|
this.request<NoContentResult, UnprocessableEntity>({
|
|
11126
11154
|
path: `/api/logout`,
|
|
11127
11155
|
method: "POST",
|
|
11156
|
+
query: query,
|
|
11128
11157
|
secure: true,
|
|
11129
11158
|
format: "json",
|
|
11130
11159
|
...params,
|
|
@@ -16487,6 +16516,32 @@ export class Api<
|
|
|
16487
16516
|
...params,
|
|
16488
16517
|
}),
|
|
16489
16518
|
|
|
16519
|
+
/**
|
|
16520
|
+
* No description
|
|
16521
|
+
*
|
|
16522
|
+
* @tags LoanRecommendations
|
|
16523
|
+
* @name MintLoanRecommendationProposal
|
|
16524
|
+
* @summary Mint a confirmable pending update from a recommendation
|
|
16525
|
+
* @request POST:/api/loans/{loanId}/recommendations/{id}/proposals
|
|
16526
|
+
* @secure
|
|
16527
|
+
* @response `200` `MintedProposal` OK
|
|
16528
|
+
* @response `400` `ProblemDetails` Bad Request
|
|
16529
|
+
* @response `404` `ProblemDetails` Not Found
|
|
16530
|
+
* @response `409` `ProblemDetails` Conflict
|
|
16531
|
+
*/
|
|
16532
|
+
mintLoanRecommendationProposal: (
|
|
16533
|
+
loanId: string,
|
|
16534
|
+
id: string,
|
|
16535
|
+
params: RequestParams = {},
|
|
16536
|
+
) =>
|
|
16537
|
+
this.request<MintedProposal, ProblemDetails>({
|
|
16538
|
+
path: `/api/loans/${loanId}/recommendations/${id}/proposals`,
|
|
16539
|
+
method: "POST",
|
|
16540
|
+
secure: true,
|
|
16541
|
+
format: "json",
|
|
16542
|
+
...params,
|
|
16543
|
+
}),
|
|
16544
|
+
|
|
16490
16545
|
/**
|
|
16491
16546
|
* No description
|
|
16492
16547
|
*
|
|
@@ -16508,7 +16563,7 @@ export class Api<
|
|
|
16508
16563
|
}),
|
|
16509
16564
|
|
|
16510
16565
|
/**
|
|
16511
|
-
* @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.
|
|
16566
|
+
* @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.
|
|
16512
16567
|
*
|
|
16513
16568
|
* @tags LoanRoleTasks
|
|
16514
16569
|
* @name CreateLoanRoleTask
|