diff --git a/packages/insomnia-smoke-test/tests/smoke/pre-request-script-ui.test.ts b/packages/insomnia-smoke-test/tests/smoke/pre-request-script-ui.test.ts index facc1e602f..d47bfeb5d8 100644 --- a/packages/insomnia-smoke-test/tests/smoke/pre-request-script-ui.test.ts +++ b/packages/insomnia-smoke-test/tests/smoke/pre-request-script-ui.test.ts @@ -85,7 +85,7 @@ test.describe('pre-request UI tests', async () => { }, }, { - name: 'environments/ envrionment from script should be overidden by folder environment', + name: 'environments / envrionment from script should be overidden by folder environment', preReqScript: ` // "customValue" is already defined in the folder environment. // folder version will override the following wone @@ -98,6 +98,29 @@ test.describe('pre-request UI tests', async () => { customValue: 'fromFolder', }, }, + { + name: 'variables / manipulate variables and set them to environment', + preReqScript: ` + // set local + pm.variables.set('varStr', 'varStr'); + pm.variables.set('varNum', 777); + pm.variables.set('varBool', true); + // has + pm.environment.set('varStr', pm.variables.get('varStr')); + pm.environment.set('varNum', pm.variables.get('varNum')); + pm.environment.set('varBool', pm.variables.get('varBool')); + `, + body: `{ + "varStr": "{{ _.varStr }}", + "varNum": {{ _.varNum }}, + "varBool": {{ _.varBool }} + }`, + expectedBody: { + varStr: 'varStr', + varNum: 777, + varBool: true, + }, + }, ]; for (let i = 0; i < testCases.length; i++) { diff --git a/packages/insomnia/src/sdk/objects/environments.ts b/packages/insomnia/src/sdk/objects/environments.ts index fe426f99fb..9ed42f4cc2 100644 --- a/packages/insomnia/src/sdk/objects/environments.ts +++ b/packages/insomnia/src/sdk/objects/environments.ts @@ -34,3 +34,79 @@ export class Environment { return Object.fromEntries(this.kvs.entries()); }; } + +export class Variables { + // TODO: support vars for all levels + private globals: Environment; + private collection: Environment; + private environment: Environment; + private data: Environment; + private local: Environment; + + constructor( + args: { + globals: Environment; + collection: Environment; + environment: Environment; + data: Environment; + }, + ) { + this.globals = args.globals; + this.collection = args.collection; + this.environment = args.environment; + this.data = args.data; + this.local = new Environment({}); + } + + has = (variableName: string) => { + const globalsHas = this.globals.has(variableName); + const collectionHas = this.collection.has(variableName); + const environmentHas = this.environment.has(variableName); + const dataHas = this.data.has(variableName); + const localHas = this.local.has(variableName); + + return globalsHas || collectionHas || environmentHas || dataHas || localHas; + }; + + get = (variableName: string) => { + let finalVal: boolean | number | string | object | undefined = undefined; + [ + this.local, + this.data, + this.environment, + this.collection, + this.globals, + ].forEach(vars => { + const value = vars.get(variableName); + if (!finalVal && value) { + finalVal = value; + } + }); + + return finalVal; + }; + + set = (variableName: string, variableValue: boolean | number | string) => { + this.local.set(variableName, variableValue); + }; + + // replaceIn = (template: string) => { + // const context = this.toObject(); + // return getIntepolator().render(template, context); + // }; + + toObject = () => { + return [ + this.globals, + this.collection, + this.environment, + this.data, + this.local, + ].map( + vars => vars.toObject() + ).reduce( + (ctx, obj) => ({ ...ctx, ...obj }), + {}, + ); + }; +} diff --git a/packages/insomnia/src/sdk/objects/insomnia.ts b/packages/insomnia/src/sdk/objects/insomnia.ts index 230aa29f91..a9f5e688c8 100644 --- a/packages/insomnia/src/sdk/objects/insomnia.ts +++ b/packages/insomnia/src/sdk/objects/insomnia.ts @@ -1,33 +1,59 @@ import type { Request } from '../../models/request'; -import { Environment } from './environments'; +import { Environment, Variables } from './environments'; export interface RequestContext { request: Request; timelinePath: string; environment?: object; baseEnvironment?: object; + collectionVariables?: object; + globals?: object; + iterationData?: object; } export class InsomniaObject { public environment: Environment; public collectionVariables: Environment; public baseEnvironment: Environment; + public variables: Variables; + // TODO: follows will be enabled after Insomnia supports them + private _globals: Environment; + private _iterationData: Environment; constructor( rawObj: { + globals: Environment; + iterationData: Environment; environment: Environment; baseEnvironment: Environment; + variables: Variables; }, ) { + this._globals = rawObj.globals; this.environment = rawObj.environment; this.baseEnvironment = rawObj.baseEnvironment; this.collectionVariables = this.baseEnvironment; // collectionVariables is mapped to baseEnvironment + this._iterationData = rawObj.iterationData; + this.variables = rawObj.variables; + } + + // TODO: remove this after enabled globals + get globals() { + throw new Error('Globals is not supported yet'); + } + + // TODO: remove this after enabled iterationData + get iterationData() { + throw new Error('iterationData is not supported yet'); } toObject = () => { return { + globals: this._globals.toObject(), environment: this.environment.toObject(), baseEnvironment: this.baseEnvironment.toObject(), + iterationData: this._iterationData.toObject(), + variables: this.variables.toObject(), }; }; } @@ -35,13 +61,26 @@ export class InsomniaObject { export function initInsomniaObject( rawObj: RequestContext, ) { + const globals = new Environment(rawObj.globals); const environment = new Environment(rawObj.environment); const baseEnvironment = new Environment(rawObj.baseEnvironment); + const iterationData = new Environment(rawObj.iterationData); + const collectionVariables = new Environment(rawObj.collectionVariables); + + const variables = new Variables({ + globals, + environment, + collection: collectionVariables, + data: iterationData, + }); return new InsomniaObject( { + globals, environment, baseEnvironment, + iterationData, + variables, }, ); };