mirror of
https://github.com/Kong/insomnia
synced 2024-11-08 06:39:48 +00:00
move insomnia-url helpers to src (#5389)
* remove insomnia-url package * duplicate all that noise * fix tests and decouple insomnia-cookies * update package lock * fix test
This commit is contained in:
parent
f24d1fa672
commit
ef7f67cf5c
@ -1 +0,0 @@
|
||||
dist
|
@ -1,9 +0,0 @@
|
||||
const { OFF, TYPESCRIPT_CONVERSION } = require('eslint-config-helpers');
|
||||
|
||||
/** @type { import('eslint').Linter.Config } */
|
||||
module.exports = {
|
||||
extends: '../../.eslintrc.js',
|
||||
rules: {
|
||||
'@typescript-eslint/no-use-before-define': OFF(TYPESCRIPT_CONVERSION),
|
||||
},
|
||||
};
|
@ -1,5 +0,0 @@
|
||||
# Insomnia URL Utilities
|
||||
|
||||
[![Npm Version](https://img.shields.io/npm/v/insomnia-url.svg)](https://www.npmjs.com/package/insomnia-url)
|
||||
|
||||
Utilities for URLs.
|
@ -1,9 +0,0 @@
|
||||
/** @type { import('@jest/types').Config.InitialOptions } */
|
||||
module.exports = {
|
||||
preset: '../../jest-preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
isolatedModules: true,
|
||||
},
|
||||
},
|
||||
};
|
5935
packages/insomnia-url/package-lock.json
generated
5935
packages/insomnia-url/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,36 +0,0 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "insomnia-url",
|
||||
"version": "3.6.1-beta.3",
|
||||
"author": "Kong <office@konghq.com>",
|
||||
"description": "URL Utilities",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Kong/insomnia.git",
|
||||
"directory": "packages/insomnia-url"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Kong/insomnia/issues"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"package.json",
|
||||
"READEM.md"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@jest/globals": "^28.1.0",
|
||||
"jest": "^28.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"bootstrap": "npm run build",
|
||||
"lint": "eslint . --ext .js,.ts,.tsx --cache",
|
||||
"lint:fix": "npm run lint -- --fix",
|
||||
"clean": "tsc --build tsconfig.build.json --clean",
|
||||
"postclean": "rimraf dist",
|
||||
"build": "tsc --build tsconfig.build.json",
|
||||
"test": "jest --silent"
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
export { setDefaultProtocol } from './protocol';
|
||||
|
||||
export {
|
||||
joinUrlAndQueryString,
|
||||
extractQueryStringFromUrl,
|
||||
buildQueryParameter,
|
||||
buildQueryStringFromParams,
|
||||
deconstructQueryStringToParams,
|
||||
smartEncodeUrl,
|
||||
flexibleEncodeComponent,
|
||||
} from './querystring';
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
},
|
||||
"include": [
|
||||
"src",
|
||||
],
|
||||
"exclude": [
|
||||
"**/*.test.ts",
|
||||
],
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
{
|
||||
"extends": "./tsconfig.build.json",
|
||||
"compilerOptions": {
|
||||
"composite": false,
|
||||
"rootDir": ".",
|
||||
},
|
||||
"include": [
|
||||
".eslintrc.js",
|
||||
"jest.config.js",
|
||||
"src",
|
||||
],
|
||||
"exclude": [
|
||||
"dist",
|
||||
],
|
||||
}
|
@ -85,7 +85,6 @@
|
||||
"insomnia-plugin-response": "^3.6.1-beta.3",
|
||||
"insomnia-plugin-uuid": "^3.6.1-beta.3",
|
||||
"insomnia-testing": "^3.6.1-beta.3",
|
||||
"insomnia-url": "^3.6.1-beta.3",
|
||||
"isomorphic-git": "^1.10.4",
|
||||
"js-yaml": "^3.14.1",
|
||||
"jshint": "^2.11.1",
|
||||
|
@ -1,7 +1,6 @@
|
||||
import clone from 'clone';
|
||||
import fs from 'fs';
|
||||
import { jarFromCookies } from 'insomnia-cookies';
|
||||
import { smartEncodeUrl } from 'insomnia-url';
|
||||
import { Cookie as toughCookie } from 'tough-cookie';
|
||||
|
||||
import * as models from '../models';
|
||||
@ -14,6 +13,7 @@ import { getAuthHeader } from '../network/authentication';
|
||||
import * as plugins from '../plugins';
|
||||
import * as pluginContexts from '../plugins/context/index';
|
||||
import { RenderError } from '../templating/index';
|
||||
import { smartEncodeUrl } from '../utils/url/querystring';
|
||||
import { getAppVersion } from './constants';
|
||||
import { database } from './database';
|
||||
import { filterHeaders, getSetCookieHeaders, hasAuthHeader } from './misc';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import clone from 'clone';
|
||||
import { setDefaultProtocol } from 'insomnia-url';
|
||||
import orderedJSON from 'json-order';
|
||||
|
||||
import * as models from '../models';
|
||||
@ -13,6 +12,7 @@ import { WebSocketRequest } from '../models/websocket-request';
|
||||
import { isWorkspace, Workspace } from '../models/workspace';
|
||||
import * as templating from '../templating';
|
||||
import * as templatingUtils from '../templating/utils';
|
||||
import { setDefaultProtocol } from '../utils/url/protocol';
|
||||
import { CONTENT_TYPE_GRAPHQL, JSON_ORDER_SEPARATOR } from './constants';
|
||||
import { database as db } from './database';
|
||||
|
||||
|
@ -468,7 +468,7 @@ export const getHttpVersion = (preferredHttpVersion: string) => {
|
||||
return { log: `Unknown HTTP version specified ${preferredHttpVersion}` };
|
||||
}
|
||||
};
|
||||
export const setDefaultProtocol = (url: string, defaultProto?: string) => {
|
||||
const setDefaultProtocol = (url: string, defaultProto?: string) => {
|
||||
const trimmedUrl = url.trim();
|
||||
defaultProto = defaultProto || 'http:';
|
||||
|
||||
|
@ -2,11 +2,6 @@ import electron, { ipcMain } from 'electron';
|
||||
import fs from 'fs';
|
||||
import { IncomingMessage } from 'http';
|
||||
import { jarFromCookies } from 'insomnia-cookies';
|
||||
import {
|
||||
buildQueryStringFromParams,
|
||||
joinUrlAndQueryString,
|
||||
setDefaultProtocol,
|
||||
} from 'insomnia-url';
|
||||
import mkdirp from 'mkdirp';
|
||||
import path from 'path';
|
||||
import { KeyObject, PxfObject } from 'tls';
|
||||
@ -33,6 +28,8 @@ import { getBasicAuthHeader } from '../../network/basic-auth/get-header';
|
||||
import { getBearerAuthHeader } from '../../network/bearer-auth/get-header';
|
||||
import { addSetCookiesToToughCookieJar } from '../../network/network';
|
||||
import { urlMatchesCertHost } from '../../network/url-matches-cert-host';
|
||||
import { setDefaultProtocol } from '../../utils/url/protocol';
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from '../../utils/url/querystring';
|
||||
|
||||
export interface WebSocketConnection extends WebSocket {
|
||||
_id: string;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import electron from 'electron';
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from 'insomnia-url';
|
||||
|
||||
import {
|
||||
CHECK_FOR_UPDATES_INTERVAL,
|
||||
@ -11,6 +10,7 @@ import {
|
||||
} from '../common/constants';
|
||||
import { delay } from '../common/misc';
|
||||
import * as models from '../models/index';
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from '../utils/url/querystring';
|
||||
const { autoUpdater, BrowserWindow, ipcMain } = electron;
|
||||
|
||||
async function getUpdateUrl(force: boolean): Promise<string | null> {
|
||||
|
@ -1,5 +1,3 @@
|
||||
import { deconstructQueryStringToParams } from 'insomnia-url';
|
||||
|
||||
import {
|
||||
AUTH_ASAP,
|
||||
AUTH_AWS_IAM,
|
||||
@ -26,6 +24,7 @@ import { database as db } from '../common/database';
|
||||
import { getContentTypeHeader } from '../common/misc';
|
||||
import { SIGNATURE_METHOD_HMAC_SHA1 } from '../network/o-auth-1/constants';
|
||||
import { GRANT_TYPE_AUTHORIZATION_CODE } from '../network/o-auth-2/constants';
|
||||
import { deconstructQueryStringToParams } from '../utils/url/querystring';
|
||||
import type { BaseModel } from './index';
|
||||
|
||||
export const name = 'Request';
|
||||
|
@ -1,10 +1,10 @@
|
||||
import axios, { AxiosRequestConfig } from 'axios';
|
||||
import * as https from 'https';
|
||||
import { setDefaultProtocol } from 'insomnia-url';
|
||||
import { parse as urlParse } from 'url';
|
||||
|
||||
import { isDevelopment } from '../common/constants';
|
||||
import * as models from '../models';
|
||||
import { setDefaultProtocol } from '../utils/url/protocol';
|
||||
import { isUrlMatchedInNoProxyRule } from './is-url-matched-in-no-proxy-rule';
|
||||
|
||||
export async function axiosRequest(config: AxiosRequestConfig) {
|
||||
|
@ -1,12 +1,6 @@
|
||||
import clone from 'clone';
|
||||
import fs from 'fs';
|
||||
import { cookiesFromJar, jarFromCookies } from 'insomnia-cookies';
|
||||
import {
|
||||
buildQueryStringFromParams,
|
||||
joinUrlAndQueryString,
|
||||
setDefaultProtocol,
|
||||
smartEncodeUrl,
|
||||
} from 'insomnia-url';
|
||||
import mkdirp from 'mkdirp';
|
||||
import { join as pathJoin } from 'path';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
@ -37,6 +31,12 @@ import type { Settings } from '../models/settings';
|
||||
import { isWorkspace } from '../models/workspace';
|
||||
import * as pluginContexts from '../plugins/context/index';
|
||||
import * as plugins from '../plugins/index';
|
||||
import { setDefaultProtocol } from '../utils/url/protocol';
|
||||
import {
|
||||
buildQueryStringFromParams,
|
||||
joinUrlAndQueryString,
|
||||
smartEncodeUrl,
|
||||
} from '../utils/url/querystring';
|
||||
import { getAuthHeader, getAuthQueryParams } from './authentication';
|
||||
import { urlMatchesCertHost } from './url-matches-cert-host';
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import crypto from 'crypto';
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from 'insomnia-url';
|
||||
import { parse as urlParse } from 'url';
|
||||
|
||||
import { escapeRegex } from '../../common/misc';
|
||||
import * as models from '../../models/index';
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from '../../utils/url/querystring';
|
||||
import { getBasicAuthHeader } from '../basic-auth/get-header';
|
||||
import { sendWithSettings } from '../network';
|
||||
import * as c from './constants';
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { setDefaultProtocol } from 'insomnia-url';
|
||||
|
||||
import * as models from '../../models/index';
|
||||
import { setDefaultProtocol } from '../../utils/url/protocol';
|
||||
import { getBasicAuthHeader } from '../basic-auth/get-header';
|
||||
import { sendWithSettings } from '../network';
|
||||
import * as c from './constants';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from 'insomnia-url';
|
||||
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from '../../utils/url/querystring';
|
||||
import * as c from './constants';
|
||||
import { getOAuthSession, responseToObject } from './misc';
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { setDefaultProtocol } from 'insomnia-url';
|
||||
|
||||
import * as models from '../../models/index';
|
||||
import { setDefaultProtocol } from '../../utils/url/protocol';
|
||||
import { getBasicAuthHeader } from '../basic-auth/get-header';
|
||||
import * as network from '../network';
|
||||
import * as c from './constants';
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { setDefaultProtocol } from 'insomnia-url';
|
||||
|
||||
import * as models from '../../models/index';
|
||||
import { setDefaultProtocol } from '../../utils/url/protocol';
|
||||
import { getBasicAuthHeader } from '../basic-auth/get-header';
|
||||
import { sendWithSettings } from '../network';
|
||||
import * as c from './constants';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { setDefaultProtocol } from 'insomnia-url';
|
||||
import { parse as urlParse } from 'url';
|
||||
|
||||
import { escapeRegex } from '../common/misc';
|
||||
import { setDefaultProtocol } from '../utils/url/protocol';
|
||||
import certificateUrlParse from './certificate-url-parse';
|
||||
|
||||
const DEFAULT_PORT = 443;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from 'insomnia-url';
|
||||
import React, { FC, ReactNode } from 'react';
|
||||
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from '../../../utils/url/querystring';
|
||||
import { Link } from './link';
|
||||
|
||||
interface Props {
|
||||
|
@ -8,7 +8,6 @@ import { DefinitionNode, DocumentNode, GraphQLNonNull, GraphQLSchema, Kind, NonN
|
||||
import { buildClientSchema, getIntrospectionQuery } from 'graphql/utilities';
|
||||
import { Maybe } from 'graphql-language-service';
|
||||
import { jarFromCookies } from 'insomnia-cookies';
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString, setDefaultProtocol } from 'insomnia-url';
|
||||
import prettier from 'prettier';
|
||||
import React, { FC, useEffect, useRef, useState } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
@ -22,6 +21,8 @@ import type { Request } from '../../../../models/request';
|
||||
import type { Settings } from '../../../../models/settings';
|
||||
import { axiosRequest } from '../../../../network/axios-request';
|
||||
import { jsonPrettify } from '../../../../utils/prettify/json';
|
||||
import { setDefaultProtocol } from '../../../../utils/url/protocol';
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from '../../../../utils/url/querystring';
|
||||
import { Dropdown } from '../../base/dropdown/dropdown';
|
||||
import { DropdownButton } from '../../base/dropdown/dropdown-button';
|
||||
import { DropdownDivider } from '../../base/dropdown/dropdown-divider';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import classnames from 'classnames';
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from 'insomnia-url';
|
||||
import React, { forwardRef, Fragment, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
@ -11,6 +10,7 @@ import { isRequest, Request } from '../../../models/request';
|
||||
import { isRequestGroup, RequestGroup } from '../../../models/request-group';
|
||||
import { isWebSocketRequest, WebSocketRequest } from '../../../models/websocket-request';
|
||||
import { Workspace } from '../../../models/workspace';
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from '../../../utils/url/querystring';
|
||||
import { updateRequestMetaByParentId } from '../../hooks/create-request';
|
||||
import { activateWorkspace } from '../../redux/modules/workspace';
|
||||
import { selectActiveRequest, selectActiveWorkspace, selectActiveWorkspaceMeta, selectGrpcRequestMetas, selectRequestMetas, selectWorkspaceRequestsAndRequestGroups, selectWorkspacesForActiveProject } from '../../redux/selectors';
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { deconstructQueryStringToParams, extractQueryStringFromUrl } from 'insomnia-url';
|
||||
import React, { FC, useCallback, useEffect, useRef } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import styled from 'styled-components';
|
||||
@ -11,6 +10,7 @@ import { update } from '../../../models/helpers/request-operations';
|
||||
import type { Request } from '../../../models/request';
|
||||
import type { Settings } from '../../../models/settings';
|
||||
import type { Workspace } from '../../../models/workspace';
|
||||
import { deconstructQueryStringToParams, extractQueryStringFromUrl } from '../../../utils/url/querystring';
|
||||
import { useActiveRequestSyncVCSVersion, useGitVCSVersion } from '../../hooks/use-vcs-version';
|
||||
import { selectActiveEnvironment, selectActiveRequestMeta } from '../../redux/selectors';
|
||||
import { PanelContainer, TabItem, Tabs } from '../base/tabs';
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString, smartEncodeUrl } from 'insomnia-url';
|
||||
import React, { FC, useState } from 'react';
|
||||
import { useAsync } from 'react-use';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { Request } from '../../models/request';
|
||||
import { WebSocketRequest } from '../../models/websocket-request';
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString, smartEncodeUrl } from '../../utils/url/querystring';
|
||||
import { useNunjucks } from '../context/nunjucks/use-nunjucks';
|
||||
import { CopyButton as _CopyButton } from './base/copy-button';
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from 'insomnia-url';
|
||||
import React, { FC, useCallback, useLayoutEffect, useRef } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { getRenderContext, render, RENDER_PURPOSE_SEND } from '../../../common/render';
|
||||
import * as models from '../../../models';
|
||||
import { WebSocketRequest } from '../../../models/websocket-request';
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from '../../../utils/url/querystring';
|
||||
import { ReadyState } from '../../context/websocket-client/use-ws-ready-state';
|
||||
import { OneLineEditor, OneLineEditorHandle } from '../codemirror/one-line-editor';
|
||||
import { createKeybindingsHandler, useDocBodyKeyboardShortcuts } from '../keydown-binder';
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from 'insomnia-url';
|
||||
import React, { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import styled from 'styled-components';
|
||||
@ -8,6 +7,7 @@ import { getRenderContext, render, RENDER_PURPOSE_SEND } from '../../../common/r
|
||||
import * as models from '../../../models';
|
||||
import { Environment } from '../../../models/environment';
|
||||
import { WebSocketRequest } from '../../../models/websocket-request';
|
||||
import { buildQueryStringFromParams, joinUrlAndQueryString } from '../../../utils/url/querystring';
|
||||
import { ReadyState, useWSReadyState } from '../../context/websocket-client/use-ws-ready-state';
|
||||
import { useActiveRequestSyncVCSVersion, useGitVCSVersion } from '../../hooks/use-vcs-version';
|
||||
import { selectActiveRequestMeta, selectSettings } from '../../redux/selectors';
|
||||
|
@ -25,13 +25,10 @@ export const joinUrlAndQueryString = (url: string, qs: string) => {
|
||||
if (!qs) {
|
||||
return url;
|
||||
}
|
||||
|
||||
if (!url) {
|
||||
return qs;
|
||||
}
|
||||
|
||||
const [base, ...hashes] = url.split('#');
|
||||
|
||||
// TODO: Make this work with URLs that have a #hash component
|
||||
const baseUrl = base || '';
|
||||
const joiner = getJoiner(base);
|
||||
@ -94,23 +91,18 @@ export const buildQueryParameter = (
|
||||
*/
|
||||
export const buildQueryStringFromParams = (
|
||||
parameters: { name: string; value?: string }[],
|
||||
|
||||
/** allow empty names and values */
|
||||
strict?: boolean,
|
||||
) => {
|
||||
strict = strict === undefined ? true : strict;
|
||||
const items = [];
|
||||
|
||||
for (const param of parameters) {
|
||||
const built = buildQueryParameter(param, strict);
|
||||
|
||||
if (!built) {
|
||||
continue;
|
||||
}
|
||||
|
||||
items.push(built);
|
||||
}
|
||||
|
||||
return items.join('&');
|
||||
};
|
||||
|
@ -1,6 +1,37 @@
|
||||
const { jarFromCookies, cookiesFromJar } = require('insomnia-cookies');
|
||||
const { CookieJar } = require('tough-cookie');
|
||||
|
||||
const jarFromCookies = (cookies) => {
|
||||
let jar;
|
||||
try {
|
||||
// For some reason, fromJSON modifies `cookies`.
|
||||
// Create a copy first just to be sure.
|
||||
const copy = JSON.stringify({ cookies });
|
||||
jar = CookieJar.fromJSON(copy);
|
||||
} catch (error) {
|
||||
console.log('[cookies] Failed to initialize cookie jar', error);
|
||||
jar = new CookieJar();
|
||||
}
|
||||
jar.rejectPublicSuffixes = false;
|
||||
jar.looseMode = true;
|
||||
return jar;
|
||||
};
|
||||
const cookiesFromJar = (cookieJar) => {
|
||||
return new Promise(resolve => {
|
||||
cookieJar.store.getAllCookies((err, cookies) => {
|
||||
if (err) {
|
||||
console.warn('Failed to get cookies form jar', err);
|
||||
resolve([]);
|
||||
} else {
|
||||
// NOTE: Perform toJSON so we have a plain JS object instead of Cookie instance
|
||||
resolve(cookies.map(cookie => cookie.toJSON()));
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const tag = require('..').templateTags[0];
|
||||
|
||||
|
||||
describe('plugin', () => {
|
||||
describe('RequestExtension cookie', () => {
|
||||
it('should get cookie by name', async () => {
|
||||
|
@ -1,9 +1,229 @@
|
||||
const {
|
||||
buildQueryStringFromParams,
|
||||
joinUrlAndQueryString,
|
||||
smartEncodeUrl,
|
||||
} = require('insomnia-url');
|
||||
const { jarFromCookies } = require('insomnia-cookies');
|
||||
const { format, parse } = require('url');
|
||||
|
||||
/**
|
||||
* URL encode a string in a flexible way
|
||||
* @param str string to encode
|
||||
* @param ignore characters to ignore
|
||||
*/
|
||||
const flexibleEncodeComponent = (str = '', ignore = '') => {
|
||||
// Sometimes spaces screw things up because of url.parse
|
||||
str = str.replace(/%20/g, ' ');
|
||||
|
||||
// Handle all already-encoded characters so we don't touch them
|
||||
str = str.replace(/%([0-9a-fA-F]{2})/g, '__ENC__$1');
|
||||
|
||||
// Do a special encode of ignored chars, so they aren't touched.
|
||||
// This first pass, surrounds them with a special tag (anything unique
|
||||
// will work), so it can change them back later
|
||||
// Example: will replace %40 with __LEAVE_40_LEAVE__, and we'll change
|
||||
// it back to %40 at the end.
|
||||
for (const c of ignore) {
|
||||
const code = encodeURIComponent(c).replace('%', '');
|
||||
const escaped = c.replace(ESCAPE_REGEX_MATCH, '\\$&');
|
||||
const re2 = new RegExp(escaped, 'g');
|
||||
str = str.replace(re2, `__RAW__${code}`);
|
||||
}
|
||||
|
||||
// Encode it
|
||||
str = encodeURIComponent(str);
|
||||
|
||||
// Put back the raw version of the ignored chars
|
||||
for (const match of str.match(/__RAW__([0-9a-fA-F]{2})/g) || []) {
|
||||
const code = match.replace('__RAW__', '');
|
||||
str = str.replace(match, decodeURIComponent(`%${code}`));
|
||||
}
|
||||
|
||||
// Put back the encoded version of the ignored chars
|
||||
for (const match of str.match(/__ENC__([0-9a-fA-F]{2})/g) || []) {
|
||||
const code = match.replace('__ENC__', '');
|
||||
str = str.replace(match, `%${code}`);
|
||||
}
|
||||
|
||||
return str;
|
||||
};
|
||||
/**
|
||||
* Build a querystring parameter from a param object
|
||||
*/
|
||||
const buildQueryParameter = (
|
||||
param,
|
||||
|
||||
/** allow empty names and values */
|
||||
strict,
|
||||
) => {
|
||||
strict = strict === undefined ? true : strict;
|
||||
|
||||
// Skip non-name ones in strict mode
|
||||
if (strict && !param.name) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Cast number values to strings
|
||||
if (typeof param.value === 'number') {
|
||||
param.value = String(param.value);
|
||||
}
|
||||
|
||||
if (!strict || param.value) {
|
||||
// Don't encode ',' in values
|
||||
const value = flexibleEncodeComponent(param.value || '').replace(/%2C/gi, ',');
|
||||
const name = flexibleEncodeComponent(param.name || '');
|
||||
|
||||
return `${name}=${value}`;
|
||||
} else {
|
||||
return flexibleEncodeComponent(param.name);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Build a querystring from a list of name/value pairs
|
||||
*/
|
||||
const buildQueryStringFromParams = (
|
||||
parameters,
|
||||
/** allow empty names and values */
|
||||
strict,
|
||||
) => {
|
||||
strict = strict === undefined ? true : strict;
|
||||
const items = [];
|
||||
for (const param of parameters) {
|
||||
const built = buildQueryParameter(param, strict);
|
||||
if (!built) {
|
||||
continue;
|
||||
}
|
||||
items.push(built);
|
||||
}
|
||||
return items.join('&');
|
||||
};
|
||||
const getJoiner = (url) => {
|
||||
url = url || '';
|
||||
return url.indexOf('?') === -1 ? '?' : '&';
|
||||
};
|
||||
const joinUrlAndQueryString = (url, qs) => {
|
||||
if (!qs) {
|
||||
return url;
|
||||
}
|
||||
if (!url) {
|
||||
return qs;
|
||||
}
|
||||
const [base, ...hashes] = url.split('#');
|
||||
// TODO: Make this work with URLs that have a #hash component
|
||||
const baseUrl = base || '';
|
||||
const joiner = getJoiner(base);
|
||||
const hash = hashes.length ? `#${hashes.join('#')}` : '';
|
||||
return `${baseUrl}${joiner}${qs}${hash}`;
|
||||
};
|
||||
const setDefaultProtocol = (url, defaultProto) => {
|
||||
const trimmedUrl = url.trim();
|
||||
defaultProto = defaultProto || 'http:';
|
||||
|
||||
// If no url, don't bother returning anything
|
||||
if (!trimmedUrl) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Default the proto if it doesn't exist
|
||||
if (trimmedUrl.indexOf('://') === -1) {
|
||||
return `${defaultProto}//${trimmedUrl}`;
|
||||
}
|
||||
|
||||
return trimmedUrl;
|
||||
};
|
||||
/**
|
||||
* Deconstruct a querystring to name/value pairs
|
||||
* @param [qs] {string}
|
||||
* @param [strict=true] {boolean} - allow empty names and values
|
||||
* @returns {{name: string, value: string}[]}
|
||||
*/
|
||||
const deconstructQueryStringToParams = (
|
||||
qs,
|
||||
|
||||
/** allow empty names and values */
|
||||
strict,
|
||||
) => {
|
||||
strict = strict === undefined ? true : strict;
|
||||
const pairs = [];
|
||||
|
||||
if (!qs) {
|
||||
return pairs;
|
||||
}
|
||||
|
||||
const stringPairs = qs.split('&');
|
||||
|
||||
for (const stringPair of stringPairs) {
|
||||
// NOTE: This only splits on first equals sign. '1=2=3' --> ['1', '2=3']
|
||||
const [encodedName, ...encodedValues] = stringPair.split('=');
|
||||
const encodedValue = encodedValues.join('=');
|
||||
|
||||
let name = '';
|
||||
try {
|
||||
name = decodeURIComponent(encodedName || '');
|
||||
} catch (error) {
|
||||
// Just leave it
|
||||
name = encodedName;
|
||||
}
|
||||
|
||||
let value = '';
|
||||
try {
|
||||
value = decodeURIComponent(encodedValue || '');
|
||||
} catch (error) {
|
||||
// Just leave it
|
||||
value = encodedValue;
|
||||
}
|
||||
|
||||
if (strict && !name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pairs.push({ name, value });
|
||||
}
|
||||
|
||||
return pairs;
|
||||
};
|
||||
const ESCAPE_REGEX_MATCH = /[-[\]/{}()*+?.\\^$|]/g;
|
||||
/** see list of allowed characters https://datatracker.ietf.org/doc/html/rfc3986#section-2.2 */
|
||||
const RFC_3986_GENERAL_DELIMITERS = ':@'; // (unintentionally?) missing: /?#[]
|
||||
/** see list of allowed characters https://datatracker.ietf.org/doc/html/rfc3986#section-2.2 */
|
||||
const RFC_3986_SUB_DELIMITERS = '$+,;='; // (unintentionally?) missing: !&'()*
|
||||
/** see list of allowed characters https://datatracker.ietf.org/doc/html/rfc3986#section-2.2 */
|
||||
const URL_PATH_CHARACTER_WHITELIST = `${RFC_3986_GENERAL_DELIMITERS}${RFC_3986_SUB_DELIMITERS}`;
|
||||
/**
|
||||
* Automatically encode the path and querystring components
|
||||
* @param url url to encode
|
||||
* @param encode enable encoding
|
||||
*/
|
||||
const smartEncodeUrl = (url, encode) => {
|
||||
// Default autoEncode = true if not passed
|
||||
encode = encode === undefined ? true : encode;
|
||||
const urlWithProto = setDefaultProtocol(url);
|
||||
if (!encode) {
|
||||
return urlWithProto;
|
||||
} else {
|
||||
// Parse the URL into components
|
||||
const parsedUrl = parse(urlWithProto);
|
||||
// ~~~~~~~~~~~ //
|
||||
// 1. Pathname //
|
||||
// ~~~~~~~~~~~ //
|
||||
if (parsedUrl.pathname) {
|
||||
const segments = parsedUrl.pathname.split('/');
|
||||
parsedUrl.pathname = segments
|
||||
.map(s => flexibleEncodeComponent(s, URL_PATH_CHARACTER_WHITELIST))
|
||||
.join('/');
|
||||
}
|
||||
// ~~~~~~~~~~~~~~ //
|
||||
// 2. Querystring //
|
||||
// ~~~~~~~~~~~~~~ //
|
||||
if (parsedUrl.query) {
|
||||
const qsParams = deconstructQueryStringToParams(parsedUrl.query);
|
||||
const encodedQsParams = [];
|
||||
for (const { name, value } of qsParams) {
|
||||
encodedQsParams.push({
|
||||
name: flexibleEncodeComponent(name),
|
||||
value: flexibleEncodeComponent(value),
|
||||
});
|
||||
}
|
||||
parsedUrl.query = buildQueryStringFromParams(encodedQsParams);
|
||||
parsedUrl.search = `?${parsedUrl.query}`;
|
||||
}
|
||||
return format(parsedUrl);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.templateTags = [
|
||||
{
|
||||
@ -215,7 +435,25 @@ async function getRequestUrl(context, request) {
|
||||
|
||||
return smartEncodeUrl(finalUrl, request.settingEncodeUrl);
|
||||
}
|
||||
|
||||
const { CookieJar } = require('tough-cookie');
|
||||
/**
|
||||
* Get a request.jar() from a list of cookie objects
|
||||
*/
|
||||
const jarFromCookies = (cookies) => {
|
||||
let jar;
|
||||
try {
|
||||
// For some reason, fromJSON modifies `cookies`.
|
||||
// Create a copy first just to be sure.
|
||||
const copy = JSON.stringify({ cookies });
|
||||
jar = CookieJar.fromJSON(copy);
|
||||
} catch (error) {
|
||||
console.log('[cookies] Failed to initialize cookie jar', error);
|
||||
jar = new CookieJar();
|
||||
}
|
||||
jar.rejectPublicSuffixes = false;
|
||||
jar.looseMode = true;
|
||||
return jar;
|
||||
};
|
||||
function getCookieValue(cookieJar, url, name) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const jar = jarFromCookies(cookieJar.cookies);
|
||||
|
44
plugins/insomnia-plugin-request/package-lock.json
generated
44
plugins/insomnia-plugin-request/package-lock.json
generated
@ -1,22 +1,44 @@
|
||||
{
|
||||
"name": "insomnia-plugin-request",
|
||||
"version": "3.6.1-beta.3",
|
||||
"lockfileVersion": 1,
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "insomnia-plugin-request",
|
||||
"version": "3.6.1-beta.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"insomnia-cookies": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/insomnia-cookies/-/insomnia-cookies-2.1.4.tgz",
|
||||
"integrity": "sha512-2Fr+FMGguK1xsv2n2jdt1+kLRe94q1A5v7nwVeO7DgdtO54TCaLlbkVo1LkFXGKDRp12Z04KChGHV7Bzisw6fA==",
|
||||
"requires": {
|
||||
"tough-cookie": "^2.3.3"
|
||||
"tough-cookie": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"insomnia-url": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/insomnia-url/-/insomnia-url-2.2.2.tgz",
|
||||
"integrity": "sha512-I41gUSrjLJICQ1707S/ItGZQW/r5Wtovy2d3JGNOClDkAMUzMDZ54dBp4oUISoLlpCsVs0W1u5HedCv6M6BQEw=="
|
||||
"node_modules/psl": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
||||
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/tough-cookie": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||
"dependencies": {
|
||||
"psl": "^1.1.28",
|
||||
"punycode": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"psl": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
||||
|
@ -22,7 +22,6 @@
|
||||
"test": "jest --silent"
|
||||
},
|
||||
"dependencies": {
|
||||
"insomnia-cookies": "^3.6.1-beta.3",
|
||||
"insomnia-url": "^3.6.1-beta.3"
|
||||
"tough-cookie": "^2.3.1"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user