Como criar alias (apelidos) de comandos no windows para aumentar a produtividade
Por exemplo, para executar um projeto React Native no Android, temos que executar o comando npx react-native run-android. Fica muito mais fácil digitar apenas ra
No CMD, se executarmos o comando
doskey ra=npx react-native run-android $*podemos rodar o projeto no Android simplesmente digitando
ra
Porém, após fechar o CMD, o alias não funciona mais, é preciso criá-lo novamente... :grimacing:
Pra resolver isso é possível criar um arquivo init.cmd, por exemplo, em uma pasta bats no disco C, com o seguinte conteúdo:
@echo off
doskey ra=npx react-native run-android $*
Pra quem usa Windows Terminal
No arquivo settings.json do Windows Terminal, substitui o comando "commandline": "cmd.exe", por "commandline": "cmd.exe /K C:\\bats\\init.cmd",
Pra quem só usa CMD
É possível criar um atalho na área de trabalho e definir o "Destino" como sendo C:\Windows\System32\cmd.exe /K C:\\bats\\init.cmd
E então abrir o CMD sempre a partir desse atalho (ou defini-lo como terminal externo no VSCode)
Se alguém quiser saber mais:
https://thecloudblog.net/post/save-your-precious-dev-time-with-command-aliases-in-windows-terminal/
Nesse teste gostaríamos que você construisse um componente dropdown reutilizável. O dropdown deve abrir ao clicar no ícone "mais", e deve exibir algumas ações extras para que o usuário possa interagir.
Estado fechado:
<img width="400" alt="image" src="https://cdn.discordapp.com/attachments/693151307116314736/1001195614320742540/134912453-ea7f0734-cbbd-4768-ba66-8e3aa78a357c.png">Estado Aberto:
<img width="401" alt="image" src="https://cdn.discordapp.com/attachments/693151307116314736/1001195638609936405/134908637-27ed1d8f-e041-45f3-b1d6-cac54b7ebfaf.png">O ícone "mais" e alguns valores de cores estão incluídos abaixo, mas não se preocupe muito em combinar perfeitamente com o design. Estes foram fornecidos para poupar tempo na escolha de cores e iconografia.
Apesar de ficar totalmente a seu critério como o componente será estruturado, nós gostaríamos que você utilizasse o conceito de composição ao invés de herança para esse teste (saber mais). Nós não vamos lhe desclassificar caso opte por utilizar um ou outro, mas como vários projetos nossos já estão utilizando composição, é meio que "a preferência da casa" 😄
// composição
<Tile>
<TileHeader>Header</TileHeader>
<TileContent>Conteúdo...</TileContent>
<TileFooter>
<SecondaryButton onClick={...}>Cancelar</SecondaryButton>
<PrimaryButton onClick={...}>Prontinho!</PrimaryButton>
</TileFooter>
<Tile>
// herança
<Tile
header="Header"
content="Conteúdo..."
onCancelClick={...}
onDoneClick={...}
/>
// backgrounds
black100: hsla(225, 14%, 12%, 1)
black200: hsla(225, 14%, 14%, 1)
black300: hsla(225, 14%, 16%, 1)
black400: hsla(225, 14%, 18%, 1)
black500: hsla(225, 14%, 20%, 1)
black600: hsla(225, 14%, 22%, 1)
black700: hsla(225, 14%, 24%, 1)
black800: hsla(225, 14%, 26%, 1)
black900: hsla(225, 14%, 28%, 1)
// text
white100: hsla(225, 14%, 100%, 1)
white200: hsla(225, 14%, 100%, 0.8)
// primary
blue100: hsla(210, 100%, 37%, 1)
blue200: hsla(210, 100%, 33%, 1)
blue300: hsla(210, 100%, 35%, 1)
blue400: hsla(210, 100%, 33%, 0.5)import React from "react";
type Props = {
color?: string;
width?: number | string;
height?: number | string;
size?: number | string;
};
const MoreIcon = ({ color, size = 24, ...props }: Props) => (
<svg
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
{...props}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M10.5 16.5a1.5 1.5 0 103 0 1.5 1.5 0 00-3 0zm0-4.5a1.5 1.5 0 103 0 1.5 1.5 0 00-3 0zm0-4.5a1.5 1.5 0 103 0 1.5 1.5 0 00-3 0z"
fill={color || "currentColor"}
/>
</svg>
);
export { MoreIcon };Boa sorte, você consegue! 👊🏼
Aluguei um servidor da letscloud.io para testar os serviço, e como a configuração inicial foi bem complexa, irei deixar o passo a passo registrado aqui.
NOTA:
DNS Any Cast e adicione os seguintes registros:| Type | Name | Value | TTL |
|---|---|---|---|
| A | yourdomain.com.br | ip.da.maquina | 3600 |
| A | www | ip.da.maquina | 3600 |
| CNAME | autodiscover | autodiscoverredirection.letscloud.io | 3600 |
| NS | yourdomain.com.br | ns1.letscloud.io | 86400 |
| NS | yourdomain.com.br | ns2.letscloud.io | 86400 |
| NS | yourdomain.com.br | ns3.letscloud.io | 86400 |
| NS | yourdomain.com.br | ns4.letscloud.io | 86400 |
| TXT | yourdomain.com.br | v=spf1 include:spf.letscloud.io~ | all 3600 |
ssh usuario@ip.da.maquinacurl -sL https://deb.nodesource.com/setup_12.x -o nodesource_setup.shsudo bash nodesource_setup.shsudo apt install nodejssudo apt install build-essentialnano hello.jscole o conteúdo de teste
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})sudo npm install pm2@latest -gpm2 start hello.jscurl http://localhost:3000pm2 startup systemdsudo apt updatesudo apt install nginxsudo ufw app list
sudo ufw status
sudo ufw allow 'Nginx HTTP'
sudo ufw status
systemctl status nginx
sudo mkdir -p /var/www/your_domain/html
sudo chown -R $USER:$USER /var/www/your_domain/html
sudo chmod -R 755 /var/www/your_domain
nano /var/www/your_domain/html/index.html
// cole o conteúdo do html
<html>
<head>
<title>Welcome to your_domain!</title>
</head>
<body>
<h1>Success! The your_domain server block is working!</h1>
</body>
</html>
// crie um arquivo de configuração separado
sudo nano /etc/nginx/sites-available/your_domain
// cole o conteúdo
server {
listen 80;
listen [::]:80;
root /var/www/your_domain/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain www.your_domain;
location / {
try_files $uri $uri/ =404;
}
}
// crie um link para o arquivo
sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
// descomente a diretiva #server_names_hash_bucket_size, tirando o #
sudo nano /etc/nginx/nginx.conf
...
http {
...
server_names_hash_bucket_size 64;
...
}
...
sudo nginx -t
sudo systemctl restart nginx
sudo nano /etc/nginx/sites-available/your_domainCole o conteúdo do arquivo
server {
listen 80;
listen [::]:80;
server_name www.yourdomain.com.br;
return 301 $scheme://yourdomain.com.br$request_uri;
}
server {
listen 80;
listen [::]:80;
root /var/www/yourdomain.com.br/html;
index index.html index.htm index.nginx-debian.html;
server_name yourdomain.com.br;
location /apiemoutraporta {
proxy_pass http://127.0.0.1:5504;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location / {
proxy_pass http://127.0.0.1:5503;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Nota: /apiemoutraporta poderia ser um segundo processo que roda na porta 5504 e é acessado através da url: www.yourdomain.com.br/apiemoutraporta. Nessa segunda API você precisa configurar o express para responder às rotas da mesma forma:
app.use("/apiemoutraporta/api/", routes);
app.use(
"/apiemoutraporta/api/media",
express.static(
path.join(
__dirname,
process.env.MODE === "development" ? "./dist/media" : "./media"
)
)
);
app.use("/apiemoutraporta/.well-known", express.static(path.join(__dirname, "./.well-known")));
app.use("/apiemoutraporta/inicio", express.static(path.join(__dirname, "./landing")));
app.use("/apiemoutraporta/", express.static(path.join(__dirname, "./admin")));
app.get("/apiemoutraporta/*", (req, res) => {
res.sendFile(path.join(`${__dirname}/admin/index.html`));
});
sudo nginx -tsudo systemctl restart nginxNOTA: Caso ocorra alguma erro para iniciar o nginx no Ubuntu 20.04, possivelmente é porque o Apache está utilizando a porta 80 Para resolver, basta desabilitaar/remover o Apache: https://www.cyberciti.biz/faq/how-do-i-stop-apache-from-starting-on-linux/
Configure seu usuário git na máquina remota
git config user.name --global "Gustavo-Kuze"
git config user.email --global "gustavoksilva3@hotmail.com"
git config -l
git clone https://github.com/yourdomain/restaurant-api.git
Nota: Quando solicitado pela senha no terminal, cole Token de acesso pessoal do Github
npm i -g yarn
yarn
nano .env
yarn buildpm2 start ./dist/index.js -n apisudo apt install certbot python3-certbot-nginxsudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
sudo certbot --nginx -d yourdomain.com.br -d www.yourdomain.com.brDICA: O certificado Let's Encrypt só é válido por um período de 90 dias, e precisa ser atualizado para que o HTTPS continue funcionando. O Cert bot possui a funcionalidade de auto atualização e ela pode ser verificada da seguinte maneira:
Rode o comando para verificar se o timer está ativo:
sudo systemctl status certbot.timerO output deve ser algo semelhante à:
● certbot.timer - Run certbot twice daily
Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
Active: active (waiting) since Mon 2020-05-04 20:04:36 UTC; 2 weeks 1 days ago
Trigger: Thu 2020-05-21 05:22:32 UTC; 9h left
Triggers: ● certbot.service
É também possível simular o processo de atualização automática de certificado, executando o seguinte comando:
sudo certbot renew --dry-runO resultado deve ser algo semelhante à:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/yourdomain.com.br.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator nginx, Installer nginx
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for yourdomain.com.br
http-01 challenge for www.yourdomain.com.br
Waiting for verification...
Cleaning up challenges
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed with reload of nginx server; fullchain is
/etc/letsencrypt/live/yourdomain.com.br/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates below have not been saved.)
Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/yourdomain.com.br/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IMPORTANT NOTES:
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
É possível realizar o git pull e instalação de dependências do projeto automaticamente (com yarn, por exemplo) da seguinte maneira:
git init --bare ~/projeto.gitpost-receive hook do gitnano /projeto.git/hooks/post-receivecole
#!/bin/bash
TARGET="/pasta/de/deploy"
GIT_DIR="/projeto.git"
BRANCH="main"
while read oldrev newrev ref
do
# only checking out the master (or whatever branch you would like to deploy)
if [ "$ref" = "refs/heads/$BRANCH" ];
then
echo "Ref $ref received. Deploying ${BRANCH} branch to production..."
git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
else
echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server."
fi
done
cd /pasta/de/deploy && yarn
pm2 restart api
chmod +x post-receivegit remote add production root@ip-da-maquina-remota:projeto.gitgit push e veja seu código sendo atualizado como em um passe de mágica 🤯git push production mainhttps://phoenixnap.com/kb/install-ftp-server-on-ubuntu-vsftpd
https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04
https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-20-04
https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04
https://gist.github.com/noelboss/3fe13927025b89757f8fb12e9066f2fa#file-post-receive
O erro seguinte erro aparece ao abrir um novo terminal no Mac
zsh compinit: insecure directories, run compaudit for list.
Ignore insecure directories and continue [y] or abort compinit [n]?
compinitsudo chown $(whoami) PATH_HERE
sudo chmod -R 755 PATH_HERE
Por exemplo, se o resultado do print comando compinit forem os seguintes diretórios:
/usr/local/share/zsh
/usr/local/share/zsh/site-functions
Você deve executar a seguinte sequência de comandos:
sudo chown $(whoami) /usr/local/share/zsh
sudo chmod -R 755 /usr/local/share/zsh
sudo chown $(whoami) /usr/local/share/zsh/site-functions
sudo chmod -R 755 /usr/local/share/zsh/site-functions
adb shell setprop debug.firebase.analytics.app com.meuapp.massa
adb shell setprop debug.firebase.analytics.app .none.
Para invocar um script Python dentro do NodeJS, basta utilizar o spawn do child_process
const { spawn } = require('child_process');
const path = require('path');
const util = require('util');
const pythonProcess = spawn(
'python',
[path.resolve(__dirname, './rename_dirs.py')],
{
cwd: 'D:\\python',
},
);
pythonProcess.stdout.on('data', (data) => {
const textChunk = data.toString('utf8'); // buffer to string
util.log(textChunk);
});import os
import sys
def main():
print('Enviar dados para o NodeJS')
sys.stdout.flush()
if __name__ == '__main__':
main()NOTAS:
rename_dirs.py, é necessário executar o comando sys.stdout.flush() após o print('enviar dados para o NodeJS')No TypeScript é possível criarmos funções que alteram o comportamento de outras funções (ou classes), sem que tenhamos que alterar a implementação original da mesma. Essas funções são chamadas decorators
Um decorator pode ser declarado da seguinte maneira:
export default function decoratorFunction(logInSeconds: boolean = false) {
return function (
target: any, // contexto onde o decorator está inserido
propertyKey: string, // Nome do método
descriptor: PropertyDescriptor // description.value é o método original
) {
const originalFunction = descriptor.value;
// aqui podemos sobrescrever o comportamento do método original
descriptor.value = function (...args: any[]) {
const result = originalFunction.apply(this, args);
/*
aqui devolvemos o mesmo retorno do método original
à partir da chamada do decorator
*/
return result;
};
return descriptor; // é necessário retornar o próprio descriptor ao final
};
}export default function logProcessingTime(logInSeconds: boolean = false) {
return function (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const originalFunction = descriptor.value;
descriptor.value = function (...args: any[]) {
let divisor = logInSeconds ? 1000 : 1;
let unidade = logInSeconds ? "seconds" : "milliseconds";
console.log("-----------------------");
console.log(`${propertyKey} function params: ${JSON.stringify(args)}`);
const initialTime = performance.now();
const result = originalFunction.apply(this, args);
console.log(`${JSON.stringify(result)} function result:`);
const finalTime = performance.now();
console.log(
`${propertyKey} took ${(finalTime - initialTime) / divisor} ${unidade} to be processed`
);
console.log("-----------------------");
return result;
};
return descriptor;
};
}Agora basta importar o decorator em qualquer módulo do node que quisermos, e decorar nossa função com ele. Isso fará com que o tempo de execução da função seja mostrado no console do navegador.
Ex:
import logProcessingTime from './decorators/logProcessingTime';
@logProcessingTime()
async function listarUsuariosAsync() {
// Exemplo de chamada muito demorada à nossa API Rest
return API.get('/users');
}
// ........
const users = await listarUsuariosAsync(); // adiciona took 1.580000011017546ms to be processedO que é deeplink? 🤓
Quando o usuário clicar em um link do site em seu smartphone, uma tela do app é aberta ao invés do navegador (Chrome, Safari, etc). Isso é "deep linking".
Para que app seja associado ao website, é preciso criar uma arquivo assetlinks.json no diretório .well-known do website, de tal forma que seja possível acessá-lo assim:
https://www.ololo.com/.well-known/assetlinks.jsonDentro do arquivo é preciso informar o package_name e a hash SHA-256. Exemplo de arquivo (dados fakes):
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "br.com.ololo",
"sha256_cert_fingerprints": ["B1:A3:8A:C9:3A:4B:32:92:FF:53:6A:EB:00:32:E9:D6:B8:2A:B1:D3:A3:57:CC:A8:28:A1:1F:AD:94:92:A7:8C"]
}
}]Atente-se aos seguintes detalhes (extraídos da documentação oficial):
No arquivo AndroidManifest.xml, adicione os caminhos do site que devem ser tratados pelo app:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"
android:exported="true"
android:launchMode="singleTask">
<!-- android:autoVerify="true" é obrigatorio -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- defina os caminhos que devem ser tratados aqui: -->
<data android:scheme="https" android:host="www.ololo.com" android:pathPattern="/ololo/produto/.*/p-.*" />
<data android:scheme="https" android:host="www.ololo.com" android:pathPattern="/ololo/promocoes" />/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="ololo" />
</intent-filter>
</activity>É possível testar se o arquivo está devidamente configurado através da seguinte ferramenta: https://developers.google.com/digital-asset-links/tools/generator?hl=pt-br
Para mais informações relacionada à configuração do servidor no Android, favor acessar a documentação oficial: https://developer.android.com/training/app-links/verify-site-associations?hl=pt-br#request-verify
Para que app seja associado ao website, é preciso criar uma arquivo apple-app-site-association na raiz do site, ou no diretório .well-known, de tal forma que seja possível acessá-lo assim:
https://www.ololo.com/apple-app-site-associationExemplo de arquivo (dados fakes):
{
"applinks": {
"apps": [],
"details": [
{
"appID": "7VCZVTXU85.br.com.ololo",
"paths": [
"/ololo/promocoes",
"/ololo/produto/*/p-*"
]
}
]
},
"webcredentials": {
"apps": [
"7VCZVTXU85.br.com.ololo"
]
}
}Atente-se aos seguintes detalhes:
apple-app-site-association precisa ser servido com o header "application/pkcs7-mime"Segue um exemplo de como servir o header "application/pkcs7-mime" no Node JS:
var aasa = fs.readFileSync(__dirname + '/static/apple-app-site-association');
app.get('/apple-app-site-association', function(req, res, next) {
res.set('Content-Type', 'application/pkcs7-mime');
res.status(200).send(aasa);
});AppDelegate.m, adicione as seguintes instruções:#import <React/RCTLinkingManager.h>
...
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}Isto irá transmitir a URL para o código React Native
ololo.entitlements), que indica a qual domínio seu site pertence. Exemplo:<?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>aps-environment</key>
<string>development</string>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:ololo.com</string>
<string>applinks:www.ololo.com</string>
</array>
</dict>
</plist>É possível testar se o arquivo está devidamente configurado através da ferramenta: https://limitless-sierra-4673.herokuapp.com/
Para mais informações sobre como configurar o servidor no ios, favor acessar a documentação oficial: https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html
A URL clicada estará disponível no React Native através do método Linking.getInitialURL. Exemplo:
Linking.getInitialURL().then((url) => {
console.log(`Deeplink clicado: ${url}` )
});Para configurar o ngrok para rodar tanto o projeto frontend quanto o backend simultaneamente, basta adicionar o seguinte código ao arquivo "C:\Users\USER\.ngrok2\ngrok.yml"
authtoken: 1bGvuFnqnXjihKbkqtx8qVld2ie_2736j4KfrDdMHhBh3uDtn
tunnels:
portafront:
proto: http
addr: 8000
portaapi:
proto: http
addr: 8888E então ao invés de executar apenas um tunnel com o comando ngrok http 8000, por exemplo, basta executar todos os túneis definidos nesse arquivo, com:
ngrok start --all
Executar no cmd:
npm config set cache "C:\Users\Gustavo~1Kuze\AppData\Roaming\npm-cache" --globalNOTE: Se você estiver utilizando o NVM, o CMD deve ser executado como administrador
Mysql error 1452 - Cannot add or update a child row: a foreign key constraint fails
Para resolver esse problema, basta desabilitar a verificação de FKs antes de adicionar a nova referência, por exemplo:
SET foreign_key_checks = 0; // executar isso para desabilitar
/*Adicionar a foreign key aqui, ou cria manualmente no workbench*/
SET foreign_key_checks = 1; // executar isso para habilitar novamenteyarn add -D babel-eslint prettier eslint-config-prettier eslint-plugin-prettier eslint eslint-plugin-react eslint-config-airbnb eslint-plugin-jsx-a11y eslint-plugin-import eslint-import-resolver-webpack.eslintrc.json na raiz do projeto com o seguinte conteúdo:{
"extends": ["airbnb", "prettier", "prettier/react"],
"parser": "babel-eslint",
"plugins": ["react", "prettier"],
"rules": {
"react/jsx-filename-extension": [
1,
{
"extensions": [".js", "jsx"]
}
],
"prettier/prettier": "error",
"max-len": ["error", 80],
"react/prop-types": 0
},
"env": {
"browser": true
},
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"],
"paths": ["src"]
}
}
}
}"lint": "eslint src -c .eslintrc.json --ext js,jsx",
.prettierrc.json, na raiz do projeto, com o seguinte conteúdo: {
"singleQuote": true,
"trailingComma": "all"
}yarn add -D eslint eslint-config-airbnb-base eslint-plugin-import eslint-plugin-promise prettier-eslint-cli.eslintrc.json na raiz do projeto com o seguinte conteúdo:{
"env": {
"node": true
},
"extends": "airbnb-base",
"plugins": ["promise"],
"rules": {
"no-console": "warn",
"promise/always-return": "error",
"promise/no-return-wrap": "error",
"promise/param-names": "error",
"promise/catch-or-return": "error",
"promise/no-native": "off",
"promise/no-nesting": "error",
"promise/no-promise-in-callback": "error",
"promise/no-callback-in-promise": "error",
"promise/no-return-in-finally": "error",
"prefer-arrow-callback": "error",
"linebreak-style": "off"
}
}"lint": "eslint 'src/**/*.js' --fix",
"format": "prettier-eslint 'server/**/*.{js,json}' --write"cd "C:\Program Files\Java\jdk1.8.0_211\bin"
keytool -genkeypair -v -keystore MYKEYSTORE.keystore -alias MY-ALIAS -keyalg RSA -keysize 2048 -validity 10000
keytool -list -v -keystore PATH_TO_YOUR_KEYSTORE.keystore -alias YOUR_ALIAS_NAME -storepass YOUR_STORE_PASSWORD -keypass YOUR_KEY_PASSWORD
javascript:(function(){
allowCopyAndPaste = function(e){
e.stopImmediatePropagation();
return true;
};
document.addEventListener('copy', allowCopyAndPaste, true);
document.addEventListener('paste', allowCopyAndPaste, true);
document.addEventListener('onpaste', allowCopyAndPaste, true);
})();