sn-cloudlink
Advanced tools
Comparing version 1.2.1 to 1.2.2
import React from 'react'; | ||
import Home from './components/Home'; | ||
export default class App extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
} | ||
render() { | ||
return ( | ||
<div className="body-background-color body-text-color"> | ||
<Home /> | ||
</div> | ||
); | ||
} | ||
export default function App() { | ||
return ( | ||
<div className="body-background-color body-text-color"> | ||
<Home /> | ||
</div> | ||
); | ||
} |
import React from 'react'; | ||
import BridgeManager from "../lib/BridgeManager.js"; | ||
import BridgeManager from '../lib/BridgeManager.js'; | ||
export default class EmailProvider extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
var installed = this.findInstalled(); | ||
this.state = {installed: installed}; | ||
const installed = this.findInstalled(); | ||
this.state = { installed }; | ||
BridgeManager.get().addUpdateObserver(() => { | ||
this.reloadStatus(); | ||
}) | ||
}); | ||
} | ||
@@ -21,3 +20,3 @@ | ||
reloadStatus() { | ||
this.setState({installed: this.findInstalled()}); | ||
this.setState({ installed: this.findInstalled() }); | ||
} | ||
@@ -32,10 +31,12 @@ | ||
BridgeManager.get().saveItem(this.state.installed, () => { | ||
alert("A backup has been triggered for this provider. Please allow a couple minutes for your backup to be processed."); | ||
}) | ||
alert('A backup has been triggered for this provider. Please allow a couple minutes for your backup to be processed.'); | ||
}); | ||
} | ||
install = (event) => { | ||
BridgeManager.get().installExtension({name: "Daily Email Backups", url: window.email_backups_url, subtype: "backup.email_archive", frequency: "daily"}, null, () => { | ||
setTimeout(function () { | ||
alert("Daily Email Backups has been successfully installed. Backups will be delivered in encrypted format to your account email. Your first backup has been sent and should be received in a few minutes."); | ||
BridgeManager.get().installExtension({ | ||
name: 'Daily Email Backups', url: window.email_backups_url, subtype: 'backup.email_archive', frequency: 'daily' | ||
}, null, () => { | ||
setTimeout(() => { | ||
alert('Daily Email Backups has been successfully installed. Backups will be delivered in encrypted format to your account email. Your first backup has been sent and should be received in a few minutes.'); | ||
}, 10); | ||
@@ -46,27 +47,34 @@ }); | ||
handleChange = (event) => { | ||
this.setState({confirmation: event.target.value}); | ||
this.setState({ confirmation: event.target.value }); | ||
} | ||
render() { | ||
let installed = this.state.installed; | ||
const { installed } = this.state; | ||
return ( | ||
<div className={"sk-box provider " + this.props.color}> | ||
<div className={`sk-box provider ${this.props.color}`}> | ||
<div className="sk-h3 sk-panel-section-title sk-panel-row centered">{this.props.name}</div> | ||
{this.state.successfully_installed && | ||
<p>{this.props.name} has been successfully installed.</p> | ||
} | ||
{this.state.successfully_installed | ||
&& ( | ||
<p> | ||
{this.props.name} | ||
{' '} | ||
has been successfully installed. | ||
</p> | ||
)} | ||
{!installed && | ||
{!installed | ||
&& ( | ||
<div className="sk-button-group sk-panel-row stretch"> | ||
<a className={"sk-button sk-secondary-contrast"} onClick={this.install}> | ||
<a className="sk-button sk-secondary-contrast" onClick={this.install}> | ||
<div className="sk-label">Install</div> | ||
</a> | ||
</div> | ||
} | ||
)} | ||
{installed && | ||
{installed | ||
&& ( | ||
<div> | ||
<div className="sk-button-group sk-panel-row stretch"> | ||
<a className={"sk-button sk-secondary-contrast"} onClick={this.uninstall}> | ||
<a className="sk-button sk-secondary-contrast" onClick={this.uninstall}> | ||
<div className="sk-label">Uninstall</div> | ||
@@ -76,3 +84,3 @@ </a> | ||
<div className="sk-button-group stretch"> | ||
<a className={"sk-button sk-secondary-contrast"} onClick={this.performBackupNow}> | ||
<a className="sk-button sk-secondary-contrast" onClick={this.performBackupNow}> | ||
<div className="sk-label">Perform Backup</div> | ||
@@ -82,7 +90,7 @@ </a> | ||
</div> | ||
} | ||
)} | ||
</div> | ||
) | ||
); | ||
} | ||
} |
import React from 'react'; | ||
import BridgeManager from "../lib/BridgeManager.js"; | ||
import HttpManager from "../lib/HttpManager.js"; | ||
import BridgeManager from '../lib/BridgeManager.js'; | ||
import HttpManager from '../lib/HttpManager.js'; | ||
export default class HistoryProvider extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
var installed = this.findInstalled(); | ||
this.state = {installed: installed}; | ||
const installed = this.findInstalled(); | ||
this.state = { installed }; | ||
BridgeManager.get().addUpdateObserver(() => { | ||
this.reloadStatus(); | ||
}) | ||
}); | ||
} | ||
@@ -22,3 +21,3 @@ | ||
reloadStatus() { | ||
this.setState({installed: this.findInstalled()}); | ||
this.setState({ installed: this.findInstalled() }); | ||
} | ||
@@ -32,47 +31,54 @@ | ||
HttpManager.get().postAbsolute(window.revisions_url, null, (response) => { | ||
BridgeManager.get().installExtension({name: "Note History Action Menu", url: response.client_url}, "Extension", () => { | ||
setTimeout(function () { | ||
BridgeManager.get().installExtension({ name: 'Note History Action Menu', url: response.client_url }, 'Extension', () => { | ||
setTimeout(() => { | ||
alert("Note History has been successfully installed. You can browse your history via the 'Actions' menu under the note title."); | ||
}, 10); | ||
}); | ||
BridgeManager.get().installExtension({name: "Note History Server Extension", url: response.server_url, frequency: "realtime"}); | ||
BridgeManager.get().installExtension({ name: 'Note History Server Extension', url: response.server_url, frequency: 'realtime' }); | ||
}, (error) => { | ||
alert("An error occurred while trying to install this extension. Please check the console for an error description."); | ||
alert('An error occurred while trying to install this extension. Please check the console for an error description.'); | ||
console.error(error); | ||
}) | ||
}); | ||
} | ||
handleChange = (event) => { | ||
this.setState({confirmation: event.target.value}); | ||
this.setState({ confirmation: event.target.value }); | ||
} | ||
render() { | ||
let installed = this.state.installed; | ||
const { installed } = this.state; | ||
return ( | ||
<div className={"sk-box provider " + this.props.color}> | ||
<div className={`sk-box provider ${this.props.color}`}> | ||
<div className="sk-h3 sk-panel-section-title sk-panel-row centered">{this.props.name}</div> | ||
{this.state.successfully_installed && | ||
<p>{this.props.name} has been successfully installed.</p> | ||
} | ||
{this.state.successfully_installed | ||
&& ( | ||
<p> | ||
{this.props.name} | ||
{' '} | ||
has been successfully installed. | ||
</p> | ||
)} | ||
{!installed && | ||
{!installed | ||
&& ( | ||
<div className="sk-button-group sk-panel-row stretch"> | ||
<a className={"sk-button sk-secondary-contrast"} onClick={this.install}> | ||
<a className="sk-button sk-secondary-contrast" onClick={this.install}> | ||
<div className="sk-label">Install</div> | ||
</a> | ||
</div> | ||
} | ||
)} | ||
{installed && | ||
{installed | ||
&& ( | ||
<div className="sk-button-group sk-panel-row stretch"> | ||
<a className={"sk-button sk-secondary-contrast"} onClick={this.uninstall}> | ||
<a className="sk-button sk-secondary-contrast" onClick={this.uninstall}> | ||
<div className="sk-label">Uninstall</div> | ||
</a> | ||
</div> | ||
} | ||
)} | ||
</div> | ||
) | ||
); | ||
} | ||
} |
import React from 'react'; | ||
import BridgeManager from "../lib/BridgeManager.js"; | ||
import Provider from "./Provider.js" | ||
import HistoryProvider from "./HistoryProvider.js" | ||
import EmailProvider from "./EmailProvider.js" | ||
import BridgeManager from '../lib/BridgeManager.js'; | ||
import Provider from './Provider.js'; | ||
import HistoryProvider from './HistoryProvider.js'; | ||
import EmailProvider from './EmailProvider.js'; | ||
window.Providers = Object.freeze({ | ||
Dropbox: "Dropbox", | ||
Google: "Google Drive", | ||
OneDrive: "OneDrive" | ||
Dropbox: 'Dropbox', | ||
Google: 'Google Drive', | ||
OneDrive: 'OneDrive' | ||
}); | ||
export default class Home extends React.Component { | ||
constructor(props) { | ||
@@ -20,3 +19,3 @@ super(props); | ||
}) | ||
}); | ||
@@ -27,3 +26,2 @@ this.state = {}; | ||
render() { | ||
return ( | ||
@@ -39,4 +37,4 @@ <div className="sk-panel static"> | ||
<div className="sk-box-group"> | ||
<HistoryProvider name="Note History" url_fragment={"revisions"} color="info" /> | ||
<EmailProvider name="Daily Email Backups" url_fragment={"backup.email_archive"} color="success" /> | ||
<HistoryProvider name="Note History" url_fragment="revisions" color="info" /> | ||
<EmailProvider name="Daily Email Backups" url_fragment="backup.email_archive" color="success" /> | ||
</div> | ||
@@ -50,5 +48,5 @@ </div> | ||
<div className="sk-box-group"> | ||
<Provider name={Providers.Dropbox} color="info" url_fragment={"dropbox"} url_params_key={"dropbox_secret_url"} /> | ||
<Provider name={Providers.Google} color="warning" url_fragment={"gdrive"} url_params_key={"gdrive_secret_url"} /> | ||
<Provider name={Providers.OneDrive} color="success" url_fragment={"onedrive"} url_params_key={"onedrive_secret_url"} /> | ||
<Provider name={Providers.Dropbox} color="info" url_fragment="dropbox" url_params_key="dropbox_secret_url" /> | ||
<Provider name={Providers.Google} color="warning" url_fragment="gdrive" url_params_key="gdrive_secret_url" /> | ||
<Provider name={Providers.OneDrive} color="success" url_fragment="onedrive" url_params_key="onedrive_secret_url" /> | ||
</div> | ||
@@ -60,5 +58,4 @@ </div> | ||
</div> | ||
) | ||
); | ||
} | ||
} |
import React from 'react'; | ||
import BridgeManager from "../lib/BridgeManager.js"; | ||
import BridgeManager from '../lib/BridgeManager.js'; | ||
export default class Provider extends React.Component { | ||
constructor(props) { | ||
@@ -10,12 +9,12 @@ super(props); | ||
this.reloadStatus(); | ||
}) | ||
}); | ||
var params = window.parametersFromURL(window.location.href); | ||
var url = params[props.url_params_key]; | ||
var installed = this.findInstalled(); | ||
this.state = {secret_url: url, installed: installed, confirmation: ""}; | ||
const params = window.parametersFromURL(window.location.href); | ||
const url = params[props.url_params_key]; | ||
const installed = this.findInstalled(); | ||
this.state = { secret_url: url, installed, confirmation: '' }; | ||
if(url && url.length > 0) { | ||
if(!installed) { | ||
BridgeManager.get().installExtension({name: this.props.name, url: url, frequency: "daily"}); | ||
if (url && url.length > 0) { | ||
if (!installed) { | ||
BridgeManager.get().installExtension({ name: this.props.name, url, frequency: 'daily' }); | ||
} | ||
@@ -26,7 +25,7 @@ } | ||
authUrl() { | ||
if(this.props.name == Providers.Dropbox) { | ||
if (this.props.name == Providers.Dropbox) { | ||
return window.dropbox_auth_url; | ||
} else if(this.props.name == Providers.Google) { | ||
} if (this.props.name == Providers.Google) { | ||
return window.gdrive_auth_url; | ||
} else if(this.props.name == Providers.OneDrive) { | ||
} if (this.props.name == Providers.OneDrive) { | ||
return window.onedrive_auth_url; | ||
@@ -41,3 +40,3 @@ } | ||
reloadStatus() { | ||
this.setState({installed: this.findInstalled()}); | ||
this.setState({ installed: this.findInstalled() }); | ||
} | ||
@@ -52,3 +51,3 @@ | ||
event.stopPropagation(); | ||
this.setState({authBegan: true}); | ||
this.setState({ authBegan: true }); | ||
} | ||
@@ -59,4 +58,4 @@ | ||
BridgeManager.get().saveItem(this.state.installed, () => { | ||
alert("A backup has been triggered for this provider. Please allow a couple minutes for your backup to be processed."); | ||
}) | ||
alert('A backup has been triggered for this provider. Please allow a couple minutes for your backup to be processed.'); | ||
}); | ||
} | ||
@@ -68,3 +67,3 @@ | ||
} catch (e) { | ||
alert("Invalid code. Please try again."); | ||
alert('Invalid code. Please try again.'); | ||
} | ||
@@ -74,12 +73,12 @@ } | ||
handleKeyPress = (e) => { | ||
if(e.key === 'Enter') { | ||
if (e.key === 'Enter') { | ||
try { | ||
BridgeManager.get().installExtension({name: this.props.name + " Sync", url: atob(this.state.confirmation), frequency: "daily"}, null, () => { | ||
this.setState({authBegan: false, secret_url: null, successfully_installed: true}) | ||
BridgeManager.get().installExtension({ name: `${this.props.name} Sync`, url: atob(this.state.confirmation), frequency: 'daily' }, null, () => { | ||
this.setState({ authBegan: false, secret_url: null, successfully_installed: true }); | ||
setTimeout(() => { | ||
alert(`${this.props.name} has been successfully installed. Your first backup has also been queued and should be reflected in your external cloud's folder within the next few minutes.`) | ||
alert(`${this.props.name} has been successfully installed. Your first backup has also been queued and should be reflected in your external cloud's folder within the next few minutes.`); | ||
}, 100); | ||
}); | ||
} catch (e) { | ||
alert("Invalid code. Please try again."); | ||
alert('Invalid code. Please try again.'); | ||
} | ||
@@ -90,7 +89,7 @@ } | ||
handleChange = (event) => { | ||
this.setState({confirmation: event.target.value}); | ||
this.setState({ confirmation: event.target.value }); | ||
} | ||
copyCode = (event) => { | ||
var textarea = document.getElementById(this.props.name); | ||
const textarea = document.getElementById(this.props.name); | ||
@@ -100,7 +99,7 @@ textarea.select(); | ||
try { | ||
var successful = document.execCommand('copy'); | ||
const successful = document.execCommand('copy'); | ||
if (!successful) throw successful; | ||
this.setState({copied: true}); | ||
this.setState({ copied: true }); | ||
} catch (err) { | ||
console.log("Failed to copy"); | ||
console.log('Failed to copy'); | ||
} | ||
@@ -110,10 +109,11 @@ } | ||
render() { | ||
let installed = this.state.installed; | ||
let secret_url = this.state.secret_url; | ||
let expanded = this.state.authBegan || secret_url || this.state.successfully_installed; | ||
const { installed } = this.state; | ||
const { secret_url } = this.state; | ||
const expanded = this.state.authBegan || secret_url || this.state.successfully_installed; | ||
return ( | ||
<div className={"sk-box provider " + this.props.color + " " + (expanded ? "expanded" : " ")}> | ||
<div className={`sk-box provider ${this.props.color} ${expanded ? 'expanded' : ' '}`}> | ||
<div className="sk-panel-section-title sk-panel-row centered">{this.props.name}</div> | ||
{this.state.authBegan && | ||
{this.state.authBegan | ||
&& ( | ||
<div> | ||
@@ -124,5 +124,5 @@ <p className="sk-panel-row"> | ||
</p> | ||
<div className={"sk-notification dashed one-line " + this.props.color}> | ||
<div className={`sk-notification dashed one-line ${this.props.color}`}> | ||
<input | ||
className={"sk-input sk-base center-text"} | ||
className="sk-input sk-base center-text" | ||
placeholder="Enter confirmation code" | ||
@@ -135,20 +135,27 @@ value={this.state.confirmation} | ||
</div> | ||
} | ||
)} | ||
{this.state.successfully_installed && | ||
<p>{this.props.name} has been successfully installed.</p> | ||
} | ||
{this.state.successfully_installed | ||
&& ( | ||
<p> | ||
{this.props.name} | ||
{' '} | ||
has been successfully installed. | ||
</p> | ||
)} | ||
{!installed && !this.state.authBegan && !secret_url && | ||
{!installed && !this.state.authBegan && !secret_url | ||
&& ( | ||
<div className="sk-button-group sk-panel-row stretch"> | ||
<a onClick={this.install} href={this.authUrl()} target="_blank" className={"sk-button sk-secondary-contrast"}> | ||
<a onClick={this.install} href={this.authUrl()} target="_blank" className="sk-button sk-secondary-contrast"> | ||
<div className="sk-label">Install</div> | ||
</a> | ||
</div> | ||
} | ||
)} | ||
{installed && | ||
{installed | ||
&& ( | ||
<div> | ||
<div className="sk-button-group sk-panel-row stretch"> | ||
<a className={"sk-button sk-secondary-contrast"} onClick={this.uninstall}> | ||
<a className="sk-button sk-secondary-contrast" onClick={this.uninstall}> | ||
<div className="sk-label">Uninstall</div> | ||
@@ -158,3 +165,3 @@ </a> | ||
<div className="sk-button-group stretch"> | ||
<a className={"sk-button sk-secondary-contrast"} onClick={this.performBackupNow}> | ||
<a className="sk-button sk-secondary-contrast" onClick={this.performBackupNow}> | ||
<div className="sk-label">Perform Backup</div> | ||
@@ -164,13 +171,14 @@ </a> | ||
</div> | ||
} | ||
)} | ||
{secret_url && | ||
{secret_url | ||
&& ( | ||
<div className="confirmation sk-panel-row centered"> | ||
<div className="sk-panel-column stretch"> | ||
<div>Copy and paste the following confirmation code back into Standard Notes:</div> | ||
<textarea className={"sk-base selectable"} id={this.props.name} value={this.base64(secret_url)} autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> | ||
<textarea className="sk-base selectable" id={this.props.name} value={this.base64(secret_url)} autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck="false" /> | ||
<div className="sk-button-group"> | ||
<a onClick={this.copyCode} className={"sk-button sk-base"}> | ||
<a onClick={this.copyCode} className="sk-button sk-base"> | ||
<div className="sk-label"> | ||
{this.state.copied ? "Successfully Copied" : "Copy"} | ||
{this.state.copied ? 'Successfully Copied' : 'Copy'} | ||
</div> | ||
@@ -181,6 +189,6 @@ </a> | ||
</div> | ||
} | ||
)} | ||
</div> | ||
) | ||
); | ||
} | ||
} |
import ComponentManager from 'sn-components-api'; | ||
export default class BridgeManager { | ||
/* Singleton */ | ||
static instance = null; | ||
static get() { | ||
@@ -20,17 +20,17 @@ if (this.instance == null) { this.instance = new BridgeManager(); } | ||
// on ready | ||
this.componentManager.setSize("container", 750, 500); | ||
this.componentManager.setSize('container', 750, 500); | ||
}); | ||
this.componentManager.streamItems(["SF|Extension", "Extension"], (items) => { | ||
for(var item of items) { | ||
if(item.deleted) { | ||
this.componentManager.streamItems(['SF|Extension', 'Extension'], (items) => { | ||
for (const item of items) { | ||
if (item.deleted) { | ||
this.removeItemFromItems(item); | ||
continue; | ||
} | ||
if(item.isMetadataUpdate) { | ||
if (item.isMetadataUpdate) { | ||
continue; | ||
} | ||
var index = this.indexOfItem(item); | ||
if(index >= 0) { | ||
const index = this.indexOfItem(item); | ||
if (index >= 0) { | ||
this.items[index] = item; | ||
@@ -47,7 +47,7 @@ } else { | ||
removeItemFromItems(item) { | ||
this.items = this.items.filter((candidate) => {return candidate.uuid !== item.uuid}); | ||
this.items = this.items.filter((candidate) => candidate.uuid !== item.uuid); | ||
} | ||
notifyObserversOfUpdate() { | ||
for(var observer of this.updateObservers) { | ||
for (const observer of this.updateObservers) { | ||
observer.callback(); | ||
@@ -58,4 +58,4 @@ } | ||
indexOfItem(item) { | ||
for(var index in this.items) { | ||
if(this.items[index].uuid == item.uuid) { | ||
for (const index in this.items) { | ||
if (this.items[index].uuid == item.uuid) { | ||
return index; | ||
@@ -67,9 +67,8 @@ } | ||
itemForId(uuid) { | ||
return this.items.filter((item) => {return item.uuid == uuid})[0]; | ||
return this.items.filter((item) => item.uuid == uuid)[0]; | ||
} | ||
addUpdateObserver(callback) { | ||
let observer = {id: Math.random, callback: callback}; | ||
const observer = { id: Math.random, callback }; | ||
this.updateObservers.push(observer); | ||
@@ -84,8 +83,8 @@ return observer; | ||
installExtension(content, contentType, callback) { | ||
if(!contentType) { | ||
contentType = "SF|Extension"; | ||
if (!contentType) { | ||
contentType = 'SF|Extension'; | ||
} | ||
this.componentManager.createItem({ | ||
content_type: contentType, | ||
content: content | ||
content | ||
}, (item) => { | ||
@@ -101,5 +100,4 @@ callback && callback(); | ||
findInstalledExtension(possible_name, url_fragment) { | ||
return this.items.filter((item) => { | ||
return item.content.name == possible_name || (item.content.url && item.content.url.includes(url_fragment)); | ||
})[0]; | ||
return this.items.find((item) => item.content.name.startsWith(possible_name) | ||
|| item.content.url?.includes(url_fragment)); | ||
} | ||
@@ -110,3 +108,2 @@ | ||
} | ||
} |
export default class HttpManager { | ||
/* Singleton */ | ||
static instance = null; | ||
static get() { | ||
@@ -11,37 +11,36 @@ if (this.instance == null) { this.instance = new HttpManager(); } | ||
postAbsolute(url, params, onsuccess, onerror) { | ||
this.httpRequest("post", url, params, onsuccess, onerror); | ||
this.httpRequest('post', url, params, onsuccess, onerror); | ||
} | ||
patchAbsolute(url, params, onsuccess, onerror) { | ||
this.httpRequest("patch", url, params, onsuccess, onerror); | ||
this.httpRequest('patch', url, params, onsuccess, onerror); | ||
} | ||
getAbsolute(url, params, onsuccess, onerror) { | ||
this.httpRequest("get", url, params, onsuccess, onerror); | ||
this.httpRequest('get', url, params, onsuccess, onerror); | ||
} | ||
httpRequest(verb, url, params, onsuccess, onerror) { | ||
const xmlhttp = new XMLHttpRequest(); | ||
var xmlhttp = new XMLHttpRequest(); | ||
xmlhttp.onreadystatechange = function() { | ||
xmlhttp.onreadystatechange = function () { | ||
if (xmlhttp.readyState == 4) { | ||
var response = xmlhttp.responseText; | ||
if(response) { | ||
let response = xmlhttp.responseText; | ||
if (response) { | ||
try { | ||
response = JSON.parse(response); | ||
} catch(e) {} | ||
} catch (e) {} | ||
} | ||
if(xmlhttp.status >= 200 && xmlhttp.status <= 299){ | ||
onsuccess(response); | ||
} else { | ||
console.error("Request error:", response); | ||
onerror(response); | ||
} | ||
} | ||
}.bind(this) | ||
if (xmlhttp.status >= 200 && xmlhttp.status <= 299) { | ||
onsuccess(response); | ||
} else { | ||
console.error('Request error:', response); | ||
onerror(response); | ||
} | ||
} | ||
}; | ||
if(verb == "get" && Object.keys(params).length > 0) { | ||
url = url + this.formatParams(params); | ||
if (verb == 'get' && Object.keys(params).length > 0) { | ||
url += this.formatParams(params); | ||
} | ||
@@ -52,3 +51,3 @@ | ||
if(verb == "post" || verb == "patch") { | ||
if (verb == 'post' || verb == 'patch') { | ||
xmlhttp.send(JSON.stringify(params)); | ||
@@ -61,10 +60,7 @@ } else { | ||
formatParams(params) { | ||
return "?" + Object | ||
.keys(params) | ||
.map(function(key){ | ||
return key+"="+encodeURIComponent(params[key]) | ||
}) | ||
.join("&") | ||
return `?${Object | ||
.keys(params) | ||
.map((key) => `${key}=${encodeURIComponent(params[key])}`) | ||
.join('&')}`; | ||
} | ||
} |
@@ -1,14 +0,14 @@ | ||
window.parametersFromURL = function(url) { | ||
url = url.split("?").slice(-1)[0]; | ||
var obj = {}; | ||
url.replace(/([^=&]+)=([^&]*)/g, function(m, key, value) { | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import App from './App'; | ||
window.parametersFromURL = function parametersFromURL(url) { | ||
url = url.split('?').slice(-1)[0]; | ||
const obj = {}; | ||
url.replace(/([^=&]+)=([^&]*)/g, (m, key, value) => { | ||
obj[decodeURIComponent(key)] = decodeURIComponent(value); | ||
}); | ||
return obj; | ||
} | ||
}; | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import App from './App'; | ||
ReactDOM.render( | ||
@@ -15,0 +15,0 @@ <App />, |
{ | ||
"name": "sn-cloudlink", | ||
"version": "1.2.1", | ||
"version": "1.2.2", | ||
"main": "dist/dist.js", | ||
"scripts": { | ||
"lint": "eslint --cache --ignore-path .gitignore --ext .jsx,.js --format=node_modules/eslint-formatter-pretty .", | ||
"lint": "eslint --fix --cache --ignore-path .gitignore --ext .jsx,.js --format=node_modules/eslint-formatter-pretty app", | ||
"test": "npm run lint", | ||
"build": "webpack", | ||
"build": "webpack --mode production", | ||
"start": "webpack-dev-server --devtool eval --progress --hot --content-base app", | ||
@@ -16,37 +16,34 @@ "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 1" | ||
"devDependencies": { | ||
"babel-core": "6.x", | ||
"babel-eslint": "7.x", | ||
"babel-loader": "6.x", | ||
"babel-plugin-transform-runtime": "6.x", | ||
"babel-preset-es2015": "6.x", | ||
"babel-preset-react": "6.x", | ||
"babel-preset-stage-0": "6.x", | ||
"babel-runtime": "6.x", | ||
"commitizen": "^2.9.3", | ||
"conventional-changelog-cli": "1.x", | ||
"@babel/core": "^7.11.6", | ||
"@babel/plugin-proposal-class-properties": "^7.10.4", | ||
"@babel/preset-env": "^7.11.5", | ||
"@babel/preset-react": "^7.10.4", | ||
"babel-eslint": "10.x", | ||
"babel-loader": "8.x", | ||
"commitizen": "^4.2.1", | ||
"conventional-changelog-cli": "2.x", | ||
"copy-webpack-plugin": "latest", | ||
"css-loader": "~0.28.7", | ||
"cz-conventional-changelog": "^1.2.0", | ||
"css-loader": "~4.3.0", | ||
"cz-conventional-changelog": "^3.3.0", | ||
"eslint": "latest", | ||
"eslint-config-airbnb": "latest", | ||
"eslint-formatter-pretty": "^1.1.0", | ||
"eslint-plugin-compat": "^1.0.0", | ||
"eslint-formatter-pretty": "^4.0.0", | ||
"eslint-plugin-compat": "^3.8.0", | ||
"eslint-plugin-import": "latest", | ||
"eslint-plugin-jsx-a11y": "3.x", | ||
"eslint-plugin-promise": "^3.4.0", | ||
"eslint-plugin-jsx-a11y": "6.x", | ||
"eslint-plugin-promise": "^4.2.1", | ||
"eslint-plugin-react": "latest", | ||
"extract-text-webpack-plugin": "^3.0.2", | ||
"husky": "^0.12.0", | ||
"node-sass": "^4.6.0", | ||
"open-browser-webpack-plugin": "0.0.3", | ||
"react": "15.x", | ||
"react-dom": "15.x", | ||
"sass-loader": "^6.0.6", | ||
"sn-components-api": "1.2.3", | ||
"sn-stylekit": "2.0.12", | ||
"style-loader": "~0.13.1", | ||
"mini-css-extract-plugin": "^0.11.2", | ||
"node-sass": "^4.14.1", | ||
"react": "16.x", | ||
"react-dom": "16.x", | ||
"sass-loader": "^10.0.2", | ||
"sn-components-api": "1.2.8", | ||
"sn-stylekit": "2.1.0", | ||
"style-loader": "~1.2.1", | ||
"validate-commit-msg": "2.x", | ||
"webpack": "^3.8.1", | ||
"webpack-dev-server": "^2.9.7" | ||
"webpack": "^4.44.2", | ||
"webpack-cli": "^3.3.12", | ||
"webpack-dev-server": "^3.11.0" | ||
} | ||
} |
@@ -1,9 +0,7 @@ | ||
const webpack = require('webpack'); | ||
const path = require('path'); | ||
const CopyWebpackPlugin = require('copy-webpack-plugin'); | ||
const ExtractTextPlugin = require('extract-text-webpack-plugin'); | ||
const uglifyJsPlugin = webpack.optimize.UglifyJsPlugin; | ||
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | ||
module.exports = { | ||
devtool: 'cheap-source-map', | ||
module.exports = (_, { mode }) => ({ | ||
devtool: mode === 'production' ? 'source-map' : 'cheap-source-map', | ||
entry: [ | ||
@@ -18,21 +16,28 @@ path.resolve(__dirname, 'app/main.js'), | ||
}, | ||
devServer: { | ||
headers: { | ||
'Access-Control-Allow-Origin': '*', | ||
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS', | ||
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization' | ||
} | ||
}, | ||
module: { | ||
loaders: [ | ||
{ test: /\.css$/, include: path.resolve(__dirname, 'app'), loader: 'style-loader!css-loader' }, | ||
rules: [ | ||
{ | ||
test: /\.scss$/, | ||
test: /\.scss$/i, | ||
use: [ | ||
mode === 'production' ? MiniCssExtractPlugin.loader : 'style-loader', | ||
'css-loader', | ||
'sass-loader', | ||
], | ||
}, | ||
{ | ||
test: /\.js[x]?$/, | ||
include: [ | ||
path.resolve(__dirname, 'app'), | ||
path.resolve(__dirname, 'node_modules/sn-components-api/dist/dist.js') | ||
], | ||
exclude: /node_modules/, | ||
use: ExtractTextPlugin.extract({ | ||
fallback: 'style-loader', | ||
use: [ | ||
'css-loader', | ||
{ loader: 'sass-loader', query: { sourceMap: false } }, | ||
], | ||
publicPath: '../' | ||
}), | ||
}, | ||
{ test: /\.js[x]?$/, include: [ | ||
path.resolve(__dirname, 'app'), | ||
path.resolve(__dirname, 'node_modules/sn-components-api/dist/dist.js') | ||
], exclude: /node_modules/, loader: 'babel-loader' } | ||
loader: 'babel-loader' | ||
} | ||
] | ||
@@ -43,21 +48,15 @@ }, | ||
alias: { | ||
stylekit: path.join(__dirname, 'node_modules/sn-stylekit/dist/stylekit.css') | ||
stylekit: path.join(__dirname, 'node_modules/sn-stylekit/dist/stylekit.css') | ||
} | ||
}, | ||
plugins: [ | ||
new ExtractTextPlugin({ filename: './dist.css', disable: false, allChunks: true}), | ||
new uglifyJsPlugin({ | ||
compress: { | ||
warnings: false | ||
} | ||
new MiniCssExtractPlugin({ | ||
filename: 'dist.css' | ||
}), | ||
new webpack.DefinePlugin({ | ||
'process.env': { | ||
NODE_ENV: JSON.stringify('production') | ||
} | ||
}), | ||
new CopyWebpackPlugin([ | ||
{ from: './app/index.html', to: 'index.html' }, | ||
]) | ||
new CopyWebpackPlugin({ | ||
patterns: [ | ||
{ from: './app/index.html', to: 'index.html' }, | ||
] | ||
}) | ||
] | ||
}; | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
555575
31
28
1464
2