diff --git a/packages/insomnia/src/common/__tests__/render.test.ts b/packages/insomnia/src/common/__tests__/render.test.ts index f32bd6bfd96d..80c14cc10e90 100644 --- a/packages/insomnia/src/common/__tests__/render.test.ts +++ b/packages/insomnia/src/common/__tests__/render.test.ts @@ -737,4 +737,43 @@ describe('render tests', () => { ); }); }); + + describe('getRenderedRequestAndContext()', () => { + it('renders request templates in the main-process path', async () => { + const workspace = await services.workspace.create(); + const environment = await services.environment.create({ + parentId: workspace._id, + data: { + host: 'example.com', + name: 'world', + }, + }); + const request = Object.assign(models.request.init(), { + parentId: workspace._id, + name: 'Hello {{ name }}', + url: 'https://{{ host }}/{{ name }}', + }); + const originalProcessType = process.type; + + Object.defineProperty(process, 'type', { + configurable: true, + value: 'browser', + }); + + try { + const result = await renderUtils.getRenderedRequestAndContext({ + request, + environment: environment._id, + }); + + expect(result.request.name).toBe('Hello world'); + expect(result.request.url).toBe('https://example.com/world'); + } finally { + Object.defineProperty(process, 'type', { + configurable: true, + value: originalProcessType, + }); + } + }); + }); }); diff --git a/packages/insomnia/src/plugins/context/app.ts b/packages/insomnia/src/plugins/context/app.ts index 22d61e6387a7..d33ce6bb016a 100644 --- a/packages/insomnia/src/plugins/context/app.ts +++ b/packages/insomnia/src/plugins/context/app.ts @@ -42,6 +42,9 @@ export const init = (renderPurpose: RenderPurpose = 'general'): { app: AppContex }, getPath: (name: string) => { + if (!isRenderer) { + return ''; + } invariant(name.toLowerCase() === 'desktop', `Unknown path name ${name}`); return window.app.getPath('desktop'); }, @@ -50,7 +53,7 @@ export const init = (renderPurpose: RenderPurpose = 'general'): { app: AppContex showSaveDialog: async (options = {}) => { const sendOrNoRender = renderPurpose === 'send' || renderPurpose === 'no-render'; - if (!sendOrNoRender) { + if (!sendOrNoRender || !isRenderer) { return null; } @@ -63,9 +66,9 @@ export const init = (renderPurpose: RenderPurpose = 'general'): { app: AppContex }, clipboard: { - readText: () => window.clipboard.readText(), - writeText: text => window.clipboard.writeText(text), - clear: () => window.clipboard.clear(), + readText: () => (isRenderer ? window.clipboard.readText() : ''), + writeText: text => { if (isRenderer) { window.clipboard.writeText(text); } }, + clear: () => { if (isRenderer) { window.clipboard.clear(); } }, }, }, }); diff --git a/packages/insomnia/src/templating/__tests__/index.test.ts b/packages/insomnia/src/templating/__tests__/index.test.ts new file mode 100644 index 000000000000..b7a3522db2a0 --- /dev/null +++ b/packages/insomnia/src/templating/__tests__/index.test.ts @@ -0,0 +1,20 @@ +import { describe, expect, it } from 'vitest'; + +import { render } from '../index'; + +describe('templating/index (Node environment)', () => { + it('renders a simple variable template', async () => { + const result = await render('{{ name }}', { context: { name: 'world' } }); + expect(result).toBe('world'); + }); + + it('renders nested context via _ accessor', async () => { + const result = await render('{{ _.greeting }}', { context: { greeting: 'hello' } }); + expect(result).toBe('hello'); + }); + + it('returns plain text unchanged', async () => { + const result = await render('no template here'); + expect(result).toBe('no template here'); + }); +}); diff --git a/packages/insomnia/src/templating/base-extension.ts b/packages/insomnia/src/templating/base-extension.ts index 3c81f008399a..5f26db4ecdbd 100644 --- a/packages/insomnia/src/templating/base-extension.ts +++ b/packages/insomnia/src/templating/base-extension.ts @@ -120,7 +120,12 @@ export default class BaseExtension { userInfo: os.userInfo(), }; }, - readFile: async (path: string) => window.main.secureReadFile({ path }), + readFile: async (path: string) => { + if (typeof window !== 'undefined' && window.main?.secureReadFile) { + return window.main.secureReadFile({ path }); + } + return ''; + }, decode: async (buffer: Buffer, encoding = 'utf8') => iconv.decode(buffer, encoding), encode: async (input: string, encoding: BinaryToTextEncoding) => crypto.createHash('md5').update(input).digest(encoding), @@ -128,7 +133,11 @@ export default class BaseExtension { templating.render(str, { context: renderContext, }), - openInBrowser: (url: string) => window.main.openInBrowser(url), + openInBrowser: (url: string) => { + if (typeof window !== 'undefined' && window.main?.openInBrowser) { + window.main.openInBrowser(url); + } + }, models: { request: { getById: services.request.getById, diff --git a/packages/insomnia/src/templating/index.ts b/packages/insomnia/src/templating/index.ts index 3e433c2cf7e8..2d20ef8b96d6 100644 --- a/packages/insomnia/src/templating/index.ts +++ b/packages/insomnia/src/templating/index.ts @@ -2,12 +2,19 @@ import { localTemplateTags } from 'insomnia/src/templating/local-template-tags'; import type { Environment } from 'nunjucks'; import BaseExtension from './base-extension'; -import { nunjucks } from './nunjucks.client'; import { extractUndefinedVariableKey, RenderError } from './render-error'; // Some constants export const NUNJUCKS_TEMPLATE_GLOBAL_PROPERTY_NAME = '_'; +/** Load the appropriate nunjucks runtime: browser bundle for renderer, Node bundle otherwise. */ +async function loadNunjucks() { + if (process.type === 'renderer') { + return (await import('./nunjucks.client')).nunjucks; + } + return (await import('./nunjucks.node')).nunjucks; +} + type NunjucksEnvironment = Environment & { extensions: Record; }; @@ -139,7 +146,8 @@ async function getNunjucks(ignoreUndefinedEnvVariable?: boolean): Promise {}); nunjucksEnvironment.addGlobal('cycler', () => {}); nunjucksEnvironment.addGlobal('joiner', () => {}); diff --git a/packages/insomnia/src/templating/nunjucks.node.ts b/packages/insomnia/src/templating/nunjucks.node.ts new file mode 100644 index 000000000000..1ba9354f1961 --- /dev/null +++ b/packages/insomnia/src/templating/nunjucks.node.ts @@ -0,0 +1 @@ +export { default as nunjucks } from 'nunjucks';