Skip to content

Commit

Permalink
fix(sdk): misc fixes and improvements (#8297)
Browse files Browse the repository at this point in the history
* fix: include multiline and fileName in the multipart req body

* fix: reject setting null to insomnia.variables

* fix: comment

* fix: also update the scriptExecutor with getExistingConsole

* feat: support escape sequences for formatting in console

* fix: update test ouput

* refactor: support escape seqs

* fix: cli smoke test failed
  • Loading branch information
ihexxa authored Jan 21, 2025
1 parent 78a97f4 commit 95f524b
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 26 deletions.
2 changes: 1 addition & 1 deletion packages/insomnia-inso/src/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ describe('inso dev bundle', () => {
if (result.code !== 0) {
console.log(result);
}
expect(result.stdout).toContain('log: "we did it: 200"');
expect(result.stdout).toContain('log: we did it: 200');
});

it('iterationData and iterationCount args work', async () => {
Expand Down
19 changes: 17 additions & 2 deletions packages/insomnia-sdk/src/objects/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@ export interface Row {
timestamp: number;
}

export class Console {
class Console {
rows: Row[] = [];

constructor() { }

// TODO: support replacing substitution
printLog = (rows: Row[], level: LogLevel, ...values: any) => {
try {
const content = values.map(
(value: any) => {
return typeof value === 'string' ? value : JSON.stringify(value, null, 2);
}
).join(' ');

const row = {
value: `${level}: ` + values.map((a: any) => JSON.stringify(a, null, 2)).join('\n'),
value: `${level}: ${content}`,
name: 'Text',
timestamp: Date.now(),
};
Expand Down Expand Up @@ -66,3 +72,12 @@ export class Console {
.map(row => JSON.stringify(row) + '\n');
};
}

let builtInConsole = new Console();
export function getExistingConsole() {
return builtInConsole;
}
export function getNewConsole() {
builtInConsole = new Console();
return builtInConsole;
}
16 changes: 13 additions & 3 deletions packages/insomnia-sdk/src/objects/environments.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { getExistingConsole } from './console';
import { getInterpolator } from './interpolator';

export class Environment {
private _name: string;
private kvs = new Map<string, boolean | number | string>();
private kvs = new Map<string, boolean | number | string | undefined>();

constructor(name: string, jsonObject: object | undefined) {
this._name = name;
Expand All @@ -21,7 +22,11 @@ export class Environment {
return this.kvs.get(variableName);
};

set = (variableName: string, variableValue: boolean | number | string) => {
set = (variableName: string, variableValue: boolean | number | string | undefined | null) => {
if (variableValue === null) {
getExistingConsole().warn(`Variable "${variableName}" has a null value`);
return;
}
this.kvs.set(variableName, variableValue);
};

Expand Down Expand Up @@ -94,7 +99,12 @@ export class Variables {
return finalVal;
};

set = (variableName: string, variableValue: boolean | number | string) => {
set = (variableName: string, variableValue: boolean | number | string | undefined | null) => {
if (variableValue === null) {
getExistingConsole().warn(`Variable "${variableName}" has a null value`);
return;
}

this.localVars.set(variableName, variableValue);
};

Expand Down
42 changes: 32 additions & 10 deletions packages/insomnia-sdk/src/objects/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ export type RequestBodyMode = undefined | 'formdata' | 'urlencoded' | 'raw' | 'f
export interface RequestBodyOptions {
mode: RequestBodyMode;
file?: string;
formdata?: { key: string; value: string; type?: string }[];
graphql?: { query: string; operationName: string; variables: object };
formdata?: { key: string; value: string; type?: string; disabled?: boolean }[];
graphql?: { query: string; operationName: string; variables: object; disabled?: boolean };
raw?: string;
urlencoded?: { key: string; value: string; type?: string }[];
urlencoded?: { key: string; value: string; type?: string; disabled?: boolean; multiline?: boolean | string; fileName?: string }[];
options?: object;
}

Expand All @@ -29,11 +29,12 @@ export class FormParam extends Property {
value: string;
type?: string;

constructor(options: { key: string; value: string; type?: string }) {
constructor(options: { key: string; value: string; type?: string; disabled?: boolean }) {
super();
this.key = options.key;
this.value = options.value;
this.type = options.type;
this.disabled = options.disabled;
}

static _postman_propertyAllowsMultipleValues() {
Expand All @@ -49,7 +50,7 @@ export class FormParam extends Property {
// }

override toJSON() {
return { key: this.key, value: this.value, type: this.type };
return { key: this.key, value: this.value, type: this.type, disabled: this.disabled };
}

override toString() {
Expand Down Expand Up @@ -91,7 +92,14 @@ function getClassFields(opts: RequestBodyOptions) {
QueryParam,
undefined,
opts.urlencoded
.map(entry => ({ key: entry.key, value: entry.value, type: entry.type }))
.map(entry => ({
key: entry.key,
value: entry.value,
type: entry.type,
disabled: entry.disabled,
fileName: entry.fileName,
multiline: entry.multiline,
}))
.map(kv => new QueryParam(kv)),
);
}
Expand Down Expand Up @@ -569,7 +577,14 @@ export function toScriptRequestBody(insomniaReqBody: InsomniaRequestBody): Reque
reqBodyOpt = {
mode: 'urlencoded',
urlencoded: insomniaReqBody.params.map(
(param: RequestBodyParameter) => ({ key: param.name, value: param.value, type: param.type })
(param: RequestBodyParameter) => ({
key: param.name,
value: param.value,
type: param.type,
multiline: param.multiline,
disabled: param.disabled,
fileName: param.fileName,
})
),
};
}
Expand Down Expand Up @@ -621,9 +636,16 @@ export function mergeRequestBody(
text: textContent,
fileName: updatedReqBody?.file,
params: updatedReqBody?.urlencoded?.map(
(param: { key: string; value: string; type?: string }) => (
{ name: param.key, value: param.value, type: param.type }
),
(param: QueryParam) => {
return {
name: param.key,
value: param.value,
type: param.type,
fileName: param.fileName,
multiline: param.multiline,
disabled: param.disabled,
};
},
{},
),
};
Expand Down
3 changes: 1 addition & 2 deletions packages/insomnia-sdk/src/objects/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ export class Response extends Property {
throw Error('dataURI(): response body is not defined');
}

return `data:${contentInfo.contentType};baseg4, <base64-encoded-body>`;
return `data:${contentInfo.contentType};baseg4, ${bodyInBase64}`;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand All @@ -184,7 +184,6 @@ export class Response extends Property {
try {
const contentLength = this.headers.get('Content-Length');
// TODO: improve this by manual counting
console.log(this.headers.get('Content-Length'));
return contentLength == null ? -1 : parseInt(contentLength.valueOf());
} catch (e) {
throw Error('size: ${e}');
Expand Down
2 changes: 1 addition & 1 deletion packages/insomnia-sdk/src/objects/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export async function test(
testCase: msg,
status: 'failed',
executionTime,
errorMessage: `${e}`,
errorMessage: `error: ${e} | ACTUAL: ${e.actual} | EXPECTED: ${e.expected}`,
category: 'unknown',
});
}
Expand Down
16 changes: 15 additions & 1 deletion packages/insomnia-sdk/src/objects/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export function setUrlSearchParams(provider: any) {
export interface QueryParamOptions {
key: string;
value: string;
type?: string;
multiline?: string | boolean;
disabled?: boolean;
fileName?: string;
}

export class QueryParam extends Property {
Expand All @@ -17,8 +21,12 @@ export class QueryParam extends Property {
key: string;
value: string;
type?: string;
// the `multiline` and `fileName` are properties from Insomnia
// they are added here to avoid being dropped
multiline?: string | boolean;
fileName?: string;

constructor(options: { key: string; value: string; type?: string } | string) {
constructor(options: QueryParamOptions | string) {
super();

if (typeof options === 'string') {
Expand All @@ -27,13 +35,19 @@ export class QueryParam extends Property {
this.key = optionsObj.key;
this.value = optionsObj.value;
this.type = optionsObj.type;
this.multiline = optionsObj.multiline;
this.disabled = optionsObj.disabled;
this.fileName = optionsObj.fileName;
} catch (e) {
throw Error(`invalid QueryParam options ${e}`);
}
} else if (typeof options === 'object' && ('key' in options) && ('value' in options)) {
this.key = options.key;
this.value = options.value;
this.type = options.type;
this.multiline = options.multiline;
this.disabled = options.disabled;
this.fileName = options.fileName;
} else {
throw Error('unknown options for new QueryParam');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ test.describe('after-response script features tests', async () => {

const responsePane = page.getByTestId('response-pane');
await expect(responsePane).toContainText('PASS');
await expect(responsePane).toContainText('FAILunhappy tests | AssertionError: expected 199 to deeply equal 200After-response Test');
await expect(responsePane).toContainText('FAILunhappy tests | error: AssertionError: expected 199 to deeply equal 200 | ACTUAL: 199 | EXPECTED: 200');
});

test('environment and baseEnvironment can be persisted', async ({ page }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ test.describe('pre-request features tests', async () => {
await page.getByRole('tab', { name: 'Tests' }).click();

const responsePane = page.getByTestId('response-pane');
expect(responsePane).toContainText('FAILunhappy tests | AssertionError: expected 199 to deeply equal 200Pre-request Test');
expect(responsePane).toContainText('FAILunhappy tests | error: AssertionError: expected 199 to deeply equal 200 | ACTUAL: 199 | EXPECTED: 200Pre-request Test');
expect(responsePane).toContainText('PASShappy tests');
});

Expand Down
4 changes: 2 additions & 2 deletions packages/insomnia/src/hidden-window.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as Sentry from '@sentry/electron/renderer';
import { SENTRY_OPTIONS } from 'insomnia/src/common/sentry';
import { initInsomniaObject, InsomniaObject } from 'insomnia-sdk';
import { Console, mergeClientCertificates, mergeCookieJar, mergeRequests, mergeSettings, type RequestContext } from 'insomnia-sdk';
import { getNewConsole, mergeClientCertificates, mergeCookieJar, mergeRequests, mergeSettings, type RequestContext } from 'insomnia-sdk';
import * as _ from 'lodash';

export interface HiddenBrowserWindowBridgeAPI {
Expand Down Expand Up @@ -48,7 +48,7 @@ function translateTestHandlers(script: string): string {
const runScript = async (
{ script, context }: { script: string; context: RequestContext },
): Promise<RequestContext> => {
const scriptConsole = new Console();
const scriptConsole = getNewConsole();

const executionContext = await initInsomniaObject(context, scriptConsole.log);

Expand Down
4 changes: 2 additions & 2 deletions packages/insomnia/src/scriptExecutor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { appendFile } from 'node:fs/promises';

import { initInsomniaObject, InsomniaObject } from 'insomnia-sdk';
import { Console, mergeClientCertificates, mergeCookieJar, mergeRequests, mergeSettings, type RequestContext } from 'insomnia-sdk';
import { getNewConsole, mergeClientCertificates, mergeCookieJar, mergeRequests, mergeSettings, type RequestContext } from 'insomnia-sdk';
import * as _ from 'lodash';

import { invariant } from '../src/utils/invariant';
Expand All @@ -11,7 +11,7 @@ export const runScript = async (
{ script, context }: { script: string; context: RequestContext },
): Promise<RequestContext> => {
// console.log(script);
const scriptConsole = new Console();
const scriptConsole = getNewConsole();

const executionContext = await initInsomniaObject(context, scriptConsole.log);

Expand Down

0 comments on commit 95f524b

Please sign in to comment.