Initial commit 🎉
fbshipit-source-id: b6fc29740c6875d2e78953b8a7123890a67930f2 Co-authored-by: Sebastian McKenzie <sebmck@fb.com> Co-authored-by: John Knox <jknox@fb.com> Co-authored-by: Emil Sjölander <emilsj@fb.com> Co-authored-by: Pritesh Nandgaonkar <prit91@fb.com>
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>16G29</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>CocoaAsyncSocketMac</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.robbiehanson.CocoaAsyncSocketMac</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>CocoaAsyncSocketMac</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>9A235</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>17A360</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.13</string>
|
||||
<key>DTXcode</key>
|
||||
<string>0900</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>9A235</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>16G29</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>CocoaAsyncSocketMac</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.robbiehanson.CocoaAsyncSocketMac</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>CocoaAsyncSocketMac</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>9A235</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>17A360</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.13</string>
|
||||
<key>DTXcode</key>
|
||||
<string>0900</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>9A235</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>16G29</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>FBPortForwarding-Mac</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.facebook.FBPortForwarding-Mac</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>FBPortForwarding-Mac</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string></string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>9A235</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>17A360</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.13</string>
|
||||
<key>DTXcode</key>
|
||||
<string>0900</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>9A235</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014 Facebook. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>16G29</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>FBPortForwarding-Mac</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.facebook.FBPortForwarding-Mac</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>FBPortForwarding-Mac</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string></string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>9A235</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>17A360</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.13</string>
|
||||
<key>DTXcode</key>
|
||||
<string>0900</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>9A235</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014 Facebook. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>16G29</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>peertalkMac</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.facebook.peertalkMac</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>peertalkMac</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string></string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>9A235</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>17A360</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.13</string>
|
||||
<key>DTXcode</key>
|
||||
<string>0900</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>9A235</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014 Facebook. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>16G29</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>peertalkMac</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.facebook.peertalkMac</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>peertalkMac</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string></string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>9A235</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>17A360</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.13</string>
|
||||
<key>DTXcode</key>
|
||||
<string>0900</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>9A235</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014 Facebook. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
50
static/PortForwardingMacApp.app/Contents/Info.plist
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>16G29</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>PortForwardingMacApp</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.facebook.PortForwardingMacApp</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>PortForwardingMacApp</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string></string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>9A235</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>17A360</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.13</string>
|
||||
<key>DTXcode</key>
|
||||
<string>0900</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>9A235</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.10</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2013-present Facebook. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
static/PortForwardingMacApp.app/Contents/MacOS/PortForwardingMacApp
Executable file
1
static/PortForwardingMacApp.app/Contents/PkgInfo
Normal file
@@ -0,0 +1 @@
|
||||
APPL????
|
||||
16
static/anchor.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="34px" height="15px" viewBox="0 0 34 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<path d="M15.7532039,0.628345697 C16.4715168,-0.209508324 17.6268814,-0.213619078 18.3523771,0.641069382 L25.4052507,8.94988484 C26.8378145,10.6375528 29.7993348,12.0206796 32.0012238,12.0390288 L33.999137,12.0556781 L0,12.0556781 L1.99762575,12.0390288 C4.20759939,12.0206096 7.16128831,10.6501222 8.60494516,8.96621291 L15.7532039,0.628345697 Z" id="path-1"></path>
|
||||
</defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Group" transform="translate(-0.000000, 2.000000)">
|
||||
<rect id="Rectangle-Copy" fill="#FFFFFF" x="0" y="11" width="34" height="1"></rect>
|
||||
<g id="Combined-Shape" fill-rule="nonzero">
|
||||
<use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
<path stroke="rgba(0,0,0,0.3)" stroke-width="1" d="M15.3736097,0.302910233 C16.2949805,-0.771794461 17.8118778,-0.76831469 18.7335645,0.317501454 L25.7864381,8.62631692 C27.1230664,10.2009657 29.9459429,11.521884 32.0053904,11.5390462 L34.0033036,11.5556955 L33.999137,12.5556781 L0,12.5556781 L-0.00416712734,11.5556955 L1.99345861,11.5390462 C4.06137191,11.521811 6.87731445,10.2131533 8.22535095,8.64077745 L15.3736097,0.30291024 Z"></path>
|
||||
</g>
|
||||
<rect id="Rectangle" fill="#FFFFFF" x="0" y="12" width="34" height="1"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
184
static/compilePlugins.js
Normal file
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* Copyright 2018-present Facebook.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* @format
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const metro = require('metro');
|
||||
const yargs = require('yargs');
|
||||
const HOME_DIR = require('os').homedir();
|
||||
|
||||
module.exports = (reloadCallback, pluginPaths, pluginCache) => {
|
||||
const plugins = pluginEntryPoints(pluginPaths);
|
||||
if (!fs.existsSync(pluginCache)) {
|
||||
fs.mkdirSync(pluginCache);
|
||||
}
|
||||
if (yargs.argv.dynamicPlugins) {
|
||||
// watch for changes on plugins if we are loading plugins dynamically
|
||||
watchChanges(plugins, reloadCallback, pluginCache);
|
||||
}
|
||||
return Promise.all(
|
||||
Object.values(plugins).map(plugin =>
|
||||
compilePlugin(plugin, false, pluginCache),
|
||||
),
|
||||
)
|
||||
.then(dynamicPlugins => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('✅ Compiled all plugins.');
|
||||
return dynamicPlugins;
|
||||
})
|
||||
.catch(console.error);
|
||||
};
|
||||
|
||||
function watchChanges(plugins, reloadCallback, pluginCache) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('🕵️ Watching for plugin changes');
|
||||
|
||||
Object.values(plugins).map(plugin =>
|
||||
fs.watch(plugin.rootDir, (eventType, filename) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`🕵️ Detected changes in ${plugin.name}`);
|
||||
compilePlugin(plugin, true, pluginCache).then(reloadCallback);
|
||||
}),
|
||||
);
|
||||
}
|
||||
function hash(string) {
|
||||
let hash = 0;
|
||||
if (string.length === 0) {
|
||||
return hash;
|
||||
}
|
||||
let chr;
|
||||
for (let i = 0; i < string.length; i++) {
|
||||
chr = string.charCodeAt(i);
|
||||
hash = (hash << 5) - hash + chr;
|
||||
hash |= 0;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
const fileToIdMap = new Map();
|
||||
const createModuleIdFactory = () => filePath => {
|
||||
if (filePath === '__prelude__') {
|
||||
return 0;
|
||||
}
|
||||
let id = fileToIdMap.get(filePath);
|
||||
if (typeof id !== 'number') {
|
||||
id = hash(filePath);
|
||||
fileToIdMap.set(filePath, id);
|
||||
}
|
||||
return id;
|
||||
};
|
||||
function pluginEntryPoints(additionalPaths = []) {
|
||||
const defaultPluginPath = path.join(HOME_DIR, '.sonar', 'node_modules');
|
||||
const entryPoints = entryPointForPluginFolder(defaultPluginPath);
|
||||
if (typeof additionalPaths === 'string') {
|
||||
additionalPaths = [additionalPaths];
|
||||
}
|
||||
additionalPaths.forEach(additionalPath => {
|
||||
const additionalPlugins = entryPointForPluginFolder(additionalPath);
|
||||
Object.keys(additionalPlugins).forEach(key => {
|
||||
entryPoints[key] = additionalPlugins[key];
|
||||
});
|
||||
});
|
||||
return entryPoints;
|
||||
}
|
||||
function entryPointForPluginFolder(pluginPath) {
|
||||
pluginPath = pluginPath.replace('~', HOME_DIR);
|
||||
if (!fs.existsSync(pluginPath)) {
|
||||
return {};
|
||||
}
|
||||
return fs
|
||||
.readdirSync(pluginPath)
|
||||
.filter(name =>
|
||||
/*name.startsWith('sonar-plugin') && */ fs
|
||||
.lstatSync(path.join(pluginPath, name))
|
||||
.isDirectory(),
|
||||
)
|
||||
.filter(Boolean)
|
||||
.map(name => {
|
||||
let packageJSON;
|
||||
try {
|
||||
packageJSON = fs
|
||||
.readFileSync(path.join(pluginPath, name, 'package.json'))
|
||||
.toString();
|
||||
} catch (e) {}
|
||||
if (packageJSON) {
|
||||
try {
|
||||
const pkg = JSON.parse(packageJSON);
|
||||
return {
|
||||
packageJSON: pkg,
|
||||
name: pkg.name,
|
||||
entry: path.join(pluginPath, name, pkg.main || 'index.js'),
|
||||
rootDir: path.join(pluginPath, name),
|
||||
};
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`Could not load plugin "${pluginPath}", because package.json is invalid.`,
|
||||
);
|
||||
console.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter(Boolean)
|
||||
.reduce((acc, cv) => {
|
||||
acc[cv.name] = cv;
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
function changeExport(path) {
|
||||
let file = fs.readFileSync(path);
|
||||
file = file
|
||||
.toString()
|
||||
.replace(
|
||||
/\nrequire\((-?[0-9]+)\);\n*$/,
|
||||
(_, moduleID) =>
|
||||
`\nmodule.exports = global.require(${moduleID}).default;`,
|
||||
);
|
||||
fs.writeFileSync(path, file);
|
||||
}
|
||||
function compilePlugin(
|
||||
{rootDir, name, entry, packageJSON},
|
||||
force,
|
||||
pluginCache,
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const fileName = `${name}@${packageJSON.version || '0.0.0'}.js`;
|
||||
const out = path.join(pluginCache, fileName);
|
||||
const result = Object.assign({}, packageJSON, {rootDir, name, entry, out});
|
||||
// check if plugin needs to be compiled
|
||||
if (
|
||||
!force &&
|
||||
fs.existsSync(out) &&
|
||||
fs.lstatSync(rootDir).atime < fs.lstatSync(out).ctime
|
||||
) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`🥫 Using cached version of ${name}...`);
|
||||
resolve(result);
|
||||
} else {
|
||||
console.log(`⚙️ Compiling ${name}...`); // eslint-disable-line no-console
|
||||
metro
|
||||
.runBuild({
|
||||
config: {
|
||||
getProjectRoots: () => [rootDir, path.join(__dirname, '..')],
|
||||
getTransformModulePath: () =>
|
||||
path.join(__dirname, 'transforms', 'index.js'),
|
||||
// a custom hash function is required, because by default metro starts
|
||||
// numbering the modules by 1. This means all plugins would start at
|
||||
// ID 1, which causes a clash. This is why we have a custom IDFactory.
|
||||
createModuleIdFactory,
|
||||
},
|
||||
dev: false,
|
||||
entry,
|
||||
out,
|
||||
})
|
||||
.then(() => {
|
||||
changeExport(out);
|
||||
resolve(result);
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
});
|
||||
}
|
||||
1739
static/graphiql/graphiql.css
Normal file
BIN
static/icon.icns
Normal file
BIN
static/icon.ico
Normal file
|
After Width: | Height: | Size: 157 KiB |
BIN
static/icon.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
9
static/icons/android.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" ?><svg viewBox="3230 1250 120 120" xmlns="http://www.w3.org/2000/svg"><defs><style>
|
||||
.cls-1 {
|
||||
fill: #a4c639;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #fff;
|
||||
}
|
||||
</style></defs><g data-name="Group 93" id="Group_93" transform="translate(3107 1147)"><circle class="cls-1" cx="60" cy="60" data-name="Ellipse 69" id="Ellipse_69" r="60" transform="translate(123 103)"/><g data-name="Group 92" id="Group_92" transform="translate(-109 75)"><rect class="cls-2" data-name="Rectangle 44" height="31.549" id="Rectangle_44" rx="5.03" transform="translate(257 73.52)" width="10.059"/><rect class="cls-2" data-name="Rectangle 45" height="31.549" id="Rectangle_45" rx="5.03" transform="translate(316.441 73.52)" width="10.059"/><path class="cls-2" d="M0,0H45.724a0,0,0,0,1,0,0V32.408a6,6,0,0,1-6,6H6a6,6,0,0,1-6-6V0A0,0,0,0,1,0,0Z" data-name="Rectangle 46" id="Rectangle_46" transform="translate(268.888 74.434)"/><path class="cls-2" d="M0,0H10.059a0,0,0,0,1,0,0V11.888a5.03,5.03,0,0,1-5.03,5.03h0A5.03,5.03,0,0,1,0,11.888V0A0,0,0,0,1,0,0Z" data-name="Rectangle 47" id="Rectangle_47" transform="translate(278.033 111.928)"/><path class="cls-2" d="M0,0H10.059a0,0,0,0,1,0,0V11.888a5.03,5.03,0,0,1-5.03,5.03h0A5.03,5.03,0,0,1,0,11.888V0A0,0,0,0,1,0,0Z" data-name="Rectangle 48" id="Rectangle_48" transform="translate(295.408 111.928)"/><path class="cls-2" d="M22.883.25c12.5,0,22.633,9.478,22.633,21.17H.25C.25,9.728,10.383.25,22.883.25Z" data-name="Path 206" id="Path_206" transform="translate(268.867 51.551)"/><circle class="cls-1" cx="2.058" cy="2.058" data-name="Ellipse 70" id="Ellipse_70" r="2.058" transform="translate(279.13 60.717)"/><circle class="cls-1" cx="2.058" cy="2.058" data-name="Ellipse 71" id="Ellipse_71" r="2.058" transform="translate(300.163 60.717)"/><rect class="cls-2" data-name="Rectangle 49" height="9.145" id="Rectangle_49" rx="0.686" transform="matrix(0.875, -0.485, 0.485, 0.875, 276.753, 47.665)" width="1.372"/><rect class="cls-2" data-name="Rectangle 50" height="9.145" id="Rectangle_50" rx="0.686" transform="translate(305.605 47) rotate(31)" width="1.372"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
BIN
static/icons/componentkit-logo.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
static/icons/componentscript-logo.png
Executable file
|
After Width: | Height: | Size: 6.9 KiB |
9
static/icons/ios.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" ?><svg viewBox="2922 786 120 120" xmlns="http://www.w3.org/2000/svg"><defs><style>
|
||||
.cls-1 {
|
||||
fill: #c8c8c8;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #fff;
|
||||
}
|
||||
</style></defs><g data-name="Group 32" id="Group_32" transform="translate(2602 291)"><circle class="cls-1" cx="60" cy="60" data-name="Ellipse 17" id="Ellipse_17" r="60" transform="translate(320 495)"/><g data-name="Group 31" id="Group_31" transform="translate(179 179.1)"><path class="cls-2" d="M623.222,94.309S609.4,79.17,610.2,61.817s12.939-22.045,12.939-22.045A16.749,16.749,0,0,1,631.5,38a22.864,22.864,0,0,1,7.143,1.594c3.615,1.454,4.507,1.9,7.494,1.895,3.533-.006,6.046-1.681,9.257-2.645a25.088,25.088,0,0,1,6.3-.844,18.273,18.273,0,0,1,6.249,1.594,25.033,25.033,0,0,1,8.1,6.552,17.35,17.35,0,0,0-8.8,16.556c.88,11.155,11.257,15.245,11.257,15.245A70.758,70.758,0,0,1,667.76,94.575a11.3,11.3,0,0,1-8.274,4.515c-2.1.127-4.489-.8-7.218-2.125a16.273,16.273,0,0,0-6.425-1.239,13.185,13.185,0,0,0-4.753.62c-2.112.8-7.026,3.065-9.418,2.745A14.019,14.019,0,0,1,623.222,94.309Z" data-name="Path 122" id="Path_122" transform="translate(-443.163 316.54)"/><path class="cls-2" d="M647.683,36.118s-1.239-6.107,3.983-12.48A18.153,18.153,0,0,1,663.969,17,18.339,18.339,0,0,1,659.9,30.188,14.914,14.914,0,0,1,647.683,36.118Z" data-name="Path 123" id="Path_123" transform="translate(-447.409 318.9)"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/icons/litho-logo.png
Normal file
|
After Width: | Height: | Size: 812 B |
BIN
static/icons/oculus.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
7
static/icons/sidebar_bottom.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="Rectangle-Copy-5" fill="#000000" x="3" y="13" width="14" height="2"></rect>
|
||||
<path d="M2,16 L18,16 L18,4 L2,4 L2,16 Z M1,3 L19,3 L19,17 L1,17 L1,3 Z" fill="#000000" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 489 B |
7
static/icons/sidebar_left.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="Rectangle-Copy" fill="#000000" x="3" y="5" width="2" height="10"></rect>
|
||||
<path d="M2,16 L18,16 L18,4 L2,4 L2,16 Z M1,3 L19,3 L19,17 L1,17 L1,3 Z" fill="#000000" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 486 B |
7
static/icons/sidebar_right.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect fill="#000000" x="15" y="5" width="2" height="10"></rect>
|
||||
<path d="M2,16 L18,16 L18,4 L2,4 L2,16 Z M1,3 L19,3 L19,17 L1,17 L1,3 Z" fill="#000000" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 479 B |
110
static/index.dev.html
Normal file
@@ -0,0 +1,110 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link rel="stylesheet" href="graphiql/graphiql.css">
|
||||
<link rel="stylesheet" href="vis/vis.min.css">
|
||||
<title>Sonar</title>
|
||||
|
||||
<style>
|
||||
.__infinity-dev-box {
|
||||
-webkit-app-region: drag;
|
||||
z-index: 999999;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 50px;
|
||||
color: #fff;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.__infinity-dev-box-loading {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.__infinity-dev-box-error {
|
||||
background-color: #000;
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.__infinity-dev-box-text {
|
||||
font-size: 30px;
|
||||
line-height: 200px;
|
||||
margin-top: -100px;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<div class="__infinity-dev-box __infinity-dev-box-loading">
|
||||
<div class="__infinity-dev-box-text">Loading...</div>
|
||||
</div>
|
||||
|
||||
<div class="__infinity-dev-box __infinity-dev-box-error" hidden>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script>
|
||||
(function() {
|
||||
global.electronRequire = window.require;
|
||||
|
||||
let suppressErrors = false;
|
||||
|
||||
const socket = io(location.origin);
|
||||
|
||||
socket.on('refresh', () => {
|
||||
location.reload();
|
||||
});
|
||||
|
||||
socket.on('hasErrors', (html) => {
|
||||
openError(html);
|
||||
suppressErrors = true;
|
||||
});
|
||||
|
||||
function openError(html) {
|
||||
if (suppressErrors) {
|
||||
return;
|
||||
}
|
||||
|
||||
const box = document.querySelector('.__infinity-dev-box-error');
|
||||
box.removeAttribute('hidden');
|
||||
box.innerHTML = html;
|
||||
onLoad();
|
||||
}
|
||||
|
||||
function onLoad() {
|
||||
document.querySelector('.__infinity-dev-box-loading').setAttribute('hidden', true);
|
||||
}
|
||||
|
||||
function init() {
|
||||
const script = document.createElement('script');
|
||||
script.src = window.process.env.BUNDLE_URL;
|
||||
|
||||
script.onerror = () => {
|
||||
openError('Script failure. Check Chrome console for more info.');
|
||||
};
|
||||
|
||||
script.onload = onLoad;
|
||||
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
|
||||
init();
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
18
static/index.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link rel="stylesheet" href="graphiql/graphiql.css">
|
||||
<link rel="stylesheet" href="vis/vis.min.css">
|
||||
<title>Sonar</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
global.electronRequire = window.require;
|
||||
</script>
|
||||
<script src="bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
156
static/index.js
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Copyright 2018-present Facebook.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* @format
|
||||
*/
|
||||
const {app, BrowserWindow} = require('electron');
|
||||
const path = require('path');
|
||||
const url = require('url');
|
||||
const fs = require('fs');
|
||||
const yargs = require('yargs');
|
||||
const compilePlugins = require('./compilePlugins.js');
|
||||
|
||||
// ensure .sonar folder and config exist
|
||||
const sonarDir = path.join(require('os').homedir(), '.sonar');
|
||||
if (!fs.existsSync(sonarDir)) {
|
||||
fs.mkdirSync(sonarDir);
|
||||
}
|
||||
|
||||
const configPath = path.join(sonarDir, 'config.json');
|
||||
let config = {pluginPaths: [], disabledPlugins: [], lastWindowPosition: {}};
|
||||
|
||||
try {
|
||||
config = {
|
||||
...config,
|
||||
...JSON.parse(fs.readFileSync(configPath)),
|
||||
};
|
||||
} catch (e) {
|
||||
fs.writeFileSync(configPath, JSON.stringify(config));
|
||||
}
|
||||
|
||||
const pluginPaths = config.pluginPaths.concat(
|
||||
(yargs.argv.dynamicPlugins || '').split(',').filter(Boolean),
|
||||
);
|
||||
|
||||
process.env.CONFIG = JSON.stringify({
|
||||
...config,
|
||||
pluginPaths,
|
||||
});
|
||||
|
||||
// possible reference to main app window
|
||||
let win;
|
||||
let appReady = false;
|
||||
let pluginsCompiled = false;
|
||||
|
||||
// tracking
|
||||
setInterval(() => {
|
||||
if (win && win.isFocused()) {
|
||||
win.webContents.send('trackUsage');
|
||||
}
|
||||
}, 60 * 1000);
|
||||
|
||||
compilePlugins(
|
||||
() => {
|
||||
if (win) {
|
||||
win.reload();
|
||||
}
|
||||
},
|
||||
pluginPaths,
|
||||
path.join(require('os').homedir(), '.sonar', 'plugins'),
|
||||
).then(dynamicPlugins => {
|
||||
process.env.PLUGINS = JSON.stringify(dynamicPlugins);
|
||||
pluginsCompiled = true;
|
||||
tryCreateWindow();
|
||||
});
|
||||
|
||||
// check if we already have an instance of this app open
|
||||
const isSecondInstance = app.makeSingleInstance(
|
||||
(commandLine, workingDirectory) => {
|
||||
// someone tried to run a second instance, we should focus our window
|
||||
if (win) {
|
||||
if (win.isMinimized()) {
|
||||
win.restore();
|
||||
}
|
||||
|
||||
win.focus();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// if this is a second instance then quit the app to prevent collisions
|
||||
if (isSecondInstance) {
|
||||
app.quit();
|
||||
}
|
||||
|
||||
// quit app once all windows are closed
|
||||
app.on('window-all-closed', () => {
|
||||
appReady = false;
|
||||
app.quit();
|
||||
});
|
||||
|
||||
app.on('ready', function() {
|
||||
appReady = true;
|
||||
app.commandLine.appendSwitch('scroll-bounce');
|
||||
tryCreateWindow();
|
||||
// if in development install the react devtools extension
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
const {
|
||||
default: installExtension,
|
||||
REACT_DEVELOPER_TOOLS,
|
||||
REDUX_DEVTOOLS,
|
||||
} = require('electron-devtools-installer');
|
||||
installExtension(REACT_DEVELOPER_TOOLS.id);
|
||||
installExtension(REDUX_DEVTOOLS.id);
|
||||
}
|
||||
});
|
||||
function tryCreateWindow() {
|
||||
if (appReady && pluginsCompiled) {
|
||||
win = new BrowserWindow({
|
||||
show: false,
|
||||
title: 'Sonar',
|
||||
width: config.lastWindowPosition.width || 1400,
|
||||
height: config.lastWindowPosition.height || 1000,
|
||||
minWidth: 800,
|
||||
minHeight: 600,
|
||||
center: true,
|
||||
fullscreenable: false,
|
||||
backgroundThrottling: false,
|
||||
titleBarStyle: 'hiddenInset',
|
||||
webPreferences: {
|
||||
webSecurity: false,
|
||||
scrollBounce: true,
|
||||
experimentalFeatures: true,
|
||||
},
|
||||
});
|
||||
win.once('ready-to-show', () => win.show());
|
||||
win.once('close', ({sender}) => {
|
||||
const [x, y] = sender.getPosition();
|
||||
const [width, height] = sender.getSize();
|
||||
// save window position and size
|
||||
fs.writeFileSync(
|
||||
configPath,
|
||||
JSON.stringify({
|
||||
...config,
|
||||
lastWindowPosition: {
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
if (config.lastWindowPosition.x && config.lastWindowPosition.y) {
|
||||
win.setPosition(config.lastWindowPosition.x, config.lastWindowPosition.y);
|
||||
}
|
||||
const entryUrl =
|
||||
process.env.ELECTRON_URL ||
|
||||
url.format({
|
||||
pathname: path.join(__dirname, 'index.html'),
|
||||
protocol: 'file:',
|
||||
slashes: true,
|
||||
});
|
||||
win.loadURL(entryUrl);
|
||||
}
|
||||
}
|
||||
17
static/package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "sonar-static",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.0.0-beta.40",
|
||||
"@babel/generator": "^7.0.0-beta.40",
|
||||
"babel-plugin-transform-class-properties": "^7.0.0-beta.3",
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "^7.0.0-beta.3",
|
||||
"babel-plugin-transform-flow-strip-types": "^7.0.0-beta.3",
|
||||
"babel-plugin-transform-object-rest-spread": "^7.0.0-beta.3",
|
||||
"babel-preset-react": "^7.0.0-beta.3",
|
||||
"babylon": "^7.0.0-beta.40",
|
||||
"metro": "^0.28.0"
|
||||
}
|
||||
}
|
||||
BIN
static/pattern.gif
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
35
static/serviceWorker.js
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright 2018-present Facebook.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* @format
|
||||
*/
|
||||
|
||||
const CACHE_NAME = 'v1';
|
||||
|
||||
self.addEventListener('message', e => {
|
||||
if (e.data.precachedIcons) {
|
||||
caches.open(CACHE_NAME).then(cache => cache.addAll(e.data.precachedIcons));
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', function(event) {
|
||||
if (event.request.url.startsWith('https://external.xx.fbcdn.net/assets/')) {
|
||||
event.respondWith(
|
||||
// Cache falling back to the network
|
||||
caches.match(event.request).then(cacheResponse => {
|
||||
return (
|
||||
cacheResponse ||
|
||||
fetch(event.request).then(response => {
|
||||
const clone = response.clone();
|
||||
// write to cache
|
||||
caches
|
||||
.open(CACHE_NAME)
|
||||
.then(cache => cache.put(event.request, clone));
|
||||
return response;
|
||||
})
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
});
|
||||
158
static/style.css
Normal file
@@ -0,0 +1,158 @@
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html,
|
||||
body,
|
||||
div,
|
||||
span,
|
||||
applet,
|
||||
object,
|
||||
iframe,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
blockquote,
|
||||
pre,
|
||||
a,
|
||||
abbr,
|
||||
acronym,
|
||||
address,
|
||||
big,
|
||||
cite,
|
||||
code,
|
||||
del,
|
||||
dfn,
|
||||
em,
|
||||
img,
|
||||
ins,
|
||||
kbd,
|
||||
q,
|
||||
s,
|
||||
samp,
|
||||
small,
|
||||
strike,
|
||||
strong,
|
||||
sub,
|
||||
sup,
|
||||
tt,
|
||||
var,
|
||||
b,
|
||||
u,
|
||||
i,
|
||||
center,
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ol,
|
||||
ul,
|
||||
li,
|
||||
fieldset,
|
||||
form,
|
||||
label,
|
||||
legend,
|
||||
table,
|
||||
caption,
|
||||
tbody,
|
||||
tfoot,
|
||||
thead,
|
||||
tr,
|
||||
th,
|
||||
td,
|
||||
article,
|
||||
aside,
|
||||
canvas,
|
||||
details,
|
||||
embed,
|
||||
figure,
|
||||
figcaption,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
output,
|
||||
ruby,
|
||||
section,
|
||||
summary,
|
||||
time,
|
||||
mark,
|
||||
audio,
|
||||
video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol,
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote,
|
||||
q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before,
|
||||
blockquote:after,
|
||||
q:before,
|
||||
q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
*:active,
|
||||
*:focus {
|
||||
outline: none;
|
||||
}
|
||||
/**/
|
||||
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: system-ui;
|
||||
font-size: 13px;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
cursor: default;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#root {
|
||||
overflow: hidden;
|
||||
}
|
||||
31
static/transforms/dynamic-requires.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright 2018-present Facebook.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* @format
|
||||
*/
|
||||
function isDynamicRequire(node) {
|
||||
return (
|
||||
node.type === 'CallExpression' &&
|
||||
node.callee.type === 'Identifier' &&
|
||||
node.callee.name === 'require' &&
|
||||
(node.arguments.length !== 1 || node.arguments[0].type !== 'StringLiteral')
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = function(babel) {
|
||||
const t = babel.types;
|
||||
|
||||
return {
|
||||
name: 'replace-dynamic-requires',
|
||||
visitor: {
|
||||
CallExpression(path) {
|
||||
if (!isDynamicRequire(path.node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
path.replaceWith(t.identifier('triggerDynamicRequireError'));
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
87
static/transforms/electron-requires.js
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright 2018-present Facebook.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* @format
|
||||
*/
|
||||
|
||||
const BUILTINS = [
|
||||
'electron',
|
||||
'buffer',
|
||||
'child_process',
|
||||
'crypto',
|
||||
'dgram',
|
||||
'dns',
|
||||
'fs',
|
||||
'http',
|
||||
'https',
|
||||
'net',
|
||||
'os',
|
||||
'readline',
|
||||
'stream',
|
||||
'string_decoder',
|
||||
'tls',
|
||||
'tty',
|
||||
'zlib',
|
||||
'constants',
|
||||
'events',
|
||||
'url',
|
||||
'assert',
|
||||
'util',
|
||||
'path',
|
||||
'punycode',
|
||||
'querystring',
|
||||
'cluster',
|
||||
'console',
|
||||
'module',
|
||||
'process',
|
||||
'vm',
|
||||
'domain',
|
||||
'v8',
|
||||
'repl',
|
||||
'timers',
|
||||
];
|
||||
|
||||
const IGNORED_MODULES = [
|
||||
'bufferutil',
|
||||
'utf-8-validate',
|
||||
'spawn-sync',
|
||||
'./src/logcat',
|
||||
'./src/monkey',
|
||||
'./src/adb',
|
||||
];
|
||||
|
||||
function isRequire(node) {
|
||||
return (
|
||||
node.type === 'CallExpression' &&
|
||||
node.callee.type === 'Identifier' &&
|
||||
node.callee.name === 'require' &&
|
||||
node.arguments.length === 1 &&
|
||||
node.arguments[0].type === 'StringLiteral'
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = function(babel) {
|
||||
const t = babel.types;
|
||||
|
||||
return {
|
||||
name: 'infinity-import-react',
|
||||
visitor: {
|
||||
CallExpression(path) {
|
||||
if (!isRequire(path.node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const source = path.node.arguments[0].value;
|
||||
|
||||
if (BUILTINS.includes(source)) {
|
||||
path.node.callee.name = 'electronRequire';
|
||||
}
|
||||
|
||||
if (IGNORED_MODULES.includes(source)) {
|
||||
path.replaceWith(t.identifier('triggerReferenceError'));
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
45
static/transforms/fb-stubs.js
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright 2018-present Facebook.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* @format
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const replaceFBStubs = fs.existsSync(
|
||||
path.join(__dirname, '..', '..', 'src', 'fb'),
|
||||
);
|
||||
|
||||
const requireFromFolder = (folder, path) =>
|
||||
new RegExp(folder + '/[A-Za-z0-9.-_]+(.js)?$', 'g').test(path);
|
||||
|
||||
module.exports = function(babel) {
|
||||
return {
|
||||
name: 'replace-dynamic-requires',
|
||||
visitor: {
|
||||
CallExpression(path) {
|
||||
if (
|
||||
replaceFBStubs &&
|
||||
path.node.type === 'CallExpression' &&
|
||||
path.node.callee.type === 'Identifier' &&
|
||||
path.node.callee.name === 'require' &&
|
||||
path.node.arguments.length > 0
|
||||
) {
|
||||
if (requireFromFolder('fb', path.node.arguments[0].value)) {
|
||||
throw new Error(
|
||||
'Do not requrie directly from fb/, but rather from fb-stubs/ to not break flow-typing and make sure stubs are uptodate.',
|
||||
);
|
||||
} else if (
|
||||
requireFromFolder('fb-stubs', path.node.arguments[0].value)
|
||||
) {
|
||||
path.node.arguments[0].value = path.node.arguments[0].value.replace(
|
||||
'/fb-stubs/',
|
||||
'/fb/',
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
51
static/transforms/import-react.js
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright 2018-present Facebook.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* @format
|
||||
*/
|
||||
|
||||
module.exports = function(babel) {
|
||||
const t = babel.types;
|
||||
|
||||
return {
|
||||
name: 'infinity-import-react',
|
||||
visitor: {
|
||||
Program: {
|
||||
exit(path, state) {
|
||||
if (state.get('NEEDS_REACT')) {
|
||||
path.unshiftContainer('body', [
|
||||
t.variableDeclaration('var', [
|
||||
t.variableDeclarator(
|
||||
t.identifier('React'),
|
||||
t.callExpression(t.identifier('require'), [
|
||||
t.stringLiteral('react'),
|
||||
]),
|
||||
),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
ReferencedIdentifier(path, state) {
|
||||
// mark react as needing to be imported
|
||||
if (path.node.name === 'React' && !path.scope.getBinding('React')) {
|
||||
state.set('NEEDS_REACT', true);
|
||||
}
|
||||
|
||||
// replace Buffer with require('buffer')
|
||||
if (path.node.name === 'Buffer' && !path.scope.getBinding('Buffer')) {
|
||||
path.replaceWith(
|
||||
t.memberExpression(
|
||||
t.callExpression(t.identifier('require'), [
|
||||
t.stringLiteral('buffer'),
|
||||
]),
|
||||
t.identifier('Buffer'),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
64
static/transforms/index.js
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright 2018-present Facebook.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* @format
|
||||
*/
|
||||
|
||||
const generate = require('@babel/generator').default;
|
||||
const babylon = require('babylon');
|
||||
const babel = require('@babel/core');
|
||||
const metro = require('metro');
|
||||
|
||||
exports.transform = function({filename, options, src}) {
|
||||
const presets = [require('../node_modules/babel-preset-react')];
|
||||
const isSonarPlugin = !__dirname.startsWith(options.projectRoot);
|
||||
|
||||
let ast = babylon.parse(src, {
|
||||
filename,
|
||||
plugins: ['jsx', 'flow', 'classProperties', 'objectRestSpread'],
|
||||
sourceType: 'module',
|
||||
});
|
||||
|
||||
// run babel
|
||||
const plugins = [
|
||||
require('../node_modules/babel-plugin-transform-object-rest-spread'),
|
||||
require('../node_modules/babel-plugin-transform-class-properties'),
|
||||
require('../node_modules/babel-plugin-transform-flow-strip-types'),
|
||||
require('./electron-requires.js'),
|
||||
require('./fb-stubs.js'),
|
||||
require('./dynamic-requires.js'),
|
||||
];
|
||||
if (isSonarPlugin) {
|
||||
plugins.push(require('./sonar-requires.js'));
|
||||
} else {
|
||||
plugins.push(require('./import-react.js'));
|
||||
}
|
||||
plugins.unshift(require('babel-plugin-transform-es2015-modules-commonjs'));
|
||||
|
||||
ast = babel.transformFromAst(ast, src, {
|
||||
babelrc: !filename.includes('node_modules'),
|
||||
code: false,
|
||||
comments: false,
|
||||
compact: false,
|
||||
filename,
|
||||
plugins,
|
||||
presets,
|
||||
sourceMaps: true,
|
||||
}).ast;
|
||||
const result = generate(
|
||||
ast,
|
||||
{
|
||||
filename,
|
||||
sourceFileName: filename,
|
||||
sourceMaps: true,
|
||||
},
|
||||
src,
|
||||
);
|
||||
return {
|
||||
ast,
|
||||
code: result.code,
|
||||
filename,
|
||||
map: result.rawMappings.map(metro.sourceMaps.compactMapping),
|
||||
};
|
||||
};
|
||||
64
static/transforms/sonar-requires.js
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright 2018-present Facebook.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* @format
|
||||
*/
|
||||
|
||||
// do not apply this transform for these paths
|
||||
const EXCLUDE_PATHS = [
|
||||
'/node_modules/react-devtools-core/',
|
||||
'relay-devtools/DevtoolsUI',
|
||||
];
|
||||
|
||||
function isExcludedPath(path) {
|
||||
for (const epath of EXCLUDE_PATHS) {
|
||||
if (path.indexOf(epath) > -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} // $FlowFixMe
|
||||
module.exports = ({types: t}) => ({
|
||||
visitor: {
|
||||
// $FlowFixMe
|
||||
CallExpression(path, state) {
|
||||
if (isExcludedPath(state.file.opts.filename)) {
|
||||
return;
|
||||
}
|
||||
const node = path.node;
|
||||
const args = node.arguments || [];
|
||||
if (
|
||||
node.callee.name === 'require' &&
|
||||
args.length === 1 &&
|
||||
t.isStringLiteral(args[0]) &&
|
||||
args[0].value === 'sonar'
|
||||
) {
|
||||
path.replaceWith(t.identifier('window.Sonar'));
|
||||
} else if (
|
||||
node.callee.name === 'require' &&
|
||||
args.length > 0 &&
|
||||
t.isStringLiteral(args[0]) &&
|
||||
args[0].value === 'react'
|
||||
) {
|
||||
path.replaceWith(t.identifier('window.React'));
|
||||
} else if (
|
||||
node.callee.name === 'require' &&
|
||||
args.length > 0 &&
|
||||
t.isStringLiteral(args[0]) &&
|
||||
args[0].value === 'react-dom'
|
||||
) {
|
||||
path.replaceWith(t.identifier('window.ReactDOM'));
|
||||
}
|
||||
},
|
||||
Identifier(path, state) {
|
||||
if (
|
||||
path.node.name === 'React' &&
|
||||
path.parentPath.node.id !== path.node &&
|
||||
!isExcludedPath(state.file.opts.filename)
|
||||
) {
|
||||
path.replaceWith(t.identifier('window.React'));
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
BIN
static/uiperf/screenshot.png
Normal file
|
After Width: | Height: | Size: 33 KiB |