mirror of
https://github.com/Kong/insomnia.git
synced 2026-10-22 23:05:25 -04:00
Merge branch 'develop' of github.com:getinsomnia/insomnia into develop
This commit is contained in:
commit
2e25cf22cd
71 files changed
+1802
-1420
No files matched your search
Generated
+10
-10
@@ -1785,7 +1785,7 @@
|
||||
},
|
||||
"array-equal": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
|
||||
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -1916,7 +1916,7 @@
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -1929,7 +1929,7 @@
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -2036,7 +2036,7 @@
|
||||
},
|
||||
"babel-plugin-syntax-object-rest-spread": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
|
||||
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -2329,7 +2329,7 @@
|
||||
},
|
||||
"callsites": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "http://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
|
||||
"integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -3291,7 +3291,7 @@
|
||||
},
|
||||
"expand-range": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
|
||||
"integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -6129,7 +6129,7 @@
|
||||
},
|
||||
"jsesc": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
|
||||
"integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -6159,7 +6159,7 @@
|
||||
},
|
||||
"json5": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
|
||||
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -8315,7 +8315,7 @@
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "http://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
|
||||
"integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -9736,7 +9736,7 @@
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
},
|
||||
"mac": {
|
||||
"category": "public.app-category.developer-tools",
|
||||
"darkModeSupport": true,
|
||||
"target": [
|
||||
"dmg",
|
||||
"zip"
|
||||
|
||||
@@ -69,12 +69,19 @@ export const FLEXIBLE_URL_REGEX = /^(http|https):\/\/[\wàâäèéêëîïôóœ
|
||||
export const CHECK_FOR_UPDATES_INTERVAL = 1000 * 60 * 60 * 3; // 3 hours
|
||||
export const PLUGIN_PATH = path.join(getDataDirectory(), 'plugins');
|
||||
|
||||
// Available editor key maps
|
||||
export const EDITOR_KEY_MAP_DEFAULT = 'default';
|
||||
export const EDITOR_KEY_MAP_EMACS = 'emacs';
|
||||
export const EDITOR_KEY_MAP_SUBLIME = 'sublime';
|
||||
export const EDITOR_KEY_MAP_VIM = 'vim';
|
||||
|
||||
// Hotkeys
|
||||
export const MNEMONIC_SYM = isMac() ? '' : '&';
|
||||
export const MOD_SYM = isMac() ? '⌘' : 'Ctrl';
|
||||
export const ALT_SYM = isMac() ? '⌃' : 'Alt';
|
||||
export const SHIFT_SYM = isMac() ? '⇧' : 'Shift';
|
||||
export const CTRL_SYM = isMac() ? '⌃' : 'Ctrl';
|
||||
export const ALT_SYM = isMac() ? '⌥' : 'Alt';
|
||||
export const SHIFT_SYM = isMac() ? '⇧' : 'Shift';
|
||||
export const META_SYM = isMac() ? '⌘' : 'Super';
|
||||
|
||||
export function joinHotKeys(keys) {
|
||||
return keys.join(isMac() ? '' : '+');
|
||||
}
|
||||
|
||||
@@ -339,12 +339,7 @@ export async function exportHarWithRenderedRequest(
|
||||
|
||||
// Set auth header if we have it
|
||||
if (!misc.hasAuthHeader(renderedRequest.headers)) {
|
||||
const header = await getAuthHeader(
|
||||
renderedRequest._id,
|
||||
url,
|
||||
renderedRequest.method,
|
||||
renderedRequest.authentication,
|
||||
);
|
||||
const header = await getAuthHeader(renderedRequest, url);
|
||||
if (header) {
|
||||
renderedRequest.headers.push({
|
||||
name: header.name,
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// @flow
|
||||
import type { HotKeyDefinition, KeyBindings } from './hotkeys';
|
||||
import { getPlatformKeyCombinations } from './hotkeys';
|
||||
import * as models from '../models';
|
||||
|
||||
function _pressedHotKey(e: KeyboardEvent, bindings: KeyBindings): boolean {
|
||||
const isCtrlPressed = e.ctrlKey;
|
||||
const isAltPressed = e.altKey;
|
||||
const isShiftPressed = e.shiftKey;
|
||||
const isMetaPressed = e.metaKey;
|
||||
const keyCombList = getPlatformKeyCombinations(bindings);
|
||||
|
||||
for (const keyComb of keyCombList) {
|
||||
const { ctrl, alt, shift, meta, keyCode } = keyComb;
|
||||
|
||||
if ((ctrl && !isCtrlPressed) || (!ctrl && isCtrlPressed)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((alt && !isAltPressed) || (!alt && isAltPressed)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((shift && !isShiftPressed) || (!shift && isShiftPressed)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((meta && !isMetaPressed) || (!meta && isMetaPressed)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keyCode !== e.keyCode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a hotkey has been pressed.
|
||||
* @param e the activated keyboard event.
|
||||
* @param definition the hotkey definition being checked.
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
export async function pressedHotKey(
|
||||
e: KeyboardEvent,
|
||||
definition: HotKeyDefinition,
|
||||
): Promise<boolean> {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
return _pressedHotKey(e, settings.hotKeyRegistry[definition.id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call callback if the hotkey has been pressed.
|
||||
* @param e the activated keyboard event.
|
||||
* @param definition the hotkey definition being checked.
|
||||
* @param callback to be called if the hotkey has been activated.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function executeHotKey(
|
||||
e: KeyboardEvent,
|
||||
definition: HotKeyDefinition,
|
||||
callback: Function,
|
||||
): Promise<void> {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
if (_pressedHotKey(e, settings.hotKeyRegistry[definition.id])) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
@@ -2,304 +2,371 @@
|
||||
import keycodes from './keycodes';
|
||||
import { isMac } from './constants';
|
||||
|
||||
export type Hotkey = {
|
||||
/**
|
||||
* The readable definition of a hotkey.
|
||||
* The {@code id} the hotkey's reference id.
|
||||
*/
|
||||
export type HotKeyDefinition = {
|
||||
id: string,
|
||||
description: string,
|
||||
meta: boolean,
|
||||
};
|
||||
|
||||
/**
|
||||
* The combination of key presses that will activate a hotkey if pressed.
|
||||
*/
|
||||
export type KeyCombination = {
|
||||
ctrl: boolean,
|
||||
alt: boolean,
|
||||
shift: boolean,
|
||||
keycode: number | Array<number>,
|
||||
metaIsCtrl?: boolean,
|
||||
meta: boolean,
|
||||
keyCode: number,
|
||||
};
|
||||
|
||||
export const SHOW_WORKSPACE_SETTINGS: Hotkey = {
|
||||
description: 'Show Workspace Settings',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: true,
|
||||
keycode: keycodes.comma,
|
||||
/**
|
||||
* The collection of a hotkey's key combinations for each platforms.
|
||||
*/
|
||||
export type KeyBindings = {
|
||||
macKeys: Array<KeyCombination>,
|
||||
// The key combinations for both Windows and Linux.
|
||||
winLinuxKeys: Array<KeyCombination>,
|
||||
};
|
||||
|
||||
export const SHOW_REQUEST_SETTINGS: Hotkey = {
|
||||
description: 'Show Request Settings',
|
||||
meta: true,
|
||||
alt: true,
|
||||
shift: true,
|
||||
keycode: keycodes.comma,
|
||||
/**
|
||||
* The collection of defined hotkeys.
|
||||
* The registry maps a hotkey by its reference id to its key bindings.
|
||||
*/
|
||||
export type HotKeyRegistry = {
|
||||
[refId: string]: KeyBindings,
|
||||
};
|
||||
|
||||
export const SHOW_KEYBOARD_SHORTCUTS: Hotkey = {
|
||||
description: 'Show Keyboard Shortcuts',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: true,
|
||||
keycode: keycodes.forwardslash,
|
||||
};
|
||||
|
||||
export const SHOW_SETTINGS: Hotkey = {
|
||||
description: 'Show App Preferences',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.comma,
|
||||
};
|
||||
|
||||
export const TOGGLE_MAIN_MENU: Hotkey = {
|
||||
description: 'Toggle Main Menu',
|
||||
meta: true,
|
||||
alt: true,
|
||||
shift: false,
|
||||
keycode: keycodes.comma,
|
||||
};
|
||||
|
||||
export const TOGGLE_SIDEBAR: Hotkey = {
|
||||
description: 'Toggle Sidebar',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.backslash,
|
||||
};
|
||||
|
||||
export const SHOW_QUICK_SWITCHER: Hotkey = {
|
||||
description: 'Switch Requests',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.p,
|
||||
};
|
||||
|
||||
export const RELOAD_PLUGINS: Hotkey = {
|
||||
description: 'Reload Plugins',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: true,
|
||||
keycode: keycodes.r,
|
||||
};
|
||||
|
||||
export const SHOW_AUTOCOMPLETE: Hotkey = {
|
||||
description: 'Show Autocomplete',
|
||||
meta: true,
|
||||
metaIsCtrl: true,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.space,
|
||||
};
|
||||
|
||||
export const SEND_REQUEST: Hotkey = {
|
||||
description: 'Send Request',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: [keycodes.enter, keycodes.r],
|
||||
};
|
||||
|
||||
export const SEND_REQUEST_F5: Hotkey = {
|
||||
description: 'Send Request',
|
||||
meta: false,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.f5,
|
||||
};
|
||||
|
||||
export const SHOW_SEND_OPTIONS: Hotkey = {
|
||||
description: 'Send Request (Options)',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: true,
|
||||
keycode: keycodes.enter,
|
||||
};
|
||||
|
||||
export const SHOW_ENVIRONMENTS: Hotkey = {
|
||||
description: 'Show Environment Editor',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.e,
|
||||
};
|
||||
|
||||
export const TOGGLE_ENVIRONMENTS_MENU: Hotkey = {
|
||||
description: 'Switch Environments',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: true,
|
||||
keycode: keycodes.e,
|
||||
};
|
||||
|
||||
export const TOGGLE_METHOD_DROPDOWN: Hotkey = {
|
||||
description: 'Change HTTP Method',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: true,
|
||||
keycode: keycodes.l,
|
||||
};
|
||||
|
||||
export const TOGGLE_HISTORY_DROPDOWN: Hotkey = {
|
||||
description: 'Show Request History',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: true,
|
||||
keycode: keycodes.h,
|
||||
};
|
||||
|
||||
export const FOCUS_URL: Hotkey = {
|
||||
description: 'Focus URL',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.l,
|
||||
};
|
||||
|
||||
export const GENERATE_CODE: Hotkey = {
|
||||
description: 'Generate Code',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: true,
|
||||
keycode: keycodes.g,
|
||||
};
|
||||
|
||||
export const FOCUS_FILTER: Hotkey = {
|
||||
description: 'Filter Sidebar',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: true,
|
||||
keycode: keycodes.f,
|
||||
};
|
||||
|
||||
export const FOCUS_RESPONSE: Hotkey = {
|
||||
description: 'Focus Response',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.singlequote,
|
||||
};
|
||||
|
||||
export const SHOW_COOKIES: Hotkey = {
|
||||
description: 'Edit Cookies',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.k,
|
||||
};
|
||||
|
||||
export const CREATE_REQUEST: Hotkey = {
|
||||
description: 'Create Request',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.n,
|
||||
};
|
||||
|
||||
export const DELETE_REQUEST: Hotkey = {
|
||||
description: 'Delete Request',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: true,
|
||||
keycode: keycodes.delete,
|
||||
};
|
||||
|
||||
export const CREATE_FOLDER: Hotkey = {
|
||||
description: 'Create Folder',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: true,
|
||||
keycode: keycodes.n,
|
||||
};
|
||||
|
||||
export const DUPLICATE_REQUEST: Hotkey = {
|
||||
description: 'Duplicate Request',
|
||||
meta: true,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.d,
|
||||
};
|
||||
|
||||
export const CLOSE_DROPDOWN: Hotkey = {
|
||||
description: 'Close Dropdown',
|
||||
meta: false,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.esc,
|
||||
};
|
||||
|
||||
export const CLOSE_MODAL: Hotkey = {
|
||||
description: 'Close Modal',
|
||||
meta: false,
|
||||
alt: false,
|
||||
shift: false,
|
||||
keycode: keycodes.esc,
|
||||
};
|
||||
|
||||
export const UNCOVER_VARIABLES: Hotkey = {
|
||||
description: 'Uncover Variables',
|
||||
meta: false,
|
||||
alt: true,
|
||||
shift: true,
|
||||
keycode: keycodes.u,
|
||||
};
|
||||
|
||||
export function pressedHotKey(e: KeyboardEvent, definition: Hotkey): boolean {
|
||||
const isMetaPressed = isMac() ? e.metaKey : e.ctrlKey;
|
||||
const isAltPressed = isMac() ? e.ctrlKey : e.altKey;
|
||||
const isShiftPressed = e.shiftKey;
|
||||
|
||||
const { meta, alt, shift, keycode } = definition;
|
||||
const codes = Array.isArray(keycode) ? keycode : [keycode];
|
||||
|
||||
for (const code of codes) {
|
||||
if ((alt && !isAltPressed) || (!alt && isAltPressed)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((meta && !isMetaPressed) || (!meta && isMetaPressed)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((shift && !isShiftPressed) || (!shift && isShiftPressed)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (code !== e.keyCode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
function defineHotKey(id: string, description: string): HotKeyDefinition {
|
||||
return {
|
||||
id: id,
|
||||
description: description,
|
||||
};
|
||||
}
|
||||
|
||||
export function executeHotKey(e: KeyboardEvent, definition: Hotkey, callback: Function): void {
|
||||
if (pressedHotKey(e, definition)) {
|
||||
callback();
|
||||
}
|
||||
function keyComb(
|
||||
ctrl: boolean,
|
||||
alt: boolean,
|
||||
shift: boolean,
|
||||
meta: boolean,
|
||||
keyCode: number,
|
||||
): KeyCombination {
|
||||
return {
|
||||
ctrl: ctrl,
|
||||
alt: alt,
|
||||
shift: shift,
|
||||
meta: meta,
|
||||
keyCode: keyCode,
|
||||
};
|
||||
}
|
||||
|
||||
export function getChar(hotkey: Hotkey) {
|
||||
const codes = Array.isArray(hotkey.keycode) ? hotkey.keycode : [hotkey.keycode];
|
||||
const chars = [];
|
||||
function keyBinds(
|
||||
mac: KeyCombination | Array<KeyCombination>,
|
||||
winLinux: KeyCombination | Array<KeyCombination>,
|
||||
): KeyBindings {
|
||||
if (!Array.isArray(mac)) {
|
||||
mac = [mac];
|
||||
}
|
||||
|
||||
for (const keycode of codes) {
|
||||
const v = Object.keys(keycodes).find(k => keycodes[k] === keycode);
|
||||
if (!Array.isArray(winLinux)) {
|
||||
winLinux = [winLinux];
|
||||
}
|
||||
|
||||
if (!v) {
|
||||
console.error('Invalid hotkey', hotkey);
|
||||
} else if (v.toUpperCase() === 'ENTER') {
|
||||
chars.push('Enter');
|
||||
} else if (v.toUpperCase() === 'DELETE') {
|
||||
chars.push('Delete');
|
||||
} else if (v.toUpperCase() === 'COMMA') {
|
||||
chars.push(',');
|
||||
} else if (v.toUpperCase() === 'BACKSLASH') {
|
||||
chars.push('\\');
|
||||
} else if (v.toUpperCase() === 'FORWARDSLASH') {
|
||||
chars.push('/');
|
||||
} else if (v.toUpperCase() === 'SINGLEQUOTE') {
|
||||
chars.push("'");
|
||||
} else if (v.toUpperCase() === 'SPACE') {
|
||||
chars.push('Space');
|
||||
return {
|
||||
macKeys: mac,
|
||||
winLinuxKeys: winLinux,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The collection of available hotkeys' and their definitions.
|
||||
*/
|
||||
// Not using dot, because NeDB prohibits field names to contain dots.
|
||||
export const hotKeyRefs = {
|
||||
WORKSPACE_SHOW_SETTINGS: defineHotKey('workspace_showSettings', 'Show Workspace Settings'),
|
||||
|
||||
REQUEST_SHOW_SETTINGS: defineHotKey('request_showSettings', 'Show Request Settings'),
|
||||
|
||||
PREFERENCES_SHOW_KEYBOARD_SHORTCUTS: defineHotKey(
|
||||
'preferences_showKeyboardShortcuts',
|
||||
'Show Keyboard Shortcuts',
|
||||
),
|
||||
|
||||
PREFERENCES_SHOW_GENERAL: defineHotKey('preferences_showGeneral', 'Show App Preferences'),
|
||||
|
||||
TOGGLE_MAIN_MENU: defineHotKey('toggleMainMenu', 'Toggle Main Menu'),
|
||||
|
||||
SIDEBAR_TOGGLE: defineHotKey('sidebar_toggle', 'Toggle Sidebar'),
|
||||
|
||||
REQUEST_QUICK_SWITCH: defineHotKey('request_quickSwitch', 'Switch Requests'),
|
||||
|
||||
PLUGIN_RELOAD: defineHotKey('plugin_reload', 'Reload Plugins'),
|
||||
|
||||
SHOW_AUTOCOMPLETE: defineHotKey('showAutocomplete', 'Show Autocomplete'),
|
||||
|
||||
REQUEST_SEND: defineHotKey('request_send', 'Send Request'),
|
||||
|
||||
REQUEST_SHOW_OPTIONS: defineHotKey('request_showOptions', 'Send Request (Options)'),
|
||||
|
||||
ENVIRONMENT_SHOW_EDITOR: defineHotKey('environment_showEditor', 'Show Environment Editor'),
|
||||
|
||||
ENVIRONMENT_SHOW_SWITCH_MENU: defineHotKey('environment_showSwitchMenu', 'Switch Environments'),
|
||||
|
||||
REQUEST_TOGGLE_HTTP_METHOD_MENU: defineHotKey(
|
||||
'request_toggleHttpMethodMenu',
|
||||
'Change HTTP Method',
|
||||
),
|
||||
|
||||
REQUEST_TOGGLE_HISTORY: defineHotKey('request_toggleHistory', 'Show Request History'),
|
||||
|
||||
REQUEST_FOCUS_URL: defineHotKey('request_focusUrl', 'Focus URL'),
|
||||
|
||||
REQUEST_SHOW_GENERATE_CODE_EDITOR: defineHotKey(
|
||||
'request_showGenerateCodeEditor',
|
||||
'Generate Code',
|
||||
),
|
||||
|
||||
SIDEBAR_FOCUS_FILTER: defineHotKey('sidebar_focusFilter', 'Filter Sidebar'),
|
||||
|
||||
RESPONSE_FOCUS: defineHotKey('response_focus', 'Focus Response'),
|
||||
|
||||
SHOW_COOKIES_EDITOR: defineHotKey('showCookiesEditor', 'Edit Cookies'),
|
||||
|
||||
REQUEST_SHOW_CREATE: defineHotKey('request_showCreate', 'Create Request'),
|
||||
|
||||
REQUEST_SHOW_DELETE: defineHotKey('request_showDelete', 'Delete Request'),
|
||||
|
||||
REQUEST_SHOW_CREATE_FOLDER: defineHotKey('request_showCreateFolder', 'Create Folder'),
|
||||
|
||||
REQUEST_SHOW_DUPLICATE: defineHotKey('request_showDuplicate', 'Duplicate Request'),
|
||||
|
||||
CLOSE_DROPDOWN: defineHotKey('closeDropdown', 'Close Dropdown'),
|
||||
|
||||
CLOSE_MODAL: defineHotKey('closeModal', 'Close Modal'),
|
||||
|
||||
ENVIRONMENT_UNCOVER_VARIABLES: defineHotKey('environment_uncoverVariables', 'Uncover Variables'),
|
||||
};
|
||||
|
||||
/**
|
||||
* The default key bindings values of all available hotkeys.
|
||||
*/
|
||||
const defaultRegistry: HotKeyRegistry = {
|
||||
[hotKeyRefs.WORKSPACE_SHOW_SETTINGS.id]: keyBinds(
|
||||
keyComb(false, false, true, true, keycodes.comma),
|
||||
keyComb(true, false, true, false, keycodes.comma),
|
||||
),
|
||||
|
||||
[hotKeyRefs.REQUEST_SHOW_SETTINGS.id]: keyBinds(
|
||||
keyComb(false, true, true, true, keycodes.comma),
|
||||
keyComb(true, true, true, false, keycodes.comma),
|
||||
),
|
||||
|
||||
[hotKeyRefs.PREFERENCES_SHOW_KEYBOARD_SHORTCUTS.id]: keyBinds(
|
||||
keyComb(false, false, true, true, keycodes.forwardslash),
|
||||
keyComb(true, false, true, false, keycodes.forwardslash),
|
||||
),
|
||||
|
||||
[hotKeyRefs.PREFERENCES_SHOW_GENERAL.id]: keyBinds(
|
||||
keyComb(false, false, false, true, keycodes.comma),
|
||||
keyComb(true, false, false, false, keycodes.comma),
|
||||
),
|
||||
|
||||
[hotKeyRefs.TOGGLE_MAIN_MENU.id]: keyBinds(
|
||||
keyComb(false, true, false, true, keycodes.comma),
|
||||
keyComb(true, true, false, false, keycodes.comma),
|
||||
),
|
||||
|
||||
[hotKeyRefs.SIDEBAR_TOGGLE.id]: keyBinds(
|
||||
keyComb(false, false, false, true, keycodes.backslash),
|
||||
keyComb(true, false, false, false, keycodes.backslash),
|
||||
),
|
||||
|
||||
[hotKeyRefs.REQUEST_QUICK_SWITCH.id]: keyBinds(
|
||||
keyComb(false, false, false, true, keycodes.p),
|
||||
keyComb(true, false, false, false, keycodes.p),
|
||||
),
|
||||
|
||||
[hotKeyRefs.PLUGIN_RELOAD.id]: keyBinds(
|
||||
keyComb(false, false, true, true, keycodes.r),
|
||||
keyComb(true, false, true, false, keycodes.r),
|
||||
),
|
||||
|
||||
[hotKeyRefs.SHOW_AUTOCOMPLETE.id]: keyBinds(
|
||||
keyComb(true, false, false, false, keycodes.space),
|
||||
keyComb(true, false, false, false, keycodes.space),
|
||||
),
|
||||
|
||||
[hotKeyRefs.REQUEST_SEND.id]: keyBinds(
|
||||
[
|
||||
keyComb(false, false, false, true, keycodes.enter),
|
||||
keyComb(false, false, false, true, keycodes.r),
|
||||
keyComb(false, false, false, false, keycodes.f5),
|
||||
],
|
||||
[
|
||||
keyComb(true, false, false, false, keycodes.enter),
|
||||
keyComb(true, false, false, false, keycodes.r),
|
||||
keyComb(false, false, false, false, keycodes.f5),
|
||||
],
|
||||
),
|
||||
|
||||
[hotKeyRefs.REQUEST_SHOW_OPTIONS.id]: keyBinds(
|
||||
keyComb(false, false, true, true, keycodes.enter),
|
||||
keyComb(true, false, true, false, keycodes.enter),
|
||||
),
|
||||
|
||||
[hotKeyRefs.ENVIRONMENT_SHOW_EDITOR.id]: keyBinds(
|
||||
keyComb(false, false, false, true, keycodes.e),
|
||||
keyComb(true, false, false, false, keycodes.e),
|
||||
),
|
||||
|
||||
[hotKeyRefs.ENVIRONMENT_SHOW_SWITCH_MENU.id]: keyBinds(
|
||||
keyComb(false, false, true, true, keycodes.e),
|
||||
keyComb(true, false, true, false, keycodes.e),
|
||||
),
|
||||
|
||||
[hotKeyRefs.REQUEST_TOGGLE_HTTP_METHOD_MENU.id]: keyBinds(
|
||||
keyComb(false, false, true, true, keycodes.l),
|
||||
keyComb(true, false, true, false, keycodes.l),
|
||||
),
|
||||
|
||||
[hotKeyRefs.REQUEST_TOGGLE_HISTORY.id]: keyBinds(
|
||||
keyComb(false, false, true, true, keycodes.h),
|
||||
keyComb(true, false, true, false, keycodes.h),
|
||||
),
|
||||
|
||||
[hotKeyRefs.REQUEST_FOCUS_URL.id]: keyBinds(
|
||||
keyComb(false, false, false, true, keycodes.l),
|
||||
keyComb(true, false, false, false, keycodes.l),
|
||||
),
|
||||
|
||||
[hotKeyRefs.REQUEST_SHOW_GENERATE_CODE_EDITOR.id]: keyBinds(
|
||||
keyComb(false, false, true, true, keycodes.g),
|
||||
keyComb(true, false, true, false, keycodes.g),
|
||||
),
|
||||
|
||||
[hotKeyRefs.SIDEBAR_FOCUS_FILTER.id]: keyBinds(
|
||||
keyComb(false, false, true, true, keycodes.f),
|
||||
keyComb(true, false, true, false, keycodes.f),
|
||||
),
|
||||
|
||||
[hotKeyRefs.RESPONSE_FOCUS.id]: keyBinds(
|
||||
keyComb(false, false, false, true, keycodes.singlequote),
|
||||
keyComb(true, false, false, false, keycodes.singlequote),
|
||||
),
|
||||
|
||||
[hotKeyRefs.SHOW_COOKIES_EDITOR.id]: keyBinds(
|
||||
keyComb(false, false, false, true, keycodes.k),
|
||||
keyComb(true, false, false, false, keycodes.k),
|
||||
),
|
||||
|
||||
[hotKeyRefs.REQUEST_SHOW_CREATE.id]: keyBinds(
|
||||
keyComb(false, false, false, true, keycodes.n),
|
||||
keyComb(true, false, false, false, keycodes.n),
|
||||
),
|
||||
|
||||
[hotKeyRefs.REQUEST_SHOW_DELETE.id]: keyBinds(
|
||||
keyComb(false, false, true, true, keycodes.delete),
|
||||
keyComb(true, false, true, false, keycodes.delete),
|
||||
),
|
||||
|
||||
[hotKeyRefs.REQUEST_SHOW_CREATE_FOLDER.id]: keyBinds(
|
||||
keyComb(false, false, true, true, keycodes.n),
|
||||
keyComb(true, false, true, false, keycodes.n),
|
||||
),
|
||||
|
||||
[hotKeyRefs.REQUEST_SHOW_DUPLICATE.id]: keyBinds(
|
||||
keyComb(false, false, false, true, keycodes.d),
|
||||
keyComb(true, false, false, false, keycodes.d),
|
||||
),
|
||||
|
||||
[hotKeyRefs.CLOSE_DROPDOWN.id]: keyBinds(
|
||||
keyComb(false, false, false, false, keycodes.esc),
|
||||
keyComb(false, false, false, false, keycodes.esc),
|
||||
),
|
||||
|
||||
[hotKeyRefs.CLOSE_MODAL.id]: keyBinds(
|
||||
keyComb(false, false, false, false, keycodes.esc),
|
||||
keyComb(false, false, false, false, keycodes.esc),
|
||||
),
|
||||
|
||||
[hotKeyRefs.ENVIRONMENT_UNCOVER_VARIABLES.id]: keyBinds(
|
||||
keyComb(false, true, true, false, keycodes.u),
|
||||
keyComb(false, true, true, false, keycodes.u),
|
||||
),
|
||||
};
|
||||
|
||||
function copyKeyCombs(sources: Array<KeyCombination>): Array<KeyCombination> {
|
||||
let targets: Array<KeyCombination> = [];
|
||||
sources.forEach(keyComb => {
|
||||
targets.push(Object.assign({}, keyComb));
|
||||
});
|
||||
return targets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new copy of hotkey registry with default values.
|
||||
* @returns {HotKeyRegistry}
|
||||
*/
|
||||
export function newDefaultRegistry(): HotKeyRegistry {
|
||||
let newDefaults: HotKeyRegistry = {};
|
||||
for (const refId in defaultRegistry) {
|
||||
if (!defaultRegistry.hasOwnProperty(refId)) {
|
||||
continue;
|
||||
}
|
||||
const keyBindings: KeyBindings = defaultRegistry[refId];
|
||||
newDefaults[refId] = {
|
||||
macKeys: copyKeyCombs(keyBindings.macKeys),
|
||||
winLinuxKeys: copyKeyCombs(keyBindings.winLinuxKeys),
|
||||
};
|
||||
}
|
||||
return newDefaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key combinations based on the current platform.
|
||||
* @param bindings
|
||||
* @returns {Array<KeyCombination>}
|
||||
*/
|
||||
export function getPlatformKeyCombinations(bindings: KeyBindings): Array<KeyCombination> {
|
||||
if (isMac()) {
|
||||
return bindings.macKeys;
|
||||
}
|
||||
return bindings.winLinuxKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the displayed text of a key code.
|
||||
* @param keyCode
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getChar(keyCode: number): string {
|
||||
let char;
|
||||
const keyCodeStr = Object.keys(keycodes).find(k => keycodes[k] === keyCode);
|
||||
|
||||
if (!keyCodeStr) {
|
||||
console.error('Invalid key code', keyCode);
|
||||
} else {
|
||||
const cap = keyCodeStr.toUpperCase();
|
||||
if (cap === 'ENTER') {
|
||||
char = 'Enter';
|
||||
} else if (cap === 'DELETE') {
|
||||
char = 'Delete';
|
||||
} else if (cap === 'COMMA') {
|
||||
char = ',';
|
||||
} else if (cap === 'BACKSLASH') {
|
||||
char = '\\';
|
||||
} else if (cap === 'FORWARDSLASH') {
|
||||
char = '/';
|
||||
} else if (cap === 'SINGLEQUOTE') {
|
||||
char = "'";
|
||||
} else if (cap === 'SPACE') {
|
||||
char = 'Space';
|
||||
} else {
|
||||
chars.push(v.toUpperCase());
|
||||
char = cap;
|
||||
}
|
||||
}
|
||||
|
||||
return chars[0] || 'unknown';
|
||||
return char || 'unknown';
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
import type { BaseModel } from './index';
|
||||
import * as db from '../common/database';
|
||||
import { UPDATE_CHANNEL_STABLE } from '../common/constants';
|
||||
import * as hotkeys from '../common/hotkeys';
|
||||
|
||||
type BaseSettings = {
|
||||
showPasswords: boolean,
|
||||
@@ -34,6 +35,7 @@ type BaseSettings = {
|
||||
fontInterface: string | null,
|
||||
fontSize: number,
|
||||
fontVariantLigatures: boolean,
|
||||
hotKeyRegistry: hotkeys.HotKeyRegistry,
|
||||
};
|
||||
|
||||
export type Settings = BaseModel & BaseSettings;
|
||||
@@ -75,6 +77,7 @@ export function init(): BaseSettings {
|
||||
fontInterface: null,
|
||||
fontSize: 13,
|
||||
fontVariantLigatures: false,
|
||||
hotKeyRegistry: hotkeys.newDefaultRegistry(),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { AUTH_OAUTH_1 } from '../../common/constants';
|
||||
|
||||
describe('OAuth 1.0', () => {
|
||||
it('Does OAuth 1.0', async () => {
|
||||
const header = await getAuthHeader('req_123', 'https://insomnia.rest/', 'GET', {
|
||||
const authentication = {
|
||||
type: AUTH_OAUTH_1,
|
||||
consumerKey: 'consumerKey',
|
||||
consumerSecret: 'consumerSecret',
|
||||
@@ -13,7 +13,9 @@ describe('OAuth 1.0', () => {
|
||||
signatureMethod: 'HMAC-SHA1',
|
||||
nonce: 'nonce',
|
||||
timestamp: '1234567890',
|
||||
});
|
||||
};
|
||||
const request = { url: 'https://insomnia.rest/', method: 'GET', authentication };
|
||||
const header = await getAuthHeader(request, 'https://insomnia.rest/');
|
||||
|
||||
expect(header).toEqual({
|
||||
name: 'Authorization',
|
||||
@@ -31,7 +33,7 @@ describe('OAuth 1.0', () => {
|
||||
});
|
||||
|
||||
it('Does OAuth 1.0 with RSA-SHA1', async () => {
|
||||
const header = await getAuthHeader('req_123', 'https://insomnia.rest/', 'GET', {
|
||||
const authentication = {
|
||||
type: AUTH_OAUTH_1,
|
||||
consumerKey: 'consumerKey',
|
||||
consumerSecret: 'consumerSecret',
|
||||
@@ -57,7 +59,9 @@ describe('OAuth 1.0', () => {
|
||||
'-----END RSA PRIVATE KEY-----',
|
||||
nonce: 'nonce',
|
||||
timestamp: '1234567890',
|
||||
});
|
||||
};
|
||||
const request = { url: 'https://insomnia.rest/', method: 'GET', authentication };
|
||||
const header = await getAuthHeader(request, 'https://insomnia.rest/');
|
||||
|
||||
expect(header).toEqual({
|
||||
name: 'Authorization',
|
||||
@@ -75,12 +79,14 @@ describe('OAuth 1.0', () => {
|
||||
});
|
||||
|
||||
it('Does OAuth 1.0 with defaults', async () => {
|
||||
const header = await getAuthHeader('req_123', 'https://insomnia.rest/', 'GET', {
|
||||
const authentication = {
|
||||
type: AUTH_OAUTH_1,
|
||||
consumerKey: 'consumerKey',
|
||||
consumerSecret: 'consumerSecret',
|
||||
signatureMethod: 'HMAC-SHA1',
|
||||
});
|
||||
};
|
||||
const request = { url: 'https://insomnia.rest/', method: 'GET', authentication };
|
||||
const header = await getAuthHeader(request, 'https://insomnia.rest/');
|
||||
|
||||
expect(header.name).toBe('Authorization');
|
||||
expect(header.value).toMatch(
|
||||
|
||||
@@ -11,7 +11,7 @@ import getOAuth2Token from './o-auth-2/get-token';
|
||||
import getOAuth1Token from './o-auth-1/get-token';
|
||||
import * as Hawk from 'hawk';
|
||||
import jwtAuthentication from 'jwt-authentication';
|
||||
import type { RequestAuthentication } from '../models/request';
|
||||
import type { RenderedRequest } from '../common/render';
|
||||
import { getBasicAuthHeader } from './basic-auth/get-header';
|
||||
import { getBearerAuthHeader } from './bearer-auth/get-header';
|
||||
|
||||
@@ -21,11 +21,12 @@ type Header = {
|
||||
};
|
||||
|
||||
export async function getAuthHeader(
|
||||
requestId: string,
|
||||
renderedRequest: RenderedRequest,
|
||||
url: string,
|
||||
method: string,
|
||||
authentication: RequestAuthentication,
|
||||
): Promise<Header | null> {
|
||||
const { method, authentication } = renderedRequest;
|
||||
const requestId = renderedRequest._id;
|
||||
|
||||
if (authentication.disabled) {
|
||||
return null;
|
||||
}
|
||||
@@ -69,11 +70,21 @@ export async function getAuthHeader(
|
||||
}
|
||||
|
||||
if (authentication.type === AUTH_HAWK) {
|
||||
const { id, key, algorithm, ext } = authentication;
|
||||
const header = Hawk.client.header(url, method, {
|
||||
const { id, key, algorithm, ext, validatePayload } = authentication;
|
||||
let headerOptions = {
|
||||
credentials: { id, key, algorithm },
|
||||
ext: ext,
|
||||
});
|
||||
};
|
||||
|
||||
if (validatePayload) {
|
||||
const payloadValidationFields = {
|
||||
payload: renderedRequest.body.text,
|
||||
contentType: renderedRequest.body.mimeType,
|
||||
};
|
||||
headerOptions = Object.assign({}, payloadValidationFields, headerOptions);
|
||||
}
|
||||
|
||||
const header = Hawk.client.header(url, method, headerOptions);
|
||||
return {
|
||||
name: 'Authorization',
|
||||
value: header.field,
|
||||
|
||||
@@ -594,12 +594,7 @@ export async function _actuallySend(
|
||||
} else if (renderedRequest.authentication.type === AUTH_NETRC) {
|
||||
setOpt(Curl.option.NETRC, Curl.netrc.REQUIRED);
|
||||
} else {
|
||||
const authHeader = await getAuthHeader(
|
||||
renderedRequest._id,
|
||||
finalUrl,
|
||||
renderedRequest.method,
|
||||
renderedRequest.authentication,
|
||||
);
|
||||
const authHeader = await getAuthHeader(renderedRequest, finalUrl);
|
||||
|
||||
if (authHeader) {
|
||||
headers.push({
|
||||
|
||||
@@ -78,11 +78,6 @@ async function _isInsomniaPlugin(lookupName: string): Promise<Object> {
|
||||
},
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
if (err) {
|
||||
reject(new Error(`${lookupName} npm error: ${err.message}`));
|
||||
return;
|
||||
}
|
||||
|
||||
if (stderr) {
|
||||
reject(new Error(`Yarn error ${stderr.toString('utf8')}`));
|
||||
return;
|
||||
@@ -91,8 +86,15 @@ async function _isInsomniaPlugin(lookupName: string): Promise<Object> {
|
||||
let yarnOutput;
|
||||
try {
|
||||
yarnOutput = JSON.parse(stdout.toString('utf8'));
|
||||
} catch (err) {
|
||||
reject(new Error(`Yarn response not JSON: ${err.message}`));
|
||||
} catch (ex) {
|
||||
// Output is not JSON. Check if yarn/electron terminated with non-zero exit code.
|
||||
// In certain environments electron can exit with error even if output is OK.
|
||||
// Parsing is attemted before checking exit code as workaround for false errors.
|
||||
if (err) {
|
||||
reject(new Error(`${lookupName} npm error: ${err.message}`));
|
||||
} else {
|
||||
reject(new Error(`Yarn response not JSON: ${ex.message}`));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -149,7 +151,10 @@ async function _installPluginToTmpDir(lookupName: string): Promise<{ tmpDir: str
|
||||
},
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
if (err) {
|
||||
// Check yarn/electron process exit code.
|
||||
// In certain environments electron can exit with error even if the command was perfomed sucesfully.
|
||||
// Checking for sucess message in output is a workaround for false errors.
|
||||
if (err && !stdout.toString('utf8').includes('success')) {
|
||||
reject(new Error(`${lookupName} install error: ${err.message}`));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import type { Hotkey as HotkeyType } from '../../../../common/hotkeys';
|
||||
import Hotkey from '../../hotkey';
|
||||
import type { KeyBindings } from '../../../../common/hotkeys';
|
||||
|
||||
type Props = {
|
||||
hotkey: HotkeyType,
|
||||
keyBindings: KeyBindings,
|
||||
};
|
||||
|
||||
class DropdownHint extends React.PureComponent<Props> {
|
||||
render() {
|
||||
const { hotkey } = this.props;
|
||||
return <Hotkey className="dropdown__hint" hotkey={hotkey} />;
|
||||
const { keyBindings } = this.props;
|
||||
return <Hotkey className="dropdown__hint" keyBindings={keyBindings} />;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ import DropdownItem from './dropdown-item';
|
||||
import DropdownDivider from './dropdown-divider';
|
||||
import { fuzzyMatch } from '../../../../common/misc';
|
||||
import KeydownBinder from '../../keydown-binder';
|
||||
import * as hotkeys from '../../../../common/hotkeys';
|
||||
import { executeHotKey } from '../../../../common/hotkeys-listener';
|
||||
import { hotKeyRefs } from '../../../../common/hotkeys';
|
||||
|
||||
const dropdownsContainer = document.querySelector('#dropdowns-container');
|
||||
|
||||
@@ -115,7 +116,7 @@ class Dropdown extends PureComponent {
|
||||
|
||||
this._handleDropdownNavigation(e);
|
||||
|
||||
hotkeys.executeHotKey(e, hotkeys.CLOSE_DROPDOWN, () => {
|
||||
executeHotKey(e, hotKeyRefs.CLOSE_DROPDOWN, () => {
|
||||
this.hide();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ import PropTypes from 'prop-types';
|
||||
import autobind from 'autobind-decorator';
|
||||
import classnames from 'classnames';
|
||||
import KeydownBinder from '../keydown-binder';
|
||||
import * as hotkeys from '../../../common/hotkeys';
|
||||
import { hotKeyRefs } from '../../../common/hotkeys';
|
||||
import { pressedHotKey } from '../../../common/hotkeys-listener';
|
||||
|
||||
// Keep global z-index reference so that every modal will
|
||||
// appear over top of an existing one.
|
||||
@@ -21,7 +22,7 @@ class Modal extends PureComponent {
|
||||
};
|
||||
}
|
||||
|
||||
_handleKeyDown(e) {
|
||||
async _handleKeyDown(e) {
|
||||
if (!this.state.open) {
|
||||
return;
|
||||
}
|
||||
@@ -32,7 +33,7 @@ class Modal extends PureComponent {
|
||||
}
|
||||
|
||||
const closeOnKeyCodes = this.props.closeOnKeyCodes || [];
|
||||
const pressedEscape = hotkeys.pressedHotKey(e, hotkeys.CLOSE_MODAL);
|
||||
const pressedEscape = await pressedHotKey(e, hotKeyRefs.CLOSE_MODAL);
|
||||
const pressedCloseButton = closeOnKeyCodes.find(c => c === e.keyCode);
|
||||
|
||||
// Pressed escape
|
||||
|
||||
@@ -10,7 +10,8 @@ import { showModal } from '../modals/index';
|
||||
import FilterHelpModal from '../modals/filter-help-modal';
|
||||
import * as misc from '../../../common/misc';
|
||||
import prettify from 'insomnia-prettify';
|
||||
import { DEBOUNCE_MILLIS, isMac } from '../../../common/constants';
|
||||
import { DEBOUNCE_MILLIS, EDITOR_KEY_MAP_VIM, isMac } from '../../../common/constants';
|
||||
import keyCodes from '../../../common/keycodes';
|
||||
import './base-imports';
|
||||
import { getTagDefinitions } from '../../../templating/index';
|
||||
import Dropdown from '../base/dropdown/dropdown';
|
||||
@@ -287,6 +288,7 @@ class CodeEditor extends React.Component {
|
||||
this.codeMirror.on('blur', this._codemirrorBlur);
|
||||
this.codeMirror.on('paste', this._codemirrorPaste);
|
||||
this.codeMirror.on('scroll', this._codemirrorScroll);
|
||||
this.codeMirror.on('keyHandled', this._codemirrorKeyHandled);
|
||||
|
||||
// Prevent these things if we're type === "password"
|
||||
this.codeMirror.on('copy', this._codemirrorPreventWhenTypePassword);
|
||||
@@ -664,6 +666,18 @@ class CodeEditor extends React.Component {
|
||||
this._persistState();
|
||||
}
|
||||
|
||||
_codemirrorKeyHandled(codeMirror, keyName, event) {
|
||||
const { keyMap } = this.props;
|
||||
const { keyCode } = event;
|
||||
|
||||
const isVimKeyMap = keyMap === EDITOR_KEY_MAP_VIM;
|
||||
const pressedEscape = keyCode === keyCodes.esc;
|
||||
|
||||
if (isVimKeyMap && pressedEscape) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
_codemirrorValueBeforeChange(doc, change) {
|
||||
// If we're in single-line mode, merge all changed lines into one
|
||||
if (this.props.singleLine && change.text && change.text.length > 1) {
|
||||
|
||||
@@ -11,17 +11,19 @@ import {
|
||||
} from '../base/dropdown';
|
||||
import { showModal } from '../modals/index';
|
||||
import Tooltip from '../tooltip';
|
||||
import * as hotkeys from '../../../common/hotkeys';
|
||||
import KeydownBinder from '../keydown-binder';
|
||||
import type { Workspace } from '../../../models/workspace';
|
||||
import type { Environment } from '../../../models/environment';
|
||||
import type { HotKeyRegistry } from '../../../common/hotkeys';
|
||||
import { hotKeyRefs } from '../../../common/hotkeys';
|
||||
import { executeHotKey } from '../../../common/hotkeys-listener';
|
||||
|
||||
type Props = {
|
||||
workspace: Workspace,
|
||||
handleChangeEnvironment: Function,
|
||||
workspace: Workspace,
|
||||
environments: Array<Environment>,
|
||||
environmentHighlightColorStyle: String,
|
||||
hotKeyRegistry: HotKeyRegistry,
|
||||
|
||||
// Optional
|
||||
className?: string,
|
||||
@@ -57,7 +59,7 @@ class EnvironmentsDropdown extends React.PureComponent<Props> {
|
||||
}
|
||||
|
||||
_handleKeydown(e: KeyboardEvent) {
|
||||
hotkeys.executeHotKey(e, hotkeys.TOGGLE_ENVIRONMENTS_MENU, () => {
|
||||
executeHotKey(e, hotKeyRefs.ENVIRONMENT_SHOW_SWITCH_MENU, () => {
|
||||
this._dropdown && this._dropdown.toggle(true);
|
||||
});
|
||||
}
|
||||
@@ -69,6 +71,7 @@ class EnvironmentsDropdown extends React.PureComponent<Props> {
|
||||
environments,
|
||||
activeEnvironment,
|
||||
environmentHighlightColorStyle,
|
||||
hotKeyRegistry,
|
||||
...other
|
||||
} = this.props;
|
||||
|
||||
@@ -125,7 +128,7 @@ class EnvironmentsDropdown extends React.PureComponent<Props> {
|
||||
|
||||
<DropdownItem onClick={this._handleShowEnvironmentModal}>
|
||||
<i className="fa fa-wrench" /> Manage Environments
|
||||
<DropdownHint hotkey={hotkeys.SHOW_ENVIRONMENTS} />
|
||||
<DropdownHint keyBindings={hotKeyRegistry[hotKeyRefs.ENVIRONMENT_SHOW_EDITOR.id]} />
|
||||
</DropdownItem>
|
||||
</Dropdown>
|
||||
</KeydownBinder>
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
DropdownItem,
|
||||
} from '../base/dropdown/index';
|
||||
import * as models from '../../../models';
|
||||
import * as hotkeys from '../../../common/hotkeys';
|
||||
import { hotKeyRefs } from '../../../common/hotkeys';
|
||||
|
||||
@autobind
|
||||
class RequestActionsDropdown extends PureComponent {
|
||||
@@ -44,6 +44,7 @@ class RequestActionsDropdown extends PureComponent {
|
||||
const {
|
||||
request, // eslint-disable-line no-unused-vars
|
||||
handleShowSettings,
|
||||
hotKeyRegistry,
|
||||
...other
|
||||
} = this.props;
|
||||
|
||||
@@ -54,11 +55,13 @@ class RequestActionsDropdown extends PureComponent {
|
||||
</DropdownButton>
|
||||
<DropdownItem onClick={this._handleDuplicate}>
|
||||
<i className="fa fa-copy" /> Duplicate
|
||||
<DropdownHint hotkey={hotkeys.DUPLICATE_REQUEST} />
|
||||
<DropdownHint keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_SHOW_DUPLICATE.id]} />
|
||||
</DropdownItem>
|
||||
<DropdownItem onClick={this._handleGenerateCode}>
|
||||
<i className="fa fa-code" /> Generate Code
|
||||
<DropdownHint hotkey={hotkeys.GENERATE_CODE} />
|
||||
<DropdownHint
|
||||
keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_SHOW_GENERATE_CODE_EDITOR.id]}
|
||||
/>
|
||||
</DropdownItem>
|
||||
<DropdownItem onClick={this._handleCopyAsCurl}>
|
||||
<i className="fa fa-copy" /> Copy as Curl
|
||||
@@ -71,7 +74,7 @@ class RequestActionsDropdown extends PureComponent {
|
||||
|
||||
<DropdownItem onClick={handleShowSettings}>
|
||||
<i className="fa fa-wrench" /> Settings
|
||||
<DropdownHint hotkey={hotkeys.SHOW_REQUEST_SETTINGS} />
|
||||
<DropdownHint keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_SHOW_SETTINGS.id]} />
|
||||
</DropdownItem>
|
||||
</Dropdown>
|
||||
);
|
||||
@@ -84,6 +87,7 @@ RequestActionsDropdown.propTypes = {
|
||||
handleCopyAsCurl: PropTypes.func.isRequired,
|
||||
handleShowSettings: PropTypes.func.isRequired,
|
||||
request: PropTypes.object.isRequired,
|
||||
hotKeyRegistry: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default RequestActionsDropdown;
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
import EnvironmentEditModal from '../modals/environment-edit-modal';
|
||||
import * as models from '../../../models';
|
||||
import { showPrompt, showModal } from '../modals/index';
|
||||
import * as hotkeys from '../../../common/hotkeys';
|
||||
import { hotKeyRefs } from '../../../common/hotkeys';
|
||||
|
||||
@autobind
|
||||
class RequestGroupActionsDropdown extends PureComponent {
|
||||
@@ -63,6 +63,7 @@ class RequestGroupActionsDropdown extends PureComponent {
|
||||
render() {
|
||||
const {
|
||||
requestGroup, // eslint-disable-line no-unused-vars
|
||||
hotKeyRegistry,
|
||||
...other
|
||||
} = this.props;
|
||||
|
||||
@@ -73,11 +74,11 @@ class RequestGroupActionsDropdown extends PureComponent {
|
||||
</DropdownButton>
|
||||
<DropdownItem onClick={this._handleRequestCreate}>
|
||||
<i className="fa fa-plus-circle" /> New Request
|
||||
<DropdownHint hotkey={hotkeys.CREATE_REQUEST} />
|
||||
<DropdownHint keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_SHOW_CREATE.id]} />
|
||||
</DropdownItem>
|
||||
<DropdownItem onClick={this._handleRequestGroupCreate}>
|
||||
<i className="fa fa-folder" /> New Folder
|
||||
<DropdownHint hotkey={hotkeys.CREATE_FOLDER} />
|
||||
<DropdownHint keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_SHOW_CREATE_FOLDER.id]} />
|
||||
</DropdownItem>
|
||||
<DropdownDivider />
|
||||
<DropdownItem onClick={this._handleRequestGroupDuplicate}>
|
||||
@@ -102,6 +103,7 @@ class RequestGroupActionsDropdown extends PureComponent {
|
||||
|
||||
RequestGroupActionsDropdown.propTypes = {
|
||||
workspace: PropTypes.object.isRequired,
|
||||
hotKeyRegistry: PropTypes.object.isRequired,
|
||||
handleCreateRequest: PropTypes.func.isRequired,
|
||||
handleCreateRequestGroup: PropTypes.func.isRequired,
|
||||
handleDuplicateRequestGroup: PropTypes.func.isRequired,
|
||||
|
||||
@@ -6,9 +6,10 @@ import StatusTag from '../tags/status-tag';
|
||||
import URLTag from '../tags/url-tag';
|
||||
import PromptButton from '../base/prompt-button';
|
||||
import KeydownBinder from '../keydown-binder';
|
||||
import * as hotkeys from '../../../common/hotkeys';
|
||||
import TimeTag from '../tags/time-tag';
|
||||
import SizeTag from '../tags/size-tag';
|
||||
import { executeHotKey } from '../../../common/hotkeys-listener';
|
||||
import { hotKeyRefs } from '../../../common/hotkeys';
|
||||
|
||||
@autobind
|
||||
class ResponseHistoryDropdown extends PureComponent {
|
||||
@@ -29,7 +30,7 @@ class ResponseHistoryDropdown extends PureComponent {
|
||||
}
|
||||
|
||||
_handleKeydown(e) {
|
||||
hotkeys.executeHotKey(e, hotkeys.TOGGLE_HISTORY_DROPDOWN, () => {
|
||||
executeHotKey(e, hotKeyRefs.REQUEST_TOGGLE_HISTORY, () => {
|
||||
this._dropdown && this._dropdown.toggle(true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,8 +17,9 @@ import WorkspaceShareSettingsModal from '../modals/workspace-share-settings-moda
|
||||
import * as session from '../../../sync/session';
|
||||
import LoginModal from '../modals/login-modal';
|
||||
import Tooltip from '../tooltip';
|
||||
import * as hotkeys from '../../../common/hotkeys';
|
||||
import KeydownBinder from '../keydown-binder';
|
||||
import { hotKeyRefs } from '../../../common/hotkeys';
|
||||
import { executeHotKey } from '../../../common/hotkeys-listener';
|
||||
|
||||
@autobind
|
||||
class WorkspaceDropdown extends PureComponent {
|
||||
@@ -91,7 +92,7 @@ class WorkspaceDropdown extends PureComponent {
|
||||
}
|
||||
|
||||
_handleKeydown(e) {
|
||||
hotkeys.executeHotKey(e, hotkeys.TOGGLE_MAIN_MENU, () => {
|
||||
executeHotKey(e, hotKeyRefs.TOGGLE_MAIN_MENU, () => {
|
||||
this._dropdown && this._dropdown.toggle(true);
|
||||
});
|
||||
}
|
||||
@@ -103,6 +104,7 @@ class WorkspaceDropdown extends PureComponent {
|
||||
activeWorkspace,
|
||||
unseenWorkspaces,
|
||||
isLoading,
|
||||
hotKeyRegistry,
|
||||
...other
|
||||
} = this.props;
|
||||
|
||||
@@ -145,7 +147,7 @@ class WorkspaceDropdown extends PureComponent {
|
||||
<DropdownDivider>{activeWorkspace.name}</DropdownDivider>
|
||||
<DropdownItem onClick={this._handleShowWorkspaceSettings}>
|
||||
<i className="fa fa-wrench" /> Workspace Settings
|
||||
<DropdownHint hotkey={hotkeys.SHOW_WORKSPACE_SETTINGS} />
|
||||
<DropdownHint keyBindings={hotKeyRegistry[hotKeyRefs.WORKSPACE_SHOW_SETTINGS.id]} />
|
||||
</DropdownItem>
|
||||
|
||||
<DropdownItem onClick={this._handleShowShareSettings}>
|
||||
@@ -176,7 +178,7 @@ class WorkspaceDropdown extends PureComponent {
|
||||
|
||||
<DropdownItem onClick={this._handleShowSettings}>
|
||||
<i className="fa fa-cog" /> Preferences
|
||||
<DropdownHint hotkey={hotkeys.SHOW_SETTINGS} />
|
||||
<DropdownHint keyBindings={hotKeyRegistry[hotKeyRefs.PREFERENCES_SHOW_GENERAL.id]} />
|
||||
</DropdownItem>
|
||||
<DropdownItem onClick={this._handleShowExport}>
|
||||
<i className="fa fa-share" /> Import/Export
|
||||
@@ -215,6 +217,7 @@ WorkspaceDropdown.propTypes = {
|
||||
workspaces: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
unseenWorkspaces: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
activeWorkspace: PropTypes.object.isRequired,
|
||||
hotKeyRegistry: PropTypes.object.isRequired,
|
||||
|
||||
// Optional
|
||||
className: PropTypes.string,
|
||||
|
||||
@@ -49,6 +49,11 @@ class HawkAuth extends React.PureComponent<Props> {
|
||||
this._handleChangeProperty('ext', value);
|
||||
}
|
||||
|
||||
_handleChangePayloadValidation(): void {
|
||||
const { request } = this.props;
|
||||
this._handleChangeProperty('validatePayload', !request.authentication.validatePayload);
|
||||
}
|
||||
|
||||
renderHawkAuthenticationFields(): React.Node {
|
||||
const hawkAuthId = this.renderInputRow('Auth ID', 'id', this._handleChangeHawkAuthId);
|
||||
|
||||
@@ -66,7 +71,13 @@ class HawkAuth extends React.PureComponent<Props> {
|
||||
|
||||
const ext = this.renderInputRow('Ext', 'ext', this._handleChangeExt);
|
||||
|
||||
return [hawkAuthId, hawkAuthKey, algorithm, ext];
|
||||
const payloadValidation = this.renderButtonRow(
|
||||
'Validate Payload',
|
||||
'validatePayload',
|
||||
this._handleChangePayloadValidation,
|
||||
);
|
||||
|
||||
return [hawkAuthId, hawkAuthKey, algorithm, ext, payloadValidation];
|
||||
}
|
||||
|
||||
renderSelectRow(
|
||||
@@ -115,7 +126,7 @@ class HawkAuth extends React.PureComponent<Props> {
|
||||
isVariableUncovered,
|
||||
} = this.props;
|
||||
|
||||
const {authentication} = request;
|
||||
const { authentication } = request;
|
||||
|
||||
const id = label.replace(/ /g, '-');
|
||||
return (
|
||||
@@ -146,6 +157,44 @@ class HawkAuth extends React.PureComponent<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
renderButtonRow(label: string, property: string, onChange: Function): React.Element<*> {
|
||||
const { request } = this.props;
|
||||
const { authentication } = request;
|
||||
const id = label.replace(/ /g, '-');
|
||||
return (
|
||||
<tr key={id}>
|
||||
<td className="pad-right no-wrap valign-middle">
|
||||
<label htmlFor={id} className="label--small no-pad">
|
||||
{label}
|
||||
</label>
|
||||
</td>
|
||||
<td className="wide">
|
||||
<div
|
||||
className={classnames('form-control form-control--underlined no-margin', {
|
||||
'form-control--inactive': authentication.disabled,
|
||||
})}>
|
||||
<Button
|
||||
className="btn btn--super-duper-compact"
|
||||
id={id}
|
||||
onClick={this._handleChangePayloadValidation}
|
||||
value={authentication.validatePayload}
|
||||
title={
|
||||
authentication.validatePayload
|
||||
? 'Enable payload validation'
|
||||
: 'Disable payload validation'
|
||||
}>
|
||||
{authentication.validatePayload ? (
|
||||
<i className="fa fa-check-square-o" />
|
||||
) : (
|
||||
<i className="fa fa-square-o" />
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const fields = this.renderHawkAuthenticationFields();
|
||||
const { authentication } = this.props.request;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import type { Hotkey as HotkeyType } from '../../common/hotkeys';
|
||||
import { ALT_SYM, CTRL_SYM, isMac, joinHotKeys, META_SYM, SHIFT_SYM } from '../../common/constants';
|
||||
import type { KeyBindings } from '../../common/hotkeys';
|
||||
import * as hotkeys from '../../common/hotkeys';
|
||||
import { ALT_SYM, CTRL_SYM, isMac, joinHotKeys, MOD_SYM, SHIFT_SYM } from '../../common/constants';
|
||||
|
||||
type Props = {
|
||||
hotkey: HotkeyType,
|
||||
keyBindings: KeyBindings,
|
||||
|
||||
// Optional
|
||||
className?: string,
|
||||
@@ -14,22 +14,18 @@ type Props = {
|
||||
|
||||
class Hotkey extends React.PureComponent<Props> {
|
||||
render() {
|
||||
const { hotkey, className } = this.props;
|
||||
const { alt, shift, meta, metaIsCtrl } = hotkey;
|
||||
const { keyBindings, className } = this.props;
|
||||
|
||||
const keyComb = hotkeys.getPlatformKeyCombinations(keyBindings)[0];
|
||||
const { ctrl, alt, shift, meta, keyCode } = keyComb;
|
||||
const chars = [];
|
||||
|
||||
alt && chars.push(ALT_SYM);
|
||||
shift && chars.push(SHIFT_SYM);
|
||||
ctrl && chars.push(CTRL_SYM);
|
||||
meta && chars.push(META_SYM);
|
||||
|
||||
if (meta) {
|
||||
if (metaIsCtrl) {
|
||||
chars.push(CTRL_SYM);
|
||||
} else {
|
||||
chars.push(isMac() ? MOD_SYM : CTRL_SYM);
|
||||
}
|
||||
}
|
||||
|
||||
chars.push(hotkeys.getChar(hotkey));
|
||||
chars.push(hotkeys.getChar(keyCode));
|
||||
|
||||
return (
|
||||
<span className={classnames(className, { 'font-normal': isMac() })}>
|
||||
|
||||
@@ -137,7 +137,7 @@ class SettingsModal extends PureComponent {
|
||||
<Theme handleChangeTheme={this._handleChangeTheme} activeTheme={settings.theme} />
|
||||
</TabPanel>
|
||||
<TabPanel className="react-tabs__tab-panel pad scrollable">
|
||||
<SettingsShortcuts />
|
||||
<SettingsShortcuts hotKeyRegistry={settings.hotKeyRegistry} />
|
||||
</TabPanel>
|
||||
<TabPanel className="react-tabs__tab-panel pad scrollable">
|
||||
<Account />
|
||||
|
||||
@@ -29,8 +29,8 @@ import { showModal } from './modals/index';
|
||||
import RequestSettingsModal from './modals/request-settings-modal';
|
||||
import MarkdownPreview from './markdown-preview';
|
||||
import type { Settings } from '../../models/settings';
|
||||
import * as hotkeys from '../../common/hotkeys';
|
||||
import ErrorBoundary from './error-boundary';
|
||||
import { hotKeyRefs } from '../../common/hotkeys';
|
||||
|
||||
type Props = {
|
||||
// Functions
|
||||
@@ -171,38 +171,42 @@ class RequestPane extends React.PureComponent<Props> {
|
||||
const paneHeaderClasses = 'pane__header theme--pane__header';
|
||||
const paneBodyClasses = 'pane__body theme--pane__body';
|
||||
|
||||
const hotKeyRegistry = settings.hotKeyRegistry;
|
||||
|
||||
if (!request) {
|
||||
return (
|
||||
<section className={paneClasses}>
|
||||
<header className={paneHeaderClasses}/>
|
||||
<header className={paneHeaderClasses} />
|
||||
<div className={paneBodyClasses + ' pane__body--placeholder'}>
|
||||
<div>
|
||||
<table className="table--fancy">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>New Request</td>
|
||||
<td className="text-right">
|
||||
<code>
|
||||
<Hotkey hotkey={hotkeys.CREATE_REQUEST}/>
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Switch Requests</td>
|
||||
<td className="text-right">
|
||||
<code>
|
||||
<Hotkey hotkey={hotkeys.SHOW_QUICK_SWITCHER}/>
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Edit Environments</td>
|
||||
<td className="text-right">
|
||||
<code>
|
||||
<Hotkey hotkey={hotkeys.SHOW_ENVIRONMENTS}/>
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>New Request</td>
|
||||
<td className="text-right">
|
||||
<code>
|
||||
<Hotkey keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_SHOW_CREATE.id]} />
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Switch Requests</td>
|
||||
<td className="text-right">
|
||||
<code>
|
||||
<Hotkey keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_QUICK_SWITCH.id]} />
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Edit Environments</td>
|
||||
<td className="text-right">
|
||||
<code>
|
||||
<Hotkey
|
||||
keyBindings={hotKeyRegistry[hotKeyRefs.ENVIRONMENT_SHOW_EDITOR.id]}
|
||||
/>
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -251,6 +255,7 @@ class RequestPane extends React.PureComponent<Props> {
|
||||
isVariableUncovered={isVariableUncovered}
|
||||
handleGetRenderContext={handleGetRenderContext}
|
||||
request={request}
|
||||
hotKeyRegistry={settings.hotKeyRegistry}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</header>
|
||||
@@ -266,7 +271,7 @@ class RequestPane extends React.PureComponent<Props> {
|
||||
? getContentTypeName(request.body.mimeType)
|
||||
: 'Body'}
|
||||
{numBodyParams ? <span className="bubble space-left">{numBodyParams}</span> : null}
|
||||
<i className="fa fa-caret-down space-left"/>
|
||||
<i className="fa fa-caret-down space-left" />
|
||||
</ContentTypeDropdown>
|
||||
</Tab>
|
||||
<Tab tabIndex="-1">
|
||||
@@ -275,7 +280,7 @@ class RequestPane extends React.PureComponent<Props> {
|
||||
request={request}
|
||||
className="tall">
|
||||
{getAuthTypeName(request.authentication.type) || 'Auth'}
|
||||
<i className="fa fa-caret-down space-left"/>
|
||||
<i className="fa fa-caret-down space-left" />
|
||||
</AuthDropdown>
|
||||
</Tab>
|
||||
<Tab tabIndex="-1">
|
||||
@@ -295,7 +300,7 @@ class RequestPane extends React.PureComponent<Props> {
|
||||
Docs
|
||||
{request.description && (
|
||||
<span className="bubble space-left">
|
||||
<i className="fa fa--skinny fa-check txt-xxs"/>
|
||||
<i className="fa fa--skinny fa-check txt-xxs" />
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
@@ -341,7 +346,7 @@ class RequestPane extends React.PureComponent<Props> {
|
||||
<ErrorBoundary
|
||||
key={uniqueKey}
|
||||
errorClassName="tall wide vertically-align font-error pad text-center">
|
||||
<RenderedQueryString handleRender={handleRender} request={request}/>
|
||||
<RenderedQueryString handleRender={handleRender} request={request} />
|
||||
</ErrorBoundary>
|
||||
</code>
|
||||
</div>
|
||||
@@ -419,10 +424,10 @@ class RequestPane extends React.PureComponent<Props> {
|
||||
<div className="overflow-hidden editor vertically-center text-center">
|
||||
<p className="pad text-sm text-center">
|
||||
<span className="super-faint">
|
||||
<i className="fa fa-file-text-o" style={{ fontSize: '8rem', opacity: 0.3 }}/>
|
||||
<i className="fa fa-file-text-o" style={{ fontSize: '8rem', opacity: 0.3 }} />
|
||||
</span>
|
||||
<br/>
|
||||
<br/>
|
||||
<br />
|
||||
<br />
|
||||
<button
|
||||
className="btn btn--clicky faint"
|
||||
onClick={this._handleEditDescriptionAdd}>
|
||||
|
||||
@@ -14,9 +14,11 @@ import { showPrompt } from './modals/index';
|
||||
import MethodDropdown from './dropdowns/method-dropdown';
|
||||
import PromptButton from './base/prompt-button';
|
||||
import OneLineEditor from './codemirror/one-line-editor';
|
||||
import * as hotkeys from '../../common/hotkeys';
|
||||
import KeydownBinder from './keydown-binder';
|
||||
import type { Request } from '../../models/request';
|
||||
import type { HotKeyRegistry } from '../../common/hotkeys';
|
||||
import { hotKeyRefs } from '../../common/hotkeys';
|
||||
import { executeHotKey } from '../../common/hotkeys-listener';
|
||||
|
||||
type Props = {
|
||||
handleAutocompleteUrls: Function,
|
||||
@@ -32,6 +34,7 @@ type Props = {
|
||||
onUrlChange: (r: Request, url: string) => Promise<Request>,
|
||||
request: Request,
|
||||
uniquenessKey: string,
|
||||
hotKeyRegistry: HotKeyRegistry,
|
||||
};
|
||||
|
||||
type State = {
|
||||
@@ -142,21 +145,21 @@ class RequestUrlBar extends React.PureComponent<Props, State> {
|
||||
this.setState({ downloadPath: null });
|
||||
}
|
||||
|
||||
_handleKeyDown(e: KeyboardEvent) {
|
||||
async _handleKeyDown(e: KeyboardEvent) {
|
||||
if (!this._input) {
|
||||
return;
|
||||
}
|
||||
|
||||
hotkeys.executeHotKey(e, hotkeys.FOCUS_URL, () => {
|
||||
executeHotKey(e, hotKeyRefs.REQUEST_FOCUS_URL, () => {
|
||||
this._input && this._input.focus();
|
||||
this._input && this._input.selectAll();
|
||||
});
|
||||
|
||||
hotkeys.executeHotKey(e, hotkeys.TOGGLE_METHOD_DROPDOWN, () => {
|
||||
executeHotKey(e, hotKeyRefs.REQUEST_TOGGLE_HTTP_METHOD_MENU, () => {
|
||||
this._methodDropdown && this._methodDropdown.toggle();
|
||||
});
|
||||
|
||||
hotkeys.executeHotKey(e, hotkeys.SHOW_SEND_OPTIONS, () => {
|
||||
executeHotKey(e, hotKeyRefs.REQUEST_SHOW_OPTIONS, () => {
|
||||
this._dropdown && this._dropdown.toggle(true);
|
||||
});
|
||||
}
|
||||
@@ -248,6 +251,7 @@ class RequestUrlBar extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
renderSendButton() {
|
||||
const { hotKeyRegistry } = this.props;
|
||||
const { currentInterval, currentTimeout, downloadPath } = this.state;
|
||||
|
||||
let cancelButton = null;
|
||||
@@ -287,7 +291,7 @@ class RequestUrlBar extends React.PureComponent<Props, State> {
|
||||
<DropdownDivider>Basic</DropdownDivider>
|
||||
<DropdownItem onClick={this._handleClickSend}>
|
||||
<i className="fa fa-arrow-circle-o-right" /> Send Now
|
||||
<DropdownHint hotkey={hotkeys.SEND_REQUEST} />
|
||||
<DropdownHint keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_SEND.id]} />
|
||||
</DropdownItem>
|
||||
<DropdownItem onClick={this._handleGenerateCode}>
|
||||
<i className="fa fa-code" /> Generate Client Code
|
||||
|
||||
@@ -24,8 +24,9 @@ import { PREVIEW_MODE_SOURCE } from '../../common/constants';
|
||||
import { getSetCookieHeaders, nullFn } from '../../common/misc';
|
||||
import { cancelCurrentRequest } from '../../network/network';
|
||||
import Hotkey from './hotkey';
|
||||
import * as hotkeys from '../../common/hotkeys';
|
||||
import ErrorBoundary from './error-boundary';
|
||||
import type { HotKeyRegistry } from '../../common/hotkeys';
|
||||
import { hotKeyRefs } from '../../common/hotkeys';
|
||||
|
||||
type Props = {
|
||||
// Functions
|
||||
@@ -47,6 +48,7 @@ type Props = {
|
||||
editorLineWrapping: boolean,
|
||||
loadStartTime: number,
|
||||
responses: Array<Response>,
|
||||
hotKeyRegistry: HotKeyRegistry,
|
||||
|
||||
// Other
|
||||
request: ?Request,
|
||||
@@ -170,6 +172,7 @@ class ResponsePane extends React.PureComponent<Props> {
|
||||
filter,
|
||||
filterHistory,
|
||||
showCookiesModal,
|
||||
hotKeyRegistry,
|
||||
} = this.props;
|
||||
|
||||
const paneClasses = 'response-pane theme--pane pane';
|
||||
@@ -197,7 +200,7 @@ class ResponsePane extends React.PureComponent<Props> {
|
||||
<td>Send Request</td>
|
||||
<td className="text-right">
|
||||
<code>
|
||||
<Hotkey hotkey={hotkeys.SEND_REQUEST} />
|
||||
<Hotkey keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_SEND.id]} />
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -205,7 +208,7 @@ class ResponsePane extends React.PureComponent<Props> {
|
||||
<td>Focus Url Bar</td>
|
||||
<td className="text-right">
|
||||
<code>
|
||||
<Hotkey hotkey={hotkeys.FOCUS_URL} />
|
||||
<Hotkey keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_FOCUS_URL.id]} />
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -213,7 +216,7 @@ class ResponsePane extends React.PureComponent<Props> {
|
||||
<td>Manage Cookies</td>
|
||||
<td className="text-right">
|
||||
<code>
|
||||
<Hotkey hotkey={hotkeys.SHOW_COOKIES} />
|
||||
<Hotkey keyBindings={hotKeyRegistry[hotKeyRefs.SHOW_COOKIES_EDITOR.id]} />
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -221,7 +224,9 @@ class ResponsePane extends React.PureComponent<Props> {
|
||||
<td>Edit Environments</td>
|
||||
<td className="text-right">
|
||||
<code>
|
||||
<Hotkey hotkey={hotkeys.SHOW_ENVIRONMENTS} />
|
||||
<Hotkey
|
||||
keyBindings={hotKeyRegistry[hotKeyRefs.ENVIRONMENT_SHOW_EDITOR.id]}
|
||||
/>
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -9,6 +9,10 @@ import {
|
||||
isWindows,
|
||||
UPDATE_CHANNEL_BETA,
|
||||
UPDATE_CHANNEL_STABLE,
|
||||
EDITOR_KEY_MAP_DEFAULT,
|
||||
EDITOR_KEY_MAP_EMACS,
|
||||
EDITOR_KEY_MAP_SUBLIME,
|
||||
EDITOR_KEY_MAP_VIM,
|
||||
} from '../../../common/constants';
|
||||
import type { Settings } from '../../../models/settings';
|
||||
import CheckForUpdatesButton from '../check-for-updates-button';
|
||||
@@ -331,10 +335,10 @@ class General extends React.PureComponent<Props, State> {
|
||||
defaultValue={settings.editorKeyMap}
|
||||
name="editorKeyMap"
|
||||
onChange={this._handleUpdateSetting}>
|
||||
<option value="default">Default</option>
|
||||
<option value="vim">Vim</option>
|
||||
<option value="emacs">Emacs</option>
|
||||
<option value="sublime">Sublime</option>
|
||||
<option value={EDITOR_KEY_MAP_DEFAULT}>Default</option>
|
||||
<option value={EDITOR_KEY_MAP_VIM}>Vim</option>
|
||||
<option value={EDITOR_KEY_MAP_EMACS}>Emacs</option>
|
||||
<option value={EDITOR_KEY_MAP_SUBLIME}>Sublime</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
// @flow
|
||||
import React, { PureComponent } from 'react';
|
||||
import autobind from 'autobind-decorator';
|
||||
import Hotkey from '../hotkey';
|
||||
import * as hotkeys from '../../../common/hotkeys';
|
||||
import type { HotKeyDefinition, HotKeyRegistry } from '../../../common/hotkeys';
|
||||
import { hotKeyRefs } from '../../../common/hotkeys';
|
||||
|
||||
type Props = {
|
||||
hotKeyRegistry: HotKeyRegistry,
|
||||
};
|
||||
|
||||
@autobind
|
||||
class Shortcuts extends PureComponent {
|
||||
renderHotkey(hotkey, i) {
|
||||
class Shortcuts extends PureComponent<Props> {
|
||||
renderHotKey(def: HotKeyDefinition, i: number) {
|
||||
return (
|
||||
<tr key={i}>
|
||||
<td>{hotkey.description}</td>
|
||||
<td>{def.description}</td>
|
||||
<td className="text-right">
|
||||
<code>
|
||||
<Hotkey hotkey={hotkey} />
|
||||
<Hotkey keyBindings={this.props.hotKeyRegistry[def.id]} />
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -19,33 +25,38 @@ class Shortcuts extends PureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
const hotKeyDefs: Array<HotKeyDefinition> = [
|
||||
hotKeyRefs.PREFERENCES_SHOW_KEYBOARD_SHORTCUTS,
|
||||
hotKeyRefs.REQUEST_QUICK_SWITCH,
|
||||
hotKeyRefs.REQUEST_SEND,
|
||||
hotKeyRefs.REQUEST_SHOW_OPTIONS,
|
||||
hotKeyRefs.REQUEST_SHOW_CREATE,
|
||||
hotKeyRefs.REQUEST_SHOW_DELETE,
|
||||
hotKeyRefs.REQUEST_SHOW_CREATE_FOLDER,
|
||||
hotKeyRefs.REQUEST_SHOW_DUPLICATE,
|
||||
hotKeyRefs.SHOW_COOKIES_EDITOR,
|
||||
hotKeyRefs.ENVIRONMENT_SHOW_EDITOR,
|
||||
hotKeyRefs.ENVIRONMENT_SHOW_SWITCH_MENU,
|
||||
hotKeyRefs.REQUEST_FOCUS_URL,
|
||||
hotKeyRefs.RESPONSE_FOCUS,
|
||||
hotKeyRefs.REQUEST_TOGGLE_HTTP_METHOD_MENU,
|
||||
hotKeyRefs.SIDEBAR_TOGGLE,
|
||||
hotKeyRefs.REQUEST_TOGGLE_HISTORY,
|
||||
hotKeyRefs.SHOW_AUTOCOMPLETE,
|
||||
hotKeyRefs.PREFERENCES_SHOW_GENERAL,
|
||||
hotKeyRefs.WORKSPACE_SHOW_SETTINGS,
|
||||
hotKeyRefs.REQUEST_SHOW_SETTINGS,
|
||||
hotKeyRefs.TOGGLE_MAIN_MENU,
|
||||
hotKeyRefs.PLUGIN_RELOAD,
|
||||
hotKeyRefs.ENVIRONMENT_UNCOVER_VARIABLES,
|
||||
];
|
||||
return (
|
||||
<div>
|
||||
<table className="table--fancy">
|
||||
<tbody>
|
||||
{this.renderHotkey(hotkeys.SHOW_KEYBOARD_SHORTCUTS)}
|
||||
{this.renderHotkey(hotkeys.SHOW_QUICK_SWITCHER)}
|
||||
{this.renderHotkey(hotkeys.SEND_REQUEST)}
|
||||
{this.renderHotkey(hotkeys.SHOW_SEND_OPTIONS)}
|
||||
{this.renderHotkey(hotkeys.CREATE_REQUEST)}
|
||||
{this.renderHotkey(hotkeys.DELETE_REQUEST)}
|
||||
{this.renderHotkey(hotkeys.CREATE_FOLDER)}
|
||||
{this.renderHotkey(hotkeys.DUPLICATE_REQUEST)}
|
||||
{this.renderHotkey(hotkeys.SHOW_COOKIES)}
|
||||
{this.renderHotkey(hotkeys.SHOW_ENVIRONMENTS)}
|
||||
{this.renderHotkey(hotkeys.TOGGLE_ENVIRONMENTS_MENU)}
|
||||
{this.renderHotkey(hotkeys.FOCUS_URL)}
|
||||
{this.renderHotkey(hotkeys.FOCUS_RESPONSE)}
|
||||
{this.renderHotkey(hotkeys.TOGGLE_METHOD_DROPDOWN)}
|
||||
{this.renderHotkey(hotkeys.TOGGLE_SIDEBAR)}
|
||||
{this.renderHotkey(hotkeys.TOGGLE_HISTORY_DROPDOWN)}
|
||||
{this.renderHotkey(hotkeys.SHOW_AUTOCOMPLETE)}
|
||||
{this.renderHotkey(hotkeys.SHOW_SETTINGS)}
|
||||
{this.renderHotkey(hotkeys.SHOW_WORKSPACE_SETTINGS)}
|
||||
{this.renderHotkey(hotkeys.SHOW_REQUEST_SETTINGS)}
|
||||
{this.renderHotkey(hotkeys.TOGGLE_MAIN_MENU)}
|
||||
{this.renderHotkey(hotkeys.RELOAD_PLUGINS)}
|
||||
{this.renderHotkey(hotkeys.UNCOVER_VARIABLES)}
|
||||
{hotKeyDefs.map((def: HotKeyDefinition, idx: number) => {
|
||||
return this.renderHotKey(def, idx);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,7 @@ import * as models from '../../../models/index';
|
||||
import type { RequestGroup } from '../../../models/request-group';
|
||||
import type { Workspace } from '../../../models/workspace';
|
||||
import type { Request } from '../../../models/request';
|
||||
import type { HotKeyRegistry } from '../../../common/hotkeys';
|
||||
|
||||
type Child = {
|
||||
doc: Request | RequestGroup,
|
||||
@@ -29,6 +30,7 @@ type Props = {
|
||||
childObjects: Array<Child>,
|
||||
workspace: Workspace,
|
||||
filter: string,
|
||||
hotKeyRegistry: HotKeyRegistry,
|
||||
|
||||
// Optional
|
||||
activeRequest?: Request,
|
||||
@@ -50,6 +52,7 @@ class SidebarChildren extends React.PureComponent<Props> {
|
||||
handleActivateRequest,
|
||||
activeRequest,
|
||||
workspace,
|
||||
hotKeyRegistry,
|
||||
} = this.props;
|
||||
|
||||
const activeRequestId = activeRequest ? activeRequest._id : 'n/a';
|
||||
@@ -73,6 +76,7 @@ class SidebarChildren extends React.PureComponent<Props> {
|
||||
isActive={child.doc._id === activeRequestId}
|
||||
request={child.doc}
|
||||
workspace={workspace}
|
||||
hotKeyRegistry={hotKeyRegistry}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -113,6 +117,7 @@ class SidebarChildren extends React.PureComponent<Props> {
|
||||
numChildren={child.children.length}
|
||||
workspace={workspace}
|
||||
requestGroup={requestGroup}
|
||||
hotKeyRegistry={hotKeyRegistry}
|
||||
children={children}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -4,13 +4,16 @@ import autobind from 'autobind-decorator';
|
||||
import { Dropdown, DropdownHint, DropdownButton, DropdownItem } from '../base/dropdown';
|
||||
import { DEBOUNCE_MILLIS } from '../../../common/constants';
|
||||
import KeydownBinder from '../keydown-binder';
|
||||
import * as hotkeys from '../../../common/hotkeys';
|
||||
import type { HotKeyRegistry } from '../../../common/hotkeys';
|
||||
import { hotKeyRefs } from '../../../common/hotkeys';
|
||||
import { executeHotKey } from '../../../common/hotkeys-listener';
|
||||
|
||||
type Props = {
|
||||
onChange: string => void,
|
||||
requestCreate: () => void,
|
||||
requestGroupCreate: () => void,
|
||||
filter: string,
|
||||
hotKeyRegistry: HotKeyRegistry,
|
||||
};
|
||||
|
||||
@autobind
|
||||
@@ -48,13 +51,13 @@ class SidebarFilter extends React.PureComponent<Props> {
|
||||
}
|
||||
|
||||
_handleKeydown(e: KeyboardEvent) {
|
||||
hotkeys.executeHotKey(e, hotkeys.FOCUS_FILTER, () => {
|
||||
executeHotKey(e, hotKeyRefs.SIDEBAR_FOCUS_FILTER, () => {
|
||||
this._input && this._input.focus();
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { filter } = this.props;
|
||||
const { filter, hotKeyRegistry } = this.props;
|
||||
return (
|
||||
<KeydownBinder onKeydown={this._handleKeydown}>
|
||||
<div className="sidebar__filter">
|
||||
@@ -79,11 +82,13 @@ class SidebarFilter extends React.PureComponent<Props> {
|
||||
</DropdownButton>
|
||||
<DropdownItem onClick={this._handleRequestCreate}>
|
||||
<i className="fa fa-plus-circle" /> New Request
|
||||
<DropdownHint hotkey={hotkeys.CREATE_REQUEST} />
|
||||
<DropdownHint keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_SHOW_CREATE.id]} />
|
||||
</DropdownItem>
|
||||
<DropdownItem onClick={this._handleRequestGroupCreate}>
|
||||
<i className="fa fa-folder" /> New Folder
|
||||
<DropdownHint hotkey={hotkeys.CREATE_FOLDER} />
|
||||
<DropdownHint
|
||||
keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_SHOW_CREATE_FOLDER.id]}
|
||||
/>
|
||||
</DropdownItem>
|
||||
</Dropdown>
|
||||
</div>
|
||||
|
||||
@@ -55,6 +55,7 @@ class SidebarRequestGroupRow extends PureComponent {
|
||||
isDragging,
|
||||
isDraggingOver,
|
||||
workspace,
|
||||
hotKeyRegistry,
|
||||
} = this.props;
|
||||
|
||||
const { dragDirection } = this.state;
|
||||
@@ -98,6 +99,7 @@ class SidebarRequestGroupRow extends PureComponent {
|
||||
handleMoveRequestGroup={handleMoveRequestGroup}
|
||||
workspace={workspace}
|
||||
requestGroup={requestGroup}
|
||||
hotKeyRegistry={hotKeyRegistry}
|
||||
right
|
||||
/>
|
||||
</div>
|
||||
@@ -122,6 +124,7 @@ class SidebarRequestGroupRow extends PureComponent {
|
||||
workspace={workspace}
|
||||
requestCreate={handleCreateRequest}
|
||||
filter={filter}
|
||||
hotKeyRegistry={hotKeyRegistry}
|
||||
/>
|
||||
)}
|
||||
</ul>
|
||||
@@ -146,6 +149,7 @@ SidebarRequestGroupRow.propTypes = {
|
||||
isCollapsed: PropTypes.bool.isRequired,
|
||||
workspace: PropTypes.object.isRequired,
|
||||
requestGroup: PropTypes.object.isRequired,
|
||||
hotKeyRegistry: PropTypes.object.isRequired,
|
||||
|
||||
// React DnD
|
||||
isDragging: PropTypes.bool,
|
||||
|
||||
@@ -78,6 +78,7 @@ class SidebarRequestRow extends PureComponent {
|
||||
request,
|
||||
requestGroup,
|
||||
isActive,
|
||||
hotKeyRegistry,
|
||||
} = this.props;
|
||||
|
||||
const { dragDirection } = this.state;
|
||||
@@ -134,6 +135,7 @@ class SidebarRequestRow extends PureComponent {
|
||||
handleShowSettings={this._handleShowRequestSettings}
|
||||
request={request}
|
||||
requestGroup={requestGroup}
|
||||
hotKeyRegistry={hotKeyRegistry}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -161,6 +163,7 @@ SidebarRequestRow.propTypes = {
|
||||
// Other
|
||||
filter: PropTypes.string.isRequired,
|
||||
isActive: PropTypes.bool.isRequired,
|
||||
hotKeyRegistry: PropTypes.object.isRequired,
|
||||
|
||||
// React DnD
|
||||
isDragging: PropTypes.bool,
|
||||
|
||||
@@ -55,6 +55,7 @@ class Sidebar extends PureComponent {
|
||||
handleActivateRequest,
|
||||
activeRequest,
|
||||
environmentHighlightColorStyle,
|
||||
hotKeyRegistry,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@@ -77,6 +78,7 @@ class Sidebar extends PureComponent {
|
||||
activeWorkspace={workspace}
|
||||
workspaces={workspaces}
|
||||
unseenWorkspaces={unseenWorkspaces}
|
||||
hotKeyRegistry={hotKeyRegistry}
|
||||
handleExportFile={handleExportFile}
|
||||
handleImportFile={handleImportFile}
|
||||
handleSetActiveWorkspace={handleSetActiveWorkspace}
|
||||
@@ -90,6 +92,7 @@ class Sidebar extends PureComponent {
|
||||
environments={environments}
|
||||
workspace={workspace}
|
||||
environmentHighlightColorStyle={environmentHighlightColorStyle}
|
||||
hotKeyRegistry={hotKeyRegistry}
|
||||
/>
|
||||
<button className="btn btn--super-compact" onClick={showCookiesModal}>
|
||||
<div className="sidebar__menu__thing">
|
||||
@@ -104,6 +107,7 @@ class Sidebar extends PureComponent {
|
||||
requestCreate={this._handleCreateRequestInWorkspace}
|
||||
requestGroupCreate={this._handleCreateRequestGroupInWorkspace}
|
||||
filter={filter || ''}
|
||||
hotKeyRegistry={hotKeyRegistry}
|
||||
/>
|
||||
|
||||
<SidebarChildren
|
||||
@@ -121,6 +125,7 @@ class Sidebar extends PureComponent {
|
||||
workspace={workspace}
|
||||
activeRequest={activeRequest}
|
||||
filter={filter || ''}
|
||||
hotKeyRegistry={hotKeyRegistry}
|
||||
/>
|
||||
|
||||
<SyncButton className="sidebar__footer" key={workspace._id} workspace={workspace} />
|
||||
@@ -159,6 +164,7 @@ Sidebar.propTypes = {
|
||||
unseenWorkspaces: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
environments: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
environmentHighlightColorStyle: PropTypes.string.isRequired,
|
||||
hotKeyRegistry: PropTypes.object.isRequired,
|
||||
|
||||
// Optional
|
||||
filter: PropTypes.string,
|
||||
|
||||
@@ -16,8 +16,9 @@ import {
|
||||
PREVIEW_MODE_FRIENDLY,
|
||||
PREVIEW_MODE_RAW,
|
||||
} from '../../../common/constants';
|
||||
import * as hotkeys from '../../../common/hotkeys';
|
||||
import KeydownBinder from '../keydown-binder';
|
||||
import { executeHotKey } from '../../../common/hotkeys-listener';
|
||||
import { hotKeyRefs } from '../../../common/hotkeys';
|
||||
|
||||
let alwaysShowLargeResponses = false;
|
||||
|
||||
@@ -180,7 +181,7 @@ class ResponseViewer extends React.Component<Props, State> {
|
||||
return;
|
||||
}
|
||||
|
||||
hotkeys.executeHotKey(e, hotkeys.FOCUS_RESPONSE, () => {
|
||||
executeHotKey(e, hotKeyRefs.RESPONSE_FOCUS, () => {
|
||||
if (!this._isViewSelectable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -633,6 +633,7 @@ class Wrapper extends React.PureComponent<Props, State> {
|
||||
workspaces={workspaces}
|
||||
environments={environments}
|
||||
environmentHighlightColorStyle={settings.environmentHighlightColorStyle}
|
||||
hotKeyRegistry={settings.hotKeyRegistry}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
|
||||
@@ -697,6 +698,7 @@ class Wrapper extends React.PureComponent<Props, State> {
|
||||
editorIndentSize={settings.editorIndentSize}
|
||||
editorKeyMap={settings.editorKeyMap}
|
||||
editorLineWrapping={settings.editorLineWrapping}
|
||||
hotKeyRegistry={settings.hotKeyRegistry}
|
||||
previewMode={responsePreviewMode}
|
||||
filter={responseFilter}
|
||||
filterHistory={responseFilterHistory}
|
||||
|
||||
@@ -58,7 +58,8 @@ import * as render from '../../common/render';
|
||||
import { getKeys } from '../../templating/utils';
|
||||
import { showAlert, showModal, showPrompt } from '../components/modals/index';
|
||||
import { exportHarRequest } from '../../common/har';
|
||||
import * as hotkeys from '../../common/hotkeys';
|
||||
import { hotKeyRefs } from '../../common/hotkeys';
|
||||
import { executeHotKey } from '../../common/hotkeys-listener';
|
||||
import KeydownBinder from '../components/keydown-binder';
|
||||
import ErrorBoundary from '../components/error-boundary';
|
||||
import * as plugins from '../../plugins';
|
||||
@@ -100,20 +101,20 @@ class App extends PureComponent {
|
||||
_setGlobalKeyMap() {
|
||||
this._globalKeyMap = [
|
||||
[
|
||||
hotkeys.SHOW_KEYBOARD_SHORTCUTS,
|
||||
hotKeyRefs.PREFERENCES_SHOW_KEYBOARD_SHORTCUTS,
|
||||
() => {
|
||||
showModal(SettingsModal, TAB_INDEX_SHORTCUTS);
|
||||
},
|
||||
],
|
||||
[
|
||||
hotkeys.SHOW_WORKSPACE_SETTINGS,
|
||||
hotKeyRefs.WORKSPACE_SHOW_SETTINGS,
|
||||
() => {
|
||||
const { activeWorkspace } = this.props;
|
||||
showModal(WorkspaceSettingsModal, activeWorkspace);
|
||||
},
|
||||
],
|
||||
[
|
||||
hotkeys.SHOW_REQUEST_SETTINGS,
|
||||
hotKeyRefs.REQUEST_SHOW_SETTINGS,
|
||||
() => {
|
||||
if (this.props.activeRequest) {
|
||||
showModal(RequestSettingsModal, {
|
||||
@@ -123,29 +124,28 @@ class App extends PureComponent {
|
||||
},
|
||||
],
|
||||
[
|
||||
hotkeys.SHOW_QUICK_SWITCHER,
|
||||
hotKeyRefs.REQUEST_QUICK_SWITCH,
|
||||
() => {
|
||||
showModal(RequestSwitcherModal);
|
||||
},
|
||||
],
|
||||
[hotkeys.SEND_REQUEST, this._handleSendShortcut],
|
||||
[hotkeys.SEND_REQUEST_F5, this._handleSendShortcut],
|
||||
[hotKeyRefs.REQUEST_SEND, this._handleSendShortcut],
|
||||
[
|
||||
hotkeys.SHOW_ENVIRONMENTS,
|
||||
hotKeyRefs.ENVIRONMENT_SHOW_EDITOR,
|
||||
() => {
|
||||
const { activeWorkspace } = this.props;
|
||||
showModal(WorkspaceEnvironmentsEditModal, activeWorkspace);
|
||||
},
|
||||
],
|
||||
[
|
||||
hotkeys.SHOW_COOKIES,
|
||||
hotKeyRefs.SHOW_COOKIES_EDITOR,
|
||||
() => {
|
||||
const { activeWorkspace } = this.props;
|
||||
showModal(CookiesModal, activeWorkspace);
|
||||
},
|
||||
],
|
||||
[
|
||||
hotkeys.CREATE_REQUEST,
|
||||
hotKeyRefs.REQUEST_SHOW_CREATE,
|
||||
() => {
|
||||
const { activeRequest, activeWorkspace } = this.props;
|
||||
const parentId = activeRequest ? activeRequest.parentId : activeWorkspace._id;
|
||||
@@ -153,7 +153,7 @@ class App extends PureComponent {
|
||||
},
|
||||
],
|
||||
[
|
||||
hotkeys.DELETE_REQUEST,
|
||||
hotKeyRefs.REQUEST_SHOW_DELETE,
|
||||
() => {
|
||||
const { activeRequest } = this.props;
|
||||
|
||||
@@ -174,7 +174,7 @@ class App extends PureComponent {
|
||||
},
|
||||
],
|
||||
[
|
||||
hotkeys.CREATE_FOLDER,
|
||||
hotKeyRefs.REQUEST_SHOW_CREATE_FOLDER,
|
||||
() => {
|
||||
const { activeRequest, activeWorkspace } = this.props;
|
||||
const parentId = activeRequest ? activeRequest.parentId : activeWorkspace._id;
|
||||
@@ -182,19 +182,19 @@ class App extends PureComponent {
|
||||
},
|
||||
],
|
||||
[
|
||||
hotkeys.GENERATE_CODE,
|
||||
hotKeyRefs.REQUEST_SHOW_GENERATE_CODE_EDITOR,
|
||||
async () => {
|
||||
showModal(GenerateCodeModal, this.props.activeRequest);
|
||||
},
|
||||
],
|
||||
[
|
||||
hotkeys.DUPLICATE_REQUEST,
|
||||
hotKeyRefs.REQUEST_SHOW_DUPLICATE,
|
||||
async () => {
|
||||
await this._requestDuplicate(this.props.activeRequest);
|
||||
},
|
||||
],
|
||||
[
|
||||
hotkeys.UNCOVER_VARIABLES,
|
||||
hotKeyRefs.ENVIRONMENT_UNCOVER_VARIABLES,
|
||||
async () => {
|
||||
await this._updateIsVariableUncovered();
|
||||
},
|
||||
@@ -743,7 +743,7 @@ class App extends PureComponent {
|
||||
|
||||
_handleKeyDown(e) {
|
||||
for (const [definition, callback] of this._globalKeyMap) {
|
||||
hotkeys.executeHotKey(e, definition, callback);
|
||||
executeHotKey(e, definition, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Generated
+745
-919
File diff suppressed because it is too large.
Load diff
@@ -180,9 +180,9 @@
|
||||
"cross-env": "^2.0.0",
|
||||
"css-loader": "^0.28.11",
|
||||
"electron": "^3.0.4",
|
||||
"electron-builder": "^20.20.4",
|
||||
"electron-builder-lib": "^20.20.4",
|
||||
"electron-builder-squirrel-windows": "^20.20.4",
|
||||
"electron-builder": "^20.38.5",
|
||||
"electron-builder-lib": "^20.23.1",
|
||||
"electron-builder-squirrel-windows": "^20.38.5",
|
||||
"electron-rebuild": "^1.8.2",
|
||||
"eslint": "^4.19.1",
|
||||
"eslint-config-semistandard": "^12.0.1",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "insomnia-cookies",
|
||||
"version": "0.0.11",
|
||||
"version": "0.0.13",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "insomnia-httpsnippet",
|
||||
"version": "1.16.17",
|
||||
"version": "1.16.19",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @description
|
||||
* HTTP code snippet generator for the browser Fetch API
|
||||
*
|
||||
* @author
|
||||
* @peoplenarthax
|
||||
*
|
||||
* for any questions or issues regarding the generated code snippet, please open an issue mentioning the author.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
var CodeBuilder = require('../../helpers/code-builder');
|
||||
|
||||
module.exports = function(source, options) {
|
||||
var opts = util._extend(
|
||||
{
|
||||
indent: ' ',
|
||||
},
|
||||
options,
|
||||
);
|
||||
|
||||
var code = new CodeBuilder(opts.indent);
|
||||
|
||||
var url = source.fullUrl;
|
||||
var fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: source.method,
|
||||
headers: source.allHeaders,
|
||||
};
|
||||
|
||||
switch (source.postData.mimeType) {
|
||||
case 'application/x-www-form-urlencoded':
|
||||
fetchOptions.body = source.postData.paramsObj
|
||||
? source.postData.paramsObj
|
||||
: source.postData.text;
|
||||
break;
|
||||
|
||||
case 'application/json':
|
||||
fetchOptions.body = source.postData.text;
|
||||
break;
|
||||
|
||||
case 'multipart/form-data':
|
||||
code.push('let form = new FormData();');
|
||||
|
||||
source.postData.params.forEach(function(param) {
|
||||
code.push(
|
||||
'form.append(%s, %s);',
|
||||
JSON.stringify(param.name),
|
||||
JSON.stringify(param.value || param.fileName || ''),
|
||||
);
|
||||
});
|
||||
delete fetchOptions.headers;
|
||||
fetchOptions.body = '[form]';
|
||||
|
||||
code.blank();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (source.postData.text) {
|
||||
fetchOptions.data = source.postData.text;
|
||||
}
|
||||
}
|
||||
|
||||
code
|
||||
.push(
|
||||
'const fetchOptions = ' +
|
||||
JSON.stringify(fetchOptions, null, opts.indent).replace('"[form]"', 'form'),
|
||||
)
|
||||
.blank()
|
||||
.push('fetch("' + url + '", fetchOptions)')
|
||||
.push(1, '.then(response => response.json())')
|
||||
.push(1, '.then(data => console.log(data));');
|
||||
|
||||
return code.join();
|
||||
};
|
||||
|
||||
module.exports.info = {
|
||||
key: 'fetch',
|
||||
title: 'Fetch API',
|
||||
link: 'https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API',
|
||||
description: 'Browser API that offers a simple interface for fetching resources',
|
||||
};
|
||||
@@ -9,5 +9,6 @@ module.exports = {
|
||||
},
|
||||
|
||||
jquery: require('./jquery'),
|
||||
fetch: require('./fetch'),
|
||||
xhr: require('./xhr'),
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @description
|
||||
* HTTP code snippet generator for native XMLHttpRequest
|
||||
* HTTP code snippet generator for jQuery
|
||||
*
|
||||
* @author
|
||||
* @AhmadNassri
|
||||
|
||||
@@ -63,6 +63,12 @@
|
||||
"link": "http://api.jquery.com/jquery.ajax/",
|
||||
"description": "Perform an asynchronous HTTP (Ajax) requests with jQuery"
|
||||
},
|
||||
{
|
||||
"key": "fetch",
|
||||
"title": "Fetch API",
|
||||
"link": "https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API",
|
||||
"description": "Browser API that offers a simple interface for fetching resources"
|
||||
},
|
||||
{
|
||||
"key": "xhr",
|
||||
"title": "XMLHttpRequest",
|
||||
@@ -137,7 +143,7 @@
|
||||
"extname": ".m",
|
||||
"default": "nsurlsession",
|
||||
"clients": [
|
||||
{
|
||||
{
|
||||
"key": "nsurlsession",
|
||||
"title": "NSURLSession",
|
||||
"link": "https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSURLSession_class/index.html",
|
||||
@@ -151,7 +157,7 @@
|
||||
"extname": ".swift",
|
||||
"default": "nsurlsession",
|
||||
"clients": [
|
||||
{
|
||||
{
|
||||
"key": "nsurlsession",
|
||||
"title": "NSURLSession",
|
||||
"link": "https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSURLSession_class/index.html",
|
||||
@@ -165,7 +171,7 @@
|
||||
"extname": ".go",
|
||||
"default": "native",
|
||||
"clients": [
|
||||
{
|
||||
{
|
||||
"key": "native",
|
||||
"title": "NewRequest",
|
||||
"link": "http://golang.org/pkg/net/http/#NewRequest",
|
||||
|
||||
Vendored
Executable
+15
@@ -0,0 +1,15 @@
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: {
|
||||
foo: 'bar',
|
||||
hello: 'world',
|
||||
},
|
||||
};
|
||||
|
||||
fetch('http://mockbin.com/har', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
Vendored
Executable
+13
@@ -0,0 +1,13 @@
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body:
|
||||
'{"number":1,"string":"f\\"oo","arr":[1,2,3],"nested":{"a":"b"},"arr_mix":[1,"a",{"arr_mix_nested":{}}],"boolean":false}',
|
||||
};
|
||||
|
||||
fetch('http://mockbin.com/har', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
cookie: 'foo=bar; bar=baz',
|
||||
},
|
||||
};
|
||||
|
||||
fetch('http://mockbin.com/har', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
Vendored
Executable
+9
@@ -0,0 +1,9 @@
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'PROPFIND',
|
||||
headers: {},
|
||||
};
|
||||
|
||||
fetch('http://mockbin.com/har', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
cookie: 'foo=bar; bar=baz',
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: {
|
||||
foo: 'bar',
|
||||
},
|
||||
};
|
||||
|
||||
fetch('http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'x-foo': 'Bar',
|
||||
},
|
||||
};
|
||||
|
||||
fetch('http://mockbin.com/har', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'GET',
|
||||
headers: {},
|
||||
};
|
||||
|
||||
fetch('https://mockbin.com/har', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
Vendored
Executable
+12
@@ -0,0 +1,12 @@
|
||||
let form = new FormData();
|
||||
form.append('foo', 'Hello World');
|
||||
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'POST',
|
||||
body: form,
|
||||
};
|
||||
|
||||
fetch('http://mockbin.com/har', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
Vendored
Executable
+12
@@ -0,0 +1,12 @@
|
||||
let form = new FormData();
|
||||
form.append('foo', 'test/fixtures/files/hello.txt');
|
||||
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'POST',
|
||||
body: form,
|
||||
};
|
||||
|
||||
fetch('http://mockbin.com/har', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
Vendored
Executable
+12
@@ -0,0 +1,12 @@
|
||||
let form = new FormData();
|
||||
form.append('foo', 'bar');
|
||||
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'POST',
|
||||
body: form,
|
||||
};
|
||||
|
||||
fetch('http://mockbin.com/har', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'GET',
|
||||
headers: {},
|
||||
};
|
||||
|
||||
fetch('http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'GET',
|
||||
headers: {},
|
||||
};
|
||||
|
||||
fetch('http://mockbin.com/har', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
Vendored
Executable
+12
@@ -0,0 +1,12 @@
|
||||
const fetchOptions = {
|
||||
mode: 'cors',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'text/plain',
|
||||
},
|
||||
data: 'Hello World',
|
||||
};
|
||||
|
||||
fetch('http://mockbin.com/har', fetchOptions)
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
||||
@@ -0,0 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function(snippet, fixtures) {};
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "insomnia-importers",
|
||||
"version": "2.0.12",
|
||||
"version": "2.0.14",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "insomnia-libcurl",
|
||||
"version": "0.0.22",
|
||||
"version": "0.0.24",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "insomnia-xpath",
|
||||
"version": "1.0.8",
|
||||
"version": "1.0.10",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -19,12 +19,19 @@ function assertTemplateFails(args, expected) {
|
||||
}
|
||||
|
||||
describe('Base64EncodeExtension', () => {
|
||||
it('encodes nothing', assertTemplate(['encode'], ''));
|
||||
it('encodes something', assertTemplate(['encode', 'my string'], 'bXkgc3RyaW5n'));
|
||||
it('decodes nothing', assertTemplate(['decode'], ''));
|
||||
it('decodes something', assertTemplate(['decode', 'bXkgc3RyaW5n'], 'my string'));
|
||||
it('encodes nothing', assertTemplate(['encode', 'normal', ''], ''));
|
||||
it('encodes something', assertTemplate(['encode', 'normal', 'my string'], 'bXkgc3RyaW5n'));
|
||||
it('urlencodes nothing', assertTemplate(['encode', 'url', ''], ''));
|
||||
it('urlencodes something', assertTemplate(['encode', 'url', 'hello world'], 'aGVsbG8gd29ybGQ'));
|
||||
it('decodes nothing', assertTemplate(['decode', 'normal', ''], ''));
|
||||
it('decodes something', assertTemplate(['decode', 'normal', 'bXkgc3RyaW5n'], 'my string'));
|
||||
it('urldecodes nothing', assertTemplate(['decode', 'url', ''], ''));
|
||||
it('urldecodes something', assertTemplate(['decode', 'url', 'aGVsbG8gd29ybGQ'], 'hello world'));
|
||||
it(
|
||||
'fails on invalid op',
|
||||
assertTemplateFails(['foo'], 'Unsupported operation "foo". Must be encode or decode.'),
|
||||
'fails on invalid action',
|
||||
assertTemplateFails(
|
||||
['foo', 'normal', ''],
|
||||
'Unsupported operation "foo". Must be encode or decode.',
|
||||
),
|
||||
);
|
||||
});
|
||||
@@ -12,21 +12,34 @@ module.exports.templateTags = [
|
||||
{ displayName: 'Decode', value: 'decode' },
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Kind',
|
||||
type: 'enum',
|
||||
options: [{ displayName: 'Normal', value: 'normal' }, { displayName: 'URL', value: 'url' }],
|
||||
},
|
||||
{
|
||||
displayName: 'Value',
|
||||
type: 'string',
|
||||
placeholder: 'My text',
|
||||
},
|
||||
],
|
||||
run(context, op, text) {
|
||||
run(context, action, kind, text) {
|
||||
text = text || '';
|
||||
|
||||
if (op === 'encode') {
|
||||
return Buffer.from(text, 'utf8').toString('base64');
|
||||
} else if (op === 'decode') {
|
||||
if (action === 'encode') {
|
||||
if (kind === 'normal') {
|
||||
return Buffer.from(text, 'utf8').toString('base64');
|
||||
} else if (kind === 'url') {
|
||||
return Buffer.from(text, 'utf8')
|
||||
.toString('base64')
|
||||
.replace(/\+/g, '-')
|
||||
.replace(/\//g, '_')
|
||||
.replace(/=/g, '');
|
||||
}
|
||||
} else if (action === 'decode') {
|
||||
return Buffer.from(text, 'base64').toString('utf8');
|
||||
} else {
|
||||
throw new Error('Unsupported operation "' + op + '". Must be encode or decode.');
|
||||
throw new Error('Unsupported operation "' + action + '". Must be encode or decode.');
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -14,6 +14,6 @@
|
||||
"description": "Encode/Decode base64 strings"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node --version"
|
||||
"test": "jest --silent"
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "insomnia-plugin-cookie-jar",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.9",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "insomnia-plugin-jsonpath",
|
||||
"version": "1.0.11",
|
||||
"version": "1.0.13",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "insomnia-plugin-now",
|
||||
"version": "1.0.10",
|
||||
"version": "1.0.12",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "insomnia-plugin-os",
|
||||
"version": "1.0.12",
|
||||
"version": "1.0.14",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -31,7 +31,7 @@ module.exports.templateTags = [
|
||||
description: 'fully qualified URL',
|
||||
},
|
||||
{
|
||||
displayName: 'Query Paramter',
|
||||
displayName: 'Query Parameter',
|
||||
value: 'parameter',
|
||||
description: 'query parameter by name',
|
||||
},
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "insomnia-plugin-response",
|
||||
"version": "1.0.15",
|
||||
"version": "1.0.17",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "insomnia-plugin-uuid",
|
||||
"version": "1.0.9",
|
||||
"version": "1.0.11",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
Reference in new issue
Block a user