swaggie 1.9.0 → 2.0.1
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 +117 -31
- package/dist/browser.js +24 -5
- package/dist/cli.js +54 -7
- package/dist/gen/genMocks.js +470 -0
- package/dist/gen/genOperations.js +112 -20
- package/dist/gen/genTypes.js +6 -5
- package/dist/gen/header.js +0 -1
- package/dist/gen/index.js +14 -1
- package/dist/generated/bundledTemplates.js +17 -19
- package/dist/index.js +17 -1
- package/dist/swagger/operations.js +16 -7
- package/dist/swagger/typesExtractor.js +12 -11
- package/dist/types.d.ts +55 -5
- package/dist/utils/documentLoader.js +1 -3
- package/dist/utils/fileUtils.js +22 -0
- package/dist/utils/refResolver.js +9 -21
- package/dist/utils/templateEngine.js +18 -0
- package/dist/utils/templateManager.js +123 -14
- package/dist/utils/templateValidator.js +127 -0
- package/dist/utils/utils.js +19 -13
- package/package.json +5 -4
- package/templates/axios/operation.ejs +25 -21
- package/templates/fetch/operation.ejs +4 -0
- package/templates/ng1/operation.ejs +11 -3
- package/templates/ng2/baseClient.ejs +9 -49
- package/templates/ng2/client.ejs +3 -7
- package/templates/ng2/operation.ejs +34 -17
- package/templates/swr/baseClient.ejs +7 -0
- package/templates/swr/client.ejs +63 -0
- package/templates/swr/swrMutationOperation.ejs +32 -0
- package/templates/swr/swrOperation.ejs +18 -0
- package/templates/tsq/baseClient.ejs +1 -0
- package/templates/tsq/client.ejs +67 -0
- package/templates/tsq/mutationOperation.ejs +31 -0
- package/templates/tsq/queryOperation.ejs +19 -0
- package/templates/xior/operation.ejs +25 -21
- package/templates/swr-axios/barrel.ejs +0 -58
- package/templates/swr-axios/baseClient.ejs +0 -20
- package/templates/swr-axios/client.ejs +0 -21
- package/templates/swr-axios/operation.ejs +0 -40
- package/templates/swr-axios/swrOperation.ejs +0 -50
- package/templates/tsq-xior/barrel.ejs +0 -0
- package/templates/tsq-xior/baseClient.ejs +0 -14
- package/templates/tsq-xior/client.ejs +0 -22
- package/templates/tsq-xior/operation.ejs +0 -40
- package/templates/tsq-xior/queryOperation.ejs +0 -30
package/README.md
CHANGED
|
@@ -21,13 +21,15 @@ See the [Example section](#example) for a quick demo, or visit the full document
|
|
|
21
21
|
## Features
|
|
22
22
|
|
|
23
23
|
- Generates TypeScript code from OpenAPI 3.0, 3.1, and 3.2 specs
|
|
24
|
-
- Supports multiple HTTP client libraries out of the box: `fetch`, `axios`, `xior`, `
|
|
24
|
+
- Supports multiple HTTP client libraries out of the box: `fetch`, `axios`, `xior`, `Angular 1`, `Angular 2+`; with optional reactive layers (`swr`, `tsq`) that compose with any compatible HTTP client
|
|
25
|
+
- **Auto-generated mock/stub files** for Vitest and Jest — typed spies for every client method and hook, with ergonomic helpers like `mockSWR()` and `mockQuery()`
|
|
25
26
|
- Custom templates — bring your own to fit your existing codebase
|
|
26
27
|
- Supports `allOf`, `oneOf`, `anyOf`, `$ref`, nullable types, and various enum definitions
|
|
27
28
|
- Handles multiple content types: JSON, plain text, multipart/form-data, URL-encoded, and binary
|
|
28
29
|
- JSDoc comments on all generated functions
|
|
29
30
|
- Generates a single, small, tree-shakable output file
|
|
30
31
|
- Dev-only dependency — zero runtime overhead
|
|
32
|
+
- Ability to generate automatic client mocks for `vitest` and `jest`
|
|
31
33
|
|
|
32
34
|
---
|
|
33
35
|
|
|
@@ -72,24 +74,27 @@ swaggie -s https://petstore3.swagger.io/api/v3/openapi.json -o ./client/petstore
|
|
|
72
74
|
**Available options:**
|
|
73
75
|
|
|
74
76
|
```
|
|
75
|
-
-V, --version
|
|
76
|
-
-c, --config <path>
|
|
77
|
-
-s, --src <url|path>
|
|
78
|
-
-o, --out <filePath>
|
|
79
|
-
-b, --baseUrl <string>
|
|
80
|
-
-t, --template <string>
|
|
81
|
-
-m, --mode <mode>
|
|
82
|
-
-d, --schemaStyle <style>
|
|
83
|
-
--enumStyle <style>
|
|
84
|
-
--enumNamesStyle <s>
|
|
85
|
-
--dateFormat <format>
|
|
86
|
-
--nullables <strategy>
|
|
87
|
-
--preferAny
|
|
88
|
-
--skipDeprecated
|
|
89
|
-
--servicePrefix
|
|
90
|
-
--allowDots
|
|
91
|
-
--arrayFormat
|
|
92
|
-
-
|
|
77
|
+
-V, --version Output the version number
|
|
78
|
+
-c, --config <path> Path to a JSON configuration file
|
|
79
|
+
-s, --src <url|path> URL or file path to the OpenAPI spec
|
|
80
|
+
-o, --out <filePath> Output file path (omit to print to stdout)
|
|
81
|
+
-b, --baseUrl <string> Base URL that will be used as a default value in the clients
|
|
82
|
+
-t, --template <string> Template to use. Single name: "axios", "fetch", "xior", "ng1", "ng2", "swr", "tsq". Reactive pair: "swr,axios" / "tsq,xior" / etc. (default: "axios")
|
|
83
|
+
-m, --mode <mode> Generation mode: "full" or "schemas" (default: "full")
|
|
84
|
+
-d, --schemaStyle <style> Schema object style: "interface" or "type" (default: "interface")
|
|
85
|
+
--enumStyle <style> Enum style for plain string enums: "union" or "enum" (default: "union")
|
|
86
|
+
--enumNamesStyle <s> Enum member name casing: "original" or "PascalCase" (default: "original")
|
|
87
|
+
--dateFormat <format> How date fields are emitted in generated types
|
|
88
|
+
--nullables <strategy> Nullable handling: "include", "nullableAsOptional", or "ignore"
|
|
89
|
+
--preferAny Use "any" instead of "unknown" for untyped values (default: false)
|
|
90
|
+
--skipDeprecated Exclude deprecated operations from the output (default: false)
|
|
91
|
+
--servicePrefix Prefix for service names — useful when generating multiple APIs
|
|
92
|
+
--allowDots Use dot notation to serialize nested object query params
|
|
93
|
+
--arrayFormat How arrays are serialized: "indices", "repeat", or "brackets"
|
|
94
|
+
-C, --useClient Prepend 'use client'; directive (Next.js App Router + SWR/TSQ)
|
|
95
|
+
--mocks <path> Output path for a generated mock/stub file (requires --testingFramework and --out)
|
|
96
|
+
-T, --testingFramework <name> Framework for generated mocks: "vitest" or "jest" (requires --mocks and --out)
|
|
97
|
+
-h, --help Show help
|
|
93
98
|
```
|
|
94
99
|
|
|
95
100
|
### Formatting the Output
|
|
@@ -142,24 +147,72 @@ The `$schema` field enables autocompletion and inline documentation in most edit
|
|
|
142
147
|
|
|
143
148
|
## Templates
|
|
144
149
|
|
|
145
|
-
Swaggie
|
|
150
|
+
Swaggie's templates are split into two independent layers that you can combine freely.
|
|
146
151
|
|
|
147
|
-
|
|
148
|
-
| ----------- | ----------------------------------------------------------------------------------------- |
|
|
149
|
-
| `axios` | Default. Recommended for React, Vue, and similar frameworks |
|
|
150
|
-
| `xior` | Lightweight modern alternative to axios ([xior](https://github.com/suhaotian/xior#intro)) |
|
|
151
|
-
| `swr-axios` | SWR hooks for GET requests, backed by axios |
|
|
152
|
-
| `tsq-xior` | TanStack Query hooks for GET requests, backed by xior |
|
|
153
|
-
| `fetch` | Uses the native browser Fetch API |
|
|
154
|
-
| `ng1` | Angular 1 client |
|
|
155
|
-
| `ng2` | Angular 2+ client (uses HttpClient and InjectionTokens) |
|
|
152
|
+
### HTTP client templates
|
|
156
153
|
|
|
157
|
-
|
|
154
|
+
These are standalone and cover the most common client libraries:
|
|
155
|
+
|
|
156
|
+
| Template | Description |
|
|
157
|
+
| -------- | ----------- |
|
|
158
|
+
| `axios` | Default. Recommended for React, Vue, and most Node.js projects |
|
|
159
|
+
| `fetch` | Native browser/Node 18+ Fetch API — zero runtime dependencies |
|
|
160
|
+
| `xior` | Lightweight Axios-compatible alternative ([xior](https://github.com/suhaotian/xior#intro)) |
|
|
161
|
+
| `ng1` | Angular 1 client |
|
|
162
|
+
| `ng2` | Angular 2+ client (uses `HttpClient` and `InjectionToken`) |
|
|
163
|
+
|
|
164
|
+
### Reactive query layer templates
|
|
165
|
+
|
|
166
|
+
These add a reactive data-fetching layer (SWR or TanStack Query hooks) on top of any compatible http client. They cannot be used alone — pair them with a basic template using a 2-element array:
|
|
167
|
+
|
|
168
|
+
| Template | Description |
|
|
169
|
+
| -------- | ----------- |
|
|
170
|
+
| `swr` | [SWR](https://swr.vercel.app) hooks for queries and mutations |
|
|
171
|
+
| `tsq` | [TanStack Query](https://tanstack.com/query) hooks for queries and mutations |
|
|
172
|
+
|
|
173
|
+
Compatible http client templates: `axios`, `fetch`, `xior`. Angular clients are not compatible with reactive layers.
|
|
174
|
+
|
|
175
|
+
### Usage examples
|
|
176
|
+
|
|
177
|
+
**Single http template (existing behaviour):**
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{ "template": "axios" }
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
swaggie -s ./openapi.json -o ./client.ts -t axios
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Pair combination — in config:**
|
|
188
|
+
|
|
189
|
+
```json
|
|
190
|
+
{ "template": ["swr", "axios"] }
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# CLI: comma-separated pair
|
|
195
|
+
swaggie -s ./openapi.json -o ./client.ts -t swr,axios
|
|
196
|
+
swaggie -s ./openapi.json -o ./client.ts -t tsq,xior
|
|
197
|
+
swaggie -s ./openapi.json -o ./client.ts -t swr,fetch
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Reactive template only — defaults to `fetch` as the http client:**
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{ "template": "swr" }
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Custom templates
|
|
207
|
+
|
|
208
|
+
Pass the path to your own template directory as the template value:
|
|
158
209
|
|
|
159
210
|
```bash
|
|
160
211
|
swaggie -s https://petstore3.swagger.io/api/v3/openapi.json -o ./client/petstore.ts --template ./my-swaggie-template/
|
|
161
212
|
```
|
|
162
213
|
|
|
214
|
+
Custom paths also work as part of a composite pair: `["./my-l2", "axios"]`.
|
|
215
|
+
|
|
163
216
|
---
|
|
164
217
|
|
|
165
218
|
## Example
|
|
@@ -179,7 +232,7 @@ import Axios, { AxiosPromise } from 'axios';
|
|
|
179
232
|
|
|
180
233
|
const axios = Axios.create({
|
|
181
234
|
baseURL: '/api',
|
|
182
|
-
paramsSerializer: (params) =>
|
|
235
|
+
paramsSerializer: (params: any) =>
|
|
183
236
|
encodeParams(params, null, {
|
|
184
237
|
allowDots: true,
|
|
185
238
|
arrayFormat: 'repeat',
|
|
@@ -359,6 +412,39 @@ Either tool needs to be installed separately and configured for your project.
|
|
|
359
412
|
|
|
360
413
|
---
|
|
361
414
|
|
|
415
|
+
## Generating Mocks
|
|
416
|
+
|
|
417
|
+
Swaggie can generate a companion mock file alongside your client — a set of typed spy stubs for every method and hook, ready to drop into your tests.
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
swaggie -s ./spec.json -o ./src/api/client.ts -t swr,axios \
|
|
421
|
+
--mocks ./src/__mocks__/api.ts --testingFramework vitest
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
Or in a config file:
|
|
425
|
+
|
|
426
|
+
```json
|
|
427
|
+
{
|
|
428
|
+
"src": "./openapi.json",
|
|
429
|
+
"out": "./src/api/client.ts",
|
|
430
|
+
"template": ["swr", "axios"],
|
|
431
|
+
"mocks": "./src/__mocks__/api.ts",
|
|
432
|
+
"testingFramework": "vitest"
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
The generated mock file exports the same names as the real client, so `vi.mock('./api', () => import('./__mocks__/api'))` is all you need in tests. For (SWR/TSQ) templates, hook stubs come with shorthand helpers:
|
|
437
|
+
|
|
438
|
+
```ts
|
|
439
|
+
pet.queries.usePetById.mockSWR({ data: { id: 1, name: 'Rex' } });
|
|
440
|
+
pet.mutations.useAddPet.mockSWRMutation({ isMutating: false });
|
|
441
|
+
// TanStack Query equivalents: mockQuery() / mockMutation()
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
See the [Mocking guide](https://yhnavein.github.io/swaggie/guide/mocking) for full details.
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
362
448
|
## Using Swaggie Programmatically
|
|
363
449
|
|
|
364
450
|
You can also call Swaggie directly from Node.js/bun/deno/etc:
|
package/dist/browser.js
CHANGED
|
@@ -9,6 +9,8 @@ var _bundledTemplates = require('./generated/bundledTemplates');
|
|
|
9
9
|
var _utils = require('./utils/utils');
|
|
10
10
|
var _documentLoaderbrowser = require('./utils/documentLoader.browser');
|
|
11
11
|
var _templateEngine = require('./utils/templateEngine');
|
|
12
|
+
var _templateValidator = require('./utils/templateValidator');
|
|
13
|
+
var _templateManager = require('./utils/templateManager');
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* Browser-friendly code generation entrypoint.
|
|
@@ -52,12 +54,27 @@ async function generateCode(spec, options) {
|
|
|
52
54
|
return _header.FILE_HEADER + _genTypes2.default.call(void 0, spec, options, false);
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
_templateValidator.validateTemplate.call(void 0, options.template);
|
|
58
|
+
|
|
59
|
+
if (Array.isArray(options.template)) {
|
|
60
|
+
const [l2, l1] = options.template;
|
|
61
|
+
const l1Files = _bundledTemplates.BUNDLED_TEMPLATES[l1 ];
|
|
62
|
+
const l2Files = _bundledTemplates.BUNDLED_TEMPLATES[l2 ];
|
|
63
|
+
if (!l1Files) {
|
|
64
|
+
throw new Error(`Bundled templates for L1 '${l1}' are not available`);
|
|
65
|
+
}
|
|
66
|
+
if (!l2Files) {
|
|
67
|
+
throw new Error(`Bundled templates for L2 '${l2}' are not available`);
|
|
68
|
+
}
|
|
69
|
+
_templateEngine.initTemplateEngineFromBundled.call(void 0, _templateManager.mergeTemplateFiles.call(void 0, l1Files, l2Files));
|
|
70
|
+
} else {
|
|
71
|
+
const templateFiles = _bundledTemplates.BUNDLED_TEMPLATES[options.template ];
|
|
72
|
+
if (!templateFiles) {
|
|
73
|
+
throw new Error(`Bundled templates for '${options.template}' are not available`);
|
|
74
|
+
}
|
|
75
|
+
_templateEngine.initTemplateEngineFromBundled.call(void 0, templateFiles);
|
|
58
76
|
}
|
|
59
77
|
|
|
60
|
-
_templateEngine.initTemplateEngineFromBundled.call(void 0, templateFiles);
|
|
61
78
|
const operationsCode = await _genOperations2.default.call(void 0, spec, options);
|
|
62
79
|
|
|
63
80
|
return operationsCode + _genTypes2.default.call(void 0, spec, options);
|
|
@@ -70,6 +87,7 @@ async function generateCode(spec, options) {
|
|
|
70
87
|
const {
|
|
71
88
|
allowDots,
|
|
72
89
|
arrayFormat,
|
|
90
|
+
queryParamsAsObject,
|
|
73
91
|
mode,
|
|
74
92
|
schemaStyle,
|
|
75
93
|
enumStyle,
|
|
@@ -86,11 +104,12 @@ async function generateCode(spec, options) {
|
|
|
86
104
|
),
|
|
87
105
|
...(allowDots !== undefined ? { allowDots } : {}),
|
|
88
106
|
...(arrayFormat !== undefined ? { arrayFormat } : {}),
|
|
107
|
+
...(queryParamsAsObject !== undefined ? { queryParamsAsObject } : {}),
|
|
89
108
|
};
|
|
90
109
|
|
|
91
110
|
return {
|
|
92
111
|
...rest,
|
|
93
|
-
template: _nullishCoalesce(template, () => ( _swagger.APP_DEFAULTS.template)),
|
|
112
|
+
template: _templateValidator.normalizeTemplate.call(void 0, _nullishCoalesce(template, () => ( _swagger.APP_DEFAULTS.template))),
|
|
94
113
|
servicePrefix: _nullishCoalesce(rest.servicePrefix, () => ( _swagger.APP_DEFAULTS.servicePrefix)),
|
|
95
114
|
nullableStrategy: _nullishCoalesce(_nullishCoalesce(nullables, () => ( rest.nullableStrategy)), () => ( _swagger.APP_DEFAULTS.nullableStrategy)),
|
|
96
115
|
generationMode: _nullishCoalesce(_nullishCoalesce(mode, () => ( rest.generationMode)), () => ( _swagger.APP_DEFAULTS.generationMode)),
|
package/dist/cli.js
CHANGED
|
@@ -13,12 +13,14 @@ const arrayFormatOption = new (0, _commander.Option)(
|
|
|
13
13
|
'Determines how arrays should be serialized'
|
|
14
14
|
).choices(['indices', 'repeat', 'brackets']);
|
|
15
15
|
|
|
16
|
+
const testingFrameworkOption = new (0, _commander.Option)(
|
|
17
|
+
'-T, --testingFramework <framework>',
|
|
18
|
+
'Test framework for generated mock stubs (requires --mocks and --out)'
|
|
19
|
+
).choices(['vitest', 'jest']);
|
|
20
|
+
|
|
16
21
|
const packageJson = readPackageJson();
|
|
17
22
|
|
|
18
|
-
const modeOption = new (0, _commander.Option)('-m, --mode <mode>', 'Generation mode').choices([
|
|
19
|
-
'full',
|
|
20
|
-
'schemas',
|
|
21
|
-
]);
|
|
23
|
+
const modeOption = new (0, _commander.Option)('-m, --mode <mode>', 'Generation mode').choices(['full', 'schemas']);
|
|
22
24
|
const schemaStyleOption = new (0, _commander.Option)(
|
|
23
25
|
'-d, --schemaStyle <style>',
|
|
24
26
|
'Schema object declaration style'
|
|
@@ -39,6 +41,10 @@ const nullableStrategyOption = new (0, _commander.Option)(
|
|
|
39
41
|
'--nullables <strategy>',
|
|
40
42
|
"Controls how OpenAPI 'nullable' is translated into TypeScript types"
|
|
41
43
|
).choices(['include', 'nullableAsOptional', 'ignore']);
|
|
44
|
+
const queryParamsAsObjectOption = new (0, _commander.Option)(
|
|
45
|
+
'--queryParamsAsObject [threshold]',
|
|
46
|
+
'Group query params into a single object; pass a number to group only when query params count is greater than threshold'
|
|
47
|
+
).argParser(parseQueryParamsAsObjectArg);
|
|
42
48
|
|
|
43
49
|
const program = new (0, _commander.Command)();
|
|
44
50
|
program
|
|
@@ -63,9 +69,18 @@ program
|
|
|
63
69
|
.option('-b, --baseUrl <string>', 'Base URL that will be used as a default value in the clients')
|
|
64
70
|
.option(
|
|
65
71
|
'-t, --template <string>',
|
|
66
|
-
'Template used for generating API client.
|
|
72
|
+
'Template used for generating API client. ' +
|
|
73
|
+
'L1 (HTTP client) templates: "axios" (default), "fetch", "xior", "ng1", "ng2". ' +
|
|
74
|
+
'L2 (reactive layer) templates must be paired with an L1 using a comma-separated value: ' +
|
|
75
|
+
'"swr,axios", "swr,fetch", "tsq,xior", "tsq,fetch", etc. ' +
|
|
76
|
+
'Providing only an L2 name (e.g. "swr") defaults to "fetch" as the L1.',
|
|
77
|
+
parseTemplateArg
|
|
67
78
|
)
|
|
68
79
|
.option('--preferAny', 'Use "any" type instead of "unknown"')
|
|
80
|
+
.option(
|
|
81
|
+
'-C, --useClient',
|
|
82
|
+
"Prepend 'use client'; to the generated file. Required for Next.js App Router with SWR or TanStack Query hooks"
|
|
83
|
+
)
|
|
69
84
|
.option(
|
|
70
85
|
'--skipDeprecated',
|
|
71
86
|
'Skip deprecated operations. When enabled, deprecated operations will be skipped from the generated code'
|
|
@@ -84,13 +99,19 @@ program
|
|
|
84
99
|
.addOption(enumStyleOption)
|
|
85
100
|
.addOption(enumNamesStyleOption)
|
|
86
101
|
.addOption(dateFormatOption)
|
|
87
|
-
.addOption(nullableStrategyOption)
|
|
102
|
+
.addOption(nullableStrategyOption)
|
|
103
|
+
.addOption(queryParamsAsObjectOption)
|
|
104
|
+
.option(
|
|
105
|
+
'--mocks <path>',
|
|
106
|
+
'Output path for the generated mock/stub file (requires --testingFramework and --out)'
|
|
107
|
+
)
|
|
108
|
+
.addOption(testingFrameworkOption);
|
|
88
109
|
|
|
89
110
|
program.parse(process.argv);
|
|
90
111
|
|
|
91
112
|
const options = program.opts();
|
|
92
113
|
|
|
93
|
-
_index.runCodeGenerator.call(void 0, options).then(complete, error);
|
|
114
|
+
_index.runCodeGenerator.call(void 0, options ).then(complete, error);
|
|
94
115
|
|
|
95
116
|
function complete([code, opts]) {
|
|
96
117
|
if (opts.out) {
|
|
@@ -116,3 +137,29 @@ function readPackageJson() {
|
|
|
116
137
|
throw new Error('Could not read package.json file');
|
|
117
138
|
}
|
|
118
139
|
}
|
|
140
|
+
|
|
141
|
+
function parseTemplateArg(value) {
|
|
142
|
+
const parts = value.split(',').map((s) => s.trim());
|
|
143
|
+
if (parts.length === 1) {
|
|
144
|
+
return parts[0];
|
|
145
|
+
}
|
|
146
|
+
if (parts.length === 2) {
|
|
147
|
+
return [parts[0], parts[1]];
|
|
148
|
+
}
|
|
149
|
+
throw new Error(
|
|
150
|
+
`--template accepts at most 2 comma-separated values (e.g. "swr,axios"). Got ${parts.length}.`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function parseQueryParamsAsObjectArg(value) {
|
|
155
|
+
if (value === undefined) {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const threshold = Number(value);
|
|
160
|
+
if (!Number.isInteger(threshold) || threshold < 0) {
|
|
161
|
+
throw new Error('--queryParamsAsObject threshold must be a non-negative integer');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return threshold;
|
|
165
|
+
}
|