Merge branch 'master' into chore/linter

# Conflicts:
#	lib/contracts/contribution.js
#	lib/contracts/contributor.js
#	lib/contracts/proposal.js
#	lib/kredits.js
#	lib/serializers/contributor.js
#	yarn.lock
This commit is contained in:
2019-04-24 19:12:18 +02:00
31 changed files with 32965 additions and 120 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -2
View File
@@ -1,4 +1,3 @@
{
"4": "0x76e069b47b79442657eaf0555a32c6b16fa1b8b4",
"41787949": "0xa35aacdfccac54d3d96e0d29050c773b251c2c83"
"4": "0x76e069b47b79442657eaf0555a32c6b16fa1b8b4"
}
+1 -2
View File
@@ -1,4 +1,3 @@
{
"4": "0xcd75458fbc4aa2231252d5b21f1391fd031e5cb2",
"41787949": "0x183af3950364390a266edff2a0e7c4c2f95c0691"
"4": "0xc34edf7d11b7f8433d597f0bb0697acdff55ef14"
}
+4 -14
View File
@@ -1,19 +1,9 @@
const Record = require('./record');
const ContributionSerializer = require('../serializers/contribution');
const Base = require('./base');
class Contribution extends Base {
all () {
return this.functions.contributionsCount()
.then(async (count) => {
let contributions = [];
for (let id = 1; id <= count; id++) {
const contribution = await this.getById(id);
contributions.push(contribution);
}
return contributions;
});
class Contribution extends Record {
get count () {
return this.functions.contributionsCount();
}
getById (id) {
+39 -20
View File
@@ -1,25 +1,16 @@
const RSVP = require('rsvp');
const Record = require('./record');
const ContributorSerializer = require('../serializers/contributor');
const Base = require('./base');
const formatKredits = require('../utils/format-kredits');
class Contributor extends Base {
all () {
return this.functions.contributorsCount()
.then(count => {
let contributors = [];
for (let id = 1; id <= count; id++) {
contributors.push(this.getById(id));
}
return RSVP.all(contributors);
});
class Contributor extends Record {
get count () {
return this.functions.contributorsCount();
}
getById (id) {
return this.functions.getContributorById(id)
.then((data) => {
.then(data => {
data.balanceInt = formatKredits(data.balance);
return this.ipfs.catAndMerge(data, ContributorSerializer.deserialize);
});
}
@@ -48,12 +39,16 @@ class Contributor extends Base {
});
}
add (contributorAttr, callOptions = {}) {
let json = ContributorSerializer.serialize(contributorAttr);
// TODO: validate against schema
async add (contributorAttr, callOptions = {}) {
let contributor = new ContributorSerializer(contributorAttr);
try { await contributor.validate(); }
catch (error) { return Promise.reject(error); }
const jsonStr = contributor.serialize();
return this.ipfs
.add(json)
.add(jsonStr)
.then((ipfsHashAttr) => {
let contributor = [
contributorAttr.account,
@@ -65,6 +60,30 @@ class Contributor extends Base {
return this.functions.addContributor(...contributor, callOptions);
});
}
updateProfile (contributorId, updateAttr, callOptions = {}) {
return this.getById(contributorId).then(async (contributor) => {
let updatedContributorAttr = Object.assign(contributor, updateAttr)
let updatedContributor = new ContributorSerializer(updatedContributorAttr);
try { await updatedContributor.validate(); }
catch (error) { return Promise.reject(error); }
const jsonStr = updatedContributor.serialize();
return this.ipfs
.add(jsonStr)
.then(ipfsHashAttr => {
return this.functions.updateContributorProfileHash(
contributorId,
ipfsHashAttr.hashDigest,
ipfsHashAttr.hashFunction,
ipfsHashAttr.hashSize,
callOptions
);
});
});
}
}
module.exports = Contributor;
+4 -15
View File
@@ -1,20 +1,9 @@
const RSVP = require('rsvp');
const Record = require('./record');
const ContributionSerializer = require('../serializers/contribution');
const Base = require('./base');
class Proposal extends Base {
all () {
return this.functions.proposalsCount()
.then(count => {
let proposals = [];
for (let id = 1; id <= count; id++) {
proposals.push(this.getById(id));
}
return RSVP.all(proposals);
});
class Proposal extends Record {
get count () {
return this.functions.proposalsCount();
}
getById (id) {
+14
View File
@@ -0,0 +1,14 @@
const Base = require('./base');
const paged = require('../utils/pagination');
class Record extends Base {
all(options = {}) {
return this.count
.then((count) => {
let records = paged(count, options).map((id) => this.getById(id));
return Promise.all(records);
});
}
}
module.exports = Record
+2 -2
View File
@@ -1,5 +1,4 @@
const ethers = require('ethers');
const RSVP = require('rsvp');
const Preflight = require('./utils/preflight');
@@ -57,7 +56,8 @@ class Kredits {
);
});
});
return RSVP.all(addressPromises).then(() => { return this; });
return Promise.all(addressPromises).then(() => { return this });
});
}
+69 -36
View File
@@ -1,3 +1,5 @@
const schemas = require('kosmos-schemas');
const validator = require('../utils/validator');
/**
* Handle serialization for JSON-LD object of the contributor, according to
* https://github.com/67P/kosmos-schemas/blob/master/schemas/contributor.json
@@ -6,41 +8,9 @@
* @public
*/
class Contributor {
/**
* Deserialize JSON to object
*
* @method
* @public
*/
static deserialize (serialized) {
let {
name,
kind,
url,
accounts,
} = JSON.parse(serialized.toString('utf8'));
let github_username, github_uid, wiki_username;
let github = accounts.find((a) => a.site === 'github.com');
let wiki = accounts.find((a) => a.site === 'wiki.kosmos.org');
if (github) {
(({ username: github_username, uid: github_uid} = github));
}
if (wiki) {
(({ username: wiki_username } = wiki));
}
return {
name,
kind,
url,
accounts,
github_uid,
github_username,
wiki_username,
ipfsData: serialized,
};
constructor (attrs) {
Object.keys(attrs).forEach(a => this[a] = attrs[a]);
}
/**
@@ -49,15 +19,16 @@ class Contributor {
* @method
* @public
*/
static serialize (deserialized) {
serialize () {
let {
name,
kind,
url,
github_uid,
github_username,
gitea_username,
wiki_username,
} = deserialized;
} = this;
let data = {
"@context": "https://schema.kosmos.org",
@@ -80,6 +51,14 @@ class Contributor {
});
}
if (gitea_username) {
data.accounts.push({
"site": "gitea.kosmos.org",
"username": gitea_username,
"url": `https://gitea.kosmos.org/${gitea_username}`
});
}
if (wiki_username) {
data.accounts.push({
"site": "wiki.kosmos.org",
@@ -91,6 +70,60 @@ class Contributor {
// Write it pretty to ipfs
return JSON.stringify(data, null, 2);
}
/**
* Validate serialized data against schema
*
* @public
*/
validate () {
const serialized = JSON.parse(this.serialize());
const valid = validator.validate(serialized, schemas['contributor']);
return valid ? Promise.resolve() : Promise.reject(validator.error);
}
/**
* Deserialize JSON to object
*
* @method
* @public
*/
static deserialize (serialized) {
let {
name,
kind,
url,
accounts,
} = JSON.parse(serialized.toString('utf8'));
let github_username, github_uid, gitea_username, wiki_username;
let github = accounts.find(a => a.site === 'github.com');
let gitea = accounts.find(a => a.site === 'gitea.kosmos.org');
let wiki = accounts.find(a => a.site === 'wiki.kosmos.org');
if (github) {
(({ username: github_username, uid: github_uid} = github));
}
if (gitea) {
(({ username: gitea_username } = gitea));
}
if (wiki) {
(({ username: wiki_username } = wiki));
}
return {
name,
kind,
url,
accounts,
github_uid,
github_username,
gitea_username,
wiki_username,
ipfsData: serialized,
};
}
}
module.exports = Contributor;
+10
View File
@@ -0,0 +1,10 @@
const ethersUtils = require('ethers').utils;
module.exports = function (value, options = {}) {
let etherValue = ethersUtils.formatEther(value);
if (options.asFloat) {
return parseFloat(etherValue);
} else {
return parseInt(etherValue);
}
}
+46
View File
@@ -0,0 +1,46 @@
function pageNumber(number, size, recordCount) {
let numberOfPages = Math.ceil(recordCount / size);
number = parseInt(number) || 1;
// Ensure page number is in range
number = number < 1 ? 1 : number;
number = number > numberOfPages ? numberOfPages : number;
return number;
}
function buildIds(order, number, size, recordCount) {
let offset = size * (number - 1);
let start;
let mapFunction;
if (order === 'asc') {
start = 1 + offset;
mapFunction = (_, i) => start + i;
} else {
start = recordCount - offset;
mapFunction = (_, i) => start - i;
}
// Ensure size is in range
let end = offset + size;
if (end > recordCount) {
let diff = end - recordCount;
size = size - diff;
}
return Array.from({ length: size }, mapFunction);
}
module.exports = function paged(recordCount, options = {}) {
let { order, page } = options;
order = order || 'desc';
page = page || {};
let size = parseInt(page.size) || 25;
let number = pageNumber(page.number, size, recordCount);
return buildIds(order, number, size, recordCount);
};