Flow types on wrapper.js

This commit is contained in:
Gregory Schier 2017-07-18 21:48:28 -07:00
parent fe1a0903b6
commit 361f03e5a9
11 changed files with 278 additions and 186 deletions

View File

@ -33,6 +33,9 @@ common text editors. Read more and download plugins at [editorconfig.org](http:/
Development on Insomnia can be done on Mac, Windows, or Linux as long as you have
[NodeJS 7.4](https://nodejs.org) and [Git](https://git-scm.com/).
<details>
<summary>Initial Dev Setup</summary>
```bash
# Install dependencies and build addons for Electron
npm install
@ -45,6 +48,20 @@ npm run dev
npm test
```
</details>
<details>
<summary>Editor Requirements</summary>
You can use any editor you'd like, but make sure to have support/plugins for
the following tools:
- [ESLint](http://eslint.org/) For catching syntax problems and common errors
- [JSX Syntax](https://facebook.github.io/react/docs/jsx-in-depth.html) For React components
- [Flow](https://flow.org/) For type annotations
</details>
## License
[GNU AGPLv3](LICENSE) &copy; [Insomnia](https://insomnia.rest)

View File

@ -1,58 +1,73 @@
// @flow
import type {BaseModel} from './index';
import * as db from '../common/database';
type BaseOAuth2Token = {
refreshToken: string,
accessToken: string,
expiresAt: number | null, // Should be Date.now() if valid
// Error handling
error: string,
errorDescription: string,
errorUri: string
};
export type OAuth2Token = BaseModel & BaseOAuth2Token;
export const name = 'OAuth 2.0 Token';
export const type = 'OAuth2Token';
export const prefix = 'oa2';
export const canDuplicate = false;
export function init () {
export function init (): BaseOAuth2Token {
return {
parentId: null,
refreshToken: null,
accessToken: null,
refreshToken: '',
accessToken: '',
expiresAt: null, // Should be Date.now() if valid
// Error handling
error: null,
errorDescription: null,
errorUri: null
error: '',
errorDescription: '',
errorUri: ''
};
}
export function migrate (doc) {
export function migrate<T> (doc: T): T {
return doc;
}
export function create (patch = {}) {
export function create (patch: Object = {}): Promise<OAuth2Token> {
if (!patch.parentId) {
throw new Error('New OAuth2Token missing `parentId`', patch);
throw new Error(`New OAuth2Token missing \`parentId\` ${JSON.stringify(patch)}`);
}
return db.docCreate(type, patch);
}
export function update (token, patch) {
export function update (token: OAuth2Token, patch: Object): Promise<OAuth2Token> {
return db.docUpdate(token, patch);
}
export function remove (token) {
export function remove (token: OAuth2Token): Promise<void> {
return db.remove(token);
}
export function getByParentId (parentId) {
export function getByParentId (parentId: string): Promise<OAuth2Token | null> {
return db.getWhere(type, {parentId});
}
export async function getOrCreateByParentId (parentId, patch = {}) {
export async function getOrCreateByParentId (parentId: string): Promise<OAuth2Token> {
let token = await db.getWhere(type, {parentId});
if (!token) {
token = await create({parentId}, patch);
token = await create({parentId});
}
return token;
}
export function all () {
export function all (): Promise<Array<OAuth2Token>> {
return db.all(type);
}

View File

@ -50,7 +50,6 @@ type BaseRequest = {
headers: Array<RequestHeader>,
authentication: RequestAuthentication,
metaSortKey: number,
bodyPath: string,
// Settings
settingStoreCookies: boolean,
@ -61,7 +60,7 @@ type BaseRequest = {
export type Request = BaseModel & BaseRequest;
export function init () {
export function init (): BaseRequest {
return {
url: '',
name: 'New Request',

View File

@ -1,5 +1,7 @@
// @flow
import type {Request} from './request';
import type {BaseModel} from './index';
import * as models from './index';
import fs from 'fs';
import crypto from 'crypto';
import path from 'path';
@ -7,7 +9,6 @@ import mkdirp from 'mkdirp';
import * as electron from 'electron';
import {MAX_RESPONSES} from '../common/constants';
import * as db from '../common/database';
import * as models from './index';
import {compress, decompress} from '../common/misc';
export const name = 'Response';
@ -25,7 +26,7 @@ export type ResponseTimelineEntry = {
value: string
}
export type Response = {
type BaseResponse = {
statusCode: number,
statusMessage: string,
contentType: string,
@ -43,7 +44,9 @@ export type Response = {
settingSendCookies: boolean | null
};
export function init (): Response {
export type Response = BaseModel & BaseResponse;
export function init (): BaseResponse {
return {
statusCode: 0,
statusMessage: '',
@ -81,8 +84,8 @@ export async function removeForRequest (parentId: string) {
await db.removeWhere(type, {parentId});
}
export function remove (request: Request) {
return db.remove(request);
export function remove (response: Response) {
return db.remove(response);
}
export function findRecentForRequest (requestId: string, limit: number) {

View File

@ -1,11 +1,35 @@
// @flow
import type {BaseModel} from './index';
import * as db from '../common/database';
type BaseSettings = {
showPasswords: boolean,
useBulkHeaderEditor: boolean,
followRedirects: boolean,
editorFontSize: number,
editorIndentSize: number,
editorLineWrapping: boolean,
editorKeyMap: string,
httpProxy: string,
httpsProxy: string,
noProxy: string,
proxyEnabled: boolean,
timeout: number,
validateSSL: boolean,
forceVerticalLayout: boolean,
autoHideMenuBar: boolean,
theme: string,
disableAnalyticsTracking: boolean
};
export type Settings = BaseModel & Settings;
export const name = 'Settings';
export const type = 'Settings';
export const prefix = 'set';
export const canDuplicate = false;
export function init () {
export function init (): BaseSettings {
return {
showPasswords: false,
useBulkHeaderEditor: false,
@ -27,11 +51,11 @@ export function init () {
};
}
export function migrate (doc) {
export function migrate <T> (doc: T): T {
return doc;
}
export async function all () {
export async function all (): Promise<Array<Settings>> {
const settings = await db.all(type);
if (settings.length === 0) {
return [await getOrCreate()];
@ -40,15 +64,15 @@ export async function all () {
}
}
export async function create (patch = {}) {
export async function create (patch: Object = {}): Promise<Settings> {
return db.docCreate(type, patch);
}
export async function update (settings, patch) {
export async function update (settings: Settings, patch: Object): Promise<Settings> {
return db.docUpdate(settings, patch);
}
export async function getOrCreate (patch = {}) {
export async function getOrCreate (patch: Object = {}): Promise<Settings> {
const results = await db.all(type);
if (results.length === 0) {
return await create(patch);

View File

@ -1,8 +1,8 @@
// @flow
import type {ResponseTimelineEntry} from '../models/response';
import type {BaseModel} from '../models/index';
import type {Request, RequestHeader} from '../models/request';
import type {Workspace} from '../models/workspace';
import type {Settings} from '../models/settings';
import electron from 'electron';
import mkdirp from 'mkdirp';
@ -37,22 +37,13 @@ type CookieJar = {
cookies: Array<Cookie>
}
type RenderedRequest = BaseModel & Request & {
type RenderedRequest = Request & {
cookies: Array<{name: string, value: string, disabled: boolean}>,
cookieJar: CookieJar
};
type ResponsePatch = {};
type Settings = {
_id: string,
followRedirects: boolean,
timeout: number,
httpProxy: string,
httpsProxy: string,
noProxy: string
};
// Time since user's last keypress to wait before making the request
const MAX_DELAY_TIME = 1000;
@ -73,7 +64,10 @@ export function _actuallySend (
return new Promise(async resolve => {
let timeline: Array<ResponseTimelineEntry> = [];
// Define helper to add base fields when responding
// Initialize the curl handle
const curl = new Curl();
/** Helper function to respond with a success */
function respond (patch: ResponsePatch, bodyBuffer: ?Buffer = null): void {
const response = Object.assign({
parentId: renderedRequest._id,
@ -85,11 +79,12 @@ export function _actuallySend (
resolve({bodyBuffer, response});
}
function handleError (err, prefix = null) {
/** Helper function to respond with an error */
function handleError (err: Error): void {
respond({
url: renderedRequest.url,
parentId: renderedRequest._id,
error: prefix ? `${prefix}: ${err.message}` : err.message,
error: err.message,
elapsedTime: 0,
statusMessage: 'Error',
settingSendCookies: renderedRequest.settingSendCookies,
@ -97,26 +92,21 @@ export function _actuallySend (
});
}
try {
// Initialize the curl handle
const curl = new Curl();
// Define helper to setOpt for better error handling
const setOpt = (opt, val, optional = false) => {
const name = Object.keys(Curl.option).find(name => Curl.option[name] === opt);
try {
curl.setOpt(opt, val);
} catch (err) {
if (!optional) {
throw new Error(`${err.message} (${opt} ${name || 'n/a'})`);
} else {
console.warn(`Failed to set optional Curl opt (${opt} ${name || 'n/a'})`);
}
/** Helper function to set Curl options */
function setOpt (opt: string, val: any, optional: boolean = false) {
const name = Object.keys(Curl.option).find(name => Curl.option[name] === opt);
try {
curl.setOpt(opt, val);
} catch (err) {
if (!optional) {
throw new Error(`${err.message} (${opt} ${name || 'n/a'})`);
} else {
console.warn(`Failed to set optional Curl opt (${opt} ${name || 'n/a'})`);
}
};
const setOptionalOpt = (opt, val) => setOpt(opt, val, true);
}
}
try {
// Setup the cancellation logic
cancelRequestFunction = () => {
respond({
@ -133,7 +123,7 @@ export function _actuallySend (
// Set all the basic options
setOpt(Curl.option.CUSTOMREQUEST, renderedRequest.method);
setOpt(Curl.option.NOBODY, renderedRequest.method.toLowerCase() === 'head' ? 1 : 0);
setOpt(Curl.option.NOBODY, renderedRequest.method.toUpperCase() === 'HEAD' ? 1 : 0);
setOpt(Curl.option.FOLLOWLOCATION, settings.followRedirects);
setOpt(Curl.option.TIMEOUT_MS, settings.timeout); // 0 for no timeout
setOpt(Curl.option.VERBOSE, true); // True so debug function works
@ -186,7 +176,7 @@ export function _actuallySend (
let lastPercent = 0;
// NOTE: This option was added in 7.32.0 so make it optional
setOptionalOpt(Curl.option.XFERINFOFUNCTION, (dltotal, dlnow, ultotal, ulnow) => {
setOpt(Curl.option.XFERINFOFUNCTION, (dltotal, dlnow, ultotal, ulnow) => {
if (dltotal === 0) {
return 0;
}
@ -198,7 +188,7 @@ export function _actuallySend (
}
return 0;
});
}, true);
// Set the URL, including the query parameters
const qs = querystring.buildFromParams(renderedRequest.parameters);

View File

@ -1,6 +1,7 @@
// @flow
import type {Request} from '../../models/request';
import type {Workspace} from '../../models/workspace';
import type {OAuth2Token} from '../../models/o-auth-2-token';
import React from 'react';
import autobind from 'autobind-decorator';
@ -55,8 +56,8 @@ type Props = {
forceRefreshCounter: number,
// Optional
request: Request,
oAuth2Token: Object
request: ?Request,
oAuth2Token: ?OAuth2Token
}
@autobind
@ -119,6 +120,11 @@ class RequestPane extends React.PureComponent<void, Props, void> {
_handleImportQueryFromUrl () {
const {request} = this.props;
if (!request) {
console.warn('Tried to import query when no request active');
return;
}
let query;
try {
query = querystring.extractFromUrl(request.url);

View File

@ -1,5 +1,4 @@
// @flow
import type {BaseModel} from '../../models/index';
import type {Request} from '../../models/request';
import type {Response} from '../../models/response';
@ -51,8 +50,8 @@ class ResponsePane extends PureComponent {
responses: Array<Object>,
// Other
request?: BaseModel & Request,
response?: BaseModel & Response
request: ?Request,
response: ?Response
};
_trackTab (name: string) {

View File

@ -1,4 +1,11 @@
import React, {PropTypes, PureComponent} from 'react';
// @flow
import type {Settings} from '../../models/settings';
import type {Response} from '../../models/response';
import type {OAuth2Token} from '../../models/o-auth-2-token';
import type {Workspace} from '../../models/workspace';
import type {Request, RequestAuthentication, RequestBody, RequestHeader, RequestParameter} from '../../models/request';
import React from 'react';
import autobind from 'autobind-decorator';
import classnames from 'classnames';
import {registerModal, showModal} from './modals/index';
@ -31,12 +38,90 @@ import {updateMimeType} from '../../models/request';
import {trackEvent} from '../../analytics/index';
import * as importers from 'insomnia-importers';
const rUpdate = models.request.update;
const rUpdate = (request, ...args) => {
if (!request) {
throw new Error('Tried to update null request');
}
return models.request.update(request, ...args);
};
const sUpdate = models.settings.update;
type Props = {
// Helper Functions
handleActivateRequest: Function,
handleSetSidebarFilter: Function,
handleToggleMenuBar: Function,
handleImportFileToWorkspace: Function,
handleImportUriToWorkspace: Function,
handleExportFile: Function,
handleSetActiveWorkspace: Function,
handleSetActiveEnvironment: Function,
handleMoveDoc: Function,
handleCreateRequest: Function,
handleDuplicateRequest: Function,
handleDuplicateRequestGroup: Function,
handleDuplicateWorkspace: Function,
handleCreateRequestGroup: Function,
handleGenerateCodeForActiveRequest: Function,
handleGenerateCode: Function,
handleCopyAsCurl: Function,
handleCreateRequestForWorkspace: Function,
handleSetRequestPaneRef: Function,
handleSetResponsePaneRef: Function,
handleSetResponsePreviewMode: Function,
handleRender: Function,
handleGetRenderContext: Function,
handleSetResponseFilter: Function,
handleSetActiveResponse: Function,
handleSetSidebarRef: Function,
handleStartDragSidebar: Function,
handleResetDragSidebar: Function,
handleStartDragPaneHorizontal: Function,
handleStartDragPaneVertical: Function,
handleResetDragPaneHorizontal: Function,
handleResetDragPaneVertical: Function,
handleSetRequestGroupCollapsed: Function,
handleSendRequestWithEnvironment: Function,
handleSendAndDownloadRequestWithEnvironment: Function,
// Properties
loadStartTime: number,
isLoading: boolean,
paneWidth: number,
paneHeight: number,
responsePreviewMode: string,
responseFilter: string,
responseFilterHistory: Array<string>,
sidebarWidth: number,
sidebarHidden: boolean,
sidebarFilter: string,
sidebarChildren: Array<Object>,
settings: Settings,
workspaces: Array<Workspace>,
workspaceChildren: Array<Object>,
environments: Array<Object>,
activeRequestResponses: Array<Response>,
activeWorkspace: Workspace,
// Optional
oAuth2Token: ?OAuth2Token,
activeRequest: ?Request,
activeResponse: ?Response,
activeEnvironment: ?Object
};
type State = {
forceRefreshKey: number
};
@autobind
class Wrapper extends PureComponent {
constructor (props) {
class Wrapper extends React.PureComponent<void, Props, State> {
props: Props;
state: State;
constructor (props: Props) {
super(props);
this.state = {
forceRefreshKey: Date.now()
@ -44,7 +129,7 @@ class Wrapper extends PureComponent {
}
// Request updaters
async _handleForceUpdateRequest (patch) {
async _handleForceUpdateRequest (patch: Object): Promise<Request> {
const newRequest = await rUpdate(this.props.activeRequest, patch);
// Give it a second for the app to render first. If we don't wait, it will refresh
@ -54,45 +139,52 @@ class Wrapper extends PureComponent {
return newRequest;
}
_handleUpdateRequestBody (body) {
rUpdate(this.props.activeRequest, {body});
_handleUpdateRequestBody (body: RequestBody): Promise<Request> {
return rUpdate(this.props.activeRequest, {body});
}
_handleUpdateRequestMethod (method) {
rUpdate(this.props.activeRequest, {method});
_handleUpdateRequestMethod (method: string): Promise<Request> {
return rUpdate(this.props.activeRequest, {method});
}
_handleUpdateRequestParameters (parameters) {
rUpdate(this.props.activeRequest, {parameters});
_handleUpdateRequestParameters (parameters: Array<RequestParameter>): Promise<Request> {
return rUpdate(this.props.activeRequest, {parameters});
}
_handleUpdateRequestAuthentication (authentication) {
rUpdate(this.props.activeRequest, {authentication});
_handleUpdateRequestAuthentication (authentication: RequestAuthentication): Promise<Request> {
return rUpdate(this.props.activeRequest, {authentication});
}
_handleUpdateRequestHeaders (headers) {
rUpdate(this.props.activeRequest, {headers});
_handleUpdateRequestHeaders (headers: Array<RequestHeader>): Promise<Request> {
return rUpdate(this.props.activeRequest, {headers});
}
_handleUpdateRequestUrl (url) {
rUpdate(this.props.activeRequest, {url});
_handleUpdateRequestUrl (url: string): Promise<Request> {
return rUpdate(this.props.activeRequest, {url});
}
// Special request updaters
async _handleUpdateRequestMimeType (mimeType) {
await updateMimeType(this.props.activeRequest, mimeType);
async _handleUpdateRequestMimeType (mimeType: string): Promise<Request | null> {
if (!this.props.activeRequest) {
console.warn('Tried to update request mime-type when no active request');
return null;
}
const newRequest = await updateMimeType(this.props.activeRequest, mimeType);
// Force it to update, because other editor components (header editor)
// needs to change. Need to wait a delay so the next render can finish
setTimeout(this._forceRequestPaneRefresh, 300);
return newRequest;
}
_handleStartDragSidebar (e) {
_handleStartDragSidebar (e: Event): void {
e.preventDefault();
this.props.handleStartDragSidebar();
}
async _handleImport (text) {
async _handleImport (text: string): Promise<Request | null> {
// Allow user to paste any import file into the url. If it results in
// only one item, it will overwrite the current request.
try {
@ -121,49 +213,59 @@ class Wrapper extends PureComponent {
}
// Settings updaters
_handleUpdateSettingsShowPasswords (showPasswords) {
sUpdate(this.props.settings, {showPasswords});
_handleUpdateSettingsShowPasswords (showPasswords: boolean): Promise<Request> {
return sUpdate(this.props.settings, {showPasswords});
}
_handleUpdateSettingsUseBulkHeaderEditor (useBulkHeaderEditor) {
sUpdate(this.props.settings, {useBulkHeaderEditor});
_handleUpdateSettingsUseBulkHeaderEditor (useBulkHeaderEditor: boolean): Promise<Request> {
return sUpdate(this.props.settings, {useBulkHeaderEditor});
}
// Other Helpers
_handleImportFile () {
_handleImportFile (): void {
this.props.handleImportFileToWorkspace(this.props.activeWorkspace._id);
}
_handleImportUri (uri) {
_handleImportUri (uri: string): void {
this.props.handleImportUriToWorkspace(this.props.activeWorkspace._id, uri);
}
_handleExportWorkspaceToFile () {
_handleExportWorkspaceToFile (): void {
this.props.handleExportFile(this.props.activeWorkspace._id);
}
_handleSetActiveResponse (responseId) {
_handleSetActiveResponse (responseId: string | null): void {
if (!this.props.activeRequest) {
console.warn('Tried to set active response when request not active');
return;
}
this.props.handleSetActiveResponse(this.props.activeRequest._id, responseId);
}
_handleShowEnvironmentsModal () {
_handleShowEnvironmentsModal (): void {
showModal(WorkspaceEnvironmentsEditModal, this.props.activeWorkspace);
}
_handleShowCookiesModal () {
_handleShowCookiesModal (): void {
showModal(CookiesModal, this.props.activeWorkspace);
}
_handleShowRequestSettingsModal () {
_handleShowRequestSettingsModal (): void {
showModal(RequestSettingsModal, {request: this.props.activeRequest});
}
_handleDeleteResponses () {
_handleDeleteResponses (): void {
if (!this.props.activeRequest) {
console.warn('Tried to delete responses when request not active');
return;
}
models.response.removeForRequest(this.props.activeRequest._id);
this._handleSetActiveResponse(null);
}
async _handleDeleteResponse (response) {
async _handleDeleteResponse (response: Response): Promise<void> {
if (response) {
await models.response.remove(response);
}
@ -174,7 +276,7 @@ class Wrapper extends PureComponent {
}
}
async _handleRemoveActiveWorkspace () {
async _handleRemoveActiveWorkspace (): Promise<void> {
const {workspaces, activeWorkspace} = this.props;
if (workspaces.length <= 1) {
showModal(AlertModal, {
@ -188,45 +290,36 @@ class Wrapper extends PureComponent {
trackEvent('Workspace', 'Delete');
}
models.workspace.remove(activeWorkspace);
await models.workspace.remove(activeWorkspace);
}
async _handleDuplicateActiveWorkspace () {
const {activeWorkspace} = this.props;
trackEvent('Workspace', 'Duplicate');
const newWorkspace = await models.workspace.duplicate(activeWorkspace);
await this.props.handleSetActiveWorkspace(newWorkspace._id);
}
_handleSendRequestWithActiveEnvironment () {
_handleSendRequestWithActiveEnvironment (): void {
const {activeRequest, activeEnvironment, handleSendRequestWithEnvironment} = this.props;
const activeRequestId = activeRequest ? activeRequest._id : 'n/a';
const activeEnvironmentId = activeEnvironment ? activeEnvironment._id : 'n/a';
handleSendRequestWithEnvironment(activeRequestId, activeEnvironmentId);
}
_handleSendAndDownloadRequestWithActiveEnvironment (filename) {
_handleSendAndDownloadRequestWithActiveEnvironment (filename: string): void {
const {activeRequest, activeEnvironment, handleSendAndDownloadRequestWithEnvironment} = this.props;
const activeRequestId = activeRequest ? activeRequest._id : 'n/a';
const activeEnvironmentId = activeEnvironment ? activeEnvironment._id : 'n/a';
handleSendAndDownloadRequestWithEnvironment(activeRequestId, activeEnvironmentId, filename);
}
_handleSetPreviewMode (previewMode) {
_handleSetPreviewMode (previewMode: string): void {
const activeRequest = this.props.activeRequest;
const activeRequestId = activeRequest ? activeRequest._id : 'n/a';
this.props.handleSetResponsePreviewMode(activeRequestId, previewMode);
}
_handleSetResponseFilter (filter) {
_handleSetResponseFilter (filter: string): void {
const activeRequest = this.props.activeRequest;
const activeRequestId = activeRequest ? activeRequest._id : 'n/a';
this.props.handleSetResponseFilter(activeRequestId, filter);
}
_forceRequestPaneRefresh () {
_forceRequestPaneRefresh (): void {
this.setState({forceRefreshKey: Date.now()});
}
@ -508,70 +601,4 @@ class Wrapper extends PureComponent {
}
}
Wrapper.propTypes = {
// Helper Functions
handleActivateRequest: PropTypes.func.isRequired,
handleSetSidebarFilter: PropTypes.func.isRequired,
handleToggleMenuBar: PropTypes.func.isRequired,
handleImportFileToWorkspace: PropTypes.func.isRequired,
handleImportUriToWorkspace: PropTypes.func.isRequired,
handleExportFile: PropTypes.func.isRequired,
handleSetActiveWorkspace: PropTypes.func.isRequired,
handleSetActiveEnvironment: PropTypes.func.isRequired,
handleMoveDoc: PropTypes.func.isRequired,
handleCreateRequest: PropTypes.func.isRequired,
handleDuplicateRequest: PropTypes.func.isRequired,
handleDuplicateRequestGroup: PropTypes.func.isRequired,
handleDuplicateWorkspace: PropTypes.func.isRequired,
handleCreateRequestGroup: PropTypes.func.isRequired,
handleGenerateCodeForActiveRequest: PropTypes.func.isRequired,
handleGenerateCode: PropTypes.func.isRequired,
handleCopyAsCurl: PropTypes.func.isRequired,
handleCreateRequestForWorkspace: PropTypes.func.isRequired,
handleSetRequestPaneRef: PropTypes.func.isRequired,
handleSetResponsePaneRef: PropTypes.func.isRequired,
handleSetResponsePreviewMode: PropTypes.func.isRequired,
handleRender: PropTypes.func.isRequired,
handleGetRenderContext: PropTypes.func.isRequired,
handleSetResponseFilter: PropTypes.func.isRequired,
handleSetActiveResponse: PropTypes.func.isRequired,
handleSetSidebarRef: PropTypes.func.isRequired,
handleStartDragSidebar: PropTypes.func.isRequired,
handleResetDragSidebar: PropTypes.func.isRequired,
handleStartDragPaneHorizontal: PropTypes.func.isRequired,
handleStartDragPaneVertical: PropTypes.func.isRequired,
handleResetDragPaneHorizontal: PropTypes.func.isRequired,
handleResetDragPaneVertical: PropTypes.func.isRequired,
handleSetRequestGroupCollapsed: PropTypes.func.isRequired,
handleSendRequestWithEnvironment: PropTypes.func.isRequired,
handleSendAndDownloadRequestWithEnvironment: PropTypes.func.isRequired,
// Properties
loadStartTime: PropTypes.number.isRequired,
isLoading: PropTypes.bool.isRequired,
paneWidth: PropTypes.number.isRequired,
paneHeight: PropTypes.number.isRequired,
responsePreviewMode: PropTypes.string.isRequired,
responseFilter: PropTypes.string.isRequired,
responseFilterHistory: PropTypes.arrayOf(PropTypes.string.isRequired).isRequired,
sidebarWidth: PropTypes.number.isRequired,
sidebarHidden: PropTypes.bool.isRequired,
sidebarFilter: PropTypes.string.isRequired,
sidebarChildren: PropTypes.arrayOf(PropTypes.object).isRequired,
settings: PropTypes.object.isRequired,
workspaces: PropTypes.arrayOf(PropTypes.object).isRequired,
workspaceChildren: PropTypes.arrayOf(PropTypes.object).isRequired,
environments: PropTypes.arrayOf(PropTypes.object).isRequired,
activeRequestResponses: PropTypes.arrayOf(PropTypes.object).isRequired,
activeWorkspace: PropTypes.shape({
_id: PropTypes.string.isRequired
}).isRequired,
// Optional
oAuth2Token: PropTypes.object,
activeRequest: PropTypes.object,
activeResponse: PropTypes.object,
activeEnvironment: PropTypes.object
};
export default Wrapper;

3
flow-typed/classnames.js vendored Normal file
View File

@ -0,0 +1,3 @@
declare module 'classnames' {
declare module.exports: (...args: Array<any>) => Object
}

9
flow-typed/insomnia-importers.js vendored Normal file
View File

@ -0,0 +1,9 @@
declare module 'insomnia-importers' {
declare module.exports: {
convert: (data: string) => {
data: {
resources: Array<Object>
}
}
}
}