mirror of
https://github.com/zhigang1992/devhub.git
synced 2026-06-17 11:11:21 +08:00
Move auth to the server
Experimenting with an weird redux based server
This commit is contained in:
5
now.json
5
now.json
@@ -3,10 +3,15 @@
|
||||
"alias": "devhubapp.com",
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "packages/server/dist/api/redux/index.js", "use": "@now/node" },
|
||||
{ "src": "packages/server/dist/oauth/providers/github/*.js", "use": "@now/node" },
|
||||
{ "src": "packages/web/dist/**", "use": "@now/static" }
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"src": "/api/redux",
|
||||
"dest": "/packages/server/dist/api/redux/index.js"
|
||||
},
|
||||
{
|
||||
"src": "/auth/github",
|
||||
"dest": "/packages/server/dist/oauth/providers/github/auth.js"
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
"dependencies": {
|
||||
"axios": "^0.18.0",
|
||||
"lodash.omit": "^4.5.0",
|
||||
"micro": "^9.3.3",
|
||||
"qs": "^6.5.2",
|
||||
"shared-core": "0.17.1",
|
||||
"url": "^0.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -20,11 +22,13 @@
|
||||
"@types/jest": "^23.3.9",
|
||||
"@types/lodash": "^4.14.118",
|
||||
"@types/lodash.omit": "^4.5.4",
|
||||
"@types/micro": "^7.3.3",
|
||||
"@types/qs": "^6.5.1",
|
||||
"@types/ramda": "^0.26.0",
|
||||
"babel-jest": "^23.6.0",
|
||||
"husky": "^1.1.4",
|
||||
"jest": "^23.6.0",
|
||||
"micro-dev": "^3.0.0",
|
||||
"postinstall-postinstall": "^2.0.0",
|
||||
"prettier": "^1.15.2",
|
||||
"ts-jest": "^23.10.4",
|
||||
|
||||
72
packages/server/src/api/redux/index.ts
Normal file
72
packages/server/src/api/redux/index.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import axios from 'axios'
|
||||
import { IncomingMessage, ServerResponse } from 'http'
|
||||
import { json, send } from 'micro'
|
||||
|
||||
import { AllActions } from 'shared-core/dist/redux/types'
|
||||
|
||||
const sendReduxResponse = (
|
||||
res: ServerResponse,
|
||||
code: number,
|
||||
data: {
|
||||
action: AllActions
|
||||
},
|
||||
) => send(res, code, data)
|
||||
|
||||
module.exports = async (req: IncomingMessage, res: ServerResponse) => {
|
||||
// res.setHeader('Access-Control-Allow-Origin', '*')
|
||||
|
||||
if (req.method !== 'POST') {
|
||||
send(res, 404)
|
||||
return
|
||||
}
|
||||
|
||||
const body = await json(req)
|
||||
|
||||
const { action } = (body || {}) as { action?: AllActions }
|
||||
|
||||
if (!(action && action.type)) {
|
||||
send(
|
||||
res,
|
||||
400,
|
||||
'Invalid request. Required valid action field inside body object.',
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
switch (action.type) {
|
||||
case 'LOGIN_REQUEST': {
|
||||
try {
|
||||
const { data, status } = await axios.get(
|
||||
`https://api.github.com/user?access_token=${action.payload.token}`,
|
||||
)
|
||||
|
||||
sendReduxResponse(res, status, {
|
||||
action: {
|
||||
type: 'LOGIN_SUCCESS',
|
||||
payload: {
|
||||
user: data,
|
||||
},
|
||||
},
|
||||
})
|
||||
return
|
||||
} catch (error) {
|
||||
sendReduxResponse(res, error.response.status, {
|
||||
action: {
|
||||
type: 'LOGIN_FAILURE',
|
||||
payload: undefined,
|
||||
error: {
|
||||
code: error.response.status,
|
||||
message: error.response.data.message,
|
||||
},
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
send(res, 400, 'Unknown action type.')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Http2ServerRequest } from 'http2'
|
||||
import { IncomingMessage } from 'http'
|
||||
import omit from 'lodash.omit'
|
||||
import qs from 'qs'
|
||||
import { ParsedUrlQuery } from 'querystring'
|
||||
@@ -13,7 +13,7 @@ export function isLocalhost(host: string) {
|
||||
)
|
||||
}
|
||||
|
||||
export function getCurrentHostURL(req: Http2ServerRequest) {
|
||||
export function getCurrentHostURL(req: IncomingMessage) {
|
||||
const host = req.headers.host || ''
|
||||
|
||||
return isLocalhost(host)
|
||||
@@ -21,12 +21,12 @@ export function getCurrentHostURL(req: Http2ServerRequest) {
|
||||
: `https://${host}`
|
||||
}
|
||||
|
||||
export function getDefaultCallbackURL(req: Http2ServerRequest) {
|
||||
export function getDefaultCallbackURL(req: IncomingMessage) {
|
||||
return `${getCurrentHostURL(req)}/auth/github/callback`
|
||||
}
|
||||
|
||||
export function getCallbackURLWithQuery(
|
||||
req: Http2ServerRequest,
|
||||
req: IncomingMessage,
|
||||
callbackUrl?: string,
|
||||
query?: object,
|
||||
) {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import axios from 'axios'
|
||||
import { Http2ServerRequest, Http2ServerResponse } from 'http2'
|
||||
import { IncomingMessage, ServerResponse } from 'http'
|
||||
import qs from 'qs'
|
||||
|
||||
import { mergeQueryWithURL } from '../helpers'
|
||||
|
||||
const redirectUsingHTML = (
|
||||
res: Http2ServerResponse,
|
||||
res: ServerResponse,
|
||||
_statusCode: number,
|
||||
url: string,
|
||||
) => {
|
||||
@@ -20,7 +20,7 @@ const redirectUsingHTML = (
|
||||
}
|
||||
|
||||
const redirectUsingHTMLAndPostMessage = (
|
||||
res: Http2ServerResponse,
|
||||
res: ServerResponse,
|
||||
_statusCode: number,
|
||||
url: string,
|
||||
) => {
|
||||
@@ -58,8 +58,8 @@ const redirectUsingHTMLAndPostMessage = (
|
||||
}
|
||||
|
||||
export function authorize(
|
||||
req: Http2ServerRequest,
|
||||
res: Http2ServerResponse,
|
||||
req: IncomingMessage,
|
||||
res: ServerResponse,
|
||||
{ AUTHORIZE_URL }: { AUTHORIZE_URL: string },
|
||||
query?: object,
|
||||
) {
|
||||
@@ -67,8 +67,8 @@ export function authorize(
|
||||
}
|
||||
|
||||
export async function callback(
|
||||
req: Http2ServerRequest,
|
||||
res: Http2ServerResponse,
|
||||
req: IncomingMessage,
|
||||
res: ServerResponse,
|
||||
{
|
||||
CALLBACK_URL,
|
||||
CLIENT_ID,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Http2ServerRequest, Http2ServerResponse } from 'http2'
|
||||
import { IncomingMessage, ServerResponse } from 'http'
|
||||
import url from 'url'
|
||||
|
||||
import {
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
} from '../../helpers'
|
||||
import { authorize } from '../../lib/oauth'
|
||||
|
||||
module.exports = (req: Http2ServerRequest, res: Http2ServerResponse) => {
|
||||
const query = url.parse(req.url, true).query || {}
|
||||
module.exports = (req: IncomingMessage, res: ServerResponse) => {
|
||||
const query = url.parse(req.url || '', true).query || {}
|
||||
const redirectUri = getFirstStringFromQuery(query, 'redirect_uri')
|
||||
|
||||
authorize(
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Http2ServerRequest, Http2ServerResponse } from 'http2'
|
||||
import { IncomingMessage, ServerResponse } from 'http'
|
||||
import url from 'url'
|
||||
|
||||
import { getFirstStringFromQuery } from '../../helpers'
|
||||
import { callback } from '../../lib/oauth'
|
||||
|
||||
module.exports = (req: Http2ServerRequest, res: Http2ServerResponse) => {
|
||||
const query = url.parse(req.url, true).query || {}
|
||||
module.exports = (req: IncomingMessage, res: ServerResponse) => {
|
||||
const query = url.parse(req.url || '', true).query || {}
|
||||
const callbackUrl = getFirstStringFromQuery(query, 'callback_url')
|
||||
|
||||
callback(
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import { GitHubUser } from 'shared-core/dist/types'
|
||||
import {
|
||||
createAction,
|
||||
createErrorAction,
|
||||
} from 'shared-core/dist/utils/helpers/redux'
|
||||
|
||||
export function loginRequest(payload: { token: string }) {
|
||||
return createAction('LOGIN_REQUEST', payload)
|
||||
}
|
||||
|
||||
export function loginSuccess(user: GitHubUser) {
|
||||
return createAction('LOGIN_SUCCESS', user)
|
||||
}
|
||||
|
||||
type HttpError = Error & { code: number } // TODO: Get this type from somewhere else
|
||||
export function loginFailure<E extends HttpError>(error: E) {
|
||||
return createErrorAction('LOGIN_FAILURE', error)
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
return createAction('LOGOUT')
|
||||
}
|
||||
@@ -1,5 +1,2 @@
|
||||
export * from './auth'
|
||||
export * from './columns'
|
||||
export * from './config'
|
||||
export * from 'shared-core/dist/redux/actions'
|
||||
export * from './navigation'
|
||||
export * from './subscriptions'
|
||||
|
||||
@@ -34,7 +34,7 @@ export const authReducer: Reducer<State> = (state = initialState, action) => {
|
||||
isLoggingIn: false,
|
||||
lastLoginAt: new Date().toISOString(),
|
||||
token: state.token,
|
||||
user: action.payload,
|
||||
user: action.payload.user,
|
||||
}
|
||||
|
||||
case 'LOGIN_FAILURE':
|
||||
|
||||
@@ -20,13 +20,33 @@ function* onLoginRequest(
|
||||
try {
|
||||
github.authenticate(action.payload.token || '')
|
||||
|
||||
const response = yield fetch('/api/redux', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ action }),
|
||||
})
|
||||
const body = yield response.json()
|
||||
if (!(body && body.action && body.action.type))
|
||||
throw new Error('Invalid response')
|
||||
|
||||
yield put(body.action)
|
||||
return
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
||||
if (error && error.response && error.response.action) {
|
||||
yield put(error.response.action)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = yield call(github.octokit.users.get, {})
|
||||
const user = response.data as GitHubUser
|
||||
if (!(user && user.id && user.login)) throw new Error('Invalid response')
|
||||
|
||||
yield put(actions.loginSuccess(user))
|
||||
} catch (e) {
|
||||
yield put(actions.loginFailure(e))
|
||||
yield put(actions.loginSuccess({ user }))
|
||||
} catch (error) {
|
||||
yield put(actions.loginFailure(error))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ function getDefaultColumns(username: string): ColumnAndSubscriptions[] {
|
||||
function* onLoginSuccess(
|
||||
action: ExtractActionFromActionCreator<typeof actions.loginSuccess>,
|
||||
) {
|
||||
const username = action.payload.login
|
||||
const username = action.payload.user.login
|
||||
const hasCreatedColumn = yield select(selectors.hasCreatedColumnSelector)
|
||||
if (!hasCreatedColumn)
|
||||
yield put(actions.replaceColumns(getDefaultColumns(username)))
|
||||
|
||||
18
packages/shared-core/src/redux/actions/auth.ts
Normal file
18
packages/shared-core/src/redux/actions/auth.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { GitHubUser } from '../../types'
|
||||
import { createAction, createErrorAction } from '../../utils/helpers/redux'
|
||||
|
||||
export function loginRequest(payload: { token: string }) {
|
||||
return createAction('LOGIN_REQUEST', payload)
|
||||
}
|
||||
|
||||
export function loginSuccess(payload: { user: GitHubUser }) {
|
||||
return createAction('LOGIN_SUCCESS', payload)
|
||||
}
|
||||
|
||||
export function loginFailure(error: { code: number; message: string }) {
|
||||
return createErrorAction('LOGIN_FAILURE', error)
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
return createAction('LOGOUT')
|
||||
}
|
||||
@@ -3,8 +3,8 @@ import {
|
||||
ColumnFilters,
|
||||
GitHubEvent,
|
||||
GitHubNotificationReason,
|
||||
} from 'shared-core/dist/types'
|
||||
import { createAction } from 'shared-core/dist/utils/helpers/redux'
|
||||
} from '../../types'
|
||||
import { createAction } from '../../utils/helpers/redux'
|
||||
|
||||
export function replaceColumns(payload: ColumnAndSubscriptions[]) {
|
||||
return createAction('REPLACE_COLUMNS', payload)
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ThemePair } from 'shared-core/dist/types'
|
||||
import { createAction } from 'shared-core/dist/utils/helpers/redux'
|
||||
import { ThemePair } from '../../types'
|
||||
import { createAction } from '../../utils/helpers/redux'
|
||||
|
||||
export function setTheme(payload: {
|
||||
id: ThemePair['id']
|
||||
4
packages/shared-core/src/redux/actions/index.ts
Normal file
4
packages/shared-core/src/redux/actions/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './auth'
|
||||
export * from './columns'
|
||||
export * from './config'
|
||||
export * from './subscriptions'
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createAction } from 'shared-core/dist/utils/helpers/redux'
|
||||
import { createAction } from '../../utils/helpers/redux'
|
||||
|
||||
export function deleteColumnSubscription(columnId: string) {
|
||||
return createAction('DELETE_COLUMN_SUBSCRIPTION', columnId)
|
||||
9
packages/shared-core/src/redux/types/index.ts
Normal file
9
packages/shared-core/src/redux/types/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { ExtractActionFromActionCreator } from '../../types'
|
||||
|
||||
import * as actions from '../actions'
|
||||
|
||||
export type AllActions = ExtractActionFromActionCreator<
|
||||
typeof actions[keyof typeof actions]
|
||||
>
|
||||
|
||||
export type Reducer<S = any> = (state: S | undefined, action: AllActions) => S
|
||||
147
yarn.lock
147
yarn.lock
@@ -1050,6 +1050,13 @@
|
||||
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.118.tgz#247bab39bfcc6d910d4927c6e06cbc70ec376f27"
|
||||
integrity sha512-iiJbKLZbhSa6FYRip/9ZDX6HXhayXLDGY2Fqws9cOkEQ6XeKfaxB0sC541mowZJueYyMnVUmmG+al5/4fCDrgw==
|
||||
|
||||
"@types/micro@^7.3.3":
|
||||
version "7.3.3"
|
||||
resolved "https://registry.npmjs.org/@types/micro/-/micro-7.3.3.tgz#31ead8df18ac10d58b7be1186d4b2d977b13a938"
|
||||
integrity sha512-I3n3QYT7lqAxkyAoTZyg1yrvo38BxW/7ZafLAXZF/zZQOnAnQzg6j9XOuSmUEL5GGVFKWw4iqM+ZLnqb2154TA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*", "@types/node@^10.12.6":
|
||||
version "10.12.6"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-10.12.6.tgz#7fc213c1b811c90fc9a3edb6206742b95d697678"
|
||||
@@ -2601,6 +2608,15 @@ caseless@~0.12.0:
|
||||
resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||
|
||||
chalk@2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.0.tgz#a060a297a6b57e15b61ca63ce84995daa0fe6e52"
|
||||
integrity sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw==
|
||||
dependencies:
|
||||
ansi-styles "^3.2.1"
|
||||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.3.0"
|
||||
|
||||
chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.0, chalk@^2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
|
||||
@@ -2636,6 +2652,25 @@ check-types@^7.3.0:
|
||||
resolved "https://registry.npmjs.org/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4"
|
||||
integrity sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg==
|
||||
|
||||
chokidar@2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "http://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz#dcbd4f6cbb2a55b4799ba8a840ac527e5f4b1176"
|
||||
integrity sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==
|
||||
dependencies:
|
||||
anymatch "^2.0.0"
|
||||
async-each "^1.0.0"
|
||||
braces "^2.3.0"
|
||||
glob-parent "^3.1.0"
|
||||
inherits "^2.0.1"
|
||||
is-binary-path "^1.0.0"
|
||||
is-glob "^4.0.0"
|
||||
normalize-path "^2.1.1"
|
||||
path-is-absolute "^1.0.0"
|
||||
readdirp "^2.0.0"
|
||||
upath "^1.0.0"
|
||||
optionalDependencies:
|
||||
fsevents "^1.1.2"
|
||||
|
||||
chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26"
|
||||
@@ -2996,7 +3031,7 @@ content-disposition@0.5.2:
|
||||
resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
|
||||
integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ=
|
||||
|
||||
content-type@~1.0.4:
|
||||
content-type@1.0.4, content-type@~1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
||||
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
||||
@@ -3406,6 +3441,11 @@ date-now@^0.1.4:
|
||||
resolved "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
|
||||
integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=
|
||||
|
||||
debounce@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/debounce/-/debounce-1.1.0.tgz#6a1a4ee2a9dc4b7c24bb012558dbcdb05b37f408"
|
||||
integrity sha512-ZQVKfRVlwRfD150ndzEK8M90ABT+Y/JQKs4Y7U4MXdpuoUkkrr4DwKbVux3YjylA5bUMUj0Nc3pMxPJX6N2QQQ==
|
||||
|
||||
debounce@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131"
|
||||
@@ -3554,6 +3594,11 @@ denodeify@^1.2.1:
|
||||
resolved "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631"
|
||||
integrity sha1-OjYof1A05pnnV3kBBSwubJQlFjE=
|
||||
|
||||
depd@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"
|
||||
integrity sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=
|
||||
|
||||
depd@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
||||
@@ -3751,6 +3796,11 @@ dotenv-expand@4.2.0:
|
||||
resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-4.2.0.tgz#def1f1ca5d6059d24a766e587942c21106ce1275"
|
||||
integrity sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU=
|
||||
|
||||
dotenv@5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "http://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef"
|
||||
integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==
|
||||
|
||||
dotenv@6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.npmjs.org/dotenv/-/dotenv-6.0.0.tgz#24e37c041741c5f4b25324958ebbc34bca965935"
|
||||
@@ -4881,7 +4931,7 @@ fs.realpath@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
|
||||
fsevents@1.2.4, fsevents@^1.2.2, fsevents@^1.2.3:
|
||||
fsevents@1.2.4, fsevents@^1.1.2, fsevents@^1.2.2, fsevents@^1.2.3:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426"
|
||||
integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==
|
||||
@@ -4948,6 +4998,11 @@ get-own-enumerable-property-symbols@^3.0.0:
|
||||
resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203"
|
||||
integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==
|
||||
|
||||
get-port@3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc"
|
||||
integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=
|
||||
|
||||
get-stdin@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b"
|
||||
@@ -5438,6 +5493,16 @@ http-deceiver@^1.2.7:
|
||||
resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
|
||||
integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=
|
||||
|
||||
http-errors@1.6.2:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736"
|
||||
integrity sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=
|
||||
dependencies:
|
||||
depd "1.1.1"
|
||||
inherits "2.0.3"
|
||||
setprototypeof "1.0.3"
|
||||
statuses ">= 1.3.1 < 2"
|
||||
|
||||
http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3:
|
||||
version "1.6.3"
|
||||
resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
|
||||
@@ -5523,6 +5588,11 @@ hyphenate-style-name@^1.0.2:
|
||||
resolved "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b"
|
||||
integrity sha1-MRYKNpMK2vH8BMYHT360FGXU7Es=
|
||||
|
||||
iconv-lite@0.4.19:
|
||||
version "0.4.19"
|
||||
resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
|
||||
integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==
|
||||
|
||||
iconv-lite@0.4.23:
|
||||
version "0.4.23"
|
||||
resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
|
||||
@@ -5766,7 +5836,7 @@ ip-regex@^2.1.0:
|
||||
resolved "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
|
||||
integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=
|
||||
|
||||
ip@^1.1.0, ip@^1.1.5:
|
||||
ip@1.1.5, ip@^1.1.0, ip@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
|
||||
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
|
||||
@@ -6091,7 +6161,7 @@ is-root@2.0.0:
|
||||
resolved "https://registry.npmjs.org/is-root/-/is-root-2.0.0.tgz#838d1e82318144e5a6f77819d90207645acc7019"
|
||||
integrity sha512-F/pJIk8QD6OX5DNhRB7hWamLsUilmkDGho48KbgZ6xg/lmAZXHxzXQ91jzB3yRSw5kdQGGGc4yz8HYhTYIMWPg==
|
||||
|
||||
is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
|
||||
is-stream@1.1.0, is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||
@@ -6740,6 +6810,15 @@ jsesc@~0.5.0:
|
||||
resolved "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
|
||||
integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
|
||||
|
||||
jsome@2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.npmjs.org/jsome/-/jsome-2.5.0.tgz#5e417eef4341ffeb83ee8bfa9265b36d56fe49ed"
|
||||
integrity sha1-XkF+70NB/+uD7ov6kmWzbVb+Se0=
|
||||
dependencies:
|
||||
chalk "^2.3.0"
|
||||
json-stringify-safe "^5.0.1"
|
||||
yargs "^11.0.0"
|
||||
|
||||
json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
|
||||
@@ -6767,7 +6846,7 @@ json-stable-stringify@^1.0.1:
|
||||
dependencies:
|
||||
jsonify "~0.0.0"
|
||||
|
||||
json-stringify-safe@~5.0.1:
|
||||
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||
@@ -7566,6 +7645,36 @@ metro@0.48.3, metro@^0.48.1:
|
||||
xpipe "^1.0.5"
|
||||
yargs "^9.0.0"
|
||||
|
||||
micro-dev@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/micro-dev/-/micro-dev-3.0.0.tgz#cea7ef2b4318765b74004e98ec92ac7e12fcff37"
|
||||
integrity sha512-hxI93KdT7Y8utmVn3NsXqMEKOQj0RpHiY1+PW8rtbiDyd3e/D6NN7OEdG8R0uSFI3GuJbkYN76Z2QTZafyfN/w==
|
||||
dependencies:
|
||||
boxen "1.3.0"
|
||||
chalk "2.4.1"
|
||||
chokidar "2.0.3"
|
||||
clipboardy "1.2.3"
|
||||
debounce "1.1.0"
|
||||
dotenv "5.0.1"
|
||||
get-port "3.2.0"
|
||||
ip "1.1.5"
|
||||
jsome "2.5.0"
|
||||
mri "1.1.1"
|
||||
pkg-up "2.0.0"
|
||||
pretty-error "2.1.1"
|
||||
string-length "2.0.0"
|
||||
|
||||
micro@^9.3.3:
|
||||
version "9.3.3"
|
||||
resolved "https://registry.npmjs.org/micro/-/micro-9.3.3.tgz#32728c7be15e807691ead85da27fd8117a8bca24"
|
||||
integrity sha512-GbCp4NFQguARch0odX+BuWDja2Kc1pbYZqWfRvEDihGFTJG8U77C0L+Owg2j7TPyhQ5Tc+7z/SxspRqjdiZCjQ==
|
||||
dependencies:
|
||||
arg "2.0.0"
|
||||
chalk "2.4.0"
|
||||
content-type "1.0.4"
|
||||
is-stream "1.1.0"
|
||||
raw-body "2.3.2"
|
||||
|
||||
micromatch@^2.3.11:
|
||||
version "2.3.11"
|
||||
resolved "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
|
||||
@@ -7814,6 +7923,11 @@ move-concurrently@^1.0.1:
|
||||
rimraf "^2.5.4"
|
||||
run-queue "^1.0.3"
|
||||
|
||||
mri@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/mri/-/mri-1.1.1.tgz#85aa26d3daeeeedf80dc5984af95cc5ca5cad9f1"
|
||||
integrity sha1-haom09ru7t+A3FmEr5XMXKXK2fE=
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
@@ -9372,7 +9486,7 @@ pretty-bytes@^4.0.2:
|
||||
resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9"
|
||||
integrity sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=
|
||||
|
||||
pretty-error@^2.0.2:
|
||||
pretty-error@2.1.1, pretty-error@^2.0.2:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3"
|
||||
integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=
|
||||
@@ -9594,6 +9708,16 @@ range-parser@1.2.0, range-parser@^1.0.3, range-parser@~1.2.0:
|
||||
resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
|
||||
integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=
|
||||
|
||||
raw-body@2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"
|
||||
integrity sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=
|
||||
dependencies:
|
||||
bytes "3.0.0"
|
||||
http-errors "1.6.2"
|
||||
iconv-lite "0.4.19"
|
||||
unpipe "1.0.0"
|
||||
|
||||
raw-body@2.3.3:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3"
|
||||
@@ -10688,6 +10812,11 @@ setimmediate@^1.0.4, setimmediate@^1.0.5:
|
||||
resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
|
||||
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
|
||||
|
||||
setprototypeof@1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04"
|
||||
integrity sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=
|
||||
|
||||
setprototypeof@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
|
||||
@@ -11040,7 +11169,7 @@ static-extend@^0.1.1:
|
||||
define-property "^0.2.5"
|
||||
object-copy "^0.1.0"
|
||||
|
||||
"statuses@>= 1.4.0 < 2":
|
||||
"statuses@>= 1.3.1 < 2", "statuses@>= 1.4.0 < 2":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
|
||||
@@ -11102,7 +11231,7 @@ string-argv@^0.0.2:
|
||||
resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736"
|
||||
integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY=
|
||||
|
||||
string-length@^2.0.0:
|
||||
string-length@2.0.0, string-length@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed"
|
||||
integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=
|
||||
@@ -11793,7 +11922,7 @@ unzip-response@^2.0.1:
|
||||
resolved "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97"
|
||||
integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=
|
||||
|
||||
upath@^1.0.5:
|
||||
upath@^1.0.0, upath@^1.0.5:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd"
|
||||
integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==
|
||||
|
||||
Reference in New Issue
Block a user