Move app/src (mostly) to flipper-ui-core/src

Summary:
This diff moves all UI code from app/src to app/flipper-ui-core. That is now slightly too much (e.g. node deps are not removed yet), but from here it should be easier to move things out again, as I don't want this diff to be open for too long to avoid too much merge conflicts.

* But at least flipper-ui-core is Electron free :)
* Killed all cross module imports as well, as they where now even more in the way
* Some unit test needed some changes, most not too big (but emotion hashes got renumbered in the snapshots, feel free to ignore that)
* Found some files that were actually meaningless (tsconfig in plugins, WatchTools files, that start generating compile errors, removed those

Follow up work:
* make flipper-ui-core configurable, and wire up flipper-server-core in Electron instead of here
* remove node deps (aigoncharov)
* figure out correct place to load GKs, plugins, make intern requests etc., and move to the correct module
* clean up deps

Reviewed By: aigoncharov

Differential Revision: D32427722

fbshipit-source-id: 14fe92e1ceb15b9dcf7bece367c8ab92df927a70
This commit is contained in:
Michel Weststrate
2021-11-16 05:25:40 -08:00
committed by Facebook GitHub Bot
parent 54b7ce9308
commit 7e50c0466a
293 changed files with 483 additions and 497 deletions

View File

@@ -0,0 +1,21 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
/*
* This class exists to allow error reporting to your own service.
* The recommended way to use this, is to instantiate it inside Logger,
* so that all logged errors get reported to this class.
*/
export function cleanStack(_stack: string, _loc?: string) {}
import ScribeLogger from './ScribeLogger';
export default class ErrorReporter {
constructor(_scribeLogger: ScribeLogger) {}
report(_err: Error) {}
}

View File

@@ -0,0 +1,66 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
export type GKID = string;
export const TEST_PASSING_GK = 'TEST_PASSING_GK';
export const TEST_FAILING_GK = 'TEST_FAILING_GK';
export type GKMap = {[key: string]: boolean};
const whitelistedGKs: Array<GKID> = [];
export function loadGKs(_username: string, _gks: Array<GKID>): Promise<GKMap> {
return Promise.reject(
new Error('Implement your custom logic for loading GK'),
);
}
export function loadDistilleryGK(
_gk: GKID,
): Promise<{[key: string]: {result: boolean}}> {
return Promise.reject(
new Error('Implement your custom logic for loading GK'),
);
}
export default class GK {
static init() {}
static get(id: GKID): boolean {
if (process.env.NODE_ENV === 'test' && id === TEST_PASSING_GK) {
return true;
}
if (whitelistedGKs.includes(id)) {
return true;
}
return false;
}
static serializeGKs() {
return '';
}
static async withWhitelistedGK(
id: GKID,
callback: () => Promise<void> | void,
) {
whitelistedGKs.push(id);
try {
const p = callback();
if (p) {
await p;
}
} finally {
const idx = whitelistedGKs.indexOf(id);
if (idx !== -1) {
whitelistedGKs.splice(idx, 1);
}
}
}
}

View File

@@ -0,0 +1,72 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {ElementFramework} from '../ui/components/elements-inspector/ElementFramework';
import {ElementsInspectorElement} from 'flipper-plugin';
export enum IDEType {
'DIFFUSION',
'AS',
'XCODE',
'VSCODE',
}
export abstract class IDEFileResolver {
static async resolveFullPathsFromMyles(
_fileName: string,
_dirRoot: string,
): Promise<string[]> {
throw new Error('Method not implemented.');
}
static openInIDE(
_filePath: string,
_ide: IDEType,
_repo: string,
_lineNumber = 0,
) {
throw new Error('Method not implemented.');
}
static async getLithoComponentPath(_className: string): Promise<string> {
throw new Error('Method not implemented.');
}
static async getCKComponentPath(_className: string): Promise<string> {
throw new Error('Method not implemented.');
}
static getBestPath(
_paths: string[],
_className: string,
_extension?: string,
): string {
throw new Error('Method not implemented.');
}
static async resolvePath(
_className: string,
_framework: string,
): Promise<string> {
throw new Error('Method not implemented.');
}
static isElementFromFramework(
_node: ElementsInspectorElement,
_framework: ElementFramework,
): boolean {
throw new Error('Method not implemented.');
}
static isElementFromSupportedFramework(
_node: ElementsInspectorElement,
): boolean {
throw new Error('Method not implemented.');
}
}

View File

@@ -0,0 +1,22 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {Tristate} from '../reducers/settings';
import ReleaseChannel from '../ReleaseChannel';
export default function (_props: {
isPrefetchingEnabled: Tristate;
onEnablePrefetchingChange: (v: Tristate) => void;
isLocalPinIgnored: boolean;
onIgnoreLocalPinChange: (v: boolean) => void;
releaseChannel: ReleaseChannel;
onReleaseChannelChange: (v: ReleaseChannel) => void;
}) {
return null;
}

View File

@@ -0,0 +1,15 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {Logger, LoggerArgs, NoopLogger} from 'flipper-common';
import {Store} from '../reducers/index';
export function init(_store: Store, _args?: LoggerArgs): Logger {
return new NoopLogger();
}

View File

@@ -0,0 +1,13 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {Settings} from '../reducers/settings';
export default async function setupPrefetcher(_settings: Settings) {}
export const shouldInstallPrefetcher = () => false;

View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
export type ScribeMessage = {
category: string;
message: string;
};
export default class ScribeLogger {
constructor() {}
send(_message: ScribeMessage) {}
}

View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import React, {Component} from 'react';
import {StaticViewProps} from '../reducers/connections';
import {Text} from '../ui';
export default class extends Component<StaticViewProps, {}> {
render() {
return <Text>Build your support request deteails form.</Text>;
}
}

View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import React, {Component} from 'react';
import {StaticViewProps} from '../reducers/connections';
import {Text} from '../ui';
export default class extends Component<StaticViewProps, {}> {
render() {
return <Text>Build your support request creation form.</Text>;
}
}

View File

@@ -0,0 +1,39 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
export type FeedbackPrompt = {
preSubmitHeading: string;
postSubmitHeading: string;
commentPlaceholder: string;
bodyText: string;
predefinedComments: Array<string>;
shouldPopup: boolean;
};
export async function submitRating(
_rating: number,
_sessionId: string | null,
): Promise<void> {
throw new Error('Method not implemented.');
}
export async function submitComment(
_rating: number,
_comment: string,
_selectedPredefinedComments: string[],
_allowUserInfoSharing: boolean,
_sessionId: string | null,
): Promise<void> {
throw new Error('Method not implemented.');
}
export async function dismiss(_sessionId: string | null): Promise<void> {
throw new Error('Method not implemented.');
}
export async function getPrompt(): Promise<FeedbackPrompt> {
throw new Error('Method not implemented.');
}

View File

@@ -0,0 +1,41 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {Store} from '../../reducers/index';
import {getErrorFromErrorLike, getStringFromErrorLike} from 'flipper-common';
import {LoggerArgs, Logger} from 'flipper-common';
const instance = {
track: jest.fn(),
trackTimeSince: jest.fn(),
info: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
debug: jest.fn(),
};
export function extractError(...data: Array<any>): {
message: string;
error: Error;
} {
const message = getStringFromErrorLike(data);
const error = getErrorFromErrorLike(data) ?? new Error(message);
return {
message,
error,
};
}
export function init(_store: Store, _args?: LoggerArgs): Logger {
return instance;
}
export function getInstance(): Logger {
return instance;
}

View File

@@ -0,0 +1,81 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import os from 'os';
import {VersionCheckResult} from '../chrome/UpdateIndicator';
const updateServer = 'https://www.facebook.com/fbflipper/public/latest.json';
const getPlatformSpecifier = (): string => {
switch (os.platform()) {
case 'win32':
return 'windows';
case 'linux':
return 'linux';
case 'darwin':
return 'mac';
default:
throw new Error('Unsupported platform.');
}
};
/**
* @param resp A parsed JSON object retrieved from the update server.
*/
const parseResponse = (resp: any): VersionCheckResult => {
const version = resp.version;
const platforms = resp.platforms;
if (!version || !platforms) {
return {kind: 'error', msg: 'Incomplete response.'};
}
const platformSpecifier = getPlatformSpecifier();
const platform = platforms[platformSpecifier];
if (!platform) {
return {kind: 'error', msg: `Unsupported platform: ${platformSpecifier}.`};
}
return {
kind: 'update-available',
url: platform,
version,
};
};
export async function checkForUpdate(
currentVersion: string,
): Promise<VersionCheckResult> {
return fetch(`${updateServer}?version=${currentVersion}`).then(
(res: Response) => {
switch (res.status) {
case 204:
return {kind: 'up-to-date'};
case 200:
if (res.url.startsWith('https://www.facebook.com/login/')) {
// We're being redirected because we're not on an authenticated network.
// Treat that as being up-to-date as there's special-casing the UI for
// this is not worth it.
console.log('Skipping version check on non-authenticated network.');
return {kind: 'up-to-date'};
}
// Good use of nesting.
// eslint-disable-next-line promise/no-nesting
return res.json().then(parseResponse);
default:
const msg = `Server responded with ${res.statusText}.`;
console.warn('Version check failure: ', msg);
return {
kind: 'error',
msg,
};
}
},
);
}

View File

@@ -0,0 +1,19 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import ReleaseChannel from '../ReleaseChannel';
export default {
updateServer: 'https://www.facebook.com/fbflipper/public/latest.json',
showLogin: false,
showFlipperRating: false,
warnFBEmployees: true,
isFBBuild: false,
getReleaseChannel: () => ReleaseChannel.STABLE,
};

View File

@@ -0,0 +1,53 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {DeviceOS} from 'flipper-plugin';
export default Object.freeze({
GRAPH_APP_ID: '',
GRAPH_CLIENT_TOKEN: '',
GRAPH_ACCESS_TOKEN: '',
// this provides elevated access to scribe. we really shouldn't be exposing this.
// need to investigate how to abstract the scribe logging so it's safe.
GRAPH_SECRET: '',
GRAPH_SECRET_ACCESS_TOKEN: '',
// Provides access to Insights Validation endpoint on interngraph
INSIGHT_INTERN_APP_ID: '',
INSIGHT_INTERN_APP_TOKEN: '',
// Enables the flipper data to be exported through shareabale link
ENABLE_SHAREABLE_LINK: false,
IS_PUBLIC_BUILD: true,
FEEDBACK_GROUP_LINK: 'https://github.com/facebook/flipper/issues',
// Workplace Group ID's
DEFAULT_SUPPORT_GROUP: {
name: 'Default Support Group',
workplaceGroupID: 0,
requiredPlugins: ['Inspector'],
defaultPlugins: ['DeviceLogs'],
supportedOS: ['Android'] as Array<DeviceOS>,
deeplinkSuffix: 'default',
papercuts: '',
},
SUPPORT_GROUPS: [],
// Only WebSocket requests from the following origin prefixes will be accepted
VALID_WEB_SOCKET_REQUEST_ORIGIN_PREFIXES: [
'chrome-extension://',
'localhost:',
'http://localhost:',
'app://',
],
});

View File

@@ -0,0 +1,14 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
export default function createPaste(
_input: string,
): Promise<string | undefined> {
return Promise.reject(new Error('Not implemented!'));
}

View File

@@ -0,0 +1,101 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {Atom, createState} from 'flipper-plugin';
import {User} from '../reducers/user';
export async function getUser(): Promise<User | null> {
throw new Error('Feature not implemented');
}
export async function internGraphPOSTAPIRequest(
_endpoint: string,
_formFields: {
[key: string]: any;
} = {},
_internGraphUrl?: string,
): Promise<any> {
throw new Error('Feature not implemented');
}
export async function internGraphGETAPIRequest(
_endpoint: string,
_params: {
[key: string]: any;
} = {},
_internGraphUrl?: string,
): Promise<any> {
throw new Error('Feature not implemented');
}
export async function graphQLQuery(_query: string): Promise<any> {
throw new Error('Feature not implemented');
}
export function logoutUser(_persist: boolean = false): Promise<void> {
throw new Error('Feature not implemented');
}
export type DataExportResult = {
id: string;
os: 'string';
deviceType: string;
plugins: string[];
fileUrl: string;
flipperUrl: string;
};
export type DataExportError = {
error: string;
error_class: string;
stacktrace: string;
};
export async function shareFlipperData(
_trace: string,
): Promise<DataExportError | DataExportResult> {
new Notification('Feature not implemented');
throw new Error('Feature not implemented');
}
export async function writeKeychain(_token: string) {
throw new Error('Feature not implemented');
}
export async function uploadFlipperMedia(
_path: string,
_kind: 'Image' | 'Video',
): Promise<string> {
throw new Error('Feature not implemented');
}
export async function getFlipperMediaCDN(
_uploadID: string,
_kind: 'Image' | 'Video',
): Promise<string> {
throw new Error('Feature not implemented');
}
export async function getPreferredEditorUriScheme(): Promise<string> {
return 'vscode';
}
export async function appendAccessTokenToUrl(_url: URL): Promise<string> {
throw new Error('Implement appendAccessTokenToUrl');
}
const isLoggedInAtom = createState(false);
const isConnectedAtom = createState(true);
export function isLoggedIn(): Atom<boolean> {
return isLoggedInAtom;
}
export function isConnected(): Atom<boolean> {
return isConnectedAtom;
}