Merge pull request #593 from lbryio/add-chainquery
Implement chainquery within Spee.ch & add initial metrics tracking
This commit is contained in:
commit
a9261e9d14
70 changed files with 13006 additions and 275 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -22,4 +22,4 @@ public/bundle/bundle.js.map
|
|||
public/bundle/Lekton-*
|
||||
public/bundle/style.css
|
||||
|
||||
uploads
|
||||
uploads
|
||||
|
|
8
cli/defaults/chainqueryConfig.json
Normal file
8
cli/defaults/chainqueryConfig.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"host": "localhost",
|
||||
"port": "3306",
|
||||
"timeout": 30,
|
||||
"database": "chainquery",
|
||||
"username": "lbry",
|
||||
"password": "root"
|
||||
}
|
|
@ -2,10 +2,23 @@ import * as actions from '../constants/show_action_types';
|
|||
import { CHANNEL, ASSET_LITE, ASSET_DETAILS } from '../constants/show_request_types';
|
||||
|
||||
// basic request parsing
|
||||
export function onHandleShowPageUri (params) {
|
||||
export function onHandleShowPageUri (params, url) {
|
||||
return {
|
||||
type: actions.HANDLE_SHOW_URI,
|
||||
data: params,
|
||||
data: {
|
||||
...params,
|
||||
url,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function onHandleShowHomepage (params, url) {
|
||||
return {
|
||||
type: actions.HANDLE_SHOW_HOMEPAGE,
|
||||
data: {
|
||||
...params,
|
||||
url,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
6
client/src/api/homepageApi.js
Normal file
6
client/src/api/homepageApi.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
import Request from '../utils/request';
|
||||
|
||||
export function getHomepageChannelsData (host, name, id) {
|
||||
const url = `${host}/api/homepage/data/channels`;
|
||||
return Request(url);
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
// request actions
|
||||
export const HANDLE_SHOW_URI = 'HANDLE_SHOW_URI';
|
||||
export const HANDLE_SHOW_HOMEPAGE = 'HANDLE_SHOW_HOMEPAGE';
|
||||
export const REQUEST_ERROR = 'REQUEST_ERROR';
|
||||
export const REQUEST_UPDATE = 'REQUEST_UPDATE';
|
||||
export const ASSET_REQUEST_NEW = 'ASSET_REQUEST_NEW';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { onHandleShowPageUri } from '../../actions/show';
|
||||
import { onHandleShowHomepage } from '../../actions/show';
|
||||
import View from './view';
|
||||
|
||||
const mapStateToProps = ({ show, site, channel }) => {
|
||||
|
@ -11,7 +11,7 @@ const mapStateToProps = ({ show, site, channel }) => {
|
|||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
onHandleShowPageUri,
|
||||
onHandleShowHomepage,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(View);
|
||||
|
|
|
@ -4,6 +4,16 @@ import PublishTool from '@containers/PublishTool';
|
|||
import ContentPageWrapper from '@pages/ContentPageWrapper';
|
||||
|
||||
class HomePage extends React.Component {
|
||||
componentDidMount () {
|
||||
this.props.onHandleShowHomepage(this.props.match.params);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (nextProps.match.params !== this.props.match.params) {
|
||||
this.props.onHandleShowHomepage(nextProps.match.params);
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { homeChannel } = this.props;
|
||||
return homeChannel ? (
|
||||
|
|
|
@ -7,7 +7,7 @@ import { selectSiteHost } from '../selectors/site';
|
|||
|
||||
function * retrieveFile (action) {
|
||||
const name = action.data.name;
|
||||
const claimId = action.data.claimId;
|
||||
const claimId = action.data.claim_id || action.data.claimId;
|
||||
const host = yield select(selectSiteHost);
|
||||
// see if the file is available
|
||||
let isAvailable;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { all } from 'redux-saga/effects';
|
||||
import { watchHandleShowPageUri } from './show_uri';
|
||||
import { watchHandleShowPageUri, watchHandleShowHomepage } from './show_uri';
|
||||
import { watchNewAssetRequest } from './show_asset';
|
||||
import { watchNewChannelRequest, watchUpdateChannelClaims } from './show_channel';
|
||||
import { watchFileIsRequested } from './file';
|
||||
|
@ -13,6 +13,7 @@ import { watchChannelLogout } from './logoutChannel';
|
|||
export function * rootSaga () {
|
||||
yield all([
|
||||
watchHandleShowPageUri(),
|
||||
watchHandleShowHomepage(),
|
||||
watchNewAssetRequest(),
|
||||
watchNewChannelRequest(),
|
||||
watchUpdateChannelClaims(),
|
||||
|
|
|
@ -22,6 +22,7 @@ function * parseAndUpdateIdentifierAndClaim (modifier, claim) {
|
|||
};
|
||||
yield call(newAssetRequest, onNewAssetRequest(claimName, claimId, null, null, extension));
|
||||
}
|
||||
|
||||
function * parseAndUpdateClaimOnly (claim) {
|
||||
// this could be a request for an asset or a channel page
|
||||
// claim could be an asset claim or a channel claim
|
||||
|
@ -50,10 +51,24 @@ export function * handleShowPageUri (action) {
|
|||
const { identifier, claim } = action.data;
|
||||
if (identifier) {
|
||||
return yield call(parseAndUpdateIdentifierAndClaim, identifier, claim);
|
||||
} else if (claim) {
|
||||
yield call(parseAndUpdateClaimOnly, claim);
|
||||
}
|
||||
};
|
||||
|
||||
export function * handleShowPageHomepage (action) {
|
||||
const { identifier, claim } = action.data;
|
||||
if (identifier) {
|
||||
return yield call(parseAndUpdateIdentifierAndClaim, identifier, claim);
|
||||
} else if (claim) {
|
||||
yield call(parseAndUpdateClaimOnly, claim);
|
||||
}
|
||||
yield call(parseAndUpdateClaimOnly, claim);
|
||||
};
|
||||
|
||||
export function * watchHandleShowPageUri () {
|
||||
yield takeLatest(actions.HANDLE_SHOW_URI, handleShowPageUri);
|
||||
};
|
||||
|
||||
export function * watchHandleShowHomepage () {
|
||||
yield takeLatest(actions.HANDLE_SHOW_HOMEPAGE, handleShowPageHomepage);
|
||||
};
|
||||
|
|
724
package-lock.json
generated
724
package-lock.json
generated
|
@ -908,6 +908,12 @@
|
|||
"integrity": "sha512-EIjmpvnHj+T4nMcKwHwxZKUfDmphIKJc2qnEMhSoOvr1lYEQpuRKRz8orWr//krYIIArS/KGGLfL2YGVUYXmIA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/estree": {
|
||||
"version": "0.0.39",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
|
||||
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/geojson": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-1.0.6.tgz",
|
||||
|
@ -984,6 +990,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
|
||||
"integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es6-promisify": "5.0.0"
|
||||
}
|
||||
},
|
||||
"ajv": {
|
||||
"version": "5.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
|
||||
|
@ -1079,6 +1094,12 @@
|
|||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"dev": true
|
||||
},
|
||||
"arch": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz",
|
||||
"integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==",
|
||||
"dev": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
|
||||
|
@ -1238,6 +1259,20 @@
|
|||
"integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
|
||||
"dev": true
|
||||
},
|
||||
"async-hook-jl": {
|
||||
"version": "1.7.6",
|
||||
"resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz",
|
||||
"integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==",
|
||||
"requires": {
|
||||
"stack-chain": "1.3.7"
|
||||
}
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
|
||||
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
|
||||
"dev": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
|
@ -1914,6 +1949,16 @@
|
|||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
|
||||
"integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU="
|
||||
},
|
||||
"bl": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
|
||||
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "2.3.6",
|
||||
"safe-buffer": "5.1.2"
|
||||
}
|
||||
},
|
||||
"block-stream": {
|
||||
"version": "0.0.9",
|
||||
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
|
||||
|
@ -2131,6 +2176,35 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"buffer-alloc": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
|
||||
"integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-alloc-unsafe": "1.1.0",
|
||||
"buffer-fill": "1.0.0"
|
||||
}
|
||||
},
|
||||
"buffer-alloc-unsafe": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
|
||||
"integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
|
||||
"dev": true
|
||||
},
|
||||
"buffer-crc32": {
|
||||
"version": "0.2.13",
|
||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"buffer-fill": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
|
||||
"integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
|
||||
"dev": true
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
|
@ -2545,6 +2619,33 @@
|
|||
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
|
||||
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk="
|
||||
},
|
||||
"clipboardy": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz",
|
||||
"integrity": "sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arch": "2.1.1",
|
||||
"execa": "0.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"execa": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz",
|
||||
"integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cross-spawn": "5.1.0",
|
||||
"get-stream": "3.0.0",
|
||||
"is-stream": "1.1.0",
|
||||
"npm-run-path": "2.0.2",
|
||||
"p-finally": "1.0.0",
|
||||
"signal-exit": "3.0.2",
|
||||
"strip-eof": "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
|
||||
|
@ -2597,6 +2698,16 @@
|
|||
"shimmer": "1.2.0"
|
||||
}
|
||||
},
|
||||
"cls-hooked": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz",
|
||||
"integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==",
|
||||
"requires": {
|
||||
"async-hook-jl": "1.7.6",
|
||||
"emitter-listener": "1.1.1",
|
||||
"semver": "5.5.1"
|
||||
}
|
||||
},
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||
|
@ -3161,6 +3272,138 @@
|
|||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
|
||||
},
|
||||
"decompress": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz",
|
||||
"integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"decompress-tar": "4.1.1",
|
||||
"decompress-tarbz2": "4.1.1",
|
||||
"decompress-targz": "4.1.1",
|
||||
"decompress-unzip": "4.0.1",
|
||||
"graceful-fs": "4.1.11",
|
||||
"make-dir": "1.3.0",
|
||||
"pify": "2.3.0",
|
||||
"strip-dirs": "2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"decompress-tar": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
|
||||
"integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"file-type": "5.2.0",
|
||||
"is-stream": "1.1.0",
|
||||
"tar-stream": "1.6.1"
|
||||
}
|
||||
},
|
||||
"decompress-tarbz2": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
|
||||
"integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"decompress-tar": "4.1.1",
|
||||
"file-type": "6.2.0",
|
||||
"is-stream": "1.1.0",
|
||||
"seek-bzip": "1.0.5",
|
||||
"unbzip2-stream": "1.2.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"file-type": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
|
||||
"integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"decompress-targz": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
|
||||
"integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"decompress-tar": "4.1.1",
|
||||
"file-type": "5.2.0",
|
||||
"is-stream": "1.1.0"
|
||||
}
|
||||
},
|
||||
"decompress-unzip": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
|
||||
"integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"file-type": "3.9.0",
|
||||
"get-stream": "2.3.1",
|
||||
"pify": "2.3.0",
|
||||
"yauzl": "2.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"fd-slicer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"pend": "1.2.0"
|
||||
}
|
||||
},
|
||||
"file-type": {
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
|
||||
"integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
|
||||
"integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"object-assign": "4.1.1",
|
||||
"pinkie-promise": "2.0.1"
|
||||
}
|
||||
},
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yauzl": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
|
||||
"integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"buffer-crc32": "0.2.13",
|
||||
"fd-slicer": "1.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"deep-eql": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
|
||||
|
@ -3415,6 +3658,14 @@
|
|||
"minimalistic-crypto-utils": "1.0.1"
|
||||
}
|
||||
},
|
||||
"emitter-listener": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.1.tgz",
|
||||
"integrity": "sha1-6Lu+gkS8jg0LTvcc0UKUx/JBx+w=",
|
||||
"requires": {
|
||||
"shimmer": "1.2.0"
|
||||
}
|
||||
},
|
||||
"emojis-list": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
|
||||
|
@ -3433,6 +3684,15 @@
|
|||
"iconv-lite": "0.4.23"
|
||||
}
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "1.4.0"
|
||||
}
|
||||
},
|
||||
"enhanced-resolve": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz",
|
||||
|
@ -3517,6 +3777,23 @@
|
|||
"event-emitter": "0.3.5"
|
||||
}
|
||||
},
|
||||
"es6-promisify": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
|
||||
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es6-promise": "4.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"es6-promise": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
|
||||
"integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"es6-set": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
|
||||
|
@ -4114,6 +4391,14 @@
|
|||
"promise": "7.3.1"
|
||||
}
|
||||
},
|
||||
"express-http-context": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/express-http-context/-/express-http-context-1.1.0.tgz",
|
||||
"integrity": "sha512-LS47HseitRIxzBHDEQrlVwZkEkMaViM+nhRCrlWYxPNIu7W8KUZyNUOxiD93OghHesl7y+DhBYuz3yfaNHDvVA==",
|
||||
"requires": {
|
||||
"cls-hooked": "4.2.2"
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
|
@ -4235,6 +4520,29 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"extract-zip": {
|
||||
"version": "1.6.7",
|
||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
|
||||
"integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"concat-stream": "1.6.2",
|
||||
"debug": "2.6.9",
|
||||
"mkdirp": "0.5.1",
|
||||
"yauzl": "2.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
|
@ -4353,6 +4661,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"file-type": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
|
||||
"integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
|
||||
"dev": true
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
||||
|
@ -4522,6 +4836,18 @@
|
|||
"integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
|
||||
"dev": true
|
||||
},
|
||||
"fs-constants": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
||||
"dev": true
|
||||
},
|
||||
"fs-copy-file-sync": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fs-copy-file-sync/-/fs-copy-file-sync-1.1.1.tgz",
|
||||
"integrity": "sha512-2QY5eeqVv4m2PfyMiEuy9adxNP+ajf+8AR05cEi+OAzPcOj90hvFImeZhTmKLBgSd9EvG33jsD7ZRxsx9dThkQ==",
|
||||
"dev": true
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
|
||||
|
@ -5280,6 +5606,13 @@
|
|||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
|
||||
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
|
||||
},
|
||||
"graceful-readlink": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
|
||||
"integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"growl": {
|
||||
"version": "1.10.5",
|
||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
|
||||
|
@ -5553,6 +5886,16 @@
|
|||
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
|
||||
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM="
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
|
||||
"integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"agent-base": "4.2.1",
|
||||
"debug": "3.1.0"
|
||||
}
|
||||
},
|
||||
"husky": {
|
||||
"version": "0.14.3",
|
||||
"resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz",
|
||||
|
@ -5899,6 +6242,13 @@
|
|||
"ip-regex": "2.1.0"
|
||||
}
|
||||
},
|
||||
"is-natural-number": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
|
||||
"integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"is-npm": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
|
||||
|
@ -6030,11 +6380,43 @@
|
|||
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
|
||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
|
||||
},
|
||||
"is-wsl": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
|
||||
"integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
|
||||
"dev": true
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||
},
|
||||
"isbinaryfile": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz",
|
||||
"integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-alloc": "1.2.0"
|
||||
}
|
||||
},
|
||||
"isemail": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/isemail/-/isemail-3.1.3.tgz",
|
||||
"integrity": "sha512-5xbsG5wYADIcB+mfLsd+nst1V/D+I7EU7LEZPo2GOIMu4JzfcRs5yQoypP4avA7QtUqgxYLKBYNv4IdzBmbhdw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "2.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
|
@ -6059,6 +6441,25 @@
|
|||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"joi": {
|
||||
"version": "13.7.0",
|
||||
"resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz",
|
||||
"integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"hoek": "5.0.4",
|
||||
"isemail": "3.1.3",
|
||||
"topo": "3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"hoek": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz",
|
||||
"integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"js-base64": {
|
||||
"version": "2.4.9",
|
||||
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz",
|
||||
|
@ -6867,6 +7268,46 @@
|
|||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
||||
"dev": true
|
||||
},
|
||||
"ndb": {
|
||||
"version": "1.0.24",
|
||||
"resolved": "https://registry.npmjs.org/ndb/-/ndb-1.0.24.tgz",
|
||||
"integrity": "sha512-GS72oSI/jrI+A/hh+qmGPPav/2+qLeup0txS3SbnFBKkH0KD/WXZhvmTO4LlEXOSV23v7x62EnqcQkrnCk2ZTA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chokidar": "2.0.4",
|
||||
"clipboardy": "1.2.3",
|
||||
"fs-copy-file-sync": "1.1.1",
|
||||
"isbinaryfile": "3.0.3",
|
||||
"mime": "2.3.1",
|
||||
"ndb-node-pty-prebuilt": "0.8.0",
|
||||
"opn": "5.3.0",
|
||||
"puppeteer": "1.6.1",
|
||||
"rimraf": "2.6.2",
|
||||
"update-notifier": "2.5.0",
|
||||
"ws": "6.0.0",
|
||||
"xterm": "3.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"mime": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
|
||||
"integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"ndb-node-pty-prebuilt": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/ndb-node-pty-prebuilt/-/ndb-node-pty-prebuilt-0.8.0.tgz",
|
||||
"integrity": "sha512-j3XcGQgISib600/12hz56jaFsmpmDdFOKMHRq94+aWkxk0LqoPM5yAeJwacaPLnGm2NRFC3gTUocTIS+GSmQDQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"decompress": "4.2.0",
|
||||
"decompress-targz": "4.1.1",
|
||||
"nan": "2.10.0"
|
||||
}
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
|
||||
|
@ -10049,6 +10490,15 @@
|
|||
"mimic-fn": "1.2.0"
|
||||
}
|
||||
},
|
||||
"opn": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz",
|
||||
"integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-wsl": "1.1.0"
|
||||
}
|
||||
},
|
||||
"optimist": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
|
||||
|
@ -10933,6 +11383,12 @@
|
|||
"ipaddr.js": "1.8.0"
|
||||
}
|
||||
},
|
||||
"proxy-from-env": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
|
||||
"integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=",
|
||||
"dev": true
|
||||
},
|
||||
"prr": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
|
||||
|
@ -10984,6 +11440,39 @@
|
|||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
|
||||
},
|
||||
"puppeteer": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.6.1.tgz",
|
||||
"integrity": "sha512-qz6DLwK+PhlBMjJZOMOsgVCnweYLtmiqnmJYUDPT++ElMz+cQgbsCNKPw4YDVpg3RTbsRX/pqQqr20zrp0cuKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "3.1.0",
|
||||
"extract-zip": "1.6.7",
|
||||
"https-proxy-agent": "2.2.1",
|
||||
"mime": "2.3.1",
|
||||
"progress": "2.0.0",
|
||||
"proxy-from-env": "1.0.0",
|
||||
"rimraf": "2.6.2",
|
||||
"ws": "5.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"mime": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
|
||||
"integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
|
||||
"dev": true
|
||||
},
|
||||
"ws": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
|
||||
"integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"async-limiter": "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"q": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
|
||||
|
@ -11617,6 +12106,16 @@
|
|||
"inherits": "2.0.3"
|
||||
}
|
||||
},
|
||||
"rollup": {
|
||||
"version": "0.66.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-0.66.2.tgz",
|
||||
"integrity": "sha512-+rOLjWO170M3Y2jyyGU4ZJuTu1T1KuKNyH+RszHRzQdsuI5TulRbkSM4vlaMnwcxHm4XdgBNZ1mmNzhQIImbiQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/estree": "0.0.39",
|
||||
"@types/node": "10.9.4"
|
||||
}
|
||||
},
|
||||
"run-async": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
|
||||
|
@ -11625,6 +12124,12 @@
|
|||
"is-promise": "2.1.0"
|
||||
}
|
||||
},
|
||||
"rx": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
|
||||
"integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=",
|
||||
"dev": true
|
||||
},
|
||||
"rx-lite": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
|
||||
|
@ -11909,6 +12414,28 @@
|
|||
"source-map": "0.4.4"
|
||||
}
|
||||
},
|
||||
"seek-bzip": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz",
|
||||
"integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"commander": "2.8.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
|
||||
"integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"graceful-readlink": "1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz",
|
||||
|
@ -12442,6 +12969,11 @@
|
|||
"tweetnacl": "0.14.5"
|
||||
}
|
||||
},
|
||||
"stack-chain": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz",
|
||||
"integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU="
|
||||
},
|
||||
"stack-trace": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
||||
|
@ -12546,6 +13078,16 @@
|
|||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
|
||||
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM="
|
||||
},
|
||||
"strip-dirs": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz",
|
||||
"integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"is-natural-number": "4.0.1"
|
||||
}
|
||||
},
|
||||
"strip-eof": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
|
||||
|
@ -12717,6 +13259,21 @@
|
|||
"inherits": "2.0.3"
|
||||
}
|
||||
},
|
||||
"tar-stream": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz",
|
||||
"integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bl": "1.2.2",
|
||||
"buffer-alloc": "1.2.0",
|
||||
"end-of-stream": "1.4.1",
|
||||
"fs-constants": "1.0.0",
|
||||
"readable-stream": "2.3.6",
|
||||
"to-buffer": "1.1.1",
|
||||
"xtend": "4.0.1"
|
||||
}
|
||||
},
|
||||
"term-size": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
|
||||
|
@ -12806,6 +13363,12 @@
|
|||
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
|
||||
"integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M="
|
||||
},
|
||||
"to-buffer": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
|
||||
"integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
|
||||
"dev": true
|
||||
},
|
||||
"to-fast-properties": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||
|
@ -12840,6 +13403,23 @@
|
|||
"repeat-string": "1.6.1"
|
||||
}
|
||||
},
|
||||
"topo": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/topo/-/topo-3.0.0.tgz",
|
||||
"integrity": "sha512-Tlu1fGlR90iCdIPURqPiufqAlCZYzLjHYVVbcFWDMcX7+tK8hdZWAfsMrD/pBul9jqHHwFjNdf1WaxA9vTRRhw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"hoek": "5.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"hoek": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz",
|
||||
"integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"toposort-class": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz",
|
||||
|
@ -13021,6 +13601,45 @@
|
|||
"resolve": "1.8.1"
|
||||
}
|
||||
},
|
||||
"unbzip2-stream": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz",
|
||||
"integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"buffer": "3.6.0",
|
||||
"through": "2.3.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"base64-js": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
|
||||
"integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"buffer": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "http://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz",
|
||||
"integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"base64-js": "0.0.8",
|
||||
"ieee754": "1.1.12",
|
||||
"isarray": "1.0.0"
|
||||
}
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"undefsafe": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
|
||||
|
@ -13387,6 +14006,87 @@
|
|||
"indexof": "0.0.1"
|
||||
}
|
||||
},
|
||||
"wait-on": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.1.0.tgz",
|
||||
"integrity": "sha512-yjYwMvnOhA3PTghvzPQAmT2TSVvBMbOdBRRjMPfBD6FU5si/PkAsI8P3X5sh9ntkYjZvPQLpQRpDUyax5h4COg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-js": "2.5.7",
|
||||
"joi": "13.7.0",
|
||||
"minimist": "1.2.0",
|
||||
"request": "2.88.0",
|
||||
"rx": "4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "2.5.7",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
|
||||
"integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==",
|
||||
"dev": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz",
|
||||
"integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "5.5.2",
|
||||
"har-schema": "2.0.0"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
||||
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aws-sign2": "0.7.0",
|
||||
"aws4": "1.8.0",
|
||||
"caseless": "0.12.0",
|
||||
"combined-stream": "1.0.6",
|
||||
"extend": "3.0.2",
|
||||
"forever-agent": "0.6.1",
|
||||
"form-data": "2.3.2",
|
||||
"har-validator": "5.1.0",
|
||||
"http-signature": "1.2.0",
|
||||
"is-typedarray": "1.0.0",
|
||||
"isstream": "0.1.2",
|
||||
"json-stringify-safe": "5.0.1",
|
||||
"mime-types": "2.1.20",
|
||||
"oauth-sign": "0.9.0",
|
||||
"performance-now": "2.1.0",
|
||||
"qs": "6.5.2",
|
||||
"safe-buffer": "5.1.2",
|
||||
"tough-cookie": "2.4.3",
|
||||
"tunnel-agent": "0.6.0",
|
||||
"uuid": "3.3.2"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
|
||||
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"psl": "1.1.29",
|
||||
"punycode": "1.4.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"warning": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.2.tgz",
|
||||
|
@ -13730,6 +14430,15 @@
|
|||
"signal-exit": "3.0.2"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.0.0.tgz",
|
||||
"integrity": "sha512-c2UlYcAZp1VS8AORtpq6y4RJIkJ9dQz18W32SpR/qXGfLDZ2jU4y4wKvvZwqbi7U6gxFQTeE+urMbXU/tsDy4w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"async-limiter": "1.0.0"
|
||||
}
|
||||
},
|
||||
"x-xss-protection": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.1.0.tgz",
|
||||
|
@ -13746,6 +14455,12 @@
|
|||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
||||
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
|
||||
},
|
||||
"xterm": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/xterm/-/xterm-3.6.0.tgz",
|
||||
"integrity": "sha512-D/7/fm7oGzZksLFQdpn1TD63V+T4Ad3LZR2JfZ1QrPZ1yDjKedIKWAZXgzeHQw8S/5HYD08GdkLnjeLm/e6Yog==",
|
||||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
|
@ -13781,6 +14496,15 @@
|
|||
"integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
|
||||
}
|
||||
}
|
||||
},
|
||||
"yauzl": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
|
||||
"integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fd-slicer": "1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
package.json
10
package.json
|
@ -15,6 +15,10 @@
|
|||
"prestart": "builder run bundle",
|
||||
"start": "node server.js",
|
||||
"start:build": "builder run start",
|
||||
"chainquery:build": "rollup ./server/chainquery/index.js --file ./server/chainquery/bundle.js --format cjs",
|
||||
"devtools:server": "ndb server.js",
|
||||
"devtools:chainquery": "npm run devtools:chainquery:build && ndb ./server/chainquery/bundle.debug.js",
|
||||
"devtools:chainquery:build": "rollup ./server/chainquery/index.debug.js --file ./server/chainquery/bundle.debug.js --format cjs",
|
||||
"test": "mocha --recursive",
|
||||
"test:no-lbc": "npm test -- --grep @usesLbc --invert",
|
||||
"test:server": "mocha --recursive './server/**/*.test.js'",
|
||||
|
@ -50,6 +54,7 @@
|
|||
"cookie-session": "^2.0.0-beta.3",
|
||||
"express": "^4.15.2",
|
||||
"express-handlebars": "^3.0.0",
|
||||
"express-http-context": "^1.1.0",
|
||||
"get-video-dimensions": "^1.0.0",
|
||||
"helmet": "^3.13.0",
|
||||
"image-size": "^0.6.3",
|
||||
|
@ -108,13 +113,16 @@
|
|||
"file-loader": "^1.1.11",
|
||||
"husky": "^0.14.3",
|
||||
"mocha": "^5.2.0",
|
||||
"ndb": "^1.0.24",
|
||||
"node-sass": "^4.9.3",
|
||||
"nodemon": "^1.17.5",
|
||||
"redux-devtools": "^3.4.1",
|
||||
"regenerator-transform": "^0.13.0",
|
||||
"rollup": "^0.66.2",
|
||||
"sass-loader": "^7.1.0",
|
||||
"sequelize-cli": "^4.0.0",
|
||||
"style-loader": "^0.21.0",
|
||||
"url-loader": "^1.0.1"
|
||||
"url-loader": "^1.0.1",
|
||||
"wait-on": "^3.1.0"
|
||||
}
|
||||
}
|
||||
|
|
1116
server/chainquery/bundle.debug.js
Normal file
1116
server/chainquery/bundle.debug.js
Normal file
File diff suppressed because it is too large
Load diff
1123
server/chainquery/bundle.js
Normal file
1123
server/chainquery/bundle.js
Normal file
File diff suppressed because it is too large
Load diff
7
server/chainquery/index.debug.js
Normal file
7
server/chainquery/index.debug.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
console.log('Loading `chainquery`, please wait...')
|
||||
|
||||
import chainquery from './index'
|
||||
|
||||
global.chainquery = chainquery.default ? chainquery.default : chainquery;
|
||||
|
||||
console.log('`chainquery` has been loaded into the global context.')
|
123
server/chainquery/index.js
Normal file
123
server/chainquery/index.js
Normal file
|
@ -0,0 +1,123 @@
|
|||
const Sequelize = require('sequelize');
|
||||
const logger = require('winston');
|
||||
|
||||
import abnormalClaimTable from './tables/abnormalClaimTable';
|
||||
import addressTable from './tables/addressTable';
|
||||
import blockTable from './tables/blockTable';
|
||||
import claimTable from './tables/claimTable';
|
||||
import inputTable from './tables/inputTable';
|
||||
import outputTable from './tables/outputTable';
|
||||
import supportTable from './tables/supportTable';
|
||||
import transactionAddressTable from './tables/transactionAddressTable';
|
||||
import transactionTable from './tables/transactionTable';
|
||||
|
||||
import abnormalClaimQueries from './queries/abnormalClaimQueries';
|
||||
import addressQueries from './queries/addressQueries';
|
||||
import blockQueries from './queries/blockQueries';
|
||||
import claimQueries from './queries/claimQueries';
|
||||
import inputQueries from './queries/inputQueries';
|
||||
import outputQueries from './queries/outputQueries';
|
||||
import supportQueries from './queries/supportQueries';
|
||||
import transactionAddressQueries from './queries/transactionAddressQueries';
|
||||
import transactionQueries from './queries/transactionQueries';
|
||||
|
||||
const DATABASE_STRUCTURE = {
|
||||
'abnormal_claim': {
|
||||
table: abnormalClaimTable,
|
||||
queries: abnormalClaimQueries,
|
||||
},
|
||||
'address': {
|
||||
table: addressTable,
|
||||
queries: addressQueries,
|
||||
},
|
||||
'block': {
|
||||
table: blockTable,
|
||||
queries: blockQueries,
|
||||
},
|
||||
'claim': {
|
||||
table: claimTable,
|
||||
queries: claimQueries,
|
||||
},
|
||||
'input': {
|
||||
table: inputTable,
|
||||
queries: inputQueries,
|
||||
},
|
||||
'output': {
|
||||
table: outputTable,
|
||||
queries: outputQueries,
|
||||
},
|
||||
'support': {
|
||||
table: supportTable,
|
||||
queries: supportQueries,
|
||||
},
|
||||
'transaction_address': {
|
||||
table: transactionAddressTable,
|
||||
queries: transactionAddressQueries,
|
||||
},
|
||||
'transaction': {
|
||||
table: transactionTable,
|
||||
queries: transactionQueries,
|
||||
},
|
||||
};
|
||||
|
||||
const {
|
||||
host,
|
||||
port,
|
||||
database,
|
||||
username,
|
||||
password,
|
||||
} = require('../../config/chainqueryConfig'); // TODO: Make '@config/siteConfig' work outside Webpack for testing/dev
|
||||
|
||||
if (!database || !username || !password) {
|
||||
logger.warn('missing database, user, or password from chainqueryConfig');
|
||||
}
|
||||
|
||||
// set sequelize options
|
||||
const sequelize = new Sequelize(database, username, password, {
|
||||
host : host,
|
||||
import : port,
|
||||
dialect : 'mysql',
|
||||
dialectOptions: {
|
||||
decimalNumbers: true,
|
||||
},
|
||||
logging: false,
|
||||
pool : {
|
||||
max : 5,
|
||||
min : 0,
|
||||
idle : 10000,
|
||||
acquire: 10000,
|
||||
},
|
||||
operatorsAliases: false,
|
||||
});
|
||||
|
||||
const db = {};
|
||||
const DATABASE_STRUCTURE_KEYS = Object.keys(DATABASE_STRUCTURE);
|
||||
|
||||
for(let i = 0; i < DATABASE_STRUCTURE_KEYS.length; i++) {
|
||||
let dbKey = DATABASE_STRUCTURE_KEYS[i];
|
||||
let currentData = DATABASE_STRUCTURE[dbKey];
|
||||
|
||||
db[dbKey] = currentData.table.createModel(sequelize, Sequelize);
|
||||
db[dbKey].queries = currentData.queries(db, db[dbKey], sequelize);
|
||||
}
|
||||
|
||||
// run model.association for each model in the db object that has an association
|
||||
logger.info('associating chainquery db models...');
|
||||
DATABASE_STRUCTURE_KEYS.forEach(modelName => {
|
||||
if (db[modelName].associate) {
|
||||
logger.info('Associating chainquery model:', modelName);
|
||||
db[modelName].associate(db);
|
||||
}
|
||||
});
|
||||
|
||||
// establish mysql connection
|
||||
sequelize
|
||||
.authenticate()
|
||||
.then(() => {
|
||||
logger.info('Sequelize has established mysql connection for chainquery successfully.');
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error('Sequelize was unable to connect to the chainquery database:', err);
|
||||
});
|
||||
|
||||
export default db;
|
70
server/chainquery/models/AbnormalClaimModel.js
Normal file
70
server/chainquery/models/AbnormalClaimModel.js
Normal file
|
@ -0,0 +1,70 @@
|
|||
const getterMethods = {
|
||||
// Add as needed, prefix all methods with `generated`
|
||||
}
|
||||
|
||||
export default (sequelize, {
|
||||
BOOLEAN,
|
||||
DATE,
|
||||
DECIMAL,
|
||||
INTEGER,
|
||||
STRING,
|
||||
TEXT,
|
||||
}) => sequelize.define(
|
||||
'abnormal_claim',
|
||||
{
|
||||
id: {
|
||||
primaryKey: true,
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
name: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
claim_id: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
is_update: {
|
||||
type: BOOLEAN,
|
||||
set() { },
|
||||
},
|
||||
block_hash: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
transaction_hash: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
vout: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
output_id: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
value_as_hex: {
|
||||
type: TEXT,
|
||||
set() { },
|
||||
},
|
||||
value_as_json: {
|
||||
type: TEXT,
|
||||
set() { },
|
||||
},
|
||||
created_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
modified_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
},
|
||||
{
|
||||
freezeTableName: true,
|
||||
//getterMethods,
|
||||
timestamps: false, // don't use default timestamps columns
|
||||
}
|
||||
);
|
42
server/chainquery/models/AddressModel.js
Normal file
42
server/chainquery/models/AddressModel.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
const getterMethods = {
|
||||
// Add as needed, prefix all methods with `generated`
|
||||
}
|
||||
|
||||
export default (sequelize, {
|
||||
BOOLEAN,
|
||||
DATE,
|
||||
DECIMAL,
|
||||
INTEGER,
|
||||
STRING,
|
||||
TEXT,
|
||||
}) => sequelize.define(
|
||||
'address',
|
||||
{
|
||||
id: {
|
||||
primaryKey: true,
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
address: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
first_seen: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
created_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
modified_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
},
|
||||
{
|
||||
freezeTableName: true,
|
||||
//getterMethods,
|
||||
timestamps: false, // don't use default timestamps columns
|
||||
}
|
||||
);
|
102
server/chainquery/models/BlockModel.js
Normal file
102
server/chainquery/models/BlockModel.js
Normal file
|
@ -0,0 +1,102 @@
|
|||
const getterMethods = {
|
||||
// Add as needed, prefix all methods with `generated`
|
||||
}
|
||||
|
||||
export default (sequelize, {
|
||||
BOOLEAN,
|
||||
DATE,
|
||||
DECIMAL,
|
||||
INTEGER,
|
||||
STRING,
|
||||
TEXT,
|
||||
}) => sequelize.define(
|
||||
'block',
|
||||
{
|
||||
id: {
|
||||
primaryKey: true,
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
bits: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
chainwork: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
confirmations: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
difficulty: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
hash: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
height: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
merkle_root: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
name_claim_root: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
nonce: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
previous_block_hash: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
next_block_hash: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
block_size: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
block_time: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
version: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
version_hex: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
transaction_hashes: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
transactions_processed: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
created_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
modified_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
},
|
||||
{
|
||||
freezeTableName: true,
|
||||
//getterMethods,
|
||||
timestamps: false, // don't use default timestamps columns
|
||||
}
|
||||
);
|
171
server/chainquery/models/ClaimModel.js
Normal file
171
server/chainquery/models/ClaimModel.js
Normal file
|
@ -0,0 +1,171 @@
|
|||
const logger = require('winston');
|
||||
|
||||
const {
|
||||
assetDefaults: { thumbnail: defaultThumbnail },
|
||||
details: { host }
|
||||
} = require('../../config/siteConfig'); // TODO: Fix paths for rollup
|
||||
|
||||
const getterMethods = {
|
||||
generated_extension() {
|
||||
switch (this.content_type) {
|
||||
case 'image/jpeg':
|
||||
case 'image/jpg':
|
||||
return 'jpg';
|
||||
case 'image/png':
|
||||
return 'png';
|
||||
case 'image/gif':
|
||||
return 'gif';
|
||||
case 'video/mp4':
|
||||
return 'mp4';
|
||||
default:
|
||||
logger.debug('setting unknown file type as file extension jpg');
|
||||
return 'jpg';
|
||||
}
|
||||
},
|
||||
|
||||
// TODO: Factor this out.
|
||||
generated_thumbnail() {
|
||||
return this.thumbnail_url || defaultThumbnail;
|
||||
},
|
||||
|
||||
generated_channel() {
|
||||
console.log(this);
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
export default (sequelize, {
|
||||
BOOLEAN,
|
||||
DATE,
|
||||
DECIMAL,
|
||||
ENUM,
|
||||
INTEGER,
|
||||
STRING,
|
||||
TEXT,
|
||||
}) => sequelize.define(
|
||||
'claim',
|
||||
{
|
||||
id: {
|
||||
primaryKey: true,
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
transaction_hash_id: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
vout: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
name: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
claim_id: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
claim_type: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
publisher_id: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
publisher_sig: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
certificate: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
sd_hash: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
transaction_time: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
version: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
valid_at_height: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
height: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
effective_amount: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
author: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
description: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
content_type: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
is_nsfw: {
|
||||
type: BOOLEAN,
|
||||
set() { },
|
||||
},
|
||||
language: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
thumbnail_url: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
title: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
fee: {
|
||||
type: DECIMAL(58, 8),
|
||||
set() { },
|
||||
},
|
||||
fee_currency: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
bid_state: {
|
||||
type: ENUM('Active', 'Expired', 'Controlling', 'Spent', 'Accepted'),
|
||||
set() { },
|
||||
},
|
||||
created_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
modified_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
fee_address: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
claim_address: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
},
|
||||
{
|
||||
freezeTableName: true,
|
||||
getterMethods,
|
||||
timestamps: false, // don't use default timestamps columns
|
||||
}
|
||||
);
|
82
server/chainquery/models/InputModel.js
Normal file
82
server/chainquery/models/InputModel.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
const getterMethods = {
|
||||
// Add as needed, prefix all methods with `generated`
|
||||
}
|
||||
|
||||
export default (sequelize, {
|
||||
BOOLEAN,
|
||||
DATE,
|
||||
DECIMAL,
|
||||
INTEGER,
|
||||
STRING,
|
||||
TEXT,
|
||||
}) => sequelize.define(
|
||||
'input',
|
||||
{
|
||||
id: {
|
||||
primaryKey: true,
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
transaction_id: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
transaction_hash: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
input_address_id: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
is_coinbase: {
|
||||
type: BOOLEAN,
|
||||
set() { },
|
||||
},
|
||||
coinbase: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
prevout_hash: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
prevout_n: {
|
||||
type: INTEGER.UNSIGNED,
|
||||
set() { },
|
||||
},
|
||||
prevout_spend_updated: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
sequence: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
value: {
|
||||
type: DECIMAL(18, 8),
|
||||
set() { },
|
||||
},
|
||||
script_sig_asm: {
|
||||
type: TEXT,
|
||||
set() { },
|
||||
},
|
||||
script_sig_hex: {
|
||||
type: TEXT,
|
||||
set() { },
|
||||
},
|
||||
created: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
modified: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
},
|
||||
{
|
||||
freezeTableName: true,
|
||||
//getterMethods,
|
||||
timestamps: false, // don't use default timestamps columns
|
||||
}
|
||||
);
|
82
server/chainquery/models/OutputModel.js
Normal file
82
server/chainquery/models/OutputModel.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
const getterMethods = {
|
||||
// Add as needed, prefix all methods with `generated`
|
||||
}
|
||||
|
||||
export default (sequelize, {
|
||||
BOOLEAN,
|
||||
DATE,
|
||||
DECIMAL,
|
||||
INTEGER,
|
||||
STRING,
|
||||
TEXT,
|
||||
}) => sequelize.define(
|
||||
'output',
|
||||
{
|
||||
id: {
|
||||
primaryKey: true,
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
transaction_id: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
transaction_hash: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
value: {
|
||||
type: DECIMAL(18, 8),
|
||||
set() { },
|
||||
},
|
||||
vout: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
type: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
script_pub_key_asm: {
|
||||
type: TEXT,
|
||||
set() { },
|
||||
},
|
||||
script_pub_key_hex: {
|
||||
type: TEXT,
|
||||
set() { },
|
||||
},
|
||||
required_signatures: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
address_list: {
|
||||
type: TEXT,
|
||||
set() { },
|
||||
},
|
||||
is_spent: {
|
||||
type: BOOLEAN,
|
||||
set() { },
|
||||
},
|
||||
spent_by_input_id: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
created_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
modified_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
claim_id: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
}
|
||||
},
|
||||
{
|
||||
freezeTableName: true,
|
||||
//getterMethods,
|
||||
timestamps: false, // don't use default timestamps columns
|
||||
}
|
||||
);
|
54
server/chainquery/models/SupportModel.js
Normal file
54
server/chainquery/models/SupportModel.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
const getterMethods = {
|
||||
// Add as needed, prefix all methods with `generated`
|
||||
}
|
||||
|
||||
export default (sequelize, {
|
||||
BOOLEAN,
|
||||
DATE,
|
||||
DECIMAL,
|
||||
INTEGER,
|
||||
STRING,
|
||||
TEXT,
|
||||
}) => sequelize.define(
|
||||
'support',
|
||||
{
|
||||
id: {
|
||||
primaryKey: true,
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
supported_claim_id: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
support_amount: {
|
||||
type: DECIMAL(18, 8),
|
||||
set() { },
|
||||
},
|
||||
bid_state: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
transaction_hash_id: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
vout: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
created_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
modified_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
},
|
||||
{
|
||||
freezeTableName: true,
|
||||
//getterMethods,
|
||||
timestamps: false, // don't use default timestamps columns
|
||||
}
|
||||
);
|
39
server/chainquery/models/TransactionAddressModel.js
Normal file
39
server/chainquery/models/TransactionAddressModel.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
const getterMethods = {
|
||||
// Add as needed, prefix all methods with `generated`
|
||||
}
|
||||
|
||||
export default (sequelize, {
|
||||
BOOLEAN,
|
||||
DATE,
|
||||
DECIMAL,
|
||||
INTEGER,
|
||||
STRING,
|
||||
TEXT,
|
||||
}) => sequelize.define(
|
||||
'transaction_address',
|
||||
{
|
||||
transaction_id: {
|
||||
primaryKey: true,
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
address_id: {
|
||||
primaryKey: true,
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
debit_amount: {
|
||||
type: DECIMAL(18, 8),
|
||||
set() { },
|
||||
},
|
||||
credit_amount: {
|
||||
type: DECIMAL(18, 8),
|
||||
set() { },
|
||||
},
|
||||
},
|
||||
{
|
||||
freezeTableName: true,
|
||||
//getterMethods,
|
||||
timestamps: false, // don't use default timestamps columns
|
||||
}
|
||||
);
|
78
server/chainquery/models/TransactionModel.js
Normal file
78
server/chainquery/models/TransactionModel.js
Normal file
|
@ -0,0 +1,78 @@
|
|||
const getterMethods = {
|
||||
// Add as needed, prefix all methods with `generated`
|
||||
}
|
||||
|
||||
export default (sequelize, {
|
||||
BOOLEAN,
|
||||
DATE,
|
||||
DECIMAL,
|
||||
INTEGER,
|
||||
STRING,
|
||||
TEXT,
|
||||
}) => sequelize.define(
|
||||
'transaction',
|
||||
{
|
||||
id: {
|
||||
primaryKey: true,
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
block_hash_id: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
input_count: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
output_count: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
fee: {
|
||||
type: DECIMAL(18, 8),
|
||||
set() { },
|
||||
},
|
||||
transaction_time: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
transaction_size: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
hash: {
|
||||
type: STRING,
|
||||
set() { },
|
||||
},
|
||||
version: {
|
||||
type: INTEGER,
|
||||
set() { },
|
||||
},
|
||||
lock_time: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
raw: {
|
||||
type: TEXT,
|
||||
set() { },
|
||||
},
|
||||
created_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
modified_at: {
|
||||
type: DATE(6),
|
||||
set() { },
|
||||
},
|
||||
created_time: {
|
||||
type: DATE(6),
|
||||
set() {},
|
||||
},
|
||||
},
|
||||
{
|
||||
freezeTableName: true,
|
||||
//getterMethods,
|
||||
timestamps: false, // don't use default timestamps columns
|
||||
}
|
||||
);
|
3
server/chainquery/queries/abnormalClaimQueries.js
Normal file
3
server/chainquery/queries/abnormalClaimQueries.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default (db, table) => ({
|
||||
example: () => table.findAll(),
|
||||
})
|
3
server/chainquery/queries/addressQueries.js
Normal file
3
server/chainquery/queries/addressQueries.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default (db, table) => ({
|
||||
example: () => table.findAll(),
|
||||
})
|
3
server/chainquery/queries/blockQueries.js
Normal file
3
server/chainquery/queries/blockQueries.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default (db, table) => ({
|
||||
example: () => table.findAll(),
|
||||
})
|
198
server/chainquery/queries/claimQueries.js
Normal file
198
server/chainquery/queries/claimQueries.js
Normal file
|
@ -0,0 +1,198 @@
|
|||
const logger = require('winston');
|
||||
|
||||
const returnShortId = (claimsArray, longId) => {
|
||||
let claimIndex;
|
||||
let shortId = longId.substring(0, 1); // default short id is the first letter
|
||||
let shortIdLength = 0;
|
||||
// find the index of this claim id
|
||||
claimIndex = claimsArray.findIndex(element => {
|
||||
return element.claim_id === longId;
|
||||
});
|
||||
if (claimIndex < 0) {
|
||||
throw new Error('claim id not found in claims list');
|
||||
}
|
||||
// get an array of all claims with lower height
|
||||
let possibleMatches = claimsArray.slice(0, claimIndex);
|
||||
// remove certificates with the same prefixes until none are left.
|
||||
while (possibleMatches.length > 0) {
|
||||
shortIdLength += 1;
|
||||
shortId = longId.substring(0, shortIdLength);
|
||||
possibleMatches = possibleMatches.filter(element => {
|
||||
return (element.claim_id && (element.claim_id.substring(0, shortIdLength) === shortId));
|
||||
});
|
||||
}
|
||||
return shortId;
|
||||
};
|
||||
|
||||
const isLongClaimId = (claimId) => {
|
||||
return (claimId && (claimId.length === 40));
|
||||
}
|
||||
|
||||
const isShortClaimId = (claimId) => {
|
||||
return (claimId && (claimId.length < 40));
|
||||
}
|
||||
|
||||
export default (db, table, sequelize) => ({
|
||||
|
||||
getClaimChannelName: async (publisher_id) => {
|
||||
return await table.findAll({
|
||||
where : { claim_id: publisher_id },
|
||||
attributes: ['name'],
|
||||
}).then(result => {
|
||||
if(result.length === 0) {
|
||||
throw new Error(`no record found for ${claimId}`);
|
||||
} else if(result.length !== 1) {
|
||||
logger.warn(`more than one record matches ${claimId} in db.Claim`);
|
||||
}
|
||||
|
||||
return result[0].name;
|
||||
});
|
||||
},
|
||||
|
||||
getShortClaimIdFromLongClaimId: async (claimId, claimName) => {
|
||||
logger.debug(`claim.getShortClaimIdFromLongClaimId for ${claimName}#${claimId}`);
|
||||
return await table.findAll({
|
||||
where: { name: claimName },
|
||||
order: [['height', 'ASC']],
|
||||
}).then(result => {
|
||||
if(result.length === 0) {
|
||||
throw new Error('No claim(s) found with that claim name');
|
||||
}
|
||||
|
||||
return returnShortId(result, claimId);
|
||||
});
|
||||
},
|
||||
|
||||
getAllChannelClaims: async (channelClaimId) => {
|
||||
logger.debug(`claim.getAllChannelClaims for ${channelClaimId}`);
|
||||
return await table.findAll({
|
||||
where: { publisher_id: channelClaimId },
|
||||
order: [['height', 'DESC']],
|
||||
})
|
||||
.then(channelClaimsArray => {
|
||||
if(channelClaimsArray.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return channelClaimsArray;
|
||||
})
|
||||
},
|
||||
|
||||
getClaimIdByLongChannelId: async (channelClaimId, claimName) => {
|
||||
logger.debug(`finding claim id for claim ${claimName} from channel ${channelClaimId}`);
|
||||
return await table.findAll({
|
||||
where: { name: claimName, publisher_id: channelClaimId },
|
||||
order: [['id', 'ASC']],
|
||||
})
|
||||
.then(result => {
|
||||
switch (result.length) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
return result[0].claim_id;
|
||||
default:
|
||||
// Does this actually happen??? (from converted code)
|
||||
logger.warn(`${result.length} records found for "${claimName}" in channel "${channelClaimId}"`);
|
||||
return result[0].claim_id;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
validateLongClaimId: async (name, claimId) => {
|
||||
return await table.findOne({
|
||||
where: {
|
||||
name,
|
||||
claim_id: claimId,
|
||||
},
|
||||
}).then(result => {
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
return claimId;
|
||||
});
|
||||
},
|
||||
|
||||
getLongClaimIdFromShortClaimId: async (name, shortId) => {
|
||||
return await table.findAll({
|
||||
where: {
|
||||
name,
|
||||
claim_id: {
|
||||
[sequelize.Op.like]: `${shortId}%`,
|
||||
}},
|
||||
order: [['height', 'ASC']],
|
||||
})
|
||||
.then(result => {
|
||||
if(result.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return result[0].claim_id;
|
||||
});
|
||||
},
|
||||
|
||||
getTopFreeClaimIdByClaimName: async (name) => {
|
||||
return await table.findAll({
|
||||
// TODO: Limit 1
|
||||
where: { name },
|
||||
order: [['effective_amount', 'DESC'], ['height', 'ASC']],
|
||||
}).then(result => {
|
||||
if(result.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return result[0].claim_id;
|
||||
})
|
||||
},
|
||||
|
||||
getLongClaimId: async (claimName, claimId) => {
|
||||
// TODO: Add failure case
|
||||
logger.debug(`getLongClaimId(${claimName}, ${claimId})`);
|
||||
if (isLongClaimId(claimId)) {
|
||||
return table.queries.validateLongClaimId(claimName, claimId);
|
||||
} else if (isShortClaimId(claimId)) {
|
||||
return table.queries.getLongClaimIdFromShortClaimId(claimName, claimId);
|
||||
} else {
|
||||
return table.queries.getTopFreeClaimIdByClaimName(claimName);
|
||||
}
|
||||
},
|
||||
|
||||
resolveClaim: async (name, claimId) => {
|
||||
logger.debug(`Claim.resolveClaim: ${name} ${claimId}`);
|
||||
return table.findAll({
|
||||
where: { name, claim_id: claimId },
|
||||
}).then(claimArray => {
|
||||
if(claimArray.length === 0) {
|
||||
return null;
|
||||
} else if(claimArray.length !== 1) {
|
||||
logger.warn(`more than one record matches ${name}#${claimId} in db.Claim`);
|
||||
}
|
||||
|
||||
return claimArray[0];
|
||||
});
|
||||
},
|
||||
|
||||
getOutpoint: async (name, claimId) => {
|
||||
logger.debug(`finding outpoint for ${name}#${claimId}`);
|
||||
|
||||
return await table.findAll({
|
||||
where : { name, claim_id: claimId },
|
||||
attributes: ['transaction_hash_id'],
|
||||
}).then(result => {
|
||||
if(result.length === 0) {
|
||||
throw new Error(`no record found for ${name}#${claimId}`);
|
||||
} else if(result.length !== 1) {
|
||||
logger.warn(`more than one record matches ${name}#${claimId} in db.Claim`);
|
||||
}
|
||||
|
||||
return result[0].transaction_hash_id;
|
||||
});
|
||||
},
|
||||
|
||||
getCurrentHeight: async () => {
|
||||
return await table
|
||||
.max('height')
|
||||
.then(result => {
|
||||
return (result || 100000);
|
||||
});
|
||||
},
|
||||
|
||||
})
|
3
server/chainquery/queries/inputQueries.js
Normal file
3
server/chainquery/queries/inputQueries.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default (db, table) => ({
|
||||
example: () => table.findAll(),
|
||||
})
|
3
server/chainquery/queries/outputQueries.js
Normal file
3
server/chainquery/queries/outputQueries.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default (db, table) => ({
|
||||
example: () => table.findAll(),
|
||||
})
|
3
server/chainquery/queries/supportQueries.js
Normal file
3
server/chainquery/queries/supportQueries.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default (db, table) => ({
|
||||
example: () => table.findAll(),
|
||||
})
|
3
server/chainquery/queries/transactionAddressQueries.js
Normal file
3
server/chainquery/queries/transactionAddressQueries.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default (db, table) => ({
|
||||
example: () => table.findAll(),
|
||||
})
|
3
server/chainquery/queries/transactionQueries.js
Normal file
3
server/chainquery/queries/transactionQueries.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default (db, table) => ({
|
||||
example: () => table.findAll(),
|
||||
})
|
11
server/chainquery/tables/abnormalClaimTable.js
Normal file
11
server/chainquery/tables/abnormalClaimTable.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import AbnormalClaimModel from '../models/AbnormalClaimModel';
|
||||
|
||||
export default {
|
||||
createModel(...args) {
|
||||
return AbnormalClaimModel(...args);
|
||||
},
|
||||
|
||||
associate(db) {
|
||||
// associate
|
||||
},
|
||||
}
|
11
server/chainquery/tables/addressTable.js
Normal file
11
server/chainquery/tables/addressTable.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import AddressModel from '../models/AddressModel';
|
||||
|
||||
export default {
|
||||
createModel(...args) {
|
||||
return AddressModel(...args);
|
||||
},
|
||||
|
||||
associate(db) {
|
||||
// associate
|
||||
},
|
||||
}
|
11
server/chainquery/tables/blockTable.js
Normal file
11
server/chainquery/tables/blockTable.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import BlockModel from '../models/BlockModel';
|
||||
|
||||
export default {
|
||||
createModel(...args) {
|
||||
return BlockModel(...args);
|
||||
},
|
||||
|
||||
associate(db) {
|
||||
// associate
|
||||
},
|
||||
}
|
11
server/chainquery/tables/claimTable.js
Normal file
11
server/chainquery/tables/claimTable.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import ClaimModel from '../models/ClaimModel';
|
||||
|
||||
export default {
|
||||
createModel(...args) {
|
||||
return ClaimModel(...args);
|
||||
},
|
||||
|
||||
associate(db) {
|
||||
// associate
|
||||
},
|
||||
}
|
11
server/chainquery/tables/inputTable.js
Normal file
11
server/chainquery/tables/inputTable.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import InputModel from '../models/InputModel';
|
||||
|
||||
export default {
|
||||
createModel(...args) {
|
||||
return InputModel(...args);
|
||||
},
|
||||
|
||||
associate(db) {
|
||||
// associate
|
||||
},
|
||||
}
|
11
server/chainquery/tables/outputTable.js
Normal file
11
server/chainquery/tables/outputTable.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import OutputModel from '../models/OutputModel';
|
||||
|
||||
export default {
|
||||
createModel(...args) {
|
||||
return OutputModel(...args);
|
||||
},
|
||||
|
||||
associate(db) {
|
||||
// associate
|
||||
},
|
||||
}
|
11
server/chainquery/tables/supportTable.js
Normal file
11
server/chainquery/tables/supportTable.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import SupportModel from '../models/SupportModel';
|
||||
|
||||
export default {
|
||||
createModel(...args) {
|
||||
return SupportModel(...args);
|
||||
},
|
||||
|
||||
associate(db) {
|
||||
// associate
|
||||
},
|
||||
}
|
11
server/chainquery/tables/transactionAddressTable.js
Normal file
11
server/chainquery/tables/transactionAddressTable.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import TransactionAddressModel from '../models/TransactionAddressModel';
|
||||
|
||||
export default {
|
||||
createModel(...args) {
|
||||
return TransactionAddressModel(...args);
|
||||
},
|
||||
|
||||
associate(db) {
|
||||
// associate
|
||||
},
|
||||
}
|
11
server/chainquery/tables/transactionTable.js
Normal file
11
server/chainquery/tables/transactionTable.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import TransactionModel from '../models/TransactionModel';
|
||||
|
||||
export default {
|
||||
createModel(...args) {
|
||||
return TransactionModel(...args);
|
||||
},
|
||||
|
||||
associate(db) {
|
||||
// associate
|
||||
},
|
||||
}
|
|
@ -1,28 +1,15 @@
|
|||
const db = require('../../../../models');
|
||||
const chainquery = require('chainquery');
|
||||
const getClaimData = require('server/utils/getClaimData');
|
||||
const { returnPaginatedChannelClaims } = require('./channelPagination.js');
|
||||
|
||||
const getChannelClaims = (channelName, channelClaimId, page) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let longChannelClaimId;
|
||||
// 1. get the long channel Id (make sure channel exists)
|
||||
db.Certificate
|
||||
.getLongChannelId(channelName, channelClaimId)
|
||||
.then(result => {
|
||||
longChannelClaimId = result;
|
||||
return db
|
||||
.Claim
|
||||
.getAllChannelClaims(longChannelClaimId);
|
||||
})
|
||||
.then(channelClaimsArray => {
|
||||
// 3. format the data for the view, including pagination
|
||||
let paginatedChannelViewData = returnPaginatedChannelClaims(channelName, longChannelClaimId, channelClaimsArray, page);
|
||||
// 4. return all the channel information and contents
|
||||
resolve(paginatedChannelViewData);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
const getChannelClaims = async (channelName, channelShortId, page) => {
|
||||
const channelId = await chainquery.claim.queries.getLongClaimId(channelName, channelShortId);
|
||||
const channelClaims = await chainquery.claim.queries.getAllChannelClaims(channelId);
|
||||
|
||||
const processedChannelClaims = await channelClaims.map((claim) => getClaimData(claim));
|
||||
|
||||
return returnPaginatedChannelClaims(channelName, channelId, processedChannelClaims, page);
|
||||
};
|
||||
|
||||
module.exports = getChannelClaims;
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
const db = require('../../../../models');
|
||||
const chainquery = require('chainquery');
|
||||
const { publishing: { primaryClaimAddress, additionalClaimAddresses } } = require('@config/siteConfig');
|
||||
const Sequelize = require('sequelize');
|
||||
const Op = Sequelize.Op;
|
||||
|
||||
const claimAvailability = (name) => {
|
||||
const claimAvailability = async (name) => {
|
||||
const claimAddresses = additionalClaimAddresses || [];
|
||||
claimAddresses.push(primaryClaimAddress);
|
||||
// find any records where the name is used
|
||||
return db.Claim
|
||||
return await chainquery.claim
|
||||
.findAll({
|
||||
attributes: ['address'],
|
||||
attributes: ['claim_address'],
|
||||
where : {
|
||||
name,
|
||||
address: {
|
||||
claim_address: {
|
||||
[Op.or]: claimAddresses,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
const { handleErrorResponse } = require('../../../utils/errorHandlers.js');
|
||||
const getClaimData = require('server/utils/getClaimData');
|
||||
const chainquery = require('chainquery');
|
||||
const db = require('../../../../models');
|
||||
|
||||
/*
|
||||
|
@ -7,26 +9,32 @@ const db = require('../../../../models');
|
|||
|
||||
*/
|
||||
|
||||
const claimData = ({ ip, originalUrl, body, params }, res) => {
|
||||
const claimData = async ({ ip, originalUrl, body, params }, res) => {
|
||||
const claimName = params.claimName;
|
||||
let claimId = params.claimId;
|
||||
if (claimId === 'none') claimId = null;
|
||||
db.Claim.resolveClaim(claimName, claimId)
|
||||
.then(claimInfo => {
|
||||
if (!claimInfo) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'No claim could be found',
|
||||
});
|
||||
}
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data : claimInfo,
|
||||
|
||||
try {
|
||||
let resolvedClaim = await chainquery.claim.queries.resolveClaim(claimName, claimId).catch(() => {});
|
||||
|
||||
if(!resolvedClaim) {
|
||||
resolvedClaim = await db.Claim.resolveClaim(claimName, claimId);
|
||||
}
|
||||
|
||||
if (!resolvedClaim) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'No claim could be found',
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
handleErrorResponse(originalUrl, ip, error, res);
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data : await getClaimData(resolvedClaim),
|
||||
});
|
||||
} catch(error) {
|
||||
handleErrorResponse(originalUrl, ip, error, res);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = claimData;
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
const { getClaim } = require('../../../../lbrynet');
|
||||
const { createFileRecordDataAfterGet } = require('../../../../models/utils/createFileRecordData.js');
|
||||
const { handleErrorResponse } = require('../../../utils/errorHandlers.js');
|
||||
const getClaimData = require('server/utils/getClaimData');
|
||||
const chainquery = require('chainquery');
|
||||
const db = require('../../../../models');
|
||||
const waitOn = require('wait-on');
|
||||
|
||||
/*
|
||||
|
||||
|
@ -9,44 +12,46 @@ const db = require('../../../../models');
|
|||
|
||||
*/
|
||||
|
||||
const claimGet = ({ ip, originalUrl, params }, res) => {
|
||||
const claimGet = async ({ ip, originalUrl, params }, res) => {
|
||||
const name = params.name;
|
||||
const claimId = params.claimId;
|
||||
let resolveResult;
|
||||
let getResult;
|
||||
|
||||
db.Claim.resolveClaim(name, claimId)
|
||||
.then(result => {
|
||||
if (!result) {
|
||||
throw new Error('No matching uri found in Claim table');
|
||||
}
|
||||
resolveResult = result;
|
||||
return getClaim(`${name}#${claimId}`);
|
||||
})
|
||||
.then(result => {
|
||||
if (!result) {
|
||||
throw new Error(`Unable to Get ${name}#${claimId}`);
|
||||
}
|
||||
getResult = result;
|
||||
if (result.completed) {
|
||||
return createFileRecordDataAfterGet(resolveResult, getResult)
|
||||
.then(fileData => {
|
||||
const upsertCriteria = {name, claimId};
|
||||
return db.upsert(db.File, fileData, upsertCriteria, 'File');
|
||||
});
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
const { message, completed } = getResult;
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message,
|
||||
completed,
|
||||
try {
|
||||
let claimData = await chainquery.claim.queries.resolveClaim(name, claimId).catch(() => {});
|
||||
if(!claimData) {
|
||||
claimData = await db.Claim.resolveClaim(name, claimId);
|
||||
}
|
||||
|
||||
if(!claimData) {
|
||||
throw new Error('No matching uri found in Claim table');
|
||||
}
|
||||
|
||||
let lbrynetResult = await getClaim(`${name}#${claimId}`);
|
||||
if(!lbrynetResult) {
|
||||
throw new Error(`Unable to Get ${name}#${claimId}`);
|
||||
}
|
||||
|
||||
let fileData = await createFileRecordDataAfterGet(await getClaimData(claimData), lbrynetResult);
|
||||
const upsertCriteria = { name, claimId };
|
||||
await db.upsert(db.File, fileData, upsertCriteria, 'File');
|
||||
|
||||
try {
|
||||
await waitOn({
|
||||
resources: [ lbrynetResult.file_name ],
|
||||
delay: 100,
|
||||
timeout: 10000, // 10 seconds
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
handleErrorResponse(originalUrl, ip, error, res);
|
||||
} catch (e) {}
|
||||
|
||||
const { message, completed } = lbrynetResult;
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message,
|
||||
completed,
|
||||
});
|
||||
} catch(error) {
|
||||
handleErrorResponse(originalUrl, ip, error, res);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = claimGet;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const db = require('../../../../models');
|
||||
const chainquery = require('chainquery');
|
||||
|
||||
const { handleErrorResponse } = require('../../../utils/errorHandlers.js');
|
||||
|
||||
|
@ -19,10 +20,17 @@ const claimLongId = ({ ip, originalUrl, body, params }, res) => {
|
|||
const channelClaimId = body.channelClaimId;
|
||||
const claimName = body.claimName;
|
||||
let claimId = body.claimId;
|
||||
|
||||
getClaimId(channelName, channelClaimId, claimName, claimId)
|
||||
.then(fullClaimId => {
|
||||
claimId = fullClaimId;
|
||||
return db.Claim.getOutpoint(claimName, fullClaimId);
|
||||
return chainquery.claim.queries.getOutpoint(claimName, fullClaimId).catch(() => {});
|
||||
})
|
||||
.then(outpointResult => {
|
||||
if (!outpointResult) {
|
||||
return db.Claim.getOutpoint(claimName, claimId);
|
||||
}
|
||||
return outpointResult;
|
||||
})
|
||||
.then(outpoint => {
|
||||
return db.Blocked.isNotBlocked(outpoint);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const { handleErrorResponse } = require('../../../utils/errorHandlers.js');
|
||||
const db = require('../../../../models');
|
||||
const chainquery = require('chainquery');
|
||||
|
||||
/*
|
||||
|
||||
|
@ -7,14 +8,18 @@ const db = require('../../../../models');
|
|||
|
||||
*/
|
||||
|
||||
const claimShortId = ({ ip, originalUrl, body, params }, res) => {
|
||||
db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name)
|
||||
.then(shortId => {
|
||||
res.status(200).json({success: true, data: shortId});
|
||||
})
|
||||
.catch(error => {
|
||||
handleErrorResponse(originalUrl, ip, error, res);
|
||||
});
|
||||
const claimShortId = async ({ ip, originalUrl, body, params }, res) => {
|
||||
try {
|
||||
let shortId = await chainquery.claim.queries.getShortClaimIdFromLongClaimId(params.longId, params.name);
|
||||
|
||||
if(shortId === null) {
|
||||
shortId = await db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name);
|
||||
}
|
||||
|
||||
res.status(200).json({success: true, data: shortId});
|
||||
} catch(error) {
|
||||
handleErrorResponse(originalUrl, ip, error, res);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = claimShortId;
|
||||
|
|
28
server/controllers/api/homepage/data/getChannelData.js
Normal file
28
server/controllers/api/homepage/data/getChannelData.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
const db = require('../../../../models');
|
||||
|
||||
const getChannelData = (channelName, channelClaimId) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let longChannelClaimId;
|
||||
// 1. get the long channel Id (make sure channel exists)
|
||||
db.Certificate
|
||||
.getLongChannelId(channelName, channelClaimId)
|
||||
.then(fullClaimId => {
|
||||
longChannelClaimId = fullClaimId;
|
||||
return db
|
||||
.Certificate
|
||||
.getShortChannelIdFromLongChannelId(fullClaimId, channelName);
|
||||
})
|
||||
.then(shortChannelClaimId => {
|
||||
resolve({
|
||||
channelName,
|
||||
longChannelClaimId,
|
||||
shortChannelClaimId,
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = getChannelData;
|
35
server/controllers/api/homepage/data/index.js
Normal file
35
server/controllers/api/homepage/data/index.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
const { handleErrorResponse } = require('../../../utils/errorHandlers.js');
|
||||
|
||||
const getChannelData = require('./getChannelData.js');
|
||||
|
||||
const NO_CHANNEL = 'NO_CHANNEL';
|
||||
|
||||
/*
|
||||
|
||||
route to get data for a channel
|
||||
|
||||
*/
|
||||
|
||||
const channelData = ({ ip, originalUrl, body, params }, res) => {
|
||||
const channelName = params.channelName;
|
||||
let channelClaimId = params.channelClaimId;
|
||||
if (channelClaimId === 'none') channelClaimId = null;
|
||||
getChannelData(channelName, channelClaimId)
|
||||
.then(data => {
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data,
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
if (error === NO_CHANNEL) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'No matching channel was found',
|
||||
});
|
||||
}
|
||||
handleErrorResponse(originalUrl, ip, error, res);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = channelData;
|
|
@ -1,6 +1,7 @@
|
|||
const logger = require('winston');
|
||||
|
||||
const db = require('../../../models');
|
||||
const chainquery = require('chainquery');
|
||||
const isApprovedChannel = require('../../../../utils/isApprovedChannel');
|
||||
|
||||
const getClaimId = require('../../utils/getClaimId.js');
|
||||
|
@ -20,13 +21,20 @@ const getClaimIdAndServeAsset = (channelName, channelClaimId, claimName, claimId
|
|||
getClaimId(channelName, channelClaimId, claimName, claimId)
|
||||
.then(fullClaimId => {
|
||||
claimId = fullClaimId;
|
||||
logger.debug('Full claim id:', fullClaimId);
|
||||
return db.Claim.findOne({
|
||||
where: {
|
||||
name : claimName,
|
||||
claimId: fullClaimId,
|
||||
},
|
||||
});
|
||||
return chainquery.claim.queries.resolveClaim(claimName, fullClaimId).catch(() => {});
|
||||
})
|
||||
.then(claim => {
|
||||
if (!claim) {
|
||||
logger.debug('Full claim id:', fullClaimId);
|
||||
return db.Claim.findOne({
|
||||
where: {
|
||||
name : claimName,
|
||||
claimId: fullClaimId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return claim;
|
||||
})
|
||||
.then(claim => {
|
||||
if (serveOnlyApproved && !isApprovedChannel({ longId: claim.dataValues.certificateId }, approvedChannels)) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const handlePageRender = require('../../render/build/handlePageRender.js');
|
||||
const handleShowRender = require('../../render/build/handleShowRender.js');
|
||||
|
||||
const sendReactApp = (req, res) => {
|
||||
handlePageRender(req, res);
|
||||
handleShowRender(req, res);
|
||||
};
|
||||
|
||||
module.exports = sendReactApp;
|
||||
|
|
|
@ -1,22 +1,38 @@
|
|||
const logger = require('winston');
|
||||
|
||||
const db = require('../../models');
|
||||
const chainquery = require('chainquery');
|
||||
|
||||
const getClaimIdByChannel = (channelName, channelClaimId, claimName) => {
|
||||
const getClaimIdByChannel = async (channelName, channelClaimId, claimName) => {
|
||||
logger.debug(`getClaimIdByChannel(${channelName}, ${channelClaimId}, ${claimName})`);
|
||||
return db.Certificate
|
||||
.getLongChannelId(channelName, channelClaimId)
|
||||
.then(longChannelId => {
|
||||
return db.Claim.getClaimIdByLongChannelId(longChannelId, claimName);
|
||||
});
|
||||
|
||||
let channelId = await chainquery.claim.queries.getLongClaimIdFromShortClaimId(channelName, channelClaimId);
|
||||
|
||||
if(channelId === null) {
|
||||
channelId = await db.Certificate.getLongChannelId(channelName, channelClaimId);
|
||||
}
|
||||
|
||||
let claimId = await chainquery.claim.queries.getClaimIdByLongChannelId(channelId, claimName);
|
||||
|
||||
if(claimId === null) {
|
||||
claimId = db.Claim.getClaimIdByLongChannelId(longChannelId, claimName);
|
||||
}
|
||||
|
||||
return claimId;
|
||||
};
|
||||
|
||||
const getClaimId = (channelName, channelClaimId, name, claimId) => {
|
||||
const getClaimId = async (channelName, channelClaimId, name, claimId) => {
|
||||
logger.debug(`getClaimId: ${channelName}, ${channelClaimId}, ${name}, ${claimId})`);
|
||||
if (channelName) {
|
||||
return getClaimIdByChannel(channelName, channelClaimId, name);
|
||||
return await getClaimIdByChannel(channelName, channelClaimId, name);
|
||||
} else {
|
||||
return db.Claim.getLongClaimId(name, claimId);
|
||||
let claimIdResult = await chainquery.claim.queries.getLongClaimId(name, claimId);
|
||||
|
||||
if(claimIdResult === null) {
|
||||
claimIdResult = await db.Claim.getLongClaimId(name, claimId);
|
||||
}
|
||||
|
||||
return claimIdResult;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ const cookieSession = require('cookie-session');
|
|||
const http = require('http');
|
||||
const logger = require('winston');
|
||||
const Path = require('path');
|
||||
const httpContext = require('express-http-context');
|
||||
|
||||
// load local modules
|
||||
const db = require('./models');
|
||||
|
@ -26,6 +27,36 @@ const {
|
|||
},
|
||||
} = require('@config/siteConfig');
|
||||
|
||||
function logMetricsMiddleware(req, res, next) {
|
||||
res.on('finish', () => {
|
||||
const userAgent = req.get('user-agent');
|
||||
const routePath = httpContext.get('routePath');
|
||||
|
||||
db.Metrics.create({
|
||||
isInternal: /node\-fetch/.test(userAgent),
|
||||
isChannel: res.isChannel,
|
||||
claimId: res.claimId,
|
||||
routePath: httpContext.get('routePath'),
|
||||
params: JSON.stringify(req.params),
|
||||
ip: req.headers['x-forwarded-for'] || req.connection.remoteAddress,
|
||||
request: req.url,
|
||||
routeData: JSON.stringify(httpContext.get('routeData')),
|
||||
referrer: req.get('referrer'),
|
||||
userAgent,
|
||||
});
|
||||
});
|
||||
|
||||
next();
|
||||
}
|
||||
|
||||
function setRouteDataInContextMiddleware(routePath, routeData) {
|
||||
return function (req, res, next) {
|
||||
httpContext.set('routePath', routePath);
|
||||
httpContext.set('routeData', routeData);
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
function Server () {
|
||||
this.initialize = () => {
|
||||
// configure logging
|
||||
|
@ -43,6 +74,9 @@ function Server () {
|
|||
// set HTTP headers to protect against well-known web vulnerabilties
|
||||
app.use(helmet());
|
||||
|
||||
// Support per-request http-context
|
||||
app.use(httpContext.middleware);
|
||||
|
||||
// 'express.static' to serve static files from public directory
|
||||
const publicPath = Path.resolve(process.cwd(), 'public');
|
||||
app.use(express.static(publicPath));
|
||||
|
@ -66,7 +100,7 @@ function Server () {
|
|||
app.use(speechPassport.session());
|
||||
|
||||
// configure handlebars & register it with express app
|
||||
const viewsPath = Path.resolve(process.cwd(), 'server/views');
|
||||
const viewsPath = Path.resolve(process.cwd(), 'node_modules/spee.ch/server/views');
|
||||
app.engine('handlebars', expressHandlebars({
|
||||
async : false,
|
||||
dataType : 'text',
|
||||
|
@ -78,11 +112,20 @@ function Server () {
|
|||
app.set('view engine', 'handlebars');
|
||||
|
||||
// set the routes on the app
|
||||
require('./routes/auth/index')(app);
|
||||
require('./routes/api/index')(app);
|
||||
require('./routes/pages/index')(app);
|
||||
require('./routes/assets/index')(app);
|
||||
require('./routes/fallback/index')(app);
|
||||
const routes = require('./routes');
|
||||
|
||||
Object.keys(routes).map((routePath) => {
|
||||
let routeData = routes[routePath];
|
||||
let routeMethod = routeData.hasOwnProperty('method') ? routeData.method : 'get';
|
||||
let controllers = Array.isArray(routeData.controller) ? routeData.controller : [routeData.controller];
|
||||
|
||||
app[routeMethod](
|
||||
routePath,
|
||||
logMetricsMiddleware,
|
||||
setRouteDataInContextMiddleware(routePath, routeData),
|
||||
...controllers,
|
||||
);
|
||||
});
|
||||
|
||||
this.app = app;
|
||||
};
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
const Sequelize = require('sequelize');
|
||||
const logger = require('winston');
|
||||
|
||||
const Certificate = require('./certificate.js');
|
||||
const Channel = require('./channel.js');
|
||||
const Claim = require('./claim.js');
|
||||
const File = require('./file.js');
|
||||
const User = require('./user.js');
|
||||
const Blocked = require('./blocked.js');
|
||||
const Tor = require('./tor.js');
|
||||
const Blocked = require('./blocked');
|
||||
const Certificate = require('./certificate');
|
||||
const Channel = require('./channel');
|
||||
const Claim = require('./claim');
|
||||
const File = require('./file');
|
||||
const Metrics = require('./metrics');
|
||||
const Tor = require('./tor');
|
||||
const User = require('./user');
|
||||
|
||||
const {
|
||||
database,
|
||||
|
@ -48,13 +49,14 @@ sequelize
|
|||
|
||||
// manually add each model to the db object (note: make this dynamic)
|
||||
const db = {};
|
||||
db['Blocked'] = sequelize.import('Blocked', Blocked);
|
||||
db['Certificate'] = sequelize.import('Certificate', Certificate);
|
||||
db['Channel'] = sequelize.import('Channel', Channel);
|
||||
db['Claim'] = sequelize.import('Claim', Claim);
|
||||
db['File'] = sequelize.import('File', File);
|
||||
db['User'] = sequelize.import('User', User);
|
||||
db['Blocked'] = sequelize.import('Blocked', Blocked);
|
||||
db['Metrics'] = sequelize.import('Metrics', Metrics);
|
||||
db['Tor'] = sequelize.import('Tor', Tor);
|
||||
db['User'] = sequelize.import('User', User);
|
||||
|
||||
// run model.association for each model in the db object that has an association
|
||||
logger.info('associating db models...');
|
||||
|
|
57
server/models/metrics.js
Normal file
57
server/models/metrics.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
module.exports = (sequelize, { BOOLEAN, DATE, STRING }) => {
|
||||
const Metrics = sequelize.define(
|
||||
'Metrics',
|
||||
{
|
||||
time: {
|
||||
type: DATE(6),
|
||||
defaultValue: sequelize.NOW,
|
||||
},
|
||||
isInternal: {
|
||||
type: BOOLEAN,
|
||||
},
|
||||
isChannel: {
|
||||
type: BOOLEAN,
|
||||
defaultValue: false,
|
||||
},
|
||||
claimId: {
|
||||
type: STRING,
|
||||
defaultValue: null,
|
||||
},
|
||||
ip: {
|
||||
type: STRING,
|
||||
defaultValue: null,
|
||||
},
|
||||
request: {
|
||||
type: STRING,
|
||||
defaultValue: null,
|
||||
},
|
||||
userAgent: {
|
||||
type: STRING,
|
||||
defaultValue: null,
|
||||
},
|
||||
referrer: {
|
||||
type: STRING,
|
||||
defaultValue: null,
|
||||
},
|
||||
routePath: {
|
||||
type: STRING,
|
||||
defaultValue: null,
|
||||
},
|
||||
params: {
|
||||
type: STRING,
|
||||
defaultValue: null,
|
||||
}
|
||||
},
|
||||
{
|
||||
freezeTableName: true,
|
||||
timestamps: false, // don't use default timestamps columns
|
||||
indexes: [
|
||||
{
|
||||
fields: ['isInternal', 'isChannel', 'time', 'claimId', 'routePath'],
|
||||
},
|
||||
],
|
||||
}
|
||||
);
|
||||
|
||||
return Metrics;
|
||||
};
|
|
@ -10,6 +10,12 @@ var _reactRedux = require("react-redux");
|
|||
|
||||
var _reactRouterDom = require("react-router-dom");
|
||||
|
||||
var _renderFullPage = _interopRequireDefault(require("../renderFullPage"));
|
||||
|
||||
var _reduxSaga = _interopRequireDefault(require("redux-saga"));
|
||||
|
||||
var _effects = require("redux-saga/effects");
|
||||
|
||||
var _reactHelmet = _interopRequireDefault(require("react-helmet"));
|
||||
|
||||
var _reducers = _interopRequireDefault(require("@reducers"));
|
||||
|
@ -18,33 +24,65 @@ var _GAListener = _interopRequireDefault(require("@components/GAListener"));
|
|||
|
||||
var _app = _interopRequireDefault(require("@app"));
|
||||
|
||||
var _renderFullPage = _interopRequireDefault(require("../renderFullPage.js"));
|
||||
var _sagas = _interopRequireDefault(require("@sagas"));
|
||||
|
||||
var _actions = _interopRequireDefault(require("@actions"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
var returnSagaWithParams = function returnSagaWithParams(saga, params) {
|
||||
return (
|
||||
/*#__PURE__*/
|
||||
regeneratorRuntime.mark(function _callee() {
|
||||
return regeneratorRuntime.wrap(function _callee$(_context) {
|
||||
while (1) {
|
||||
switch (_context.prev = _context.next) {
|
||||
case 0:
|
||||
_context.next = 2;
|
||||
return (0, _effects.call)(saga, params);
|
||||
|
||||
case 2:
|
||||
case "end":
|
||||
return _context.stop();
|
||||
}
|
||||
}
|
||||
}, _callee, this);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = function (req, res) {
|
||||
var context = {}; // create a new Redux store instance
|
||||
var context = {}; // create and apply middleware
|
||||
|
||||
var store = (0, _redux.createStore)(_reducers.default); // render component to a string
|
||||
var sagaMiddleware = (0, _reduxSaga.default)();
|
||||
var middleware = (0, _redux.applyMiddleware)(sagaMiddleware); // create a new Redux store instance
|
||||
|
||||
var html = (0, _server.renderToString)(_react.default.createElement(_reactRedux.Provider, {
|
||||
store: store
|
||||
}, _react.default.createElement(_reactRouterDom.StaticRouter, {
|
||||
location: req.url,
|
||||
context: context
|
||||
}, _react.default.createElement(_GAListener.default, null, _react.default.createElement(_app.default, null))))); // get head tags from helmet
|
||||
var store = (0, _redux.createStore)(_reducers.default, middleware); // create an action to handle the given url,
|
||||
// and create a the saga needed to handle that action
|
||||
|
||||
var helmet = _reactHelmet.default.renderStatic(); // check for a redirect
|
||||
var action = _actions.default.onHandleShowPageUri(req.params);
|
||||
|
||||
var saga = returnSagaWithParams(_sagas.default.handleShowPageUri, action); // run the saga middleware with the saga call
|
||||
|
||||
sagaMiddleware.run(saga).done.then(function () {
|
||||
// render component to a string
|
||||
var html = (0, _server.renderToString)(_react.default.createElement(_reactRedux.Provider, {
|
||||
store: store
|
||||
}, _react.default.createElement(_reactRouterDom.StaticRouter, {
|
||||
location: req.url,
|
||||
context: context
|
||||
}, _react.default.createElement(_GAListener.default, null, _react.default.createElement(_app.default, null))))); // get head tags from helmet
|
||||
|
||||
var helmet = _reactHelmet.default.renderStatic(); // check for a redirect
|
||||
|
||||
|
||||
if (context.url) {
|
||||
// Somewhere a `<Redirect>` was rendered
|
||||
return res.redirect(301, context.url);
|
||||
} else {} // we're good, send the response
|
||||
// get the initial state from our Redux store
|
||||
if (context.url) {
|
||||
return res.redirect(301, context.url);
|
||||
} // get the initial state from our Redux store
|
||||
|
||||
|
||||
var preloadedState = store.getState(); // send the rendered page back to the client
|
||||
var preloadedState = store.getState(); // send the rendered page back to the client
|
||||
|
||||
res.send((0, _renderFullPage.default)(helmet, html, preloadedState));
|
||||
res.send((0, _renderFullPage.default)(helmet, html, preloadedState));
|
||||
});
|
||||
};
|
|
@ -18,6 +18,8 @@ var _effects = require("redux-saga/effects");
|
|||
|
||||
var _reactHelmet = _interopRequireDefault(require("react-helmet"));
|
||||
|
||||
var httpContext = _interopRequireWildcard(require("express-http-context"));
|
||||
|
||||
var _reducers = _interopRequireDefault(require("@reducers"));
|
||||
|
||||
var _GAListener = _interopRequireDefault(require("@components/GAListener"));
|
||||
|
@ -28,6 +30,8 @@ var _sagas = _interopRequireDefault(require("@sagas"));
|
|||
|
||||
var _actions = _interopRequireDefault(require("@actions"));
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
var returnSagaWithParams = function returnSagaWithParams(saga, params) {
|
||||
|
@ -52,20 +56,30 @@ var returnSagaWithParams = function returnSagaWithParams(saga, params) {
|
|||
};
|
||||
|
||||
module.exports = function (req, res) {
|
||||
var context = {}; // create and apply middleware
|
||||
var context = {};
|
||||
|
||||
var sagaMiddleware = (0, _reduxSaga.default)();
|
||||
var middleware = (0, _redux.applyMiddleware)(sagaMiddleware); // create a new Redux store instance
|
||||
var _httpContext$get = httpContext.get('routeData'),
|
||||
_httpContext$get$acti = _httpContext$get.action,
|
||||
action = _httpContext$get$acti === void 0 ? false : _httpContext$get$acti,
|
||||
_httpContext$get$saga = _httpContext$get.saga,
|
||||
saga = _httpContext$get$saga === void 0 ? false : _httpContext$get$saga;
|
||||
|
||||
var store = (0, _redux.createStore)(_reducers.default, middleware); // create an action to handle the given url,
|
||||
// and create a the saga needed to handle that action
|
||||
var runSaga = action !== false && saga !== false;
|
||||
|
||||
var action = _actions.default.onHandleShowPageUri(req.params);
|
||||
var renderPage = function renderPage(store) {
|
||||
// Workaround, remove when a solution for async httpContext exists
|
||||
var showState = store.getState().show;
|
||||
var assetKeys = Object.keys(showState.assetList);
|
||||
|
||||
if (assetKeys.length !== 0) {
|
||||
res.claimId = showState.assetList[assetKeys[0]].claimId;
|
||||
} else {
|
||||
var channelKeys = Object.keys(showState.channelList);
|
||||
res.claimId = showState.channelList[channelKeys[0]].longId;
|
||||
res.isChannel = true;
|
||||
} // render component to a string
|
||||
|
||||
var saga = returnSagaWithParams(_sagas.default.handleShowPageUri, action); // run the saga middleware with the saga call
|
||||
|
||||
sagaMiddleware.run(saga).done.then(function () {
|
||||
// render component to a string
|
||||
var html = (0, _server.renderToString)(_react.default.createElement(_reactRedux.Provider, {
|
||||
store: store
|
||||
}, _react.default.createElement(_reactRouterDom.StaticRouter, {
|
||||
|
@ -84,5 +98,25 @@ module.exports = function (req, res) {
|
|||
var preloadedState = store.getState(); // send the rendered page back to the client
|
||||
|
||||
res.send((0, _renderFullPage.default)(helmet, html, preloadedState));
|
||||
});
|
||||
};
|
||||
|
||||
if (runSaga) {
|
||||
// create and apply middleware
|
||||
var sagaMiddleware = (0, _reduxSaga.default)();
|
||||
var middleware = (0, _redux.applyMiddleware)(sagaMiddleware); // create a new Redux store instance
|
||||
|
||||
var store = (0, _redux.createStore)(_reducers.default, middleware); // create an action to handle the given url,
|
||||
// and create a the saga needed to handle that action
|
||||
|
||||
var boundAction = action(req.params, req.url);
|
||||
var boundSaga = returnSagaWithParams(saga, boundAction); // run the saga middleware with the saga call
|
||||
|
||||
sagaMiddleware.run(boundSaga).done.then(function () {
|
||||
return renderPage(store);
|
||||
});
|
||||
} else {
|
||||
var _store = (0, _redux.createStore)(_reducers.default);
|
||||
|
||||
renderPage(_store);
|
||||
}
|
||||
};
|
|
@ -1,46 +0,0 @@
|
|||
import React from 'react';
|
||||
import { renderToString } from 'react-dom/server';
|
||||
import { createStore } from 'redux';
|
||||
import { Provider } from 'react-redux';
|
||||
import { StaticRouter } from 'react-router-dom';
|
||||
import Helmet from 'react-helmet';
|
||||
|
||||
import Reducers from '@reducers';
|
||||
import GAListener from '@components/GAListener';
|
||||
import App from '@app';
|
||||
import renderFullPage from '../renderFullPage.js';
|
||||
|
||||
module.exports = (req, res) => {
|
||||
let context = {};
|
||||
|
||||
// create a new Redux store instance
|
||||
const store = createStore(Reducers);
|
||||
|
||||
// render component to a string
|
||||
const html = renderToString(
|
||||
<Provider store={store}>
|
||||
<StaticRouter location={req.url} context={context}>
|
||||
<GAListener>
|
||||
<App />
|
||||
</GAListener>
|
||||
</StaticRouter>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
// get head tags from helmet
|
||||
const helmet = Helmet.renderStatic();
|
||||
|
||||
// check for a redirect
|
||||
if (context.url) {
|
||||
// Somewhere a `<Redirect>` was rendered
|
||||
return res.redirect(301, context.url);
|
||||
} else {
|
||||
// we're good, send the response
|
||||
}
|
||||
|
||||
// get the initial state from our Redux store
|
||||
const preloadedState = store.getState();
|
||||
|
||||
// send the rendered page back to the client
|
||||
res.send(renderFullPage(helmet, html, preloadedState));
|
||||
};
|
|
@ -7,6 +7,7 @@ import renderFullPage from '../renderFullPage';
|
|||
import createSagaMiddleware from 'redux-saga';
|
||||
import { call } from 'redux-saga/effects';
|
||||
import Helmet from 'react-helmet';
|
||||
import * as httpContext from 'express-http-context';
|
||||
|
||||
import Reducers from '@reducers';
|
||||
import GAListener from '@components/GAListener';
|
||||
|
@ -23,46 +24,72 @@ const returnSagaWithParams = (saga, params) => {
|
|||
module.exports = (req, res) => {
|
||||
let context = {};
|
||||
|
||||
// create and apply middleware
|
||||
const sagaMiddleware = createSagaMiddleware();
|
||||
const middleware = applyMiddleware(sagaMiddleware);
|
||||
const {
|
||||
action = false,
|
||||
saga = false,
|
||||
} = httpContext.get('routeData');
|
||||
|
||||
// create a new Redux store instance
|
||||
const store = createStore(Reducers, middleware);
|
||||
const runSaga = (action !== false && saga !== false);
|
||||
|
||||
// create an action to handle the given url,
|
||||
// and create a the saga needed to handle that action
|
||||
const action = Actions.onHandleShowPageUri(req.params);
|
||||
const saga = returnSagaWithParams(Sagas.handleShowPageUri, action);
|
||||
const renderPage = (store) => {
|
||||
|
||||
// run the saga middleware with the saga call
|
||||
sagaMiddleware
|
||||
.run(saga)
|
||||
.done
|
||||
.then(() => {
|
||||
// render component to a string
|
||||
const html = renderToString(
|
||||
<Provider store={store}>
|
||||
<StaticRouter location={req.url} context={context}>
|
||||
<GAListener>
|
||||
<App />
|
||||
</GAListener>
|
||||
</StaticRouter>
|
||||
</Provider>
|
||||
);
|
||||
// Workaround, remove when a solution for async httpContext exists
|
||||
const showState = store.getState().show;
|
||||
const assetKeys = Object.keys(showState.assetList);
|
||||
if(assetKeys.length !== 0) {
|
||||
res.claimId = showState.assetList[assetKeys[0]].claimId;
|
||||
} else {
|
||||
const channelKeys = Object.keys(showState.channelList);
|
||||
res.claimId = showState.channelList[channelKeys[0]].longId;
|
||||
res.isChannel = true;
|
||||
}
|
||||
|
||||
// get head tags from helmet
|
||||
const helmet = Helmet.renderStatic();
|
||||
// render component to a string
|
||||
const html = renderToString(
|
||||
<Provider store={store}>
|
||||
<StaticRouter location={req.url} context={context}>
|
||||
<GAListener>
|
||||
<App />
|
||||
</GAListener>
|
||||
</StaticRouter>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
// check for a redirect
|
||||
if (context.url) {
|
||||
return res.redirect(301, context.url);
|
||||
}
|
||||
// get head tags from helmet
|
||||
const helmet = Helmet.renderStatic();
|
||||
|
||||
// get the initial state from our Redux store
|
||||
const preloadedState = store.getState();
|
||||
// check for a redirect
|
||||
if (context.url) {
|
||||
return res.redirect(301, context.url);
|
||||
}
|
||||
|
||||
// send the rendered page back to the client
|
||||
res.send(renderFullPage(helmet, html, preloadedState));
|
||||
});
|
||||
// get the initial state from our Redux store
|
||||
const preloadedState = store.getState();
|
||||
|
||||
// send the rendered page back to the client
|
||||
res.send(renderFullPage(helmet, html, preloadedState));
|
||||
};
|
||||
|
||||
if (runSaga) {
|
||||
// create and apply middleware
|
||||
const sagaMiddleware = createSagaMiddleware();
|
||||
const middleware = applyMiddleware(sagaMiddleware);
|
||||
|
||||
// create a new Redux store instance
|
||||
const store = createStore(Reducers, middleware);
|
||||
|
||||
// create an action to handle the given url,
|
||||
// and create a the saga needed to handle that action
|
||||
const boundAction = action(req.params, req.url);
|
||||
const boundSaga = returnSagaWithParams(saga, boundAction);
|
||||
|
||||
// run the saga middleware with the saga call
|
||||
sagaMiddleware
|
||||
.run(boundSaga)
|
||||
.done
|
||||
.then(() => renderPage(store) );
|
||||
} else {
|
||||
const store = createStore(Reducers);
|
||||
renderPage(store);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -21,31 +21,35 @@ const getTorList = require('../../controllers/api/tor');
|
|||
const getBlockedList = require('../../controllers/api/blocked');
|
||||
const getOEmbedData = require('../../controllers/api/oEmbed');
|
||||
|
||||
module.exports = (app) => {
|
||||
module.exports = {
|
||||
// homepage routes
|
||||
'/api/homepage/data/channels': { controller: [ torCheckMiddleware, channelData ] },
|
||||
|
||||
// channel routes
|
||||
app.get('/api/channel/availability/:name', torCheckMiddleware, channelAvailability);
|
||||
app.get('/api/channel/short-id/:longId/:name', torCheckMiddleware, channelShortId);
|
||||
app.get('/api/channel/data/:channelName/:channelClaimId', torCheckMiddleware, channelData);
|
||||
app.get('/api/channel/claims/:channelName/:channelClaimId/:page', torCheckMiddleware, channelClaims);
|
||||
'/api/channel/availability/:name': { controller: [ torCheckMiddleware, channelAvailability ] },
|
||||
'/api/channel/short-id/:longId/:name': { controller: [ torCheckMiddleware, channelShortId ] },
|
||||
'/api/channel/data/:channelName/:channelClaimId': { controller: [ torCheckMiddleware, channelData ] },
|
||||
'/api/channel/data/:channelName/:channelClaimId': { controller: [ torCheckMiddleware, channelData ] },
|
||||
'/api/channel/claims/:channelName/:channelClaimId/:page': { controller: [ torCheckMiddleware, channelClaims ] },
|
||||
// claim routes
|
||||
app.get('/api/claim/availability/:name', torCheckMiddleware, claimAvailability);
|
||||
app.get('/api/claim/data/:claimName/:claimId', torCheckMiddleware, claimData);
|
||||
app.get('/api/claim/get/:name/:claimId', torCheckMiddleware, claimGet);
|
||||
app.get('/api/claim/list/:name', torCheckMiddleware, claimList);
|
||||
app.post('/api/claim/long-id', torCheckMiddleware, claimLongId); // note: should be a 'get'
|
||||
app.post('/api/claim/publish', torCheckMiddleware, multipartMiddleware, claimPublish);
|
||||
app.get('/api/claim/resolve/:name/:claimId', torCheckMiddleware, claimResolve);
|
||||
app.get('/api/claim/short-id/:longId/:name', torCheckMiddleware, claimShortId);
|
||||
'/api/claim/availability/:name': { controller: [ torCheckMiddleware, claimAvailability ] },
|
||||
'/api/claim/data/:claimName/:claimId': { controller: [ torCheckMiddleware, claimData ] },
|
||||
'/api/claim/get/:name/:claimId': { controller: [ torCheckMiddleware, claimGet ] },
|
||||
'/api/claim/list/:name': { controller: [ torCheckMiddleware, claimList ] },
|
||||
'/api/claim/long-id': { method: 'post', controller: [ torCheckMiddleware, claimLongId ] }, // note: should be a 'get'
|
||||
'/api/claim/publish': { method: 'post', controller: [ torCheckMiddleware, multipartMiddleware, claimPublish ] },
|
||||
'/api/claim/resolve/:name/:claimId': { controller: [ torCheckMiddleware, claimResolve ] },
|
||||
'/api/claim/short-id/:longId/:name': { controller: [ torCheckMiddleware, claimShortId ] },
|
||||
// file routes
|
||||
app.get('/api/file/availability/:name/:claimId', torCheckMiddleware, fileAvailability);
|
||||
'/api/file/availability/:name/:claimId': { controller: [ torCheckMiddleware, fileAvailability ] },
|
||||
// user routes
|
||||
app.put('/api/user/password/', torCheckMiddleware, userPassword);
|
||||
'/api/user/password/': { method: 'put', controller: [ torCheckMiddleware, userPassword ] },
|
||||
// configs
|
||||
app.get('/api/config/site/publishing', torCheckMiddleware, publishingConfig);
|
||||
'/api/config/site/publishing': { controller: [ torCheckMiddleware, publishingConfig ] },
|
||||
// tor
|
||||
app.get('/api/tor', torCheckMiddleware, getTorList);
|
||||
'/api/tor': { controller: [ torCheckMiddleware, getTorList ] },
|
||||
// blocked
|
||||
app.get('/api/blocked', torCheckMiddleware, getBlockedList);
|
||||
'/api/blocked': { controller: [ torCheckMiddleware, getBlockedList ] },
|
||||
// open embed
|
||||
app.get('/api/oembed', torCheckMiddleware, getOEmbedData);
|
||||
'/api/oembed': { controller: [ torCheckMiddleware, getOEmbedData ] },
|
||||
};
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
const serveByClaim = require('../../controllers/assets/serveByClaim');
|
||||
const serveByIdentifierAndClaim = require('../../controllers/assets/serveByIdentifierAndClaim');
|
||||
|
||||
module.exports = (app) => {
|
||||
app.get('/:identifier/:claim', serveByIdentifierAndClaim);
|
||||
app.get('/:claim', serveByClaim);
|
||||
// TODO: Adjust build & sources to use import/export everywhere
|
||||
const Actions = require('@actions').default;
|
||||
const Sagas = require('@sagas').default;
|
||||
|
||||
module.exports = {
|
||||
'/:identifier/:claim': { controller: serveByIdentifierAndClaim, action: Actions.onHandleShowPageUri, saga: Sagas.handleShowPageUri },
|
||||
'/:claim': { controller: serveByClaim, action: Actions.onHandleShowPageUri, saga: Sagas.handleShowPageUri },
|
||||
};
|
||||
|
|
|
@ -4,9 +4,9 @@ const handleLoginRequest = require('../../controllers/auth/login');
|
|||
const handleLogoutRequest = require('../../controllers/auth/logout');
|
||||
const handleUserRequest = require('../../controllers/auth/user');
|
||||
|
||||
module.exports = (app) => {
|
||||
app.post('/signup', speechPassport.authenticate('local-signup'), handleSignupRequest);
|
||||
app.post('/login', handleLoginRequest);
|
||||
app.get('/logout', handleLogoutRequest);
|
||||
app.get('/user', handleUserRequest);
|
||||
module.exports = {
|
||||
'/signup': { method: 'post', controller: [ speechPassport.authenticate('local-signup'), handleSignupRequest ] },
|
||||
'/login': { method: 'post', controller: handleLoginRequest },
|
||||
'/logout': { controller: handleLogoutRequest },
|
||||
'/user': { controller: handleUserRequest },
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const handlePageRequest = require('../../controllers/pages/sendReactApp');
|
||||
|
||||
module.exports = (app) => {
|
||||
app.get('*', handlePageRequest);
|
||||
module.exports = {
|
||||
'*': { controller: handlePageRequest, action: 'fallback' },
|
||||
};
|
||||
|
|
7
server/routes/index.js
Normal file
7
server/routes/index.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
module.exports = {
|
||||
...require('./pages'),
|
||||
...require('./api'),
|
||||
...require('./auth'),
|
||||
...require('./assets'),
|
||||
...require('./fallback'),
|
||||
};
|
|
@ -2,14 +2,18 @@ const handlePageRequest = require('../../controllers/pages/sendReactApp');
|
|||
const handleVideoEmbedRequest = require('../../controllers/pages/sendVideoEmbedPage');
|
||||
const redirect = require('../../controllers/utils/redirect');
|
||||
|
||||
module.exports = (app) => {
|
||||
app.get('/', handlePageRequest);
|
||||
app.get('/login', handlePageRequest);
|
||||
app.get('/about', handlePageRequest);
|
||||
app.get('/tos', handlePageRequest);
|
||||
app.get('/trending', redirect('/popular'));
|
||||
app.get('/popular', handlePageRequest);
|
||||
app.get('/new', handlePageRequest);
|
||||
app.get('/multisite', handlePageRequest);
|
||||
app.get('/video-embed/:name/:claimId', handleVideoEmbedRequest); // for twitter
|
||||
// TODO: Adjust build & sources to use import/export everywhere
|
||||
const Actions = require('@actions').default;
|
||||
const Sagas = require('@sagas').default;
|
||||
|
||||
module.exports = {
|
||||
'/': { controller: handlePageRequest, action: Actions.onHandleShowHomepage, saga: Sagas.handleShowHomepage },
|
||||
'/login': { controller: handlePageRequest },
|
||||
'/about': { controller: handlePageRequest },
|
||||
'/tos': { controller: handlePageRequest },
|
||||
'/trending': { controller: redirect('/popular') },
|
||||
'/popular': { controller: handlePageRequest },
|
||||
'/new': { controller: handlePageRequest },
|
||||
'/multisite': { controller: handlePageRequest },
|
||||
'/video-embed/:name/:claimId': { controller: handleVideoEmbedRequest }, // for twitter
|
||||
};
|
||||
|
|
26
server/utils/getClaimData.js
Normal file
26
server/utils/getClaimData.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
const { details: { host } } = require('@config/siteConfig');
|
||||
const chainquery = require('chainquery');
|
||||
|
||||
module.exports = async (data) => {
|
||||
// TODO: Refactor getching the channel name out; requires invasive changes.
|
||||
const certificateId = data.publisher_id || data.certificateId;
|
||||
let channelName = data.channelName;
|
||||
|
||||
if(certificateId && !channelName) {
|
||||
channelName = await chainquery.claim.queries.getClaimChannelName(certificateId).catch(()=>{});
|
||||
}
|
||||
|
||||
return ({
|
||||
name: data.name,
|
||||
title: data.title,
|
||||
certificateId,
|
||||
channelName,
|
||||
contentType: data.content_type || data.contentType,
|
||||
claimId: data.claim_id || data.claimId,
|
||||
fileExt: data.generated_extension || data.fileExt,
|
||||
description: data.description,
|
||||
thumbnail: data.generated_thumbnail || data.thumbnail,
|
||||
outpoint: data.transaction_hash_id || data.outpoint,
|
||||
host,
|
||||
})
|
||||
}
|
|
@ -36,9 +36,13 @@ const addAlliasesForSCSS = (aliasObject) => { // scss
|
|||
|
||||
module.exports = () => {
|
||||
let moduleAliases = {};
|
||||
|
||||
moduleAliases['chainquery'] = resolve('./server/chainquery/bundle');
|
||||
moduleAliases['server'] = resolve('./server');
|
||||
|
||||
// aliases for configs
|
||||
moduleAliases['@config'] = resolve(`config`);
|
||||
moduleAliases['@devConfig'] = resolve(`devConfig`);
|
||||
moduleAliases['@config'] = resolve('config');
|
||||
moduleAliases['@devConfig'] = resolve('devConfig');
|
||||
|
||||
// create specific aliases for locally defined components in the following folders
|
||||
moduleAliases = addAliasesForCustomComponentFolder('containers', moduleAliases);
|
||||
|
|
Loading…
Reference in a new issue