@grafana/openapi-to-k6 0.1.0 → 0.1.2
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/.eslintignore +5 -0
- package/.github/workflows/publish.yaml +3 -1
- package/.github/workflows/tests.yaml +20 -4
- package/.prettierignore +4 -0
- package/README.md +13 -0
- package/dist/cli.js +11 -5
- package/dist/generator.js +20 -1
- package/dist/helper.js +8 -48
- package/dist/k6SdkClient.js +13 -7
- package/dist/logger.js +11 -2
- package/examples/basic_schema/k6-script.sample.ts +11 -0
- package/examples/basic_schema/schema.json +32 -0
- package/examples/basic_schema/simpleAPI.ts +87 -0
- package/examples/form_data_schema/formDataAPI.ts +115 -0
- package/examples/form_data_schema/k6-script.sample.ts +11 -0
- package/examples/form_data_schema/schema.json +86 -0
- package/examples/form_url_encoded_data_schema/formURLEncodedAPI.ts +114 -0
- package/examples/form_url_encoded_data_schema/k6-script.sample.ts +11 -0
- package/examples/form_url_encoded_data_schema/schema.json +86 -0
- package/examples/form_url_encoded_data_with_query_params_schema/formURLEncodedAPIWithQueryParameters.ts +130 -0
- package/examples/form_url_encoded_data_with_query_params_schema/k6-script.sample.ts +14 -0
- package/examples/form_url_encoded_data_with_query_params_schema/schema.json +107 -0
- package/examples/get_request_with_path_parameters_schema/k6-script.sample.ts +11 -0
- package/examples/get_request_with_path_parameters_schema/schema.json +57 -0
- package/examples/get_request_with_path_parameters_schema/simpleAPI.ts +94 -0
- package/examples/headers_schema/headerDemoAPI.ts +196 -0
- package/examples/headers_schema/k6-script.sample.ts +25 -0
- package/examples/headers_schema/schema.json +148 -0
- package/examples/no_title_schema/K6Client.ts +86 -0
- package/examples/no_title_schema/k6-script.sample.ts +11 -0
- package/examples/no_title_schema/schema.json +31 -0
- package/examples/post_request_with_query_params/exampleAPI.ts +124 -0
- package/examples/post_request_with_query_params/k6-script.sample.ts +14 -0
- package/examples/post_request_with_query_params/schema.json +86 -0
- package/examples/query_params_schema/exampleAPI.ts +118 -0
- package/examples/query_params_schema/k6-script.sample.ts +11 -0
- package/examples/query_params_schema/schema.json +105 -0
- package/examples/simple_post_request_schema/exampleAPI.ts +135 -0
- package/examples/simple_post_request_schema/k6-script.sample.ts +13 -0
- package/examples/simple_post_request_schema/schema.json +122 -0
- package/examples/update_examples.sh +21 -0
- package/jest.config.js +1 -0
- package/package.json +3 -2
- package/src/cli.ts +14 -6
- package/src/generator.ts +26 -7
- package/src/helper.ts +10 -60
- package/src/k6SdkClient.ts +22 -14
- package/src/logger.ts +11 -2
- package/tests/functional-tests/fixtures/schemas/no_title_schema.json +1 -1
- package/tests/functional-tests/fixtures/schemas/query_params_schema.json +1 -1
- package/tests/functional-tests/generator.test.ts +72 -32
- package/tests/helper.test.ts +0 -51
- package/tsconfig.json +1 -1
package/.eslintignore
ADDED
|
@@ -24,11 +24,13 @@ jobs:
|
|
|
24
24
|
run: |
|
|
25
25
|
NEW_VERSION=${{ github.event.release.tag_name }}
|
|
26
26
|
npm version $NEW_VERSION --no-git-tag-version
|
|
27
|
+
- name: Update generated examples
|
|
28
|
+
run: npm run update-examples
|
|
27
29
|
- name: Commit updated package.json
|
|
28
30
|
run: |
|
|
29
31
|
git config --global user.name 'github-actions[bot]'
|
|
30
32
|
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
|
31
|
-
git add package.json package-lock.json
|
|
33
|
+
git add package.json package-lock.json examples/
|
|
32
34
|
git commit -m "Update package.json version to ${{ github.event.release.tag_name }}"
|
|
33
35
|
git push origin HEAD:main
|
|
34
36
|
- run: npm run build
|
|
@@ -3,10 +3,7 @@ name: Run Tests
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
branches:
|
|
6
|
-
-
|
|
7
|
-
pull_request:
|
|
8
|
-
branches:
|
|
9
|
-
- main
|
|
6
|
+
- "**"
|
|
10
7
|
|
|
11
8
|
jobs:
|
|
12
9
|
test:
|
|
@@ -41,3 +38,22 @@ jobs:
|
|
|
41
38
|
path: './tests/e2e/k6Script.ts'
|
|
42
39
|
flags: '--compatibility-mode=experimental_enhanced'
|
|
43
40
|
inspect-flags: '--compatibility-mode=experimental_enhanced'
|
|
41
|
+
run-examples:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
needs: [test, e2e-test]
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
- uses: actions/setup-node@v4
|
|
47
|
+
with:
|
|
48
|
+
node-version: '21.5.0'
|
|
49
|
+
- run: npm ci
|
|
50
|
+
- name: Update examples
|
|
51
|
+
run: npm run update-examples
|
|
52
|
+
- name: Compare generated Clients with existing ones
|
|
53
|
+
id: diff
|
|
54
|
+
run: |
|
|
55
|
+
if [ "$(git diff --ignore-space-at-eol --text examples/ | wc -l)" -gt "0" ]; then
|
|
56
|
+
echo "Detected changes in the examples, run `npm run update-examples` to update all the examples."
|
|
57
|
+
git diff --ignore-space-at-eol --text examples/
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
package/.prettierignore
ADDED
package/README.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# openapi-to-k6
|
|
2
2
|
|
|
3
|
+
<p align="center">⚠️</p>
|
|
4
|
+
|
|
5
|
+
***This tool is currently in the experimental stage. Expect bugs, incomplete features, and breaking changes as development progresses. Use at your own risk, and please report any issues or feedback to help us improve.***
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
3
9
|
## Overview
|
|
4
10
|
|
|
5
11
|
The _openapi-to-k6_ repository is a tool designed to ease the process of writing k6 scripts.
|
|
@@ -9,6 +15,13 @@ easily call your endpoints and have auto completion in your IDE.
|
|
|
9
15
|
This allows developers to easily create performance tests for their APIs based on their existing
|
|
10
16
|
OpenAPI documentation.
|
|
11
17
|
|
|
18
|
+
Along with the client, it also generates a sample k6 script as an example of how to use the client.
|
|
19
|
+
|
|
20
|
+
To get started, install the tool with npm via `npm install openapi-to-k6` and run it to convert your
|
|
21
|
+
OpenAPI specification to a TypeScript client for k6.
|
|
22
|
+
|
|
23
|
+
To take a look at a few examples of how the generated client and sample script looks, check out the [examples](./examples) directory.
|
|
24
|
+
|
|
12
25
|
Note: Optional usage analytics are gathered to make the tool better. To disable this, use the option
|
|
13
26
|
`--disable-analytics` or set an environment variable `DISABLE_ANALYTICS=true`.
|
|
14
27
|
|
package/dist/cli.js
CHANGED
|
@@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
14
|
};
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
16
17
|
const commander_1 = require("commander");
|
|
17
18
|
const analytics_1 = require("./analytics");
|
|
18
19
|
const generator_1 = __importDefault(require("./generator"));
|
|
@@ -22,16 +23,21 @@ const program = new commander_1.Command();
|
|
|
22
23
|
const packageDetails = (0, helper_1.getPackageDetails)();
|
|
23
24
|
function generateSDK(_a) {
|
|
24
25
|
return __awaiter(this, arguments, void 0, function* ({ openApiPath, outputDir, shouldGenerateSampleK6Script, analyticsData, }) {
|
|
25
|
-
logger_1.logger.logMessage('Generating
|
|
26
|
-
logger_1.logger.logMessage(`OpenAPI
|
|
27
|
-
logger_1.logger.logMessage(`Output
|
|
26
|
+
logger_1.logger.logMessage('Generating TypeScript client for k6...\n');
|
|
27
|
+
logger_1.logger.logMessage(`OpenAPI schema: ${openApiPath}`);
|
|
28
|
+
logger_1.logger.logMessage(`Output: ${outputDir}\n`);
|
|
28
29
|
yield (0, generator_1.default)({
|
|
29
30
|
openApiPath,
|
|
30
31
|
outputDir,
|
|
31
32
|
shouldGenerateSampleK6Script,
|
|
32
33
|
analyticsData,
|
|
33
34
|
});
|
|
34
|
-
|
|
35
|
+
if (shouldGenerateSampleK6Script) {
|
|
36
|
+
logger_1.logger.logMessage(`TypeScript client and sample k6 script generated successfully.`, chalk_1.default.green);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
logger_1.logger.logMessage(`TypeScript client generated successfully.`, chalk_1.default.green);
|
|
40
|
+
}
|
|
35
41
|
});
|
|
36
42
|
}
|
|
37
43
|
program
|
|
@@ -48,7 +54,7 @@ program
|
|
|
48
54
|
const shouldDisableAnalytics = options.disableAnalytics || process.env.DISABLE_ANALYTICS === 'true';
|
|
49
55
|
const shouldDisableSampleScript = options.disableSampleScript ||
|
|
50
56
|
process.env.DISABLE_SAMPLE_SCRIPT === 'true';
|
|
51
|
-
if (options.verbose
|
|
57
|
+
if (options.verbose) {
|
|
52
58
|
logger_1.logger.setVerbose(true);
|
|
53
59
|
logger_1.logger.debug('Verbose mode enabled, showing debug logs');
|
|
54
60
|
}
|
package/dist/generator.js
CHANGED
|
@@ -12,7 +12,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
15
16
|
const orval_1 = __importDefault(require("orval"));
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const constants_1 = require("./constants");
|
|
16
19
|
const helper_1 = require("./helper");
|
|
17
20
|
const k6SdkClient_1 = require("./k6SdkClient");
|
|
18
21
|
const logger_1 = require("./logger");
|
|
@@ -27,6 +30,20 @@ const generatedFileHeaderGenerator = (info) => {
|
|
|
27
30
|
...(info.version ? [`OpenAPI spec version: ${info.version}`] : []),
|
|
28
31
|
];
|
|
29
32
|
};
|
|
33
|
+
const afterAllFilesWriteHandler = (filePaths) => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
|
+
for (const filePath of filePaths) {
|
|
35
|
+
yield (0, helper_1.formatFileWithPrettier)(filePath);
|
|
36
|
+
const fileName = path_1.default.basename(filePath);
|
|
37
|
+
if (fileName === '.ts') {
|
|
38
|
+
// Generated SDK had no name because there was no title in the schema
|
|
39
|
+
// Rename it to the default name
|
|
40
|
+
const directoryPath = path_1.default.dirname(filePath);
|
|
41
|
+
const newPath = path_1.default.join(directoryPath, `${constants_1.DEFAULT_SCHEMA_TITLE}.ts`);
|
|
42
|
+
logger_1.logger.debug(`afterAllFilesWriteHandler ~ Renaming ${filePath} to ${newPath}`);
|
|
43
|
+
fs_1.default.renameSync(filePath, newPath);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
30
47
|
exports.default = (_a) => __awaiter(void 0, [_a], void 0, function* ({ openApiPath, outputDir, shouldGenerateSampleK6Script, analyticsData, }) {
|
|
31
48
|
const schemaDetails = {
|
|
32
49
|
title: '',
|
|
@@ -48,10 +65,12 @@ exports.default = (_a) => __awaiter(void 0, [_a], void 0, function* ({ openApiPa
|
|
|
48
65
|
},
|
|
49
66
|
headers: true,
|
|
50
67
|
},
|
|
68
|
+
hooks: {
|
|
69
|
+
afterAllFilesWrite: afterAllFilesWriteHandler,
|
|
70
|
+
},
|
|
51
71
|
});
|
|
52
72
|
}));
|
|
53
73
|
if (!schemaDetails.title) {
|
|
54
74
|
logger_1.logger.warning('Could not find schema title in the OpenAPI spec. Please provide a `title` in the schema in `info` block to generate proper file names');
|
|
55
75
|
}
|
|
56
|
-
yield (0, helper_1.formatGeneratedFiles)(outputDir, schemaDetails.title, !!shouldGenerateSampleK6Script);
|
|
57
76
|
});
|
package/dist/helper.js
CHANGED
|
@@ -14,9 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.OutputOverrider = exports.getPackageDetails = void 0;
|
|
16
16
|
exports.formatFileWithPrettier = formatFileWithPrettier;
|
|
17
|
-
exports.formatGeneratedFiles = formatGeneratedFiles;
|
|
18
17
|
exports.getGeneratedClientPath = getGeneratedClientPath;
|
|
19
|
-
exports.isTsNode = isTsNode;
|
|
20
18
|
exports.djb2Hash = djb2Hash;
|
|
21
19
|
exports.getDirectoryForPath = getDirectoryForPath;
|
|
22
20
|
const core_1 = require("@orval/core");
|
|
@@ -24,7 +22,6 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
24
22
|
const path_1 = __importDefault(require("path"));
|
|
25
23
|
const prettier_1 = require("prettier");
|
|
26
24
|
const package_json_1 = __importDefault(require("../package.json"));
|
|
27
|
-
const constants_1 = require("./constants");
|
|
28
25
|
const logger_1 = require("./logger");
|
|
29
26
|
const getPackageDetails = () => {
|
|
30
27
|
const commandName = Object.keys(package_json_1.default.bin)[0] || 'openapi-to-k6';
|
|
@@ -43,6 +40,10 @@ exports.getPackageDetails = getPackageDetails;
|
|
|
43
40
|
*/
|
|
44
41
|
function formatFileWithPrettier(filePath) {
|
|
45
42
|
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
if (!fs_1.default.existsSync(filePath)) {
|
|
44
|
+
logger_1.logger.debug(`formatFileWithPrettier ~ File does not exist: ${filePath}, skipping formatting with prettier.`);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
46
47
|
// Read file contents
|
|
47
48
|
const content = fs_1.default.readFileSync(filePath, 'utf-8');
|
|
48
49
|
// Format using Prettier
|
|
@@ -53,35 +54,6 @@ function formatFileWithPrettier(filePath) {
|
|
|
53
54
|
logger_1.logger.debug(`Formatted: ${filePath}`);
|
|
54
55
|
});
|
|
55
56
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Format the generated files using Prettier.
|
|
58
|
-
*
|
|
59
|
-
* @param outputTarget - Path to the generated files.
|
|
60
|
-
* @param schemaTitle - Title of the schema.
|
|
61
|
-
*/
|
|
62
|
-
function formatGeneratedFiles(outputTarget, schemaTitle, isSampleK6ScriptGenerated) {
|
|
63
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
-
// Here we call the original function from @orval/core used by the library to generate the
|
|
65
|
-
// file name with same defaults.
|
|
66
|
-
const { path: clientPath } = yield getGeneratedClientPath(outputTarget, schemaTitle);
|
|
67
|
-
logger_1.logger.debug('Following are the details for formatting generated files:');
|
|
68
|
-
logger_1.logger.debug(`Path: ${path_1.default}`);
|
|
69
|
-
logger_1.logger.debug(`Schema Title: ${schemaTitle}`);
|
|
70
|
-
logger_1.logger.debug(`Output Target: ${outputTarget}`);
|
|
71
|
-
yield exports.formatFileWithPrettier(clientPath);
|
|
72
|
-
if (isSampleK6ScriptGenerated) {
|
|
73
|
-
const k6ScriptPath = path_1.default.join(getDirectoryForPath(clientPath), constants_1.SAMPLE_K6_SCRIPT_FILE_NAME);
|
|
74
|
-
logger_1.logger.debug(`Generated sample K6 Script Path: ${k6ScriptPath}`);
|
|
75
|
-
if (fs_1.default.existsSync(k6ScriptPath)) {
|
|
76
|
-
logger_1.logger.debug('Formatting sample k6 script file');
|
|
77
|
-
yield exports.formatFileWithPrettier(k6ScriptPath);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
logger_1.logger.error('Unable to format sample K6 script file as it does not exist!');
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
57
|
/**
|
|
86
58
|
* Get the path for the generated client file.
|
|
87
59
|
*
|
|
@@ -131,7 +103,10 @@ class OutputOverrider {
|
|
|
131
103
|
}
|
|
132
104
|
redirectOutputToNullStream(callback) {
|
|
133
105
|
return __awaiter(this, void 0, void 0, function* () {
|
|
134
|
-
|
|
106
|
+
if (!logger_1.logger.getVerbose()) {
|
|
107
|
+
// Redirect stdout and stderr to null stream only if not running in verbose mode
|
|
108
|
+
process.stdout.write = process.stderr.write = () => true;
|
|
109
|
+
}
|
|
135
110
|
try {
|
|
136
111
|
if (callback) {
|
|
137
112
|
yield callback();
|
|
@@ -149,21 +124,6 @@ class OutputOverrider {
|
|
|
149
124
|
}
|
|
150
125
|
exports.OutputOverrider = OutputOverrider;
|
|
151
126
|
OutputOverrider.instance = null;
|
|
152
|
-
/**
|
|
153
|
-
* Check if the current script is running with ts-node. i.e. directly from source.
|
|
154
|
-
*
|
|
155
|
-
* @export
|
|
156
|
-
* @returns {boolean}
|
|
157
|
-
*/
|
|
158
|
-
function isTsNode() {
|
|
159
|
-
const scriptPath = process.argv[1];
|
|
160
|
-
if (scriptPath) {
|
|
161
|
-
return scriptPath.endsWith('.ts') || scriptPath.includes('ts-node');
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
return false;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
127
|
/**
|
|
168
128
|
* Create a hash from the given string using the djb2 algorithm.
|
|
169
129
|
*
|
package/dist/k6SdkClient.js
CHANGED
|
@@ -19,6 +19,7 @@ const handlebars_1 = __importDefault(require("handlebars"));
|
|
|
19
19
|
const path_1 = __importDefault(require("path"));
|
|
20
20
|
const constants_1 = require("./constants");
|
|
21
21
|
const helper_1 = require("./helper");
|
|
22
|
+
const logger_1 = require("./logger");
|
|
22
23
|
// A map to store the operationNames for which a return type is to be written at the end to export
|
|
23
24
|
// and the return type definition
|
|
24
25
|
const returnTypesToWrite = new Map();
|
|
@@ -69,10 +70,12 @@ const getK6Dependencies = () => [
|
|
|
69
70
|
exports.getK6Dependencies = getK6Dependencies;
|
|
70
71
|
function getSchemaTitleFromContext(context) {
|
|
71
72
|
const specData = Object.values(context.specs);
|
|
73
|
+
let schemaTitle;
|
|
72
74
|
if (specData[0]) {
|
|
73
|
-
|
|
75
|
+
schemaTitle = specData[0].info.title;
|
|
74
76
|
}
|
|
75
|
-
|
|
77
|
+
schemaTitle !== null && schemaTitle !== void 0 ? schemaTitle : (schemaTitle = constants_1.DEFAULT_SCHEMA_TITLE);
|
|
78
|
+
return schemaTitle;
|
|
76
79
|
}
|
|
77
80
|
function _generateResponseTypeName(operationName) {
|
|
78
81
|
return `${(0, core_1.pascal)(operationName)}Response`;
|
|
@@ -249,15 +252,18 @@ const generateFooter = ({ operationNames }) => {
|
|
|
249
252
|
};
|
|
250
253
|
exports.generateFooter = generateFooter;
|
|
251
254
|
const k6ScriptBuilder = (verbOptions, output, context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
252
|
-
console.log(JSON.stringify({
|
|
253
|
-
verbOptions,
|
|
254
|
-
output,
|
|
255
|
-
context,
|
|
256
|
-
}, null, 2));
|
|
257
255
|
const schemaTitle = getSchemaTitleFromContext(context);
|
|
258
256
|
const { path: pathOfGeneratedClient, filename, extension, } = yield (0, helper_1.getGeneratedClientPath)(output.target, schemaTitle);
|
|
259
257
|
const directoryPath = (0, helper_1.getDirectoryForPath)(pathOfGeneratedClient);
|
|
260
258
|
const generateScriptPath = path_1.default.join(directoryPath, constants_1.SAMPLE_K6_SCRIPT_FILE_NAME);
|
|
259
|
+
logger_1.logger.debug(`k6ScriptBuilder ~ Generating sample K6 Script\n${JSON.stringify({
|
|
260
|
+
pathOfGeneratedClient,
|
|
261
|
+
filename,
|
|
262
|
+
extension,
|
|
263
|
+
schemaTitle,
|
|
264
|
+
directoryPath,
|
|
265
|
+
generateScriptPath,
|
|
266
|
+
}, null, 2)}`);
|
|
261
267
|
const clientFunctionsList = [];
|
|
262
268
|
for (const verbOption of Object.values(verbOptions)) {
|
|
263
269
|
const { operationName, summary, props } = verbOption;
|
package/dist/logger.js
CHANGED
|
@@ -25,6 +25,9 @@ class Logger {
|
|
|
25
25
|
setVerbose(verbose) {
|
|
26
26
|
this.isVerbose = verbose;
|
|
27
27
|
}
|
|
28
|
+
getVerbose() {
|
|
29
|
+
return this.isVerbose;
|
|
30
|
+
}
|
|
28
31
|
logWithColor(message, level, color) {
|
|
29
32
|
const timestamp = new Date().toISOString();
|
|
30
33
|
console.log(`${color(`[${level}]`)} ${chalk_1.default.gray(`[${timestamp}]`)} ${message}`);
|
|
@@ -32,8 +35,14 @@ class Logger {
|
|
|
32
35
|
info(message) {
|
|
33
36
|
this.logWithColor(message, LogLevel.INFO, chalk_1.default.blue);
|
|
34
37
|
}
|
|
35
|
-
logMessage(message) {
|
|
36
|
-
|
|
38
|
+
logMessage(message, color) {
|
|
39
|
+
if (color) {
|
|
40
|
+
console.log(color(message));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
console.log(message);
|
|
45
|
+
}
|
|
37
46
|
}
|
|
38
47
|
warning(message) {
|
|
39
48
|
this.logWithColor(message, LogLevel.WARNING, chalk_1.default.yellow);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openapi": "3.0.0",
|
|
3
|
+
"info": {
|
|
4
|
+
"title": "Simple API",
|
|
5
|
+
"version": "1.0.0"
|
|
6
|
+
},
|
|
7
|
+
"paths": {
|
|
8
|
+
"/example": {
|
|
9
|
+
"get": {
|
|
10
|
+
"summary": "Retrieve example data",
|
|
11
|
+
"responses": {
|
|
12
|
+
"200": {
|
|
13
|
+
"description": "Successful response",
|
|
14
|
+
"content": {
|
|
15
|
+
"application/json": {
|
|
16
|
+
"schema": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"properties": {
|
|
19
|
+
"message": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"example": "Hello, World!"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Automatically generated by @grafana/openapi-to-k6: 0.1.2
|
|
3
|
+
* Do not edit manually.
|
|
4
|
+
* Simple API
|
|
5
|
+
* OpenAPI spec version: 1.0.0
|
|
6
|
+
*/
|
|
7
|
+
import { URL } from 'https://jslib.k6.io/url/1.0.0/index.js'
|
|
8
|
+
import http from 'k6/http'
|
|
9
|
+
import type { Params, Response, ResponseBody } from 'k6/http'
|
|
10
|
+
export type GetExample200 = {
|
|
11
|
+
message?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type CreateSimpleAPIOptions = {
|
|
15
|
+
baseUrl: string
|
|
16
|
+
commonRequestParameters?: Params
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* This is the base client to use for interacting with the API.
|
|
21
|
+
*/
|
|
22
|
+
export const createSimpleAPI = (clientOptions: CreateSimpleAPIOptions) => {
|
|
23
|
+
const cleanBaseUrl = clientOptions.baseUrl.replace(/\/+$/, '')
|
|
24
|
+
/**
|
|
25
|
+
* @summary Retrieve example data
|
|
26
|
+
*/
|
|
27
|
+
const getExample = (requestParameters?: Params): GetExampleResponse => {
|
|
28
|
+
const url = new URL(cleanBaseUrl + `/example`)
|
|
29
|
+
const mergedRequestParameters = _mergeRequestParameters(
|
|
30
|
+
requestParameters || {},
|
|
31
|
+
clientOptions.commonRequestParameters
|
|
32
|
+
)
|
|
33
|
+
const response = http.request(
|
|
34
|
+
'GET',
|
|
35
|
+
url.toString(),
|
|
36
|
+
undefined,
|
|
37
|
+
mergedRequestParameters
|
|
38
|
+
)
|
|
39
|
+
let data
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
data = response.json()
|
|
43
|
+
} catch (error) {
|
|
44
|
+
data = response.body
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
response,
|
|
48
|
+
data,
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return { getExample }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type GetExampleResponse = {
|
|
56
|
+
response: Response
|
|
57
|
+
data: GetExample200 | ResponseBody
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Merges the provided request parameters with default parameters for the client.
|
|
62
|
+
*
|
|
63
|
+
* @param {Params} requestParameters - The parameters provided specifically for the request
|
|
64
|
+
* @param {Params} commonRequestParameters - Common parameters for all requests
|
|
65
|
+
* @returns {Params} - The merged parameters
|
|
66
|
+
*/
|
|
67
|
+
const _mergeRequestParameters = (
|
|
68
|
+
requestParameters?: Params,
|
|
69
|
+
commonRequestParameters?: Params
|
|
70
|
+
): Params => {
|
|
71
|
+
return {
|
|
72
|
+
...commonRequestParameters, // Default to common parameters
|
|
73
|
+
...requestParameters, // Override with request-specific parameters
|
|
74
|
+
headers: {
|
|
75
|
+
...(commonRequestParameters?.headers || {}), // Ensure headers are defined
|
|
76
|
+
...(requestParameters?.headers || {}),
|
|
77
|
+
},
|
|
78
|
+
cookies: {
|
|
79
|
+
...(commonRequestParameters?.cookies || {}), // Ensure cookies are defined
|
|
80
|
+
...(requestParameters?.cookies || {}),
|
|
81
|
+
},
|
|
82
|
+
tags: {
|
|
83
|
+
...(commonRequestParameters?.tags || {}), // Ensure tags are defined
|
|
84
|
+
...(requestParameters?.tags || {}),
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Automatically generated by @grafana/openapi-to-k6: 0.1.2
|
|
3
|
+
* Do not edit manually.
|
|
4
|
+
* Form Data API
|
|
5
|
+
* OpenAPI spec version: 1.0.0
|
|
6
|
+
*/
|
|
7
|
+
import { FormData } from 'https://jslib.k6.io/formdata/0.0.2/index.js'
|
|
8
|
+
import { URL } from 'https://jslib.k6.io/url/1.0.0/index.js'
|
|
9
|
+
import http from 'k6/http'
|
|
10
|
+
import type { Params, Response, ResponseBody } from 'k6/http'
|
|
11
|
+
export type PostUpload400 = {
|
|
12
|
+
error?: string
|
|
13
|
+
success?: boolean
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type PostUpload200 = {
|
|
17
|
+
message?: string
|
|
18
|
+
success?: boolean
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type PostUploadBody = {
|
|
22
|
+
/** Description of the file */
|
|
23
|
+
description?: string
|
|
24
|
+
/** File to upload */
|
|
25
|
+
file: Blob
|
|
26
|
+
/** User ID associated with the upload */
|
|
27
|
+
userId: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type CreateFormDataAPIOptions = {
|
|
31
|
+
baseUrl: string
|
|
32
|
+
commonRequestParameters?: Params
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* This is the base client to use for interacting with the API.
|
|
37
|
+
*/
|
|
38
|
+
export const createFormDataAPI = (clientOptions: CreateFormDataAPIOptions) => {
|
|
39
|
+
const cleanBaseUrl = clientOptions.baseUrl.replace(/\/+$/, '')
|
|
40
|
+
/**
|
|
41
|
+
* This endpoint accepts form data and file uploads.
|
|
42
|
+
* @summary Upload files and data
|
|
43
|
+
*/
|
|
44
|
+
const postUpload = (
|
|
45
|
+
postUploadBody: PostUploadBody,
|
|
46
|
+
requestParameters?: Params
|
|
47
|
+
): PostUploadResponse => {
|
|
48
|
+
const formData = new FormData()
|
|
49
|
+
formData.append('file', postUploadBody.file)
|
|
50
|
+
if (postUploadBody.description !== undefined) {
|
|
51
|
+
formData.append('description', postUploadBody.description)
|
|
52
|
+
}
|
|
53
|
+
formData.append('userId', postUploadBody.userId)
|
|
54
|
+
|
|
55
|
+
const url = new URL(cleanBaseUrl + `/upload`)
|
|
56
|
+
const mergedRequestParameters = _mergeRequestParameters(
|
|
57
|
+
requestParameters || {},
|
|
58
|
+
clientOptions.commonRequestParameters
|
|
59
|
+
)
|
|
60
|
+
const response = http.request('POST', url.toString(), formData.body(), {
|
|
61
|
+
...mergedRequestParameters,
|
|
62
|
+
headers: {
|
|
63
|
+
'Content-Type': 'multipart/form-data; boundary=' + formData.boundary,
|
|
64
|
+
...mergedRequestParameters?.headers,
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
let data
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
data = response.json()
|
|
71
|
+
} catch (error) {
|
|
72
|
+
data = response.body
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
response,
|
|
76
|
+
data,
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return { postUpload }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export type PostUploadResponse = {
|
|
84
|
+
response: Response
|
|
85
|
+
data: PostUpload200 | ResponseBody
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Merges the provided request parameters with default parameters for the client.
|
|
90
|
+
*
|
|
91
|
+
* @param {Params} requestParameters - The parameters provided specifically for the request
|
|
92
|
+
* @param {Params} commonRequestParameters - Common parameters for all requests
|
|
93
|
+
* @returns {Params} - The merged parameters
|
|
94
|
+
*/
|
|
95
|
+
const _mergeRequestParameters = (
|
|
96
|
+
requestParameters?: Params,
|
|
97
|
+
commonRequestParameters?: Params
|
|
98
|
+
): Params => {
|
|
99
|
+
return {
|
|
100
|
+
...commonRequestParameters, // Default to common parameters
|
|
101
|
+
...requestParameters, // Override with request-specific parameters
|
|
102
|
+
headers: {
|
|
103
|
+
...(commonRequestParameters?.headers || {}), // Ensure headers are defined
|
|
104
|
+
...(requestParameters?.headers || {}),
|
|
105
|
+
},
|
|
106
|
+
cookies: {
|
|
107
|
+
...(commonRequestParameters?.cookies || {}), // Ensure cookies are defined
|
|
108
|
+
...(requestParameters?.cookies || {}),
|
|
109
|
+
},
|
|
110
|
+
tags: {
|
|
111
|
+
...(commonRequestParameters?.tags || {}), // Ensure tags are defined
|
|
112
|
+
...(requestParameters?.tags || {}),
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createFormDataAPI } from './formDataAPI.ts'
|
|
2
|
+
|
|
3
|
+
const baseUrl = '<BASE_URL>'
|
|
4
|
+
const client = createFormDataAPI({ baseUrl })
|
|
5
|
+
|
|
6
|
+
export default function () {
|
|
7
|
+
/**
|
|
8
|
+
* Upload files and data
|
|
9
|
+
*/
|
|
10
|
+
const postUploadResponseData = client.postUpload(postUploadBody)
|
|
11
|
+
}
|