Skip to content

Instantly share code, notes, and snippets.

@niten2
Last active February 24, 2018 05:09
Show Gist options
  • Save niten2/00d39ddd35b8afbf23ae569d8beeb972 to your computer and use it in GitHub Desktop.
Save niten2/00d39ddd35b8afbf23ae569d8beeb972 to your computer and use it in GitHub Desktop.
JS
import settings from 'config/settings'
import { User } from "config/initialize/mongoose"
import { verifyJwt } from 'app/services/jwt'
export default async (req: any, res: any, next: any) => {
if (!req.header('Authorization') || !req.header('authorization')) {
return next()
}
const parts = req.header('Authorization').split(' ');
const token = parts[1]
if (!token) {
res.status(401)
next(new Error("token not found"))
}
let payload
try {
payload = await verifyJwt(token)
} catch (err){
res.status(401)
return next(new Error("token not valid"))
}
req.user = await User.findById(req.payload.user_id)
if (!req.user) {
res.status(401)
throw new Error("user not found")
}
req.log.info(`login as ${req.payload.user_id}, ${req.payload.email}, role = ${req.payload.role}`)
return next()
}
--------------------------
import { createJwt } from "app/services/jwt"
import Auth from 'app/middlewares/auth'
describe(__filename, () => {
describe('valid token', () => {
it("should verifyJwt", async () => {
const user = await factory.create("user")
const token = createJwt(user)
let req = { header: () => { return `Authorization ${token}` } }
let res = { status: () => {} }
let next = () => {}
await Auth(req, res, next)
expect(req.payload).toEqual(matchers.payload_json())
expect(req.user).toEqual(matchers.user_db())
})
})
describe('wrong token', async () => {
it("user not exist", async () => {
const user = await factory.build("user")
const token = createJwt(user)
let req = { header: () => { return `Authorization ${token}` } }
let res = { status: () => {} }
let next = jest.fn()
await Auth(req, res, next)
const error = next.mock.calls[0][0].message
expect(error).toEqual("user not found")
})
it("should verifyJwt", async () => {
let req = { header: () => { return "Authorization test" } }
let res = { status: () => {} }
let next = jest.fn()
await Auth(req, res, next)
expect(next.mock.calls[0]).toEqual([])
})
})
describe('empty token', () => {
it("should return error", async () => {
let req = { header: () => { return "" } }
let res = { status: () => {} }
let next = jest.fn()
await Auth(req, res, next)
expect(next.mock.calls[0]).toEqual([])
})
})
})
// NOTE policy
import { User } from "config/initialize/mongoose"
import Policy from 'app/policy'
export default async (req: any, res: any, next: any): Promise<any> => {
if (req.user) {
req.ability = await Policy(req.user)
}
return next()
}
import React from 'react'
import { graphql } from "react-apollo"
import gql from "graphql-tag"
class Hello extends React.Component {
render() {
const { loading, error, hello } = this.props.hello
if (loading) {
return <div>Loading...</div>
}
if (error) {
return (
<div style={{ color: 'red' }}>
{error}
</div>
);
}
return (
<div>
div
{hello}
</div>
);
}
}
const withData = graphql(
gql`
query hello($who: String) {
hello(who: $who)
}
`,
{
name: "hello",
options: ({ who }) => ({
variables: { who }
})
}
)
const component = withData(Hello)
export default {
component: component,
}
let map = new Map()
map.set("name", "TEST")
map.get("name")
map.has("name")
map.delete("name")
map.size("name")
let map = new Map([
["name", "test"]
])
map.values().map((value) => {})
"pre-commit": [ "lint" ],
pre-commit
expect(mock).toBeCalledWith(expect.anything())
it("should return error", async () => {
expect.assertions(1)
try {
await verifyJwt("string")
} catch (err) {
expect(err).toEqual({
name: "JsonWebTokenError",
message: "jwt malformed",
})
}
})
expect(res).toEqual(matchers.payload_json())
payload_json: (): any => {
return expect.objectContaining({
user_id: expect.any(String),
email: expect.any(String),
iat: expect.any(Number),
exp: expect.any(Number),
})
},
const util = require('util')
console.log(util.inspect(res.body, false, null))
console.log(require('util').inspect(res.body, false, null))
Math.random().toString(36).slice(-8)
var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
var schema = buildSchema(`
type Query {
ip: String
}
`)
function loggingMiddleware(req, res, next) {
console.log('ip:', req.ip);
next();
}
var root = {
ip: function (args, request) {
return request.ip;
}
};
var app = express();
app.use(loggingMiddleware);
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
}));
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
// map
await Promise.all(
names.map(async (name) => {
const AuthModels = {
"Setting": Setting,
"User": User,
}
const CrmModels = [
"Client",
"Status"
]
const model = AuthModels[name]
if (model) {
count[name] = await model.count()
}
if (CrmModels.includes(name)) {
let response = await CrmFetch(queryMeta(name))
count[name] = response.data.meta.count[name]
}
})
)
function getMethods(obj) {
var res = []
for(var m in obj) {
if(typeof obj[m] == "function") {
res.push(m)
}
}
return res
}
// import Notification from 'notification';
import { UIStore } from 'stores'
export default {
success(message = '') {
UIStore.notificationSystem.addNotification({
message,
// position: "tc",
position: "br",
level: 'success'
});
},
info(message = '') {
UIStore.notificationSystem.addNotification({
message,
position: "br",
// position: "tc",
level: 'info'
});
},
warning(message = '') {
UIStore.notificationSystem.addNotification({
message,
// position: "tc",
position: "br",
level: 'warning',
});
},
error(message = '') {
UIStore.notificationSystem.addNotification({
title: 'An error occured',
message,
// position: "tc",
position: "br",
level: 'error'
});
},
errors(errors = []) {
if (errors.length === 1) {
this.error(errors[0]);
return
}
errors = errors.reduce((message, error) => {
return message + '<li>'+error+'</li>';
}, '');
let message = '<ul>'+errors+'</ul>';
UIStore.notificationSystem.addNotification({
title: 'Following errors occured',
message,
level: 'error'
});
}
}
import { extendObservable, asFlat } from 'mobx'
class SearchStore {
constructor() {
extendObservable(this, {
searchResults: asFlat([])
})
}
get = (id) => {
var results = this._findResults(id)
return results ? results.values : undefined
}
set = (id, json) => {
var results = this._findResults(id)
if (results) {
results.values = json
} else {
this.searchResults.push({ id, values: json })
}
}
// private
_findResults(id) {
return this.searchResults.find(results =>
results.id === id
)
}
}
export default new SearchStore
import { extendObservable, transaction } from 'mobx'
import { autorun } from 'mobx'
import { SearchStore } from 'stores'
import authProvider from 'lib/auth'
import { User } from "models"
import uniqueId from 'lodash/uniqueId'
import debounce from 'lodash/debounce'
import bindAll from 'lodash/bindAll'
const HEADER_SESSION_TOKEN = 'X-DreamFactory-Session-Token'
let search = {
model: {},
searchId: uniqueId('search_')
}
extendObservable(search, {
showObjects: false,
loading: false,
city: ""
})
Object.assign(search, {
startAutoSearch(model) {
this.setModel(model)
this.startPerformSearch()
},
startPerformSearch() {
autorun(() => { this.performSearch() })
let debouncedSearch = debounce(this.performSearch, 1000)
this.disposeSearch = autorun(() => {
let action
if (this.previousQuery !== this.query) {
action = debouncedSearch
} else {
action = this.performSearch
}
action()
this.previousQuery = this.query
})
},
stopAutoSearch() {
this.disposeSearch()
},
performSearch(attributes = {}) {
let { setLastPage } = attributes
let { city } = this
let { page, perPage } = this
transaction(() => {
this.loading = true
this.searchError = false
})
this.model.search( this.searchId, {
page,
perPage,
}).then(response => {
if (setLastPage) {
transaction(() => {
this.page = this.totalPages
this.loading = false
this.searchError = !response.ok
})
} else {
transaction(() => {
this.loading = false
this.searchError = !response.ok
})
}
return true
})
},
getSearchResults() {
return SearchStore.get(this.searchId)
},
setCity(value) {
transaction(() => {
this.showObjects = true
this.city = value
})
},
setDefault() {
transaction(() => {
this.showObjects = true
this.city = ""
})
},
setModel(model) {
this.model = model
},
setPerPage(newPage) {
transaction(() => {
this.page = 1
this.perPage = newPage
})
},
})
export default bindAll(search, [
"startAutoSearch",
"startPerformSearch",
"performSearch",
"stopAutoSearch",
"getSearchResults",
"setModel",
"setCity",
"setDefault",
])
Model.where('created').gte(twoWeeksAgo).stream().pipe(writeStream);
var stream = collection.find().stream()
stream.on('error', function (err) {
console.error(err)
})
stream.on('data', function (doc) {
console.log(doc)
})
// assign a function to the "statics" object of our animalSchema
animalSchema.statics.findByName = function(name, cb) {
return this.find({ name: new RegExp(name, 'i') }, cb);
};
// ----------------
animalSchema.query.byName = function(name) {
return this.find({ name: new RegExp(name, 'i') });
};
var Animal = mongoose.model('Animal', animalSchema);
Animal.find().byName('fido').exec(function(err, animals) {
console.log(animals);
});
// index
var animalSchema = new Schema({
name: String,
type: String,
tags: { type: [String], index: true } // field level
});
personSchema.virtual('fullName').get(function () {
return this.name.first + ' ' + this.name.last;
});
findByIdAndUpdate
findById
findOneAndRemove
findOneAndUpdate
count
update
remove
Person.findOne({ 'name.last': 'Ghost' })
query.select('name occupation');
// execute the query at a later time
query.exec(function (err, person) {
if (err) return handleError(err);
console.log('%s %s is a %s.', person.name.first, person.name.last, person.occupation) // Space Ghost is a talk show host.
})
limit(10).
sort({ occupation: -1 }).
select({ name: 1, occupation: 1 }).
sort
// populate
populate({
path: 'fans',
match: { age: { $gte: 21 }},
// Explicitly exclude `_id`, see http://bit.ly/2aEfTdB
select: 'name -_id',
options: { limit: 5 }
}).
author.stories.push(story1);
author.save(callback);
user.markModified('data.mix');
var Lib = new mongoose.Schema({
userId: mongoose.Schema.ObjectId,
images: {
// правила валидации и дефолты для каждого из полей объекта массива images
type: [{
uploaded: {
type: Date,
default: Date.now
},
src: String
}],
// значение по-умолчанию для поля images
default: [{uploaded: new Date(2012, 11, 22), src: '/img/default.png'}]
}
});
module.exports = mongoose.model('Lib', Lib);
e.m.users.find({}).stream()
.on('data', function(user) {
var me = this;
me.pause();
// выполняем надо пользователем очень хитрые асинронные манипуляции
user.save(function(err) {
me.resume(err);
});
})
.on('error', function(err) {
log(err);
})
.on('close', function() {
log('All done');
});
const autoPopulate = function(next: any) {
this.populate('loans')
this.populate('territory')
next()
}
schema.
pre('findOne', autoPopulate).
pre('find', autoPopulate)
import { Client } from "api/models"
import R from "ramda"
let params = (object) => {
R.pick([
"number",
"name",
"phone",
"date_birth",
"note",
], object)
}
export default {
async index(req, res, next) {
try {
let clients = await Client.findAll()
res.json(clients)
} catch(error) {
res.json({ "error": error }).status(422)
}
},
async show(req, res) {
try {
let client = await Client.findById(req.params.id)
res.send(client)
} catch(error) {
res.json({"error": error }).status(422)
}
},
async create(req, res) {
try {
let client = await Client.create(req.body)
res.send(client)
} catch(error) {
res.json({"error": error }).status(422)
}
},
async update(req, res) {
try {
let client = await Client.findById(req.params.id)
await client.update(params(req))
res.send(user)
} catch(error) {
res.json({"error": error }).status(422)
}
},
async destroy(req, res) {
try {
const client = await Client.findById(req.params.id)
await client.destroy()
res.json({ "message": "ok" }).status(204)
} catch(error) {
res.json({"error": error }).status(422)
}
},
}
"scripts": {
"start": "node -r dotenv/config ./node_modules/.bin/react-scripts start dotenv_config_path=.env.development",
"build": "node -r dotenv/config ./node_modules/.bin/react-scripts build dotenv_config_path=.env.production"
}
npm-check-updates
ncu
NOTE - if NODE_ENV: "production" npm NOT install dev-dependens
npm config set prefix ~/.npm
# Adapter
преобразует интерфейс одного класса в другой от ожидания клиента
# Chaining
цепочка обязанностей
# Command
инкаспулирует запрос как обьект, может ставить запросы в очередь, отменять и тд
# Composite
# CompositeIterator
# Compound
# Decorator
динамическое добавление новых обязанностей
# Facade
структурирует обьекты
# Factory
# Iterator
последовательный доступ к всем элементам не раскрывая внутреннего представления
# Lazy
# Module Revealed
# Module
# Multi-Inheritance-ES6
# MVC
# Namespace
# Nullify
# Observer
от изменения состояния одного обьекта все зависящие от него оповещаются и автоматически обновляются
# Proxy
суггорат другого обьекта контролирует доступ к нему
# Singleton
# State
варьирует свое поведение в зависимости от состояния
# statics
# Strategy
опредеяет семейство обьектов, инкапсулирует и делает их взаимозаменяемыми
# Template
# Try-Finally
# Bridge
отделить абстракцию и реализаю что бы можно было менять независимо
# Interpreter
# Mediator
независимо взаимодействует с множеством обьектов
# Memento
выносит внутреенне состояние обьекта, что бы можно было его восстановить
pm2 start --no-daemon pm2.config.js
pm2 start ./initializers/server/jobs/index.js --node-args="--require babel-register" --name jobs
// router AWS
function handleRootRouteEnter (nextState, replaceState) {
const regHashMask = /^#\/?/
const { hash } = nextState.location
const isHashedRoute = regHashMask.test(hash)
if (isHashedRoute) {
const newPathname = hash.replace(regHashMask, '/')
replaceState(null, newPathname)
}
}
import { createStore } from 'redux'
import todoApp from './reducers'
let store = createStore(todoApp)
// ---------
store.dispatch(toggleTodo(1))
Вы вызываете store.dispatch(action).
Хранилище Redux вызывает функцию-редюсер, который вы ему передали.+
Главный редюсер может комбинировать результат работы нескольких редюсеров в единственное дерево состояния приложения.
Хранилище Redux сохраняет полное дерево состояния, которое возвращает главный редюсер.
Технически, вы можете написать контейнеры вручную, используя store.subscribe().
Мы не советуем вам это делать, потому что React Redux производит много оптимизаций производительности, которые было бы трудно написать руками.
По этой причине, вместо того чтобы писать контейнеры, мы генерируем их, воспользовавшись функцией connect(), предоставленной React Redux, об этом ниже.
Redux-мидлвэры, в отличие от мидлвэров Express или Koa, решают немного другие проблемы, но концептуально схожим способом.
Они предоставляют стороннюю точку расширения между отправкой действия и моментом, когда это действие достигает редюсера.
Люди используют Redux-мидлвэры для логирования, сообщения об ошибках, общения с асинхронным API, роутинга и т.д.
// containers
import { connect } from 'react-redux'
AddTodo = connect()(AddTodo)
// middlewares
/**
* Отправляет отчеты об ошибках когда обновляется состояние и уведомляются слушатели.
*/
const crashReporter = store => next => action => {
try {
return next(action)
} catch (err) {
console.error('Caught an exception!', err)
Raven.captureException(err, {
extra: {
action,
state: store.getState()
}
})
throw err
}
}
export const logger = store => next => action => {
console.log('dispatching', action)
let result = next(action)
console.log('next state', store.getState())
return result
}
// generate
function makeActionCreator(type, ...argNames) {
return function(...args) {
let action = { type }
argNames.forEach((arg, index) => {
action[argNames[index]] = args[index]
})
return action
}
}
const ADD_TODO = 'ADD_TODO'
const EDIT_TODO = 'EDIT_TODO'
const REMOVE_TODO = 'REMOVE_TODO'
export const addTodo = makeActionCreator(ADD_TODO, 'todo')
export const editTodo = makeActionCreator(EDIT_TODO, 'id', 'todo')
export const removeTodo = makeActionCreator(REMOVE_TODO, 'id')
Миддлвэр позволяет нам писать более выразительные, потенциально асинхронные генераторые действий.
Это позволяет нам отправлять в качестве действий что-то помимо простых объектов и интерпретировать значения.
Например, миддлвэр может “отлавливать” отправленные промисы (Promises) и обращать их в пару из запроса и успешных/провальных действий.
import schedule from 'node-schedule'
// const rule = new schedule.RecurrenceRule()
// rule.second = new schedule.Range(0, 59, 1);
// rule.minute = new schedule.Range(0, 59, 1);
const rule = { hour: 12, minute: 00 }
// const rule = {minute: 1}
// const rule = '1 * * * *'
schedule.scheduleJob(rule, () => {
console.log(new Date())
})
// every 1 minute
let rule = new schedule.RecurrenceRule();
rule.minute = new schedule.Range(0, 59, 1);
schedule.scheduleJob(rule, async () => { await run() })
describe('', () => {
it("", async () => {
})
})
.only()
.skip()
import * as foo from 'app/middlewares/test';
before(async () => {
sinon.stub(foo, "default").callsFake((req, res, next) => {
console.log(22222)
return next();
})
})
expect(result.from).to.be.a("string")
var file = new fs.ReadStream()
sendFile(file, res)
file.pipe(res)
file.pipe(process.stdout)
file.on("error", () => {
})
что бы при закрытии соединения закрывать файл
res.on("close", () => {
file.destroy
})
var r = fs.createReadStream('file.txt')
var z = zlib.createGzip()
var w = fs.createWriteStream('file.txt.gz')
r.pipe(z).pipe(w)
---
const http = require('http')
var server = http.createServer( (req, res) => {
var body = ''
req.setEncoding('utf8')
req.on('data', (chunk) => {
body += chunk
})
req.on('end', () => {
var data = JSON.parse(body)
res.write(typeof data)
res.end()
})
})
server.listen(1337)
schema.methods.comparePassword = (candidatePassword: string, cb: (err: any, isMatch: any) => {}) => {
bcrypt.compare(candidatePassword, this.password, (err: mongoose.Error, isMatch: boolean) => {
cb(err, isMatch)
})
}
let array: [number, string] = [1,"2"]
function ge(age: number = 1): void {
}
type User = {
test: number
field?: number
}
let user: User = {
test: 1
}
enum Job {
test = 50
test2
}
Job.test
Job.test2 == 51
function test(err: string): never {
throw new Errro(err)
}
let test: number | null
class User {
private name: string
public name: string
protected name: string
abstract logInfo(info: string): void
constructor(public job: string) {
}
}
const user = new User("job")
class User2 extends User {
constructor(job: string) {
super(job)
}
}
interface IUser {
}
class User implements IUser {
// class use interface
}
function genericGetter<T>(data: T): T {
return data
}
console.log(genericGetter("test").length)
console.log(genericGetter<string>("test").length)
console.log(genericGetter(1).length)
newGeneric: <T>(data: T) => T = genericGetter
class Multiply<T> {
}
function log(constFN: Function) {
console.log(constFN)
}
@log
class User {
constructor() {
}
}
interface Logger {
info: (content: string) => void;
error: (content: string) => void;
}
declare const logger: Logger
declare module "app/services/logger" {
export default logger
}
import React, { Component } from 'react'
import { API, BaseModel } from 'mobx-model'
import { Upload } from 'models'
import 'blueimp-file-upload'
import { Col, Clearfix, Button } from 'react-bootstrap'
import Notification from 'notification'
import Spinner from 'spinner'
import FileInput from 'react-file-input'
class Uploader extends Component {
state = {
loading: false,
data: {},
viewProgressBar: false,
fileNames: [],
}
componentWillMount() {
this.setState({ loading: true })
Upload.getS3PostSignature().then(response => {
if (response.ok) {
this.setState({ data: response.body })
this.setState({ loading: false })
this.runUploader()
return true
} else {
Notification.error("S3 Post Signature Not Found")
}
})
}
runUploader() {
const { uploader, progress, files } = this.refs
let data = this.state.data
let self = this
$(uploader).fileupload({
url: data.url,
type: 'POST',
autoUpload: true,
formData: data.fields,
paramName: 'file',
dataType: 'XML',
start: function (e) {
self.setState({ viewProgressBar: true })
},
change: function (e, data) {
$.each(data.files, function (index, file) {
let fileNames = self.state.fileNames
fileNames.push(file.name)
self.setState({ fileNames })
})
},
done: function (e, data) {
let s3_key = $(data.jqXHR.responseXML).find("Key").text();
self.setState({ viewProgressBar: false })
Upload.create({ s3_key: s3_key }).then(response => {
if (response.ok) {
Notification.info("file upload")
return true
} else {
Notification.error("Error file upload")
}
})
},
fail: function(e, data) {
Notification.errors("file not upload")
},
progressall: function (e, data) {
let progress = parseInt(data.loaded / data.total * 100, 10)
$('#progress .progress-bar').css( 'width', progress + '%' )
},
})
}
renderLoading() {
return (
<div className="sidebar-spinner"> <Spinner /> </div>)
}
renderView() {
return (
<div>
<span className="btn btn-success fileinput-button">
<i className="glyphicon glyphicon-plus"></i>
<span>Select files...</span>
<input
ref="uploader"
type="file"
name="files[]"
multiple
/>
</span>
{ this.state.viewProgressBar ? this.renderProgressBar() : null }
<br />
{ this.state.fileNames.map((file, index) =>
<div
key={index}
> {file } </div>
)}
</div>
)
}
renderProgressBar() {
return (
<div id="progress" className="progress">
<div className="progress-bar progress-bar-success"></div>
</div>
)
}
render() {
return this.state.loading ? this.renderLoading() : this.renderView()
}
}
export default Uploader
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment