@skyramp/skyramp 0.5.9 → 0.5.16

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/package.json CHANGED
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "@skyramp/skyramp",
3
- "version": "0.5.9",
3
+ "version": "0.5.16",
4
4
  "description": "module for leveraging skyramp cli functionality",
5
5
  "scripts": {
6
6
  "lint": "eslint 'src/**/*.js' 'src/**/*.ts' --fix",
7
7
  "pack": "npm pack",
8
- "reference-docs": "documentation build src/**/*.js src/classes/**/*.js -f md -o reference.md"
8
+ "reference-docs": "documentation build src/**/*.js src/classes/**/*.js -f md -o reference.md",
9
+ "postinstall": "node scripts/download-binary.js",
10
+ "clean": "rimraf node_modules && rimraf package-lock.json && rimraf skyramp && rimraf lib/*"
9
11
  },
10
12
  "files": [
11
- "lib/**",
13
+ "scripts/*.js",
12
14
  "src/*.js",
13
15
  "src/*.ts",
14
16
  "src/classes/*.js",
@@ -18,6 +20,7 @@
18
20
  "author": "",
19
21
  "license": "MIT",
20
22
  "dependencies": {
23
+ "@aws-sdk/client-s3": "^3.812.0",
21
24
  "fs": "^0.0.1-security",
22
25
  "js-yaml": "^4.1.0",
23
26
  "koffi": "2.5.12"
@@ -0,0 +1,189 @@
1
+ const https = require('https');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const crypto = require('crypto');
5
+ const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3");
6
+
7
+ function log(level, message) {
8
+ const timestamp = new Date().toISOString();
9
+ console.log(`[${timestamp}] [${level.toUpperCase()}] ${message}`);
10
+ }
11
+
12
+ let S3_PRIVATE = process.env.S3_PRIVATE || false; // Set to true if libraries are in a private S3 bucket
13
+ const AWS_REGION = process.env.AWS_REGION || 'us-west-2'; // Set your AWS region
14
+ const SKIP_DOWNLOAD = process.env.SKIP_DOWNLOAD || false; // Set to true to skip the download process
15
+ const PUBLIC_BUCKET_NAME = process.env.INT_LIBRARY_BUCKET || 'skyramp-public'; // Set to your S3 public bucket name
16
+ const PUBLIC_LIBRARY_PATH = process.env.INT_LIBRARY_PATH || `release/v${require('../package.json').version}/lib`; // Set to your S3 public library root path
17
+ const PRIVATE_BUCKET_NAME = process.env.INT_LIBRARY_BUCKET || undefined; // Set to your S3 private bucket name
18
+ const PRIVATE_LIBRARY_PATH = process.env.INT_LIBRARY_PATH || ''; // Set to your S3 private library root path
19
+
20
+ if (SKIP_DOWNLOAD) {
21
+ log('info', "Skipping download as requested by SKIP_DOWNLOAD=true.");
22
+ process.exit(0);
23
+ }
24
+
25
+ if (process.env.CI) {
26
+ log('info', "Running in CI environment. Defaulting to private S3 download.");
27
+ S3_PRIVATE = true;
28
+ }
29
+
30
+ const archMap = {
31
+ x64: 'amd64',
32
+ ia32: '386',
33
+ arm: 'arm',
34
+ arm64: 'arm64',
35
+ };
36
+
37
+ const platformMap = {
38
+ win32: 'windows',
39
+ darwin: 'darwin',
40
+ linux: 'linux',
41
+ };
42
+
43
+ const extMap = {
44
+ windows: 'dll',
45
+ darwin: 'dylib',
46
+ linux: 'so',
47
+ };
48
+
49
+ const rawPlatform = process.platform;
50
+ const rawArch = process.arch;
51
+ const platform = platformMap[rawPlatform];
52
+ const arch = archMap[rawArch];
53
+ const ext = extMap[platform];
54
+
55
+ if (!platform || !arch || !ext) {
56
+ log('error', `Unsupported platform or architecture: ${rawPlatform} / ${rawArch}`);
57
+ process.exit(1);
58
+ }
59
+
60
+ const prefix = 'skyramp';
61
+ const binaryFilename = `${prefix}-${platform}-${arch}.${ext}`;
62
+ const headerFilename = `${prefix}-${platform}-${arch}.h`;
63
+
64
+ const baseUrl = `https://${PUBLIC_BUCKET_NAME}.s3.${AWS_REGION}.amazonaws.com/${PUBLIC_LIBRARY_PATH}/`;
65
+ const localDir = path.join(__dirname, '..', 'lib');
66
+
67
+ const files = [
68
+ { name: binaryFilename, dest: path.join(localDir, binaryFilename) },
69
+ { name: headerFilename, dest: path.join(localDir, headerFilename) },
70
+ ];
71
+
72
+ async function calculateMD5(filePath) {
73
+ return new Promise((resolve, reject) => {
74
+ const hash = crypto.createHash('md5');
75
+ const stream = fs.createReadStream(filePath);
76
+ stream.on('data', data => hash.update(data));
77
+ stream.on('end', () => resolve(hash.digest('hex')));
78
+ stream.on('error', (err) => {
79
+ log('error', `Failed to calculate MD5 for ${filePath}: ${err.message}`);
80
+ reject(err);
81
+ });
82
+ });
83
+ }
84
+
85
+ async function getETag(url) {
86
+ return new Promise((resolve, reject) => {
87
+ https.get(url, { method: 'HEAD' }, res => {
88
+ if (res.statusCode !== 200) {
89
+ reject(new Error(`HTTP ${res.statusCode}: ${url}`));
90
+ return;
91
+ }
92
+ resolve(res.headers['etag']?.replace(/"/g, '')); // Remove quotes from ETag
93
+ }).on('error', (err) => {
94
+ log('error', `Error during HEAD request to ${url}: ${err.message}`);
95
+ reject(err);
96
+ });
97
+ });
98
+ }
99
+
100
+ async function download(url, dest, options = {}) {
101
+ await fs.promises.mkdir(path.dirname(dest), { recursive: true });
102
+
103
+ const { session, bucket, s3Key } = options;
104
+
105
+ return new Promise((resolve, reject) => {
106
+ if (session && bucket && s3Key) {
107
+ // Private S3 download using AWS SDK
108
+ const command = new GetObjectCommand({ Bucket: bucket, Key: s3Key });
109
+ session.send(command).then(response => {
110
+ const stream = response.Body;
111
+ const file = fs.createWriteStream(dest);
112
+ stream.pipe(file);
113
+ stream.on('error', (err) => {
114
+ log('error', `Error streaming file from S3: ${err.message}`);
115
+ reject(err);
116
+ });
117
+ file.on('finish', () => {
118
+ log('info', `Successfully downloaded ${s3Key} to ${dest}`);
119
+ file.close(resolve);
120
+ });
121
+ }).catch(err => {
122
+ log('error', `Failed to download ${s3Key} from S3: ${err.message}`);
123
+ reject(err);
124
+ });
125
+ } else {
126
+ // Public URL download using https
127
+ https.get(url, res => {
128
+ if (res.statusCode !== 200) {
129
+ const error = new Error(`HTTP ${res.statusCode}: ${url}`);
130
+ log('error', `Failed to download ${url}: ${error.message}`);
131
+ reject(error);
132
+ return;
133
+ }
134
+ const file = fs.createWriteStream(dest);
135
+ res.pipe(file);
136
+ file.on('finish', () => {
137
+ log('info', `Successfully downloaded ${url} to ${dest}`);
138
+ file.close(resolve);
139
+ });
140
+ }).on('error', (err) => {
141
+ log('error', `Error during download from ${url}: ${err.message}`);
142
+ reject(err);
143
+ });
144
+ }
145
+ });
146
+ }
147
+
148
+ (async () => {
149
+ for (const file of files) {
150
+ let options = {};
151
+ let url = baseUrl + file.name;
152
+ const localFile = file.dest;
153
+ log('info', `Processing ${file.name}...`);
154
+
155
+ try {
156
+ if (S3_PRIVATE) {
157
+ log("Pulling libraries from Private S3.");
158
+ const s3 = new S3Client({region: AWS_REGION});
159
+
160
+ url = null; // No URL needed for S3 private download client
161
+ options = {
162
+ session: s3,
163
+ bucket: PRIVATE_BUCKET_NAME,
164
+ s3Key: `${PRIVATE_LIBRARY_PATH}/${file.name}`
165
+ };
166
+ } else if (fs.existsSync(localFile)) {
167
+ log('info', `Checking ${file.name} for changes...`);
168
+ const remoteETag = await getETag(url);
169
+ const localHash = await calculateMD5(localFile);
170
+ log('debug', `Remote ETag: ${remoteETag}, Local Hash: ${localHash}`);
171
+
172
+ if (remoteETag === localHash) {
173
+ log('info', `✅ ${file.name} is up-to-date.`);
174
+ continue;
175
+ } else {
176
+ log('info', `🔄 ${file.name} differs, downloading...`);
177
+ }
178
+ } else {
179
+ log('info', `⬇️ ${file.name} not found locally, downloading...`);
180
+ }
181
+
182
+ await download(url, file.dest, options);
183
+ log('info', `✅ Saved ${file.name} to ${file.dest}`);
184
+ } catch (e) {
185
+ log('error', `❌ Failed to process ${file.name}: ${e.message}`);
186
+ process.exit(1);
187
+ }
188
+ }
189
+ })();
@@ -15,6 +15,7 @@ interface RequestV2Options {
15
15
  expectedCode?: string;
16
16
  funcHandler?: string;
17
17
  funcHandlerType?: string;
18
+ insecure?: boolean;
18
19
  }
19
20
  export declare class RequestV2 {
20
21
  /**
@@ -20,6 +20,7 @@ class RequestV2 {
20
20
  * @param {string} [options.expectedCode=''] - The expected HTTP status code of the response.
21
21
  * @param {string} [options.funcHandler=''] - The dynamic handler function for the request.
22
22
  * @param {string} [options.funcHandlerType=''] - The type of the dynamic handler (e.g., 'python', 'javascript').
23
+ * @param {boolean} [options.insecure=false] - Skip cert verification if set.
23
24
  */
24
25
  constructor(options = {}) {
25
26
  this.url = options.url || '';
@@ -35,6 +36,7 @@ class RequestV2 {
35
36
  this.expectedCode = options.expectedCode || '';
36
37
  this.funcHandler = options.funcHandler || '';
37
38
  this.funcHandlerType = options.funcHandlerType || '';
39
+ this.insecure = options.insecure || false;
38
40
  }
39
41
 
40
42
  toYaml() {
@@ -52,7 +54,8 @@ class RequestV2 {
52
54
  formParams: 'form_params',
53
55
  expectedCode: 'expected_code',
54
56
  funcHandler: 'func_handler',
55
- funcHandlerType: 'func_handler_type'
57
+ funcHandlerType: 'func_handler_type',
58
+ insecure: 'insecure'
56
59
  };
57
60
 
58
61
  const { body, ...rest } = this;
@@ -90,7 +93,8 @@ class RequestV2 {
90
93
  formParams: 'form_params',
91
94
  expectedCode: 'expected_code',
92
95
  funcHandler: 'func_handler',
93
- funcHandlerType: 'func_handler_type'
96
+ funcHandlerType: 'func_handler_type',
97
+ insecure: 'insecure'
94
98
  };
95
99
 
96
100
  const { ...rest } = this;
@@ -3,7 +3,6 @@ import { Endpoint } from './Endpoint';
3
3
  import { Scenario } from './Scenario';
4
4
  import {TrafficConfig} from './TrafficConfig';
5
5
  import { Protocol } from './Protocol';
6
- import {oauthResponseType} from './SkyrampClient';
7
6
 
8
7
  export enum Language {
9
8
  PYTHON = 'python'
@@ -61,9 +60,16 @@ interface SkyrampClientOptions {
61
60
  local_image?: boolean;
62
61
  }
63
62
 
63
+ interface AnalyzeOpenAPIOptions {
64
+ apiSchema: string;
65
+ uri: string;
66
+ }
67
+
64
68
  interface TraceCollectOptions {
65
69
  output?: string;
66
70
  workerContainerName?: string;
71
+ playwright?: boolean;
72
+ playwrightOutput?: string;
67
73
  }
68
74
 
69
75
  interface GenerateRestTestOptions {
@@ -87,21 +93,24 @@ interface GenerateRestTestOptions {
87
93
  responseStatusCode?: string;
88
94
  force?: boolean;
89
95
  deployDashboard?: boolean;
90
- formParams?: {[formParamName: string]: string | number | boolean | object};
91
- pathParams?: {[pathName: string]: string | number | boolean | object};
92
- queryParams?: {[queryName: string]: string | number | boolean | object};
96
+ formParams?: string;
97
+ pathParams?: string;
98
+ queryParams?: string;
93
99
  apiSchema?: string[];
94
100
  traceFilePath?: string;
95
101
  generateInclude?: string[];
96
102
  generateExclude?: string[];
97
103
  generateInsecure?: boolean;
98
104
  assertOption?: string;
99
- loadCount?: number;
100
- loadDuration?: number;
101
- loadNumThreads?: number;
102
- loadRampupDuration?: number;
103
- loadRampupInterval?: number;
104
- loadTargetRPS?: number;
105
+ playwright?: boolean;
106
+ playwrightOutput?: string;
107
+ playwrightInput?: string;
108
+ loadCount?: string;
109
+ loadDuration?: string;
110
+ loadNumThreads?: string;
111
+ loadRampupDuration?: string;
112
+ loadRampupInterval?: string;
113
+ loadTargetRPS?: string;
105
114
  unblock?: boolean;
106
115
  }
107
116
 
@@ -134,11 +143,6 @@ export declare class SkyrampClient {
134
143
  isDockerenv: boolean): Promise<void>;
135
144
 
136
145
  testerStartV1(options: testerStartV1Options): Promise<void>;
137
- testerStartvalidateToken(userToken: string): Promise<void>;
138
- readCredential(): Promise<credResponseType>;
139
- getOAuthURL(provider: string, port: number): string;
140
- runOAuthLoopback(provider: string, port: number): Promise<oauthResponseType>;
141
- registerUser(provider: string, email: string, oauthToken: string): Promise<string>;
142
146
 
143
147
  testerGenerate(
144
148
  protocol: Protocol,
@@ -158,4 +162,5 @@ export declare class SkyrampClient {
158
162
 
159
163
  generateRestTest(options: GenerateRestTestOptions): Promise<string>;
160
164
  traceCollect(options: TraceCollectOptions): Promise<string>;
165
+ analyzeOpenapi(options: AnalyzeOpenAPIOptions): Promise<string>;
161
166
  }
@@ -3,19 +3,6 @@ const koffi = require('koffi');
3
3
  const TrafficConfig = require('./TrafficConfig');
4
4
  const RequestV2 = require('./RequestV2');
5
5
  const ResponseV2 = require('./ResponseV2');
6
- const oauthResponseType = koffi.struct({
7
- emails: koffi.array('char*', 10),
8
- num_emails: 'int',
9
- token: 'char*',
10
- error: 'char*'
11
- });
12
-
13
- const credResponseType = koffi.struct({
14
- email: 'char*',
15
- user_token: 'char*',
16
- provider: 'char*',
17
- error: 'char*',
18
- });
19
6
 
20
7
  const workerInfoType = koffi.struct({
21
8
  container_name: 'char*',
@@ -64,19 +51,13 @@ const deployTargetWrapper = lib.func('deployTargetWrapper', 'string', ['string',
64
51
  const deleteTargetWrapper = lib.func('deleteTargetWrapper', 'string', ['string', 'string', 'string', 'string', 'string']);
65
52
  const runTesterGenerateRestWrapper = lib.func('runTesterGenerateRestWrapper', testerGenerateType, ['string', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'int', 'bool', 'bool', 'bool']);
66
53
 
67
- const generateRestTestWrapper = lib.func('generateRestTestWrapper', 'string', ['string', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'int', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'bool', 'bool', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'bool', 'string', 'int', 'int', 'int', 'int', 'int', 'int', 'bool']);
68
- const traceCollectWrapper = lib.func('traceCollectWrapper', 'string', ['string', 'string']);
69
-
70
- // credential / oauth related
71
- const readCredentialWrapper = lib.func('readCredentialWrapper', credResponseType, []);
72
- const validateTokenWrapper = lib.func('validateTokenWrapper', 'string', ['string']);
73
- const registerUserWrapper = lib.func('registerUserWrapper', 'string', ['string', 'string', 'string']);
74
- const getOAuthURL = lib.func('getOAuthURLWrapper', 'string', ['string', 'int']);
75
- const runOAuthLoopback = lib.func('runOAuthLoopback', oauthResponseType, ['string', 'int']);
54
+ const generateRestTestWrapper = lib.func('generateRestTestWrapper', 'string', ['string', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'int', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'bool', 'bool', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'bool', 'string', 'bool', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'bool']);
55
+ const traceCollectWrapper = lib.func('traceCollectWrapper', 'string', ['string', 'string', 'bool', 'string']);
56
+ const analyzeOpenapiWrapper = lib.func('analyzeOpenapiWrapper', 'string', ['string', 'string']);
76
57
 
77
58
  // contract test
78
59
  // func sendRequestWrapper(address, namespace, kubePath, kubeContext, clusterName, request, dockerNetwork, workerImage *C.char, localImage bool) *C.char {
79
- const sendRequestWrapper = lib.func('sendRequestWrapper', contractResponseType, ['string', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'bool']);
60
+ const sendRequestWrapper = lib.func('sendRequestWrapper', contractResponseType, ['string', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'string', 'bool']);
80
61
 
81
62
  // dashboard
82
63
  const deployDockerDashboardWrapper = lib.func('deployDockerDashboardWrapper', 'string', ['string']);
@@ -138,7 +119,7 @@ class SkyrampClient {
138
119
  if (options.k8SConfigPath) {
139
120
  this.kubeconfigPath = options.k8SConfigPath;
140
121
  }
141
- }
122
+ }
142
123
 
143
124
  if (this.kubeconfigPath || this.clusterName || this.context) {
144
125
  this.addKubeConfig(this.context, this.clusterName, this.kubeconfigPath);
@@ -146,10 +127,10 @@ class SkyrampClient {
146
127
  // set default worker image
147
128
  if (options.workerImage) {
148
129
  this.workerImage = options.workerImage;
149
- }
130
+ }
150
131
  if (options.local_image) {
151
132
  this.local_image = options.local_image;
152
- }
133
+ }
153
134
  } else {
154
135
  if (kubeconfigPathOrOptions || clusterName || context) {
155
136
  this.addKubeConfig(context, clusterName, kubeconfigPathOrOptions);
@@ -160,89 +141,6 @@ class SkyrampClient {
160
141
  }
161
142
  }
162
143
 
163
- setUserToken(userToken) {
164
- this.userToken = userToken;
165
- }
166
-
167
- getOAuthURL(provider, port) {
168
- return getOAuthURL(provider, port);
169
- }
170
-
171
- getUserEmail() {
172
- return this.userEmail;
173
- }
174
-
175
- getUserToken() {
176
- return this.userToken;
177
- }
178
-
179
- getUserProvider() {
180
- return this.userProvider;
181
- }
182
-
183
- async readCredential() {
184
- return new Promise((resolve, reject) => {
185
- readCredentialWrapper.async((err, res) => {
186
- if (err) {
187
- reject(err);
188
- } else if (res) {
189
- if (res.error != null) {
190
- reject(res.error);
191
- } else {
192
- this.userToken = res.user_token;
193
- this.userEmail = res.email;
194
- this.userProvider = res.provider;
195
- resolve(res);
196
- }
197
- } else {
198
- reject(new Error('failed to read credential'));
199
- }
200
- });
201
- });
202
- }
203
-
204
- async runOAuthLoopback(provider, port) {
205
- return new Promise((resolve, reject) => {
206
- runOAuthLoopback.async(provider, port, (err, res) => {
207
- if (err) {
208
- reject(err);
209
- } else if (res) {
210
- resolve(res);
211
- } else {
212
- reject(new Error("failed to get oauth token"));
213
- }
214
- });
215
- });
216
- }
217
-
218
- async validateToken(userToken) {
219
- return new Promise((resolve, reject) => {
220
- validateTokenWrapper.async(userToken, (err, res) => {
221
- if (err) {
222
- reject(err);
223
- } else if (res) {
224
- resolve(new Error(res));
225
- } else {
226
- resolve();
227
- }
228
- });
229
- });
230
- }
231
-
232
- async registerUser(provider, email, oauthToken) {
233
- return new Promise((resolve, reject) => {
234
- registerUserWrapper.async(provider, email, oauthToken, (err, res) => {
235
- if (err) {
236
- reject(err);
237
- } else if (res) {
238
- reject(new Error(res));
239
- } else {
240
- resolve();
241
- }
242
- });
243
- });
244
- }
245
-
246
144
  /**
247
145
  * Applies local changes to the Kubernetes cluster configuration.
248
146
  *
@@ -338,7 +236,7 @@ class SkyrampClient {
338
236
  * @returns {Promise} - A Promise that resolves if deployment is successful, and rejects with an error if any error occurs during deployment.
339
237
  * @throws {Error} - If there is no cluster to deploy the worker to.
340
238
  */
341
- async deploySkyrampWorker(namespace, workerImage = '', localImage = false, kubePath='', kubeContext='', clusterName='') {
239
+ async deploySkyrampWorker(namespace, workerImage = '', localImage = false, kubePath = '', kubeContext = '', clusterName = '') {
342
240
  return new Promise((resolve, reject) => {
343
241
  deploySkyrampWorkerWrapper.async(namespace, kubePath, kubeContext, clusterName, workerImage, localImage, (err, res) => {
344
242
  if (err) {
@@ -360,7 +258,7 @@ class SkyrampClient {
360
258
  * @returns {Promise} - A promise that resolves with no value upon successful deletion.
361
259
  * @throws {Error} - If there is no cluster to delete the worker from or if there is no worker to delete from the specified namespace.
362
260
  */
363
- async deleteSkyrampWorker(namespace, kubePath='', kubeContext='', clusterName='') {
261
+ async deleteSkyrampWorker(namespace, kubePath = '', kubeContext = '', clusterName = '') {
364
262
  if (this.kubeConfigPath === null) {
365
263
  throw new Error('No cluster to delete worker from.');
366
264
  }
@@ -538,7 +436,7 @@ class SkyrampClient {
538
436
  const testYamlContent = getYamlBytes(testDescription);
539
437
  const stringifiedHeaders = JSON.stringify(globalHeaders);
540
438
 
541
- return this.runTesterStartv1( namespace,
439
+ return this.runTesterStartv1(namespace,
542
440
  kubePath,
543
441
  kubeContext,
544
442
  clusterName,
@@ -673,7 +571,7 @@ class SkyrampClient {
673
571
 
674
572
  return mockDescription;
675
573
  }
676
-
574
+
677
575
  /**
678
576
  * Generates test scenarios based on the provided parameters.
679
577
  *
@@ -726,7 +624,7 @@ class SkyrampClient {
726
624
  const req = new RequestV2(options);
727
625
  return new Promise((resolve, reject) => {
728
626
  const jsonRequest = req.toJson();
729
- sendRequestWrapper.async(this.address, this.namespace, this.kubeconfigPath, this.context, this.clusterName, jsonRequest, this.dockerNetwork, this.workerImage, this.local_image, (err, res) => {
627
+ sendRequestWrapper.async(this.address, this.namespace, this.kubeconfigPath, this.context, this.clusterName, jsonRequest, this.dockerNetwork, this.workerImage, this.clientID, this.local_image, (err, res) => {
730
628
  if (err) {
731
629
  reject(err);
732
630
  } else if (res) {
@@ -776,11 +674,39 @@ class SkyrampClient {
776
674
  });
777
675
  }
778
676
 
677
+ /**
678
+ * Analyzes an OpenAPI schema and URI.
679
+ *
680
+ * @param {Object} options - The options for analysis.
681
+ * @param {string} options.apiSchema - The OpenAPI schema to analyze.
682
+ * @param {string} options.uri - The URI to analyze.
683
+ * @returns {Promise<string>} A promise that resolves with the analysis result.
684
+ */
685
+ async analyzeOpenapi(options) {
686
+ return new Promise((resolve, reject) => {
687
+ analyzeOpenapiWrapper.async(
688
+ options.apiSchema || "",
689
+ options.uri || "",
690
+ (err, res) => {
691
+ if (err) {
692
+ reject(err);
693
+ } else if (res.error) {
694
+ reject(new Error(res));
695
+ } else {
696
+ resolve(res);
697
+ }
698
+ }
699
+ );
700
+ });
701
+ }
702
+
779
703
  async traceCollect(options) {
780
704
  return new Promise((resolve, reject) => {
781
705
  traceCollectWrapper.async(
782
706
  options.output || "",
783
707
  options.workerContainerName || "",
708
+ options.playwright || false,
709
+ options.playwrightOutput || "",
784
710
  (err, res) => {
785
711
  if (err) {
786
712
  reject(err);
@@ -795,7 +721,6 @@ class SkyrampClient {
795
721
  }
796
722
 
797
723
  async generateRestTest(options) {
798
- // TODO: Fix the k8sConfig default value
799
724
  return new Promise((resolve, reject) => {
800
725
  generateRestTestWrapper.async(
801
726
  options.testType || "",
@@ -818,29 +743,30 @@ class SkyrampClient {
818
743
  options.responseStatusCode || "",
819
744
  options.force || false,
820
745
  options.deployDashboard || false,
821
- JSON.stringify(options.formParams || {}),
822
- JSON.stringify(options.pathParams || {}),
823
- JSON.stringify(options.queryParams || {}),
746
+ options.formParams || "",
747
+ options.pathParams || "",
748
+ options.queryParams || "",
824
749
  JSON.stringify(options.apiSchema || []),
825
750
  options.traceFilePath || "",
826
751
  JSON.stringify(options.generateInclude || []),
827
752
  JSON.stringify(options.generateExclude || []),
828
753
  options.generateInsecure || false,
829
754
  options.assertOption || "",
830
- options.loadCount || 0,
831
- options.loadDuration || 0,
832
- options.loadNumThreads || 0,
833
- options.loadRampupDuration || 0,
834
- options.loadRampupInterval || 0,
835
- options.loadTargetRPS || 0,
755
+ options.playwright || false,
756
+ options.playwrightOutput || "",
757
+ options.playwrightInput || "",
758
+ options.loadCount || "0",
759
+ options.loadDuration || "0",
760
+ options.loadNumThreads || "0",
761
+ options.loadRampupDuration || "0",
762
+ options.loadRampupInterval || "0",
763
+ options.loadTargetRPS || "0",
836
764
  options.unblock || false,
837
765
  (err, res) => {
838
766
  if (err) {
839
767
  reject(err);
840
- } else if (res) {
841
- reject(new Error(res));
842
768
  } else {
843
- resolve();
769
+ resolve(res);
844
770
  }
845
771
  }
846
772
  );
package/src/lib.js CHANGED
@@ -7,18 +7,18 @@ let libPath = '';
7
7
 
8
8
  if (platform === 'linux') {
9
9
  if (arch === 'x64') {
10
- libPath = 'dev-linux-amd64.so';
10
+ libPath = 'skyramp-linux-amd64.so';
11
11
  } else if (arch === 'ia32') {
12
- libPath = 'dev-linux-386.so';
12
+ libPath = 'skyramp-linux-386.so';
13
13
  }
14
14
  } else if (platform === 'darwin') {
15
15
  if (arch === 'x64') {
16
- libPath = 'dev-darwin-amd64.dylib';
16
+ libPath = 'skyramp-darwin-amd64.dylib';
17
17
  } else if (arch === 'arm64') {
18
- libPath = 'dev-darwin-arm64.dylib';
18
+ libPath = 'skyramp-darwin-arm64.dylib';
19
19
  }
20
20
  } else if (platform === 'win32') {
21
- libPath = 'dev-windows-amd64.dll';
21
+ libPath = 'skyramp-windows-amd64.dll';
22
22
  }
23
23
 
24
24
  if (!libPath) {
Binary file