diff --git a/.eslintrc b/.eslintrc new file mode 100644 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "sealcode" +} diff --git a/.prettierrc b/.prettierrc new file mode 100644 --- /dev/null +++ b/.prettierrc @@ -0,0 +1 @@ +{ "tabWidth": 4, "trailingComma": "es5", "useTabs": true } diff --git a/lib/action.js b/lib/action.js --- a/lib/action.js +++ b/lib/action.js @@ -1,7 +1,5 @@ -"use strict"; const locreq = require("locreq")(__dirname); const SubjectPath = locreq("lib/data-structures/subject-path.js"); -const Promise = require("bluebird"); function Action(RootSubject, subject_path, action_name) { this.RootSubject = RootSubject; diff --git a/lib/app/app.js b/lib/app/app.js --- a/lib/app/app.js +++ b/lib/app/app.js @@ -1,6 +1,5 @@ const locreq = require("locreq")(__dirname); const assert = require("assert"); -const path = require("path"); const Sealious = locreq("lib/main.js"); @@ -39,7 +38,7 @@ this.Query = Query; this.manifest = manifest; - this.checkManifest(manifest); + this.checkManifest(); this.i18n = i18nFactory(manifest.default_language); @@ -88,8 +87,8 @@ ); } - checkManifest(manifest) { - assert(manifest, "Please provide the app manifest"); + checkManifest() { + assert(this.manifest, "Please provide the app manifest"); [ "name", "logo", @@ -99,17 +98,14 @@ "admin_email", ].forEach(key => { assert( - manifest[key], + this.manifest[key], `Please specify '${key}' field in the app manifest` ); }); } createChip(constructor, declaration) { - const chip = new constructor( - this, - declaration - ); + const chip = new constructor(this, declaration); this.ChipManager.add_chip( constructor.type_name, declaration.name, @@ -128,6 +124,8 @@ ); await this.emit({ when: "before", action: "start" }); + await this.FileManager.init(); + await this.Datastore.start(); await this.Mail.init(); await this.ChipManager.start_chips(); diff --git a/lib/app/base-chips/access-strategy-types/and.js b/lib/app/base-chips/access-strategy-types/and.js --- a/lib/app/base-chips/access-strategy-types/and.js +++ b/lib/app/base-chips/access-strategy-types/and.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const AccessStrategy = locreq("lib/chip-types/access-strategy.js"); @@ -11,33 +10,31 @@ module.exports = function(app) { const and = { name: "and", - getRestrictingQuery: async function(context, params) { + async getRestrictingQuery(context, params) { const access_strategies = parse_params(app, params); const queries = await Promise.map(access_strategies, strategy => strategy.getRestrictingQuery(context) ); return new Query.And(...queries); }, - item_sensitive: function(params) { + item_sensitive(params) { const access_strategies = parse_params(app, params); - return Promise.map(access_strategies, function(access_strategy) { - return access_strategy.is_item_sensitive(); - }).reduce((a, b) => a || b); + return Promise.map(access_strategies, access_strategy => + access_strategy.is_item_sensitive() + ).reduce((a, b) => a || b); }, - checker_function: function(context, params, item) { - return and.item_sensitive(params).then(function(item_sensitive) { + checker_function(context, params, item) { + return and.item_sensitive(params).then(item_sensitive => { if (item_sensitive && item === undefined) { return undefined; - } else { - const access_strategies = parse_params(app, params); - const results = access_strategies.map(function(strategy) { - return strategy.check(context, item); - }); - return Promise.all(results); } + const access_strategies = parse_params(app, params); + const results = access_strategies.map(strategy => + strategy.check(context, item) + ); + return Promise.all(results); }); }, }; - return and; }; diff --git a/lib/app/base-chips/access-strategy-types/and.subtest.js b/lib/app/base-chips/access-strategy-types/and.subtest.js --- a/lib/app/base-chips/access-strategy-types/and.subtest.js +++ b/lib/app/base-chips/access-strategy-types/and.subtest.js @@ -8,9 +8,7 @@ ); describe("AndAccessStrategy", () => { - let port; async function setup(app) { - port = app.ConfigManager.get("www-server.port"); app.createChip(Sealious.Collection, { name: "numbers", fields: [ @@ -48,7 +46,7 @@ for (const { name, strategies } of collections) { app.createChip(Sealious.Collection, { - name: name, + name, fields: [ { name: "number", diff --git a/lib/app/base-chips/access-strategy-types/logged_in.js b/lib/app/base-chips/access-strategy-types/logged_in.js --- a/lib/app/base-chips/access-strategy-types/logged_in.js +++ b/lib/app/base-chips/access-strategy-types/logged_in.js @@ -1,22 +1,18 @@ -"use strict"; const Promise = require("bluebird"); const Query = require("../../../datastore/query.js"); module.exports = { name: "logged_in", - getRestrictingQuery: async function(context) { + async getRestrictingQuery(context) { if (context.user_id) { return new Query.AllowAll(); } return new Query.DenyAll(); }, - checker_function: function(context) { + checker_function(context) { if (context.user_id) { return Promise.resolve(); - } else { - return Promise.reject( - "Only logged-in users can perform this action." - ); } + return Promise.reject("Only logged-in users can perform this action."); }, }; diff --git a/lib/app/base-chips/access-strategy-types/noone.js b/lib/app/base-chips/access-strategy-types/noone.js --- a/lib/app/base-chips/access-strategy-types/noone.js +++ b/lib/app/base-chips/access-strategy-types/noone.js @@ -1,13 +1,12 @@ -"use strict"; const Promise = require("bluebird"); const Query = require("../../../datastore/query.js"); module.exports = { name: "noone", - getRestrictingQuery: async function() { + async getRestrictingQuery() { return new Query.DenyAll(); }, - checker_function: function() { + checker_function() { return Promise.reject("Noone gets in!"); }, item_sensitive: false, diff --git a/lib/app/base-chips/access-strategy-types/not.js b/lib/app/base-chips/access-strategy-types/not.js --- a/lib/app/base-chips/access-strategy-types/not.js +++ b/lib/app/base-chips/access-strategy-types/not.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const AccessStrategy = locreq("lib/chip-types/access-strategy.js"); @@ -19,31 +18,27 @@ module.exports = function(app) { return { name: "not", - getRestrictingQuery: async function(context, params) { + async getRestrictingQuery(context, params) { //assuming "not" can take only one access strategy as a parameter const strategy = parse_params(app, params)[0]; const query = await strategy.getRestrictingQuery(context); return new Query.Not(query); }, - item_sensitive: function(params) { + item_sensitive(params) { const access_strategies = parse_params(app, params); - return Promise.map(access_strategies, function(access_strategy) { - return access_strategy.is_item_sensitive(); - }).reduce((a, b) => a || b, false); + return Promise.map(access_strategies, access_strategy => + access_strategy.is_item_sensitive() + ).reduce((a, b) => a || b, false); }, - checker_function: function(context, params, item) { + checker_function(context, params, item) { const strategies = parse_params(app, params); - return Promise.map(strategies, function(strategy) { + return Promise.map(strategies, strategy => { return strategy.check(context, item); }) .any() - .then(function() { - return Promise.reject("Action not allowed"); - }) - .catch({ sealious_error: true }, function() { - return Promise.resolve(); - }); + .then(() => Promise.reject("Action not allowed")) + .catch({ sealious_error: true }, () => Promise.resolve()); }, }; }; diff --git a/lib/app/base-chips/access-strategy-types/not.subtest.js b/lib/app/base-chips/access-strategy-types/not.subtest.js --- a/lib/app/base-chips/access-strategy-types/not.subtest.js +++ b/lib/app/base-chips/access-strategy-types/not.subtest.js @@ -1,14 +1,11 @@ -const assert = require("assert"); const locreq = require("locreq")(__dirname); +const assert = require("assert"); const Promise = require("bluebird"); - const { with_running_app } = locreq("test_utils/with-test-app.js"); const assert_throws_async = locreq("test_utils/assert_throws_async.js"); describe("NotAccessStrategy", () => { - let port; async function setup(app) { - port = app.ConfigManager.get("www-server.port"); app.createChip(Sealious.Collection, { name: "numbers", fields: [ @@ -43,7 +40,7 @@ for (const { name, strategy } of collections) { app.createChip(Sealious.Collection, { - name: name, + name, fields: [ { name: "number", @@ -81,7 +78,7 @@ function create_less_than_strategy(app, number) { app.createChip(app.Sealious.AccessStrategyType, { name: `less-than(${number})`, - getRestrictingQuery: async function() { + async getRestrictingQuery() { const query = new app.Query(); const id = query.lookup({ from: "numbers", @@ -95,7 +92,7 @@ }); return query; }, - checker_function: async function(context, params, item) { + async checker_function(context, params, item) { if (item.number.number >= number) { return Promise.reject( `Given value is not lower than ${number}` @@ -110,10 +107,8 @@ with_running_app(async ({ app, rest_api }) => { await setup(app); await assert_throws_async( - async () => - await rest_api.get( - "/api/v1/collections/collection-not(public)" - ), + () => + rest_api.get("/api/v1/collections/collection-not(public)"), e => { assert.equal(e.response.status, 401); } diff --git a/lib/app/base-chips/access-strategy-types/or.js b/lib/app/base-chips/access-strategy-types/or.js --- a/lib/app/base-chips/access-strategy-types/or.js +++ b/lib/app/base-chips/access-strategy-types/or.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const Error = locreq("lib/response/error.js").Error; @@ -12,7 +11,7 @@ module.exports = function(app) { const or = { name: "or", - getRestrictingQuery: async function(context, params) { + async getRestrictingQuery(context, params) { const access_strategies = parse_params(app, params); const queries = await Promise.map(access_strategies, strategy => strategy.getRestrictingQuery(context) @@ -22,42 +21,40 @@ } return new Query.Or(...queries); }, - item_sensitive: function(params) { + item_sensitive(params) { const access_strategies = parse_params(app, params); - return Promise.map(access_strategies, function(access_strategy) { - return access_strategy.is_item_sensitive(); - }).reduce((a, b) => a || b); + return Promise.map(access_strategies, access_strategy => + access_strategy.is_item_sensitive() + ).reduce((a, b) => a || b); }, - checker_function: function(context, params, item) { + checker_function(context, params, item) { if (context.is_super) { return Promise.resolve(); } - return or.item_sensitive(params).then(function(item_sensitive) { + return or.item_sensitive(params).then(item_sensitive => { if (item_sensitive && item === undefined) { return undefined; - } else { - const access_strategies = parse_params(app, params); - const results = access_strategies.map(function(strategy) { - return strategy.check(context, item); - }); - return Promise.any(results).catch( - Promise.AggregateError, - function(aggregated_errors) { - aggregated_errors.forEach(function(error) { - if (!(error instanceof Error)) { - throw error; - } - }); - const error_message = aggregated_errors - .map( - aggregated_errors => - aggregated_errors.message - ) - .reduce((a, b) => `${a} ${b}`); - return Promise.reject(error_message); - } - ); } + const access_strategies = parse_params(app, params); + const results = access_strategies.map(strategy => + strategy.check(context, item) + ); + return Promise.any(results).catch( + Promise.AggregateError, + aggregated_errors => { + aggregated_errors.forEach(error => { + if (!(error instanceof Error)) { + throw error; + } + }); + const error_message = aggregated_errors + .map( + _aggregated_errors => _aggregated_errors.message + ) + .reduce((a, b) => `${a} ${b}`); + return Promise.reject(error_message); + } + ); }); }, }; diff --git a/lib/app/base-chips/access-strategy-types/or.subtest.js b/lib/app/base-chips/access-strategy-types/or.subtest.js --- a/lib/app/base-chips/access-strategy-types/or.subtest.js +++ b/lib/app/base-chips/access-strategy-types/or.subtest.js @@ -1,17 +1,13 @@ -const assert = require("assert"); const locreq = require("locreq")(__dirname); +const assert = require("assert"); const Promise = require("bluebird"); - const { with_running_app } = locreq("test_utils/with-test-app.js"); -const { get_collection_as, create_resource_as } = locreq("test_utils"); const create_strategies = locreq( "test_utils/access-strategy-types/create_strategies_with_complex_pipeline" ); describe("OrAccessStrategy", () => { - let port; async function setup(app) { - port = app.ConfigManager.get("www-server.port"); app.createChip(Sealious.Collection, { name: "numbers", fields: [ @@ -49,7 +45,7 @@ for (const { name, strategies } of collections) { app.createChip(Sealious.Collection, { - name: name, + name, fields: [ { name: "number", diff --git a/lib/app/base-chips/access-strategy-types/owner.js b/lib/app/base-chips/access-strategy-types/owner.js --- a/lib/app/base-chips/access-strategy-types/owner.js +++ b/lib/app/base-chips/access-strategy-types/owner.js @@ -1,10 +1,9 @@ -"use strict"; const Promise = require("bluebird"); const Query = require("../../../datastore/query.js"); module.exports = { name: "owner", - getRestrictingQuery: async function(context, params) { + async getRestrictingQuery(context, params) { if (context.user_id) { return Query.fromSingleMatch({ "_metadata.created_context.user_id": { $eq: context.user_id }, @@ -12,17 +11,16 @@ } return new Query.DenyAll(); }, - checker_function: function(context, params, item) { + checker_function(context, params, item) { if ( context.user_id && context.user_id === item._metadata.created_context.user_id ) { return Promise.resolve(); - } else { - return Promise.reject( - "Only the owner of this resource can perform this operation on this item." - ); } + return Promise.reject( + "Only the owner of this resource can perform this operation on this item." + ); }, item_sensitive: true, }; diff --git a/lib/app/base-chips/access-strategy-types/public.js b/lib/app/base-chips/access-strategy-types/public.js --- a/lib/app/base-chips/access-strategy-types/public.js +++ b/lib/app/base-chips/access-strategy-types/public.js @@ -1,14 +1,13 @@ -"use strict"; const Promise = require("bluebird"); const Query = require("../../../datastore/query.js"); module.exports = { name: "public", - getRestrictingQuery: async function() { + async getRestrictingQuery() { return new Query.AllowAll(); }, - checker_function: function() { + checker_function() { return Promise.resolve("Everybody is a winner!"); }, item_sensitive: false, diff --git a/lib/app/base-chips/access-strategy-types/same-anon.js b/lib/app/base-chips/access-strategy-types/same-anon.js --- a/lib/app/base-chips/access-strategy-types/same-anon.js +++ b/lib/app/base-chips/access-strategy-types/same-anon.js @@ -1,9 +1,8 @@ -"use strict"; const Query = require("../../../datastore/query.js"); module.exports = { name: "same-anon", - getRestrictingQuery: async function(context, params) { + async getRestrictingQuery(context, params) { if (context.anonymous_user_id) { return Query.fromSingleMatch({ "_metadata.created_context.anonymous_user_id": @@ -12,7 +11,7 @@ } return new Query.AllowAll(); }, - checker_function: function(context, params, item) { + checker_function(context, params, item) { if (context.anonymous_user_id === null) { return Promise.reject(); } @@ -21,11 +20,10 @@ item._metadata.created_context.anonymous_user_id ) { return Promise.resolve(); - } else { - return Promise.reject( - "Only the user who created this resource can have access to it" - ); } + return Promise.reject( + "Only the user who created this resource can have access to it" + ); }, item_sensitive: true, }; diff --git a/lib/app/base-chips/access-strategy-types/same-as-for-resource-in-field.js b/lib/app/base-chips/access-strategy-types/same-as-for-resource-in-field.js --- a/lib/app/base-chips/access-strategy-types/same-as-for-resource-in-field.js +++ b/lib/app/base-chips/access-strategy-types/same-as-for-resource-in-field.js @@ -2,10 +2,7 @@ module.exports = app => ({ name: "same-as-for-resource-in-field", - getRestrictingQuery: async function( - context, - { action_name, collection, field } - ) { + async getRestrictingQuery(context, { action_name, collection, field }) { const referenced_collection = get_referenced_collection( app, collection, @@ -47,11 +44,7 @@ return Query.fromCustomPipeline(pipeline); }, - checker_function: async function( - context, - { action_name, collection, field }, - item - ) { + async checker_function(context, { action_name, collection, field }, item) { const referenced_collection = get_referenced_collection( app, collection, @@ -111,7 +104,7 @@ group[prop] = add_parent_prefix(group[prop], parent_property); } const new_prop = prop_regex.test(prop) - ? parent_property + "." + prop + ? `${parent_property}.${prop}` : prop; acc[new_prop] = group[prop]; return acc; diff --git a/lib/app/base-chips/access-strategy-types/same-as-for-resource-in-field.subtest.js b/lib/app/base-chips/access-strategy-types/same-as-for-resource-in-field.subtest.js --- a/lib/app/base-chips/access-strategy-types/same-as-for-resource-in-field.subtest.js +++ b/lib/app/base-chips/access-strategy-types/same-as-for-resource-in-field.subtest.js @@ -4,13 +4,10 @@ const assert_throws_async = locreq("test_utils/assert_throws_async.js"); describe("SameAsForResourceInField", () => { - let port; let numbers; const sessions = {}; async function setup(app, rest_api, access_strategy) { numbers = []; - port = app.ConfigManager.get("www-server.port"); - app.createChip(Sealious.Collection, { name: "numbers", fields: [ @@ -62,7 +59,7 @@ const password = "password"; for (let username of ["alice", "bob"]) { - const user = await app.run_action( + await app.run_action( new app.Sealious.SuperContext(), ["collections", "users"], "create", @@ -98,8 +95,8 @@ await rest_api.post( "/api/v1/collections/number-notes", { - note: "Lorem ipsum " + (notes.length + 1), - number: number, + note: `Lorem ipsum ${notes.length + 1}`, + number, }, sessions[user] ) @@ -132,18 +129,11 @@ it("returns nothing for number-notes referring to other user's numbers", () => with_running_app(async ({ app, rest_api, base_url }) => { await setup(app, rest_api, { create: "public", show: "owner" }); - - const posted_notes = await post_number_notes( - app, - rest_api, - "alice" - ); - + await post_number_notes(app, rest_api, "alice"); const { items: got_notes } = await rest_api.get( "/api/v1/collections/number-notes", sessions.bob ); - assert.equal(got_notes.length, 0); })); @@ -159,18 +149,11 @@ ], ], }); - - const posted_notes = await post_number_notes( - app, - rest_api, - "alice" - ); - + await post_number_notes(app, rest_api, "alice"); const { items: got_notes } = await rest_api.get( "/api/v1/collections/number-notes", sessions.bob ); - assert.equal(got_notes.length, 1); })); diff --git a/lib/app/base-chips/access-strategy-types/super.js b/lib/app/base-chips/access-strategy-types/super.js --- a/lib/app/base-chips/access-strategy-types/super.js +++ b/lib/app/base-chips/access-strategy-types/super.js @@ -1,24 +1,21 @@ -"use strict"; -const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const Query = require("../../../datastore/query.js"); const Super = { name: "super", - getRestrictingQuery: async function(context) { + async getRestrictingQuery(context) { if (context.is_super) { return new Query.AllowAll(); } return new Query.DenyAll(); }, - checker_function: function(context) { + checker_function(context) { if (context.is_super) { return Promise.resolve(); - } else { - return Promise.reject( - "This action cannot be performed by a regular user, but only by the server itself." - ); } + return Promise.reject( + "This action cannot be performed by a regular user, but only by the server itself." + ); }, item_sensitive: true, }; diff --git a/lib/app/base-chips/access-strategy-types/themselves.js b/lib/app/base-chips/access-strategy-types/themselves.js --- a/lib/app/base-chips/access-strategy-types/themselves.js +++ b/lib/app/base-chips/access-strategy-types/themselves.js @@ -1,21 +1,18 @@ -"use strict"; -const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const Query = require("../../../datastore/query.js"); module.exports = { name: "themselves", item_sensitive: true, - getRestrictingQuery: async function(context, params) { + async getRestrictingQuery(context, params) { return Query.fromSingleMatch({ sealious_id: { $eq: context.user_id }, }); }, - checker_function: function(context, params, item) { + checker_function(context, params, item) { if (context.user_id === item.id) { return Promise.resolve(); - } else { - return Promise.reject(`You are not the user of id ${item.id}.`); } + return Promise.reject(`You are not the user of id ${item.id}.`); }, }; diff --git a/lib/app/base-chips/access-strategy-types/user-referenced-in-field.js b/lib/app/base-chips/access-strategy-types/user-referenced-in-field.js --- a/lib/app/base-chips/access-strategy-types/user-referenced-in-field.js +++ b/lib/app/base-chips/access-strategy-types/user-referenced-in-field.js @@ -9,7 +9,7 @@ checker_function: (context, field_name, item) => { if (!context.user_id) return Promise.reject("You're not logged in!"); else if (context.user_id === item[field_name]) return Promise.resolve(); - else return Promise.reject("Access not allowed for this user"); + return Promise.reject("Access not allowed for this user"); }, item_sensitive: true, }); diff --git a/lib/app/base-chips/access-strategy-types/user-referenced-in-field.subtest.js b/lib/app/base-chips/access-strategy-types/user-referenced-in-field.subtest.js --- a/lib/app/base-chips/access-strategy-types/user-referenced-in-field.subtest.js +++ b/lib/app/base-chips/access-strategy-types/user-referenced-in-field.subtest.js @@ -28,7 +28,7 @@ ["collections", "users"], "create", { - username: username, + username, password: "password", email: `${username.toLowerCase()}@example.com`, } diff --git a/lib/app/base-chips/access-strategy-types/users-who-can.js b/lib/app/base-chips/access-strategy-types/users-who-can.js --- a/lib/app/base-chips/access-strategy-types/users-who-can.js +++ b/lib/app/base-chips/access-strategy-types/users-who-can.js @@ -13,11 +13,7 @@ module.exports = app => ({ name: "users-who-can", - get_pre_aggregation_stage: async function( - context, - [action_name, collection], - item - ) { + async get_pre_aggregation_stage(context, [action_name, collection], item) { check_params(app, [action_name, collection]); try { await collection.get_access_strategy(action_name).check(context); @@ -26,7 +22,7 @@ return Promise.resolve(DENY); } }, - checker_function: async function(context, [action_name, collection]) { + async checker_function(context, [action_name, collection]) { check_params(app, [action_name, collection]); try { await collection.get_access_strategy(action_name).check(context); diff --git a/lib/app/base-chips/access-strategy-types/when.js b/lib/app/base-chips/access-strategy-types/when.js --- a/lib/app/base-chips/access-strategy-types/when.js +++ b/lib/app/base-chips/access-strategy-types/when.js @@ -1,4 +1,3 @@ -"use strict"; const Promise = require("bluebird"); const Query = require("../../../datastore/query.js"); @@ -29,7 +28,7 @@ module.exports = app => ({ name: "when", - getRestrictingQuery: async function( + async getRestrictingQuery( context, [ collection_name, @@ -47,7 +46,7 @@ when_false_name ); }, - checker_function: async function( + async checker_function( context, [ collection_name, diff --git a/lib/app/base-chips/access-strategy-types/when.subtest.js b/lib/app/base-chips/access-strategy-types/when.subtest.js --- a/lib/app/base-chips/access-strategy-types/when.subtest.js +++ b/lib/app/base-chips/access-strategy-types/when.subtest.js @@ -1,7 +1,6 @@ const locreq = require("locreq")(__dirname); const assert = require("assert"); const { with_stopped_app } = locreq("test_utils/with-test-app.js"); -const assert_throws_async = locreq("test_utils/assert_throws_async.js"); describe("when", () => { async function create_resources(app) { diff --git a/lib/app/base-chips/calculated-field-types/aggregate.js b/lib/app/base-chips/calculated-field-types/aggregate.js --- a/lib/app/base-chips/calculated-field-types/aggregate.js +++ b/lib/app/base-chips/calculated-field-types/aggregate.js @@ -1,22 +1,13 @@ -"use strict"; -const Promise = require("bluebird"); - module.exports = function(app) { return { name: "aggregate", - calculate: function(context, params, item, db_document) { + calculate(context, params, item, db_document) { let stages = params.stages; if (params.stages instanceof Function) { stages = params.stages(context, params, item, db_document); } return app.Datastore.aggregate(params.collection, stages).then( - function(documents) { - if (documents.length) { - return documents[0].result; - } else { - return null; - } - } + documents => (documents.length ? documents[0].result : null) ); }, }; diff --git a/lib/app/base-chips/calculated-field-types/custom.js b/lib/app/base-chips/calculated-field-types/custom.js --- a/lib/app/base-chips/calculated-field-types/custom.js +++ b/lib/app/base-chips/calculated-field-types/custom.js @@ -1,10 +1,7 @@ -"use strict"; -const Promise = require("bluebird"); - module.exports = function(app) { return { name: "custom", - calculate: function(context, params, item, db_document) { + calculate(context, params, item, db_document) { return params(app, context, item, db_document); }, }; diff --git a/lib/app/base-chips/calculated-field-types/map-reduce.js b/lib/app/base-chips/calculated-field-types/map-reduce.js --- a/lib/app/base-chips/calculated-field-types/map-reduce.js +++ b/lib/app/base-chips/calculated-field-types/map-reduce.js @@ -3,21 +3,20 @@ module.exports = function(App) { return { name: "map-reduce", - calculate: function(context, params, item) { + calculate(context, params, item) { const action_arguments = [ context, params.source.subject_path, params.source.action_name, params.source.params, - ].map(function(element) { - if (element instanceof Function) { - return element(context, params, item); - } else { - return element; - } - }); + ].map( + element => + element instanceof Function + ? element(context, params, item) + : element + ); return Promise.all(action_arguments) - .then(function(fulfilled_action_arguments) { + .then(fulfilled_action_arguments => { return App.run_action.apply( App, fulfilled_action_arguments diff --git a/lib/app/base-chips/collections/formatted-images.js b/lib/app/base-chips/collections/formatted-images.js --- a/lib/app/base-chips/collections/formatted-images.js +++ b/lib/app/base-chips/collections/formatted-images.js @@ -1,4 +1,3 @@ -"use strict"; module.exports = { name: "formatted-images", fields: [ diff --git a/lib/app/base-chips/collections/password-reset-intents.subtest.js b/lib/app/base-chips/collections/password-reset-intents.subtest.js --- a/lib/app/base-chips/collections/password-reset-intents.subtest.js +++ b/lib/app/base-chips/collections/password-reset-intents.subtest.js @@ -1,7 +1,6 @@ const locreq = require("locreq")(__dirname); const axios = require("axios"); const assert = require("assert"); -const { promise_timeout } = locreq("test_utils"); const { with_running_app, with_running_app_prod } = locreq( "test_utils/with-test-app.js" ); @@ -79,14 +78,14 @@ it("sends an email with the reset password link", async () => with_running_app_prod(async ({ app, base_url, mail_api }) => { await create_a_user(app); - const data = (await axios.post( + await axios.post( `${base_url}/api/v1/collections/password-reset-intents`, { email: "user@example.com", } - )).data; + ); const messages = (await mail_api.get_messages()).filter( - message => message.recipients[0] == "" + message => message.recipients[0] === "" ); assert(messages.length, 1); assert.equal(messages[0].recipients.length, 1); diff --git a/lib/app/base-chips/collections/registration-intents.subtest.js b/lib/app/base-chips/collections/registration-intents.subtest.js --- a/lib/app/base-chips/collections/registration-intents.subtest.js +++ b/lib/app/base-chips/collections/registration-intents.subtest.js @@ -7,19 +7,6 @@ ); describe("registration-intents", () => { - async function create_a_user(app) { - await app.run_action( - new app.Sealious.SuperContext(), - ["collections", "users"], - "create", - { - username: "user", - email: "user@example.com", - password: "password", - } - ); - } - it("doesn't allow setting a role for registration intention when the user in context can't create user-roles", async () => with_running_app(async ({ app, base_url }) => { app.ChipManager.get_chip( diff --git a/lib/app/base-chips/collections/users.js b/lib/app/base-chips/collections/users.js --- a/lib/app/base-chips/collections/users.js +++ b/lib/app/base-chips/collections/users.js @@ -1,4 +1,3 @@ -"use strict"; module.exports = app => { const user_roles = app.ChipManager.get_chip("collection", "user-roles"); const users = { diff --git a/lib/app/base-chips/collections/users.subtest.js b/lib/app/base-chips/collections/users.subtest.js --- a/lib/app/base-chips/collections/users.subtest.js +++ b/lib/app/base-chips/collections/users.subtest.js @@ -40,8 +40,8 @@ it("should correctly handle me when not logged in", async () => with_running_app(async ({ app, rest_api }) => { await assert_throws_async( - async () => - await rest_api.get( + () => + rest_api.get( "/api/v1/users/me?format%5Broles%5D=expand" ), e => { @@ -68,8 +68,8 @@ ]; for (let variant of incorrect_password_variants) { await assert_throws_async( - async () => - await rest_api.login({ + () => + rest_api.login({ username: "seal", password: variant.password, }), @@ -109,8 +109,8 @@ ]; for (let variant of incorrect_username_variants) { await assert_throws_async( - async () => - await rest_api.login({ + () => + rest_api.login({ username: variant.username, password: "seal", }), diff --git a/lib/app/base-chips/field-types/boolean.js b/lib/app/base-chips/field-types/boolean.js --- a/lib/app/base-chips/field-types/boolean.js +++ b/lib/app/base-chips/field-types/boolean.js @@ -1,10 +1,9 @@ -"use strict"; module.exports = { name: "boolean", - get_description: function() { + get_description() { return 'Boolean value. True or false. Can be a string: "true" or "false".'; }, - is_proper_value: function(context, params, value) { + is_proper_value(context, params, value) { if (typeof value === "boolean") { return Promise.resolve(); } else if (value.toString() === "1" || value.toString() === "0") { @@ -14,11 +13,10 @@ (value.toLowerCase() === "true" || value.toLowerCase() === "false") ) { return Promise.resolve(); - } else { - return Promise.reject(`Value '${value}' is not boolean format.`); } + return Promise.reject(`Value '${value}' is not boolean format.`); }, - encode: function(context, params, value) { + encode(context, params, value) { if (typeof value === "boolean") { return value; } else if (value.toString() === "1") { @@ -33,13 +31,12 @@ } } }, - filter_to_query: function(context, params, filter) { + filter_to_query(context, params, filter) { if (filter === "") { return { $exists: false }; } else if (filter === null) { return { $in: [true, false] }; - } else { - return this.encode(context, params, filter); } + return this.encode(context, params, filter); }, }; diff --git a/lib/app/base-chips/field-types/cached-value.js b/lib/app/base-chips/field-types/cached-value.js --- a/lib/app/base-chips/field-types/cached-value.js +++ b/lib/app/base-chips/field-types/cached-value.js @@ -1,16 +1,13 @@ -"use strict"; -const { getDateTime } = require("../../../utils/get-datetime.js"); - -module.exports = app => ({ +module.exports = App => ({ name: "cached-value", - get_description: function() { + get_description() { return "Caches custom values. Takes care of cache invalidation."; }, get_default_value: async () => null, value_path_after_field_name: ".value", - is_proper_value: function(context, params, new_value) { + is_proper_value(context, params, new_value) { if (!context.is_super) { return Promise.reject("This is a read-only field"); } @@ -22,7 +19,7 @@ new_value ); }, - filter_to_query: async function(context, params, field_filter) { + async filter_to_query(context, params, field_filter) { return this._call_base_method( "filter_to_query", context, @@ -30,10 +27,10 @@ field_filter ); }, - init: function(collection, field_name, params) { - const { refresh_on, get_value, base_field_type } = params; + init(collection, field_name, params) { + const { refresh_on, get_value } = params; this._check_for_possible_recursive_edits( - app, + App, refresh_on, collection.name, field_name @@ -44,27 +41,25 @@ ); if (create_action) { - app.addHook( - { when: "after", action: "start" }, - async () => - await this._refresh_outdated_cache_values( - create_action, - collection, - field_name, - params - ) + App.addHook({ when: "after", action: "start" }, () => + this._refresh_outdated_cache_values( + create_action, + collection, + field_name, + params + ) ); } for (let { event_matcher, resource_id_getter } of refresh_on) { - app.addHook(event_matcher, async (emitted_event, resource) => { + App.addHook(event_matcher, async (emitted_event, resource) => { const cache_resource_id = await resource_id_getter( emitted_event, resource ); - await app.run_action( - new app.Sealious.SuperContext( + await App.run_action( + new App.Sealious.SuperContext( emitted_event.metadata.context ), ["collections", collection.name, cache_resource_id], @@ -80,7 +75,7 @@ } }, - _check_for_possible_recursive_edits: function( + _check_for_possible_recursive_edits( app, refresh_on, collection_name, @@ -94,7 +89,9 @@ ) { return event_matcher.collection_name === collection_name; } - event_matcher.subject_path.test(`collections.${collection_name}`); + return event_matcher.subject_path.test( + `collections.${collection_name}` + ); }); if (doesAnyMatches) { throw new Error( @@ -103,7 +100,7 @@ } }, - _refresh_outdated_cache_values: async function( + async _refresh_outdated_cache_values( create_action, collection, field_name, @@ -112,8 +109,8 @@ const referenced_collection_name = create_action.event_matcher.collection_name; - const last_modified_resource = (await app.run_action( - new app.Sealious.SuperContext(), + const last_modified_resource = (await App.run_action( + new App.Sealious.SuperContext(), ["collections", referenced_collection_name], "show", { @@ -129,7 +126,7 @@ const last_modified_timestamp = last_modified_resource._metadata.last_modified_context.timestamp; - const outdated_resources = await app.Datastore.aggregate( + const outdated_resources = await App.Datastore.aggregate( collection.name, [ { @@ -151,21 +148,21 @@ return; } - const context = new app.Sealious.SuperContext(); + const context = new App.Sealious.SuperContext(); for (let resource of outdated_resources) { const cache_value = await this.encode( context, params, await params.get_value(context, resource.sealious_id) ); - await app.Datastore.update( + await App.Datastore.update( collection.name, { sealious_id: resource.sealious_id }, { $set: { [field_name]: cache_value } } ); } }, - encode: async function(context, params, value) { + async encode(context, params, value) { return { timestamp: context.timestamp, value: await this._call_base_method( @@ -176,7 +173,7 @@ ), }; }, - decode: function(context, params, value_in_db) { + decode(context, params, value_in_db) { return this._call_base_method( "decode", context, @@ -184,8 +181,8 @@ value_in_db ? value_in_db.value : null ); }, - format: function(context, params, decoded_value, format) { - const base_field_type = app.FieldType(params.base_field_type.name); + format(context, params, decoded_value, format) { + const base_field_type = App.FieldType(params.base_field_type.name); return base_field_type.format( context, params.base_field_type.params || {}, @@ -194,7 +191,7 @@ ); }, _call_base_method(method, context, params, arg) { - const base_field_type = app.FieldType(params.base_field_type.name); + const base_field_type = App.FieldType(params.base_field_type.name); return base_field_type[method]( context, params.base_field_type.params || {}, diff --git a/lib/app/base-chips/field-types/cached-value.subtest.js b/lib/app/base-chips/field-types/cached-value.subtest.js --- a/lib/app/base-chips/field-types/cached-value.subtest.js +++ b/lib/app/base-chips/field-types/cached-value.subtest.js @@ -147,7 +147,7 @@ async ({ app, dont_clear_database_on_stop, rest_api }) => { create_collections(app, "create_status_field" && false); await app.start(); - for (username of ["user_1", "user_2"]) { + for (const username of ["user_1", "user_2"]) { account_ids.push(await add_account(rest_api, { username })); } await rest_api.post("/api/v1/collections/actions", { @@ -171,7 +171,7 @@ with_running_app(async ({ app, rest_api }) => { create_collections(app); const account_ids = []; - for (username of ["user_1", "user_2"]) { + for (const username of ["user_1", "user_2"]) { account_ids.push(await add_account(rest_api, { username })); } await assert_status_equals(rest_api, account_ids[0], "created"); @@ -258,61 +258,52 @@ it("Properly responds to recursive edits", async () => with_running_app(async ({ app }) => { await assert_throws_async( - async () => { - const happy_numbers = await app.createChip( - app.Sealious.Collection, - { - name: "happy-numbers", - fields: [ - { - name: "number", - type: "int", - required: true, - }, - { - name: "double_number", - type: "cached-value", - params: { - base_field_type: { name: "int" }, - get_value: async ( + async () => + app.createChip(app.Sealious.Collection, { + name: "happy-numbers", + fields: [ + { + name: "number", + type: "int", + required: true, + }, + { + name: "double_number", + type: "cached-value", + params: { + base_field_type: { name: "int" }, + get_value: async (context, number_id) => { + const { number } = await app.run_action( context, - number_id - ) => { - const { - number, - } = await app.run_action( - context, - [ - "collections", - "happy-numbers", - number_id, - ], - "show" - ); - return number * 2; - }, - refresh_on: [ - { - event_matcher: new app.Sealious.EventMatchers.Collection( - { - when: "after", - collection_name: - "happy-numbers", - action: "create", - } - ), - resource_id_getter: ( - emitted_event, - resource - ) => resource.id, - }, - ], + [ + "collections", + "happy-numbers", + number_id, + ], + "show" + ); + return number * 2; }, + refresh_on: [ + { + event_matcher: new app.Sealious.EventMatchers.Collection( + { + when: "after", + collection_name: + "happy-numbers", + action: "create", + } + ), + resource_id_getter: ( + emitted_event, + resource + ) => resource.id, + }, + ], }, - ], - } - ); - }, + }, + ], + }), error => assert.equal( error, diff --git a/lib/app/base-chips/field-types/color.js b/lib/app/base-chips/field-types/color.js --- a/lib/app/base-chips/field-types/color.js +++ b/lib/app/base-chips/field-types/color.js @@ -1,7 +1,6 @@ -"use strict"; module.exports = { name: "color", - is_proper_value: function(context, params, new_value) { + is_proper_value(context, params, new_value) { const Color = require("color"); //putting it here not to slow down `new Sealious.app()` try { if (typeof new_value === "string") { @@ -16,7 +15,7 @@ ); } }, - encode: function(context, params, value_in_code) { + encode(context, params, value_in_code) { const Color = require("color"); //putting it here not to slow down `new Sealious.app()` const color = Color(value_in_code); return color.hexString(); diff --git a/lib/app/base-chips/field-types/context.js b/lib/app/base-chips/field-types/context.js --- a/lib/app/base-chips/field-types/context.js +++ b/lib/app/base-chips/field-types/context.js @@ -1,16 +1,14 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Context = locreq("lib/context.js"); module.exports = { name: "context", - is_proper_value: function(context, params, value) { + is_proper_value(context, params, value) { if (value instanceof Context) { return Promise.resolve(); - } else { - return Promise.reject( - "Provided value is not an instance of Sealious.Context" - ); } + return Promise.reject( + "Provided value is not an instance of Sealious.Context" + ); }, }; diff --git a/lib/app/base-chips/field-types/control-access.js b/lib/app/base-chips/field-types/control-access.js --- a/lib/app/base-chips/field-types/control-access.js +++ b/lib/app/base-chips/field-types/control-access.js @@ -1,6 +1,6 @@ module.exports = app => ({ name: "control-access", - is_proper_value: async function( + async is_proper_value( context, { target_field_type_name, target_params, target_access_strategies }, new_value, @@ -31,7 +31,7 @@ old_value ); }, - decode: function( + decode( context, { target_field_type_name, target_params, target_access_strategies }, value_in_db diff --git a/lib/app/base-chips/field-types/control-access.subtest.js b/lib/app/base-chips/field-types/control-access.subtest.js --- a/lib/app/base-chips/field-types/control-access.subtest.js +++ b/lib/app/base-chips/field-types/control-access.subtest.js @@ -11,12 +11,12 @@ name: "ssh-keys", fields: [ { - name: "public", + name: "visible", type: "text", required: true, }, { - name: "private", + name: "hidden", type: "control-access", params: { target_access_strategies: { @@ -72,22 +72,22 @@ async function fill_keys_collections(App) { const keys = [ { - public: "a-public-key", - private: "seeeeecret", + visible: "a-visible-key", + hidden: "seeeeecret", }, { - public: "go-get-it", - private: "you-cannot-see", + visible: "go-get-it", + hidden: "you-cannot-see", }, ]; - for (let { public, private } of keys) { - let key = await App.run_action( + for (let { visible, hidden } of keys) { + await App.run_action( new App.Sealious.SuperContext(), ["collections", "ssh-keys"], "create", { - public, - private, + visible, + hidden, } ); } @@ -109,7 +109,7 @@ ); ssh_keys.forEach(key => { - assert.deepEqual(key.private, ""); + assert.deepEqual(key.hidden, ""); }); })); @@ -123,7 +123,7 @@ ); ssh_keys.forEach(key => { - assert(key.private.length >= 3); + assert(key.hidden.length >= 3); }); })); @@ -136,14 +136,14 @@ rest_api.post( SSH_KEYS_URL, { - public: "XDDDDDDDDDDDD", - private: "XD", + visible: "XDDDDDDDDDDDD", + hidden: "XD", }, sessions.admin ), e => assert.equal( - e.response.data.data.private.message, + e.response.data.data.hidden.message, "Text 'XD' is too short, minimum length is 3 chars." ) ); @@ -156,8 +156,8 @@ const key = await rest_api.post( SSH_KEYS_URL, { - public: "123123", - private: "321321", + visible: "123123", + hidden: "321321", }, sessions.admin ); @@ -165,12 +165,12 @@ const updated_key = await rest_api.patch( `${SSH_KEYS_URL}/${key.id}`, { - private: "654321", + hidden: "654321", }, sessions.admin ); - assert.deepEqual(updated_key.private, "654321"); + assert.deepEqual(updated_key.hidden, "654321"); })); it("Doesn't allow regular-user to update a protected field", async () => @@ -180,8 +180,8 @@ const key = await rest_api.post( SSH_KEYS_URL, { - public: "123123", - private: "321321", + visible: "123123", + hidden: "321321", }, sessions.admin ); @@ -190,12 +190,12 @@ () => rest_api.patch( `${SSH_KEYS_URL}/${key.id}`, - { private: "331c6883dd6010864b7ead130be77cd5" }, + { hidden: "331c6883dd6010864b7ead130be77cd5" }, sessions["regular-user"] ), e => assert.deepEqual( - e.response.data.data.private.message, + e.response.data.data.hidden.message, "You are not allowed to update this field." ) ); diff --git a/lib/app/base-chips/field-types/date.js b/lib/app/base-chips/field-types/date.js --- a/lib/app/base-chips/field-types/date.js +++ b/lib/app/base-chips/field-types/date.js @@ -1,10 +1,9 @@ -"use strict"; module.exports = { name: "date", - get_description: function() { + get_description() { return "Date standard ISO 8601 (YYYY-MM-DD)"; }, - is_proper_value: function(context, params, date) { + is_proper_value(context, params, date) { const date_in_string = date.toString(); const regex = /^([0-9]{4})-(0?[1-9]|1[0-2])-([0-2]?[0-9]|30|31)$/; // granulation_per_day @@ -16,8 +15,7 @@ return Promise.reject( `Value "${date}" is not date calendar format. Expected value standard IS0 8601 (YYYY-MM-DD)` ); - } else { - return Promise.resolve(); } + return Promise.resolve(); }, }; diff --git a/lib/app/base-chips/field-types/datetime.js b/lib/app/base-chips/field-types/datetime.js --- a/lib/app/base-chips/field-types/datetime.js +++ b/lib/app/base-chips/field-types/datetime.js @@ -1,19 +1,18 @@ -"use strict"; - const { getDateTime } = require("../../../utils/get-datetime.js"); module.exports = { name: "datetime", extends: "int", - has_index: function(params) { + has_index(params) { if (params.indexed) { return 1; - } else return false; + } + return false; }, - get_description: function() { + get_description() { return "Timestamp - amount of miliseconds since epoch."; }, - is_proper_value: function(context, params, datetime) { + is_proper_value(context, params, datetime) { if (Number.isInteger(datetime)) { return Promise.resolve(); } @@ -21,11 +20,11 @@ `Value '${datetime}' is not datetime format. Only timestamps are accepted.` ); }, - encode: function(context, params, value_in_code) { - const parsed_datetime = parseInt(value_in_code); + encode(context, params, value_in_code) { + const parsed_datetime = parseInt(value_in_code, 10); return parsed_datetime; }, - format: function(context, params, decoded_value, format) { + format(context, params, decoded_value, format) { if (decoded_value === null || decoded_value === undefined) { return Promise.resolve(decoded_value); } diff --git a/lib/app/base-chips/field-types/derived-value.js b/lib/app/base-chips/field-types/derived-value.js --- a/lib/app/base-chips/field-types/derived-value.js +++ b/lib/app/base-chips/field-types/derived-value.js @@ -1,5 +1,3 @@ -const locreq = require("locreq")(__dirname); -const Errors = locreq("lib/response/error.js"); const Promise = require("bluebird"); module.exports = app => ({ @@ -7,7 +5,7 @@ get_description: () => "A value derived from an array of fields of the given collection.", get_default_value: async () => null, - is_proper_value: function(context, params, new_value) { + is_proper_value(context, params, new_value) { return this._call_base_method( "is_proper_value", context, @@ -15,7 +13,7 @@ new_value ); }, - filter_to_query: async function(context, params, field_filter) { + async filter_to_query(context, params, field_filter) { return this._call_base_method( "filter_to_query", context, @@ -23,8 +21,8 @@ field_filter ); }, - init: function(collection, field_name, params) { - const { fields, derived_fn, base_field_type } = params; + init(collection, field_name, params) { + const { fields, derived_fn } = params; if (typeof derived_fn !== "function") { throw new Error( `'derived_fn' param in ${field_name} derived-value field is not a function.` @@ -57,18 +55,18 @@ collection_name: collection.name, action: "create", }), - async (emitted_event, params) => { - this._call_is_proper_value_for_params(params, collection); + async (emitted_event, _params) => { + this._call_is_proper_value_for_params(_params, collection); const derived_fn_args = fields.map( field => - params[field] === undefined || params[field] === null + _params[field] === undefined || _params[field] === null ? "" - : params[field] + : _params[field] ); const derived_value = await derived_fn(...derived_fn_args); return { [field_name]: derived_value, - ...params, + ..._params, }; } ); @@ -79,19 +77,21 @@ collection_name: collection.name, action: "edit", }), - async ({ metadata, subject_path }, params) => { + async ({ metadata, subject_path }, _params) => { this._call_is_proper_value_for_params( metadata.context, - params, + _params, collection ); - if (fields.some(field => Object.keys(params).includes(field))) { + if ( + fields.some(field => Object.keys(_params).includes(field)) + ) { const derived_fn_args = await Promise.map( fields, async current_field => { - if (Object.keys(params).includes(current_field)) { - return params[current_field]; + if (Object.keys(_params).includes(current_field)) { + return _params[current_field]; } const resource = await app.run_action( new app.Sealious.SuperContext(), @@ -104,22 +104,22 @@ const derived_value = await derived_fn(...derived_fn_args); return { - ...params, + ..._params, [field_name]: derived_value, }; } - return params; + return _params; } ); }, - encode: async function(context, params, value) { + async encode(context, params, value) { return this._call_base_method("encode", context, params, value); }, - decode: function(context, params, value_in_db) { + decode(context, params, value_in_db) { return this._call_base_method("decode", context, params, value_in_db); }, - format: function(context, params, decoded_value, format) { + format(context, params, decoded_value, format) { return this._call_base_method( "format", context, @@ -130,7 +130,7 @@ }, async _call_is_proper_value_for_params(context, event_params, collection) { - for (param_field in event_params) { + for (const param_field in event_params) { try { await collection.fields[param_field].type.is_proper_value( context, diff --git a/lib/app/base-chips/field-types/derived-value.subtest.js b/lib/app/base-chips/field-types/derived-value.subtest.js --- a/lib/app/base-chips/field-types/derived-value.subtest.js +++ b/lib/app/base-chips/field-types/derived-value.subtest.js @@ -1,9 +1,6 @@ -const assert = require("assert"); const locreq = require("locreq")(__dirname); -const Promise = require("bluebird"); -const { with_running_app, with_stopped_app } = locreq( - "test_utils/with-test-app.js" -); +const assert = require("assert"); +const { with_running_app } = locreq("test_utils/with-test-app.js"); const assert_throws_async = locreq("test_utils/assert_throws_async.js"); const make_test_collection = (app, derived_value_params) => () => @@ -90,15 +87,11 @@ })(); await assert_throws_async( - async () => { - const person = await rest_api.post( - "/api/v1/collections/people", - { - username: "Antoine", - surname: 123123, - } - ); - }, + async () => + rest_api.post("/api/v1/collections/people", { + username: "Antoine", + surname: 123123, + }), error => assert.deepEqual( error.response.data.data.surname.message, @@ -197,15 +190,11 @@ })(); await assert_throws_async( - async () => { - const person = await rest_api.post( - "/api/v1/collections/people", - { - username: "Jan", - surname: "Kowalski", - } - ); - }, + async () => + rest_api.post("/api/v1/collections/people", { + username: "Jan", + surname: "Kowalski", + }), error => { assert.deepEqual( error.response.data.data.name_and_surname.message, diff --git a/lib/app/base-chips/field-types/email.js b/lib/app/base-chips/field-types/email.js --- a/lib/app/base-chips/field-types/email.js +++ b/lib/app/base-chips/field-types/email.js @@ -1,18 +1,16 @@ -"use strict"; module.exports = { name: "email", - get_description: function() { + get_description() { return "Email address, like something@something.sth"; }, - is_proper_value: function(context, params, value) { + is_proper_value(context, params, value) { const address = value; - const regex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + const regex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; if (regex.test(address) || address === "") { return Promise.resolve(); - } else { - return Promise.reject(`${address} is a not valid e-mail address.`); } + return Promise.reject(`${address} is a not valid e-mail address.`); }, }; diff --git a/lib/app/base-chips/field-types/enum.js b/lib/app/base-chips/field-types/enum.js --- a/lib/app/base-chips/field-types/enum.js +++ b/lib/app/base-chips/field-types/enum.js @@ -1,15 +1,13 @@ -"use strict"; module.exports = { name: "enum", - is_proper_value: async function(context, params, value) { + async is_proper_value(context, params, value) { const allowed_values = params.values instanceof Function ? await params.values() : params.values; - if (allowed_values.indexOf(value) !== -1) { + if (allowed_values.includes(value)) { return Promise.resolve(); - } else { - return Promise.reject("Allowed values: " + allowed_values.join()); } + return Promise.reject(`Allowed values: ${allowed_values.join()}`); }, }; diff --git a/lib/app/base-chips/field-types/file-reference.js b/lib/app/base-chips/field-types/file-reference.js --- a/lib/app/base-chips/field-types/file-reference.js +++ b/lib/app/base-chips/field-types/file-reference.js @@ -1,25 +1,21 @@ module.exports = function(app) { return { name: "file_reference", - is_proper_value: function(context, params, value) { - return app.Datastore.find("files", { id: value }).then(function( - results - ) { - if (results.length === 0) { - return Promise.reject("Bad file id: " + value); - } else { + is_proper_value(context, params, value) { + return app.Datastore.find("files", { id: value }).then(results => { + if (results.length) { return Promise.resolve(); } + return Promise.reject(`Bad file id: ${value}`); }); }, - format: function(context, params, file_id, format) { + format(context, params, file_id, format) { if (format === "internal") { return app.Datastore.find("files", { id: file_id }).then( a => a[0] ); - } else { - return file_id; } + return file_id; }, }; }; diff --git a/lib/app/base-chips/field-types/file.js b/lib/app/base-chips/field-types/file.js --- a/lib/app/base-chips/field-types/file.js +++ b/lib/app/base-chips/field-types/file.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const File = locreq("lib/data-structures/file.js"); @@ -9,20 +8,18 @@ return { name: "file", handles_large_data: true, - is_proper_value: function(context, params, value) { + is_proper_value(context, params, value) { if (value === undefined) { return undefined; } - if (typeof value == "string") { + if (typeof value === "string") { return axios(value) - .then(function() { - return Promise.resolve(); - }) - .catch(function() { - return Promise.reject( + .then(() => Promise.resolve()) + .catch(() => + Promise.reject( `There was a problem while getting the file: '${value}'. Is the URL correct?` - ); - }); + ) + ); } if ( value === null || @@ -31,24 +28,23 @@ (value.filename !== undefined && value.data instanceof Buffer) ) { return Promise.resolve(); + } + let type; + if (value instanceof Array) { + type = + ". If you want to upload multiple files, use array field types."; } else { - let type; - if (value instanceof Array) { - type = - ". If you want to upload multiple files, use array field types."; - } else { - type = typeof data; - } - return Promise.reject( - `Wrong file data format. Should be Sealious.File, but received ${type}` - ); + type = typeof data; } + return Promise.reject( + `Wrong file data format. Should be Sealious.File, but received ${type}` + ); }, - encode: function(context, params, value_in_code) { + encode(context, params, value_in_code) { if (typeof value_in_code === "string") { return axios(value_in_code, { responseType: "arrayBuffer", - }).then(function(file_buffer) { + }).then(file_buffer => { const filename = url .parse(value_in_code) .pathname.split("/") @@ -59,11 +55,10 @@ } if (value_in_code) { return app.FileManager.save_file(value_in_code); - } else { - return null; } + return null; }, - decode: function(context, params, value_in_database) { + decode(context, params, value_in_database) { if (value_in_database) { return Promise.resolve( new File.Reference( @@ -73,11 +68,10 @@ ); } else if (params.no_file_value) { return params.no_file_value; - } else { - return undefined; } + return undefined; }, - format: function(context, params, decoded_value, format) { + format(context, params, decoded_value, format) { if (decoded_value === undefined) { return undefined; } @@ -93,18 +87,16 @@ filename: null, empty: true, }; - } else { - return { - url: `/api/v1/uploaded-files/${decoded_value.id}/${ - decoded_value.filename - }`, - filename: decoded_value.filename, - empty: false, - }; } - } else { - return decoded_value; + return { + url: `/api/v1/uploaded-files/${decoded_value.id}/${ + decoded_value.filename + }`, + filename: decoded_value.filename, + empty: false, + }; } + return decoded_value; }, }; }; diff --git a/lib/app/base-chips/field-types/float.js b/lib/app/base-chips/field-types/float.js --- a/lib/app/base-chips/field-types/float.js +++ b/lib/app/base-chips/field-types/float.js @@ -1,20 +1,18 @@ -"use strict"; module.exports = { name: "float", - get_description: function() { + get_description() { return "Float number."; }, - is_proper_value: function(context, params, number) { + is_proper_value(context, params, number) { const test = parseFloat(number); if (test === null || isNaN(test) || isNaN(number) === true) { return Promise.reject( `Value '${number}' is not a float number format.` ); - } else { - return Promise.resolve(); } + return Promise.resolve(); }, - encode: function(context, params, value_in_code) { + encode(context, params, value_in_code) { const parsed_float = parseFloat(value_in_code); return parsed_float; }, diff --git a/lib/app/base-chips/field-types/html.js b/lib/app/base-chips/field-types/html.js --- a/lib/app/base-chips/field-types/html.js +++ b/lib/app/base-chips/field-types/html.js @@ -1,9 +1,7 @@ -"use strict"; - module.exports = { name: "html", extends: "text", - encode: function(context, params, value) { + encode(context, params, value) { const sanitizeHtml = require("sanitize-html"); //putting it here not to slow down `new Sealious.app()` return { original: value, @@ -16,7 +14,7 @@ }), }; }, - format: function(context, params, decoded_value, format) { + format(context, params, decoded_value, format) { let ret; if (decoded_value === undefined) return undefined; switch (format) { diff --git a/lib/app/base-chips/field-types/image.js b/lib/app/base-chips/field-types/image.js --- a/lib/app/base-chips/field-types/image.js +++ b/lib/app/base-chips/field-types/image.js @@ -1,48 +1,35 @@ -"use strict"; const Promise = require("bluebird"); -const assert = require("assert"); -const locreq = require("locreq")(__dirname); -const File = locreq("lib/data-structures/file.js"); module.exports = function(app) { // params.formats = {name: {size: [width_px, height_px]}} // params.default_format = format_name || "original" - const File = app.ChipManager.get_chip("field_type", "file"); - return { name: "image", extends: "file", - is_proper_value: function(context, params, new_value) { - return File.is_proper_value(context, params, new_value).then( - function() { - if ( - new_value.mime && - new_value.mime.indexOf("image/") !== 0 - ) { - return Promise.reject("Only image files are allowed"); - } + is_proper_value(context, params, new_value) { + return File.is_proper_value(context, params, new_value).then(() => { + if (new_value.mime && new_value.mime.indexOf("image/") !== 0) { + return Promise.reject("Only image files are allowed"); } - ); + }); }, - format: function(context, params, decoded_value, format) { - const formats = params.formats || {}; - + format(context, params, decoded_value, _format) { if (decoded_value === undefined) { return undefined; } - - if (format === undefined) - format = params.default_format || "original"; + const format = + _format === undefined + ? params.default_format || "original" + : _format; if (format === "original") { return File.format(context, params, decoded_value, "url"); - } else { - return ( - `/api/v1/formatted-images/${decoded_value.id}/` + - `${format}/${decoded_value.filename}` - ); } + return ( + `/api/v1/formatted-images/${decoded_value.id}/` + + `${format}/${decoded_value.filename}` + ); }, }; }; diff --git a/lib/app/base-chips/field-types/int.js b/lib/app/base-chips/field-types/int.js --- a/lib/app/base-chips/field-types/int.js +++ b/lib/app/base-chips/field-types/int.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Errors = locreq("lib/response/error.js"); @@ -23,7 +22,7 @@ false, `Value should be larger or equal to '${params.min}.`, ]; - else return [true]; + return [true]; }, (params, value) => { if (Number.isFinite(params.max) && value > params.max) @@ -31,16 +30,16 @@ false, `Value should be smaller or equal to '${params.max}.`, ]; - else return [true]; + return [true]; }, ]; const int = { name: "int", - get_description: function() { + get_description() { return "An integer number."; }, - is_proper_value: function(context, params, new_value) { + is_proper_value(context, params, new_value) { if (!Number.isInteger(new_value)) { return Promise.reject( `Value '${new_value}' is not a int number format.` @@ -50,19 +49,18 @@ const failed_checks = proper_value_checkers .map(fn => fn(params, new_value)) .filter(element => !element[0]); - if (failed_checks.length === 0) { + if (!failed_checks.length) { return Promise.resolve(); - } else { - return Promise.reject(failed_checks.map(e => e[1]).join(" ")); } + return Promise.reject(failed_checks.map(e => e[1]).join(" ")); }, - encode: function(context, params, value_in_code) { + encode(context, params, value_in_code) { return parseInt(value_in_code, 10); }, - filter_to_query: function(context, params, field_filter) { + filter_to_query(context, params, field_filter) { if (typeof field_filter !== "object") { return { - $eq: parseInt(field_filter), + $eq: parseInt(field_filter, 10), }; } // treating filter as a query here @@ -74,7 +72,7 @@ `Unknown comparator: '${comparator}'.` ); } - new_filter[new_comparator] = parseInt(field_filter[comparator]); + new_filter[new_comparator] = parseInt(field_filter[comparator], 10); } return new_filter; }, diff --git a/lib/app/base-chips/field-types/json-object.js b/lib/app/base-chips/field-types/json-object.js --- a/lib/app/base-chips/field-types/json-object.js +++ b/lib/app/base-chips/field-types/json-object.js @@ -1,13 +1,11 @@ const flattenObjectToDotNotation = require("../../../utils/flatten-object-to-dot-notation"); -("use strict"); - module.exports = { name: "json-object", - get_description: function() { + get_description() { return "Stores json object value."; }, - is_proper_value: async function(context, params, new_value) { + async is_proper_value(context, params, new_value) { let stringified_value; try { stringified_value = JSON.stringify(new_value); @@ -20,10 +18,10 @@ return Promise.reject("A primitive, not an object!"); } }, - encode: function(context, params, value_in_code) { + encode(context, params, value_in_code) { return JSON.parse(JSON.stringify(value_in_code)); }, - get_aggregation_stages: function( + get_aggregation_stages( context, params, field_name, diff --git a/lib/app/base-chips/field-types/json-object.subtest.js b/lib/app/base-chips/field-types/json-object.subtest.js --- a/lib/app/base-chips/field-types/json-object.subtest.js +++ b/lib/app/base-chips/field-types/json-object.subtest.js @@ -1,6 +1,5 @@ -const assert = require("assert"); const locreq = require("locreq")(__dirname); -const Promise = require("bluebird"); +const assert = require("assert"); const { with_running_app } = locreq("test_utils/with-test-app.js"); const assert_throws_async = locreq("test_utils/assert_throws_async.js"); diff --git a/lib/app/base-chips/field-types/password.js b/lib/app/base-chips/field-types/password.js --- a/lib/app/base-chips/field-types/password.js +++ b/lib/app/base-chips/field-types/password.js @@ -1,12 +1,10 @@ -"use strict"; const Promise = require("bluebird"); const SecureHasher = require("../../../utils/secure-hasher.js"); -const crypto = require("crypto"); module.exports = app => ({ name: "password", extends: "text", - get_description: function(context, { digits, capitals }) { + get_description(context, { digits, capitals }) { let message = "Stores a password in a correct way"; if (!digits && !capitals) { return message; @@ -23,7 +21,7 @@ return message; }, - is_proper_value: function(context, { digits, capitals }, new_value) { + is_proper_value(context, { digits, capitals }, new_value) { const pattern_array = []; if (!digits && !capitals) { return Promise.resolve(); @@ -41,20 +39,19 @@ if (isAccepted) { return Promise.resolve(); - } else { - const digits = digits || "0"; - const capitals = capitals || "0"; - return Promise.reject( - `It didn't fulfill the requirements: required digits - ${digits} , required capitals ${capitals}` - ); } - }, - encode: function(context, params, value_in_code) { - const hashing_params = Object.assign( - {}, - app.ConfigManager.get("password_hash"), - params + const requiredDigits = digits || "0"; + const requiredCapitals = capitals || "0"; + return Promise.reject( + `It didn't fulfill the requirements: required digits - ${requiredDigits} , required capitals ${requiredCapitals}` ); + }, + encode(context, params, value_in_code) { + const hashing_params = { + ...app.ConfigManager.get("password_hash"), + ...params, + }; + const salt = SecureHasher.generateRandomSalt( hashing_params.salt_length ); @@ -62,10 +59,10 @@ }, get_aggregation_stages: require("./../../../chip-types/field-type-default-methods.js") .get_aggregation_stages, - decode: function(context, params, value_in_db) { + decode(context, params, value_in_db) { return null; }, - format: function(context, params, decoded_value, format_params) { + format(context, params, decoded_value, format_params) { return decoded_value; }, }); diff --git a/lib/app/base-chips/field-types/reverse-single-reference.js b/lib/app/base-chips/field-types/reverse-single-reference.js --- a/lib/app/base-chips/field-types/reverse-single-reference.js +++ b/lib/app/base-chips/field-types/reverse-single-reference.js @@ -1,7 +1,4 @@ -"use strict"; -const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); -const Errors = locreq("lib/response/error.js"); const assert = require("assert"); function params_to_cache_key(collection, field_name, params) { @@ -62,20 +59,20 @@ return { name: "reverse-single-reference", - get_description: function() { + get_description() { return "Shows which resources from given collection point to this resource in a given field."; }, get_default_value: async () => [], is_old_value_sensitive: true, - is_proper_value: function(context, params, new_value) { + is_proper_value(context, params, new_value) { return context.is_super ? Promise.resolve() : Promise.reject("This is a read-only field"); }, - filter_to_query: async function(context, params, field_filter) { + async filter_to_query(context, params, field_filter) { if (typeof field_filter !== "object") { return { $eq: field_filter, @@ -93,7 +90,7 @@ }; }, - format: function(context, params, decoded_value, format) { + format(context, params, decoded_value, format) { // format can be "expand" or "deep-expand:", like "deep-expand:3" if (!format) { return decoded_value; // just the IDs @@ -218,7 +215,12 @@ action: "edit", }), async ({ metadata, subject_path }, resource) => { - if (!metadata.params.hasOwnProperty(params.field_name)) + if ( + !Object.prototype.hasOwnProperty.call( + metadata.params, + params.field_name + ) + ) return; const edited_id = subject_path.split(".")[2]; const no_longer_referenced = await app.Datastore.find( diff --git a/lib/app/base-chips/field-types/reverse-single-reference.subtest.js b/lib/app/base-chips/field-types/reverse-single-reference.subtest.js --- a/lib/app/base-chips/field-types/reverse-single-reference.subtest.js +++ b/lib/app/base-chips/field-types/reverse-single-reference.subtest.js @@ -1,14 +1,9 @@ -const assert = require("assert"); -const Promise = require("bluebird"); const locreq = require("locreq")(__dirname); -const axios = require("axios"); -const { create_resource_as } = locreq("test_utils"); -const { with_stopped_app, with_running_app } = locreq( - "test_utils/with-test-app.js" -); -const DatastoreMongoFactory = locreq("lib/datastore/db.js"); +const assert = require("assert"); +const { with_stopped_app } = locreq("test_utils/with-test-app.js"); describe("reverse-single-reference", () => { + /* eslint-disable no-shadow */ async function create_referencing_collections(app, with_reverse) { const A = app.createChip(app.Sealious.Collection, { name: "A", @@ -148,9 +143,7 @@ it("updates the cached value when an old reference is edited to an empty one", async () => with_reverse(async ({ app, rest_api }) => { - const { - items: [result1], - } = await rest_api.get("/api/v1/collections/B?filter[number]=1"); + await rest_api.get("/api/v1/collections/B?filter[number]=1"); const { items: [result2], } = await rest_api.get("/api/v1/collections/B?filter[number]=2"); diff --git a/lib/app/base-chips/field-types/secret-token.js b/lib/app/base-chips/field-types/secret-token.js --- a/lib/app/base-chips/field-types/secret-token.js +++ b/lib/app/base-chips/field-types/secret-token.js @@ -12,8 +12,7 @@ filter_to_query: (context, params, field_filter) => { if (context.is_super) { return { $eq: field_filter }; - } else { - return { $eq: "nice try" }; } + return { $eq: "nice try" }; }, }; diff --git a/lib/app/base-chips/field-types/settable-by.js b/lib/app/base-chips/field-types/settable-by.js --- a/lib/app/base-chips/field-types/settable-by.js +++ b/lib/app/base-chips/field-types/settable-by.js @@ -1,6 +1,6 @@ module.exports = app => ({ name: "settable-by", - encode: function(context, params, new_value, old_value) { + encode(context, params, new_value, old_value) { return params.target_field_type.encode( context, params, @@ -8,7 +8,7 @@ old_value ); }, - is_proper_value: async function( + async is_proper_value( context, { target_field_type, target_params = {}, access_strategy_description }, new_value, @@ -26,7 +26,7 @@ old_value ); }, - format: function( + format( context, { target_field_type, target_params }, decode_value, @@ -39,18 +39,14 @@ format ); }, - filter_to_query: function( - context, - { target_field_type, target_params }, - filter - ) { + filter_to_query(context, { target_field_type, target_params }, filter) { return target_field_type.filter_to_query( context, target_params, filter ); }, - get_aggregation_stages: function( + get_aggregation_stages( context, { target_field_type, target_params }, field_name, @@ -65,7 +61,7 @@ query_params ); }, - has_index: function({ target_field_type, target_params }) { + has_index({ target_field_type, target_params }) { return target_field_type.has_index(target_params); }, }); diff --git a/lib/app/base-chips/field-types/settable-by.subtest.js b/lib/app/base-chips/field-types/settable-by.subtest.js --- a/lib/app/base-chips/field-types/settable-by.subtest.js +++ b/lib/app/base-chips/field-types/settable-by.subtest.js @@ -1,7 +1,7 @@ const assert = require("assert"); const locreq = require("locreq")(__dirname); const axios = require("axios"); -const { create_resource_as, assert_throws_async } = locreq("test_utils"); +const { assert_throws_async } = locreq("test_utils"); const { with_running_app } = locreq("test_utils/with-test-app.js"); describe("settable-by", async () => { diff --git a/lib/app/base-chips/field-types/single_reference.js b/lib/app/base-chips/field-types/single_reference.js --- a/lib/app/base-chips/field-types/single_reference.js +++ b/lib/app/base-chips/field-types/single_reference.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Collection = locreq("lib/chip-types/collection.js"); const Promise = require("bluebird"); @@ -7,7 +6,7 @@ return { name: "single_reference", has_index: () => 1, - is_proper_value: function(context, params, new_value) { + is_proper_value(context, params, new_value) { const collection = new Collection(app, params.collection); const filter = params.filter || {}; if (new_value === "") { @@ -41,7 +40,7 @@ ) ); }, - encode: function(context, params, value_in_code) { + encode(context, params, value_in_code) { let resource_id; if (typeof value_in_code === "string") { resource_id = value_in_code; @@ -50,7 +49,7 @@ } return resource_id; }, - format: function(context, params, decoded_value, format) { + format(context, params, decoded_value, format) { // format can be "expand" or "deep-expand:", like "deep-expand:3" if (!format) { return decoded_value; // just the ID @@ -78,7 +77,8 @@ const field = collection.fields[field_name]; if (field.type.name === "single_reference") { query_format[field_name] = `deep-expand:${parseInt( - format_params[1] + format_params[1], + 10 ) - 1}`; } } @@ -90,7 +90,7 @@ { format: query_format } ); }, - filter_to_query: async function(context, params, field_filter) { + async filter_to_query(context, params, field_filter) { // treating filter as a query here if (typeof field_filter !== "object") { return { @@ -108,7 +108,7 @@ ); return { $in: resources.map(resource => resource.id) }; }, - get_aggregation_stages: function( + get_aggregation_stages( context, params, field_name, @@ -118,10 +118,10 @@ const collection = new Collection(app, params.collection); const filter = {}; const temp_field_name = - collection.name + - "-" + - "lookup" + - Math.floor(Math.random().toString() * Math.pow(10, 7)); + `${collection.name}-` + + `lookup${Math.floor( + Math.random().toString() * Math.pow(10, 7) + )}`; const request_filter = query.filter && query.filter[field_name]; if (!request_filter || Object.keys(request_filter).length === 0) return []; @@ -139,20 +139,19 @@ }, ]; } - for (let field_name in request_filter) { - let field = collection.fields[field_name]; + for (let _field_name in request_filter) { + let field = collection.fields[_field_name]; if (!field) return Promise.reject( - "Unknown field in filter for '" + - collection.name + - "': " + - field_name + `Unknown field in filter for '${ + collection.name + }': ${_field_name}` ); filter[ - `${temp_field_name}.0.${field_name}` - ] = field.filter_to_query(context, request_filter[field_name]); + `${temp_field_name}.0.${_field_name}` + ] = field.filter_to_query(context, request_filter[_field_name]); } - return Promise.props(filter).then(function(_filter) { + return Promise.props(filter).then(_filter => { return [ { $lookup: { diff --git a/lib/app/base-chips/field-types/single_reference.subtest.js b/lib/app/base-chips/field-types/single_reference.subtest.js --- a/lib/app/base-chips/field-types/single_reference.subtest.js +++ b/lib/app/base-chips/field-types/single_reference.subtest.js @@ -1,7 +1,5 @@ const assert = require("assert"); const locreq = require("locreq")(__dirname); -const axios = require("axios"); -const { create_resource_as } = locreq("test_utils"); const { with_running_app } = locreq("test_utils/with-test-app.js"); const assert_throws_async = locreq("test_utils/assert_throws_async.js"); const A = "/api/v1/collections/A"; @@ -146,7 +144,7 @@ b_ids.push(id); } for (let b_id of b_ids) { - const a = await rest_api.post(A, { reference_to_b: b_id }); + await rest_api.post(A, { reference_to_b: b_id }); } const { items } = await rest_api @@ -251,11 +249,7 @@ it("should work", async () => with_running_app(async ({ app, rest_api }) => { await setup(app, rest_api); - - const { items: seals } = await rest_api.get( - `${Seals}?format[water_area]=expand` - ); - + await rest_api.get(`${Seals}?format[water_area]=expand`); //TODO: will be implemented in next phase })); }); diff --git a/lib/app/base-chips/field-types/text.js b/lib/app/base-chips/field-types/text.js --- a/lib/app/base-chips/field-types/text.js +++ b/lib/app/base-chips/field-types/text.js @@ -1,20 +1,18 @@ -"use strict"; const Promise = require("bluebird"); const escape = require("escape-html"); module.exports = { name: "text", - has_index: function(params) { + has_index(params) { if (params.full_text_search || params.include_in_search) { return { original: "text" }; - } else { - return false; } + return false; }, - get_description: function(context, params) { + get_description(context, params) { return `Text with maximum length ${params.max_length}`; }, - is_proper_value: function(context, params, new_value) { + is_proper_value(context, params, new_value) { let checks = []; checks.push(text => { @@ -50,19 +48,20 @@ Promise.resolve() ); }, - encode: function(context, params, value_in_code) { + encode(context, params, value_in_code) { if (typeof value_in_code === "string" && value_in_code !== null) { const result = { original: value_in_code, safe: escape(value_in_code), - valueOf: function() { + valueOf() { return value_in_code; }, }; return Promise.resolve(result); - } else return Promise.resolve(null); + } + return Promise.resolve(null); }, - get_aggregation_stages: function( + get_aggregation_stages( context, params, field_name, @@ -97,7 +96,7 @@ }, ]; }, - format: function(context, params, decoded_value, format) { + format(context, params, decoded_value, format) { if (decoded_value === null || decoded_value === undefined) { return Promise.resolve(decoded_value); } diff --git a/lib/app/base-chips/field-types/text.subtest.js b/lib/app/base-chips/field-types/text.subtest.js --- a/lib/app/base-chips/field-types/text.subtest.js +++ b/lib/app/base-chips/field-types/text.subtest.js @@ -26,7 +26,7 @@ `${base_url}/api/v1/collections/${collection}`, resource ); - throw "This should not pass"; + throw new Error("This should not pass"); } catch (e) { assert.deepEqual(e.response.data.data.surname.message, message); } diff --git a/lib/app/base-chips/field-types/username.js b/lib/app/base-chips/field-types/username.js --- a/lib/app/base-chips/field-types/username.js +++ b/lib/app/base-chips/field-types/username.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const me_synonyms = locreq("lib/misc/me-synonyms.json"); const SuperContext = locreq("lib/super-context.js"); @@ -7,11 +6,11 @@ return { name: "username", extends: "text", - is_proper_value: async function(context, params, new_value, old_value) { + async is_proper_value(context, params, new_value, old_value) { if (old_value === new_value) { return; } - if (me_synonyms.indexOf(new_value) !== -1) { + if (me_synonyms.includes(new_value)) { throw new Error( `'${new_value}'' is a reserved keyword. Please pick another username.` ); @@ -23,7 +22,7 @@ "show", { filter: { username: new_value } } ) - .then(function({ items }) { + .then(({ items }) => { if (items.length > 0) { throw new Error("Username already taken"); } diff --git a/lib/app/base-chips/field-types/value-existing-in-collection.js b/lib/app/base-chips/field-types/value-existing-in-collection.js --- a/lib/app/base-chips/field-types/value-existing-in-collection.js +++ b/lib/app/base-chips/field-types/value-existing-in-collection.js @@ -1,12 +1,10 @@ -"use strict"; -const locreq = require("locreq")(__dirname); const assert = require("assert"); const Promise = require("bluebird"); module.exports = function(app) { return { name: "value-existing-in-collection", - is_proper_value: async function(context, params, new_value) { + async is_proper_value(_context, params, new_value) { assert.equal(typeof params.field, "string"); assert( typeof params.include_forbidden === "boolean" || @@ -15,9 +13,10 @@ const collection = params.collection; assert(collection instanceof app.Sealious.Collection); await collection.fields[params.field].is_proper_value( - context, + _context, new_value ); + let context = _context; if (params.include_forbidden) { context = new app.Sealious.SuperContext(); } @@ -37,27 +36,27 @@ ); } }, - encode: async function(context, params, value_in_code, old_value) { + async encode(context, params, value_in_code, old_value) { return params.collection.fields[params.field].encode( context, value_in_code, old_value ); }, - format: function(context, params, decoded_value, format) { + format(context, params, decoded_value, format) { return params.collection.fields[params.field].format( context, decoded_value, format ); }, - filter_to_query: function(context, params, field_filter) { + filter_to_query(context, params, field_filter) { return params.collection.fields[params.field].filter_to_query( context, field_filter ); }, - get_aggregation_stages: function(context, params, field_name, query) { + get_aggregation_stages(context, params, field_name, query) { return params.collection.fields[ params.field ].get_aggregation_stages(context, field_name, query); diff --git a/lib/app/base-chips/field-types/value-exists-in-collection.js b/lib/app/base-chips/field-types/value-exists-in-collection.js --- a/lib/app/base-chips/field-types/value-exists-in-collection.js +++ b/lib/app/base-chips/field-types/value-exists-in-collection.js @@ -1,12 +1,10 @@ -"use strict"; -const locreq = require("locreq")(__dirname); const assert = require("assert"); const Promise = require("bluebird"); module.exports = function(app) { return { name: "value-exists-in-collection", - is_proper_value: async function(context, params, new_value) { + async is_proper_value(_context, params, new_value) { assert.equal(typeof params.field, "string"); assert( typeof params.include_forbidden === "boolean" || @@ -15,9 +13,10 @@ const collection = params.collection; assert(collection instanceof app.Sealious.Collection); await collection.fields[params.field].is_proper_value( - context, + _context, new_value ); + let context = _context; if (params.include_forbidden) { context = new app.Sealious.SuperContext(); } @@ -29,35 +28,32 @@ ); if (matches.length) { return Promise.resolve(); - } else { - return Promise.reject( - `No ${collection.name} with ${ - params.field - } set to ${new_value}` - ); } + return Promise.reject( + `No ${collection.name} with ${params.field} set to ${new_value}` + ); }, - encode: async function(context, params, value_in_code, old_value) { + async encode(context, params, value_in_code, old_value) { return params.collection.fields[params.field].encode( context, value_in_code, old_value ); }, - format: function(context, params, decoded_value, format) { + format(context, params, decoded_value, format) { return params.collection.fields[params.field].format( context, decoded_value, format ); }, - filter_to_query: function(context, params, field_filter) { + filter_to_query(context, params, field_filter) { return params.collection.fields[params.field].filter_to_query( context, field_filter ); }, - get_aggregation_stages: function(context, params, field_name, query) { + get_aggregation_stages(context, params, field_name, query) { return params.collection.fields[ params.field ].get_aggregation_stages(context, field_name, query); diff --git a/lib/app/base-chips/field-types/value-not-existing-in-collection.js b/lib/app/base-chips/field-types/value-not-existing-in-collection.js --- a/lib/app/base-chips/field-types/value-not-existing-in-collection.js +++ b/lib/app/base-chips/field-types/value-not-existing-in-collection.js @@ -4,7 +4,7 @@ return { name: "value-not-existing-in-collection", extends: "value-existing-in-collection", - is_proper_value: async (context, params, new_value) => { + is_proper_value: async (_context, params, new_value) => { assert.equal(typeof params.field, "string"); assert( typeof params.include_forbidden === "boolean" || @@ -13,9 +13,10 @@ const collection = params.collection; assert(collection instanceof app.Sealious.Collection); await collection.fields[params.field].is_proper_value( - context, + _context, new_value ); + let context = _context; if (params.include_forbidden) { context = new app.Sealious.SuperContext(); } diff --git a/lib/app/base-chips/special_filters/IsReferencedByResourcesMatching.js b/lib/app/base-chips/special_filters/IsReferencedByResourcesMatching.js --- a/lib/app/base-chips/special_filters/IsReferencedByResourcesMatching.js +++ b/lib/app/base-chips/special_filters/IsReferencedByResourcesMatching.js @@ -23,6 +23,7 @@ assert(Array.isArray(allowed_values)); assert(typeof nopass_reason === "string"); } + async getFilteringQuery() { const query = new Query(); const lookup_id = query.lookup({ diff --git a/lib/app/base-chips/special_filters/IsReferencedByResourcesMatching.subtest.js b/lib/app/base-chips/special_filters/IsReferencedByResourcesMatching.subtest.js --- a/lib/app/base-chips/special_filters/IsReferencedByResourcesMatching.subtest.js +++ b/lib/app/base-chips/special_filters/IsReferencedByResourcesMatching.subtest.js @@ -1,7 +1,5 @@ const assert = require("assert"); const locreq = require("locreq")(__dirname); -const Promise = require("bluebird"); - const { with_running_app } = locreq("test_utils/with-test-app.js"); describe("IsReferencedByResourcesMatching", () => { diff --git a/lib/app/base-chips/special_filters/matches.subtest.js b/lib/app/base-chips/special_filters/matches.subtest.js --- a/lib/app/base-chips/special_filters/matches.subtest.js +++ b/lib/app/base-chips/special_filters/matches.subtest.js @@ -1,12 +1,10 @@ const assert = require("assert"); const locreq = require("locreq")(__dirname); -const Promise = require("bluebird"); const { with_running_app } = locreq("test_utils/with-test-app.js"); describe("Matches", () => { async function setup(app, rest_api) { - const port = app.ConfigManager.get("www-server.port"); app.createChip(Sealious.Collection, { name: "numbers", fields: [ diff --git a/lib/app/chip-manager.js b/lib/app/chip-manager.js --- a/lib/app/chip-manager.js +++ b/lib/app/chip-manager.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const Errors = locreq("lib/response/error.js"); @@ -16,7 +15,7 @@ ]; ChipManager.pure = { - start_chips: function(app, chips) { + start_chips(app, chips) { const promises = []; const datastore = ChipManager.pure.get_datastore_chip(app, chips); @@ -41,7 +40,7 @@ } return Promise.all(promises); }, - add_chip: function(chips, type, name, chip) { + add_chip(chips, type, name, chip) { if (chips[type] === undefined) { chips[type] = []; } @@ -49,14 +48,14 @@ throw Error(`Chip '${type}.${name}' already exists!`); chips[type][name] = chip; }, - get_all_collections: function(chips) { + get_all_collections(chips) { const names = []; for (const collection in chips.collection) { names.push(collection); } return names; }, - get_chip: function(chips, type, name) { + get_chip(chips, type, name) { try { const ret = chips[type][name]; if (ret === undefined) { @@ -73,17 +72,16 @@ ); } }, - get_chip_amount_by_type: function(chips, type) { + get_chip_amount_by_type(chips, type) { if (chips[type]) { return Object.keys(chips[type]).length; - } else { - return 0; } + return 0; }, - get_datastore_chip: function(app, chips) { + get_datastore_chip(app, chips) { return app.Datastore; }, - get_chips_by_type: function(chips, chip_type) { + get_chips_by_type(chips, chip_type) { return chips[chip_type]; }, }; diff --git a/lib/app/config-manager.js b/lib/app/config-manager.js --- a/lib/app/config-manager.js +++ b/lib/app/config-manager.js @@ -7,19 +7,24 @@ this.CUSTOM_CONFIG = {}; this.isLocked = false; } + setDefault(key, value) { this._setGivenConfig(this.DEFAULT_CONFIG, key, value); } + getDefaultConfig(key) { return dotProp.get(this.DEFAULT_CONFIG, key); } + set(key, value) { this._setGivenConfig(this.CUSTOM_CONFIG, key, value); } + _setGivenConfig(config, key, value) { this._warnIfLocked(); dotProp.set(config, key, value); } + _warnIfLocked() { if (this.isLocked) { console.warn( @@ -28,16 +33,19 @@ ); } } + setRoot(params) { this._warnIfLocked(); merge.recursive(this.CUSTOM_CONFIG, params); } + get(key) { return dotProp.get( merge.recursive(true, this.DEFAULT_CONFIG, this.CUSTOM_CONFIG), key ); } + lock() { this.isLocked = true; } diff --git a/lib/app/file-manager.js b/lib/app/file-manager.js --- a/lib/app/file-manager.js +++ b/lib/app/file-manager.js @@ -1,81 +1,56 @@ -"use strict"; const locreq = require("locreq")(__dirname); -const Promise = require("bluebird"); const UUIDGenerator = require("shortid"); const path = require("path"); const fs = require("fs"); +const { promisify } = require("util"); +const exists = promisify(fs.exists); +const mkdir = promisify(fs.mkdir); +const writeFile = promisify(fs.writeFile); const File = locreq("lib/data-structures/file.js"); -function FileManager(datastore, logger, upload_path) { - this.datastore = datastore; - this.logger = logger; - this.upload_path = upload_path; +class FileManager { + constructor(datastore, logger, upload_path) { + this.datastore = datastore; + this.logger = logger; + this.upload_path = upload_path; + } - if (!fs.existsSync(this.upload_path)) { - fs.mkdirSync(this.upload_path); + async init() { + const dirExists = await exists(this.upload_path); + if (!dirExists) await mkdir(this.upload_path); } -} -FileManager.pure = { - save_file: function(datastore, upload_path, file) { + async save_file(file) { const newID = UUIDGenerator(); - const upload_path_with_sealious_name = `${upload_path}/${newID}`; - return Promise.promisify(fs.writeFile)( - upload_path_with_sealious_name, - file.data - ) - .then(function() { - const file_database_entry = { - original_name: file.filename, - creation_context: file.context, - id: newID, - mime_type: file.mime, - }; - return datastore.insert("files", file_database_entry, {}); - }) - .then(function() { - return { - id: newID, - filename: file.filename, - }; - }); - }, - find: function(datastore, upload_path, context, query) { - return datastore.find("files", query).then(function(documents) { - const parsed_documents = documents.map(function(document) { - const ret = File.from_db_entry(document); - ret.path_on_hdd = path.resolve(upload_path, `./${ret.id}`); - return ret; - }); - return Promise.resolve(parsed_documents); - }); - }, - get_by_id: function(datastore, upload_path, context, file_id) { - return FileManager.pure - .find(datastore, upload_path, context, { id: file_id }) - .then(function(file_array) { - return Promise.resolve(file_array[0]); - }); - }, -}; + const upload_path_with_sealious_name = `${this.upload_path}/${newID}`; + await writeFile(upload_path_with_sealious_name, file.data); -FileManager.prototype = { - save_file(file) { - return FileManager.pure.save_file( - this.datastore, - this.upload_path, - file + await this.datastore.insert( + "files", + { + original_name: file.filename, + creation_context: file.context, + id: newID, + mime_type: file.mime, + }, + {} ); - }, - find(context, query) { - return FileManager.pure.find( - this.datastore, - this.upload_path, - context, - query - ); - }, -}; + return { + id: newID, + filename: file.filename, + }; + } + + async find(context, query) { + const documents = await this.datastore.find("file", query); + const parsed_documents = documents.map(doc => { + const ret = File.from_db_entry(doc); + ret.path_on_hdd = path.resolve(this.upload_path, `./${ret.id}`); + return ret; + }); + return parsed_documents; + } +} module.exports = FileManager; diff --git a/lib/app/hookable.js b/lib/app/hookable.js --- a/lib/app/hookable.js +++ b/lib/app/hookable.js @@ -9,6 +9,7 @@ this.callback = callback; this.is_blocking = is_blocking; } + appliesTo(event_description) { return event_description.isEquivalentTo(this.event_matcher); } @@ -26,6 +27,7 @@ this.subject_path = subject_path; this.action = action; } + containsAction(action_name) { if (typeof this.action === "string") { return this.action === action_name; @@ -72,6 +74,7 @@ this.action = action; this.metadata = metadata; } + isEquivalentTo(source_event) { return ( this.matchWhen(source_event) && @@ -79,9 +82,11 @@ this.matchSubjectPath(source_event) ); } + matchWhen(source_event) { return this.when === source_event.when; } + matchAction(source_event) { if (typeof source_event.action === "string") { return source_event.action === this.action; @@ -91,6 +96,7 @@ } return false; } + matchSubjectPath(source_event) { return source_event.subject_path.test(this.subject_path); } @@ -100,14 +106,16 @@ constructor() { this.hooks = []; } + addHook(event_description, callback, is_blocking) { const event_matcher = new EventMatcher(event_description); const hook = new Hook({ event_matcher, callback, is_blocking }); this.hooks.push(hook); } + async emit(_event_description, data = {}) { const emitted_event = new EventDescription(_event_description); - return await Bluebird.reduce( + return Bluebird.reduce( this.hooks.filter(hook => hook.appliesTo(emitted_event)), async (acc, hook) => (await hook.callback(emitted_event, acc)) || acc, diff --git a/lib/app/load-base-chips.js b/lib/app/load-base-chips.js --- a/lib/app/load-base-chips.js +++ b/lib/app/load-base-chips.js @@ -1,5 +1,3 @@ -"use strict"; - const locreq = require("locreq")(__dirname); const AccessStrategyType = locreq("lib/chip-types/access-strategy-type.js"); @@ -77,7 +75,7 @@ BaseChipDirs.set(Collection, "collections"); const to_load = []; -BaseChips.forEach(function(names, constructor) { +BaseChips.forEach((names, constructor) => { for (const i in names) { const chip_name = names[i]; let declaration = locreq( diff --git a/lib/app/logger.js b/lib/app/logger.js --- a/lib/app/logger.js +++ b/lib/app/logger.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const winston = require("winston"); const { getTimeDifference } = locreq("lib/utils/get-datetime.js"); @@ -54,7 +53,7 @@ transports: transports_array, }); - logger.rewriters.push(function(level, msg, meta) { + logger.rewriters.push((level, msg, meta) => { let ret = ""; if (Object.keys(meta).length) { let message = "\n"; diff --git a/lib/app/metadata.js b/lib/app/metadata.js --- a/lib/app/metadata.js +++ b/lib/app/metadata.js @@ -6,8 +6,6 @@ const matches = await app.Datastore.find(COLLECTION_NAME, { key }); if (matches.length) { return matches[0].value; - } else { - undefined; } }, async set(key, value) { @@ -15,8 +13,8 @@ if (matches.length) { await app.Datastore.update( COLLECTION_NAME, - { key: key }, - { $set: { value: value } } + { key }, + { $set: { value } } ); } else { await app.Datastore.insert(COLLECTION_NAME, { key, value }); diff --git a/lib/app/run-action-curry.js b/lib/app/run-action-curry.js --- a/lib/app/run-action-curry.js +++ b/lib/app/run-action-curry.js @@ -1,7 +1,3 @@ -"use strict"; -const assert = require("assert"); -const locreq = require("locreq")(__dirname); - const ActionResultCache = new WeakMap(); function hash_call(subject_path, action_name, params) { @@ -33,7 +29,7 @@ } let subject = null; const promise = app.RootSubject.get_subject(subject_path) - .then(function(_subject) { + .then(_subject => { subject = _subject; return app.emit( { @@ -47,8 +43,8 @@ params ); }) - .then(params => - subject.perform_action(context, action_name, params) + .then(_params => + subject.perform_action(context, action_name, _params) ) .then(response => app.emit( @@ -70,7 +66,6 @@ } else { ActionResultCache.delete(original_context); } - return promise; }; } diff --git a/lib/chip-types/access-strategy-type.js b/lib/chip-types/access-strategy-type.js --- a/lib/chip-types/access-strategy-type.js +++ b/lib/chip-types/access-strategy-type.js @@ -1,8 +1,6 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const Errors = locreq("lib/response/error.js"); -const Chip = locreq("lib/chip-types/chip.js"); function AccessStrategyType(app, declaration) { if (declaration instanceof AccessStrategyType) { @@ -25,56 +23,51 @@ AccessStrategyType.type_name = "access_strategy_type"; AccessStrategyType.pure = { - check: function(declaration, context, params, item) { + check(declaration, context, params, item) { if (context.is_super) { return Promise.resolve(); } return AccessStrategyType.pure .is_item_sensitive(declaration, params) - .then(function(is_item_sensitive) { + .then(is_item_sensitive => { if (is_item_sensitive && item === undefined) { return Promise.resolve(undefined); - } else { - return Promise.try(function() { - return Promise.method(declaration.checker_function)( - context, - params, - item - ).then(function(result) { - if (result === false) { - return Promise.reject("Access denied"); - } else { - return Promise.resolve(result); - } - }); - }); } + return Promise.try(() => { + return Promise.method(declaration.checker_function)( + context, + params, + item + ).then(result => { + if (result === false) { + return Promise.reject("Access denied"); + } + return Promise.resolve(result); + }); + }); }) - .catch(function(error) { + .catch(error => { if (typeof error === "string") { return Promise.reject(new Errors.BadContext(error)); - } else { - return Promise.reject(error); } + return Promise.reject(error); }); }, - is_item_sensitive: function(declaration, params) { + is_item_sensitive(declaration, params) { if (typeof declaration.item_sensitive === "function") { return Promise.resolve(declaration.item_sensitive(params)); - } else { - return Promise.resolve(Boolean(declaration.item_sensitive)); } + return Promise.resolve(Boolean(declaration.item_sensitive)); }, - getRestrictingQuery: function(declaration, context, params) { + getRestrictingQuery(declaration, context, params) { if (declaration.getRestrictingQuery) { return Promise.resolve( declaration.getRestrictingQuery(context, params) ).then(result => { return result; }); - } else { - return Promise.resolve([]); } + return Promise.resolve([]); }, }; diff --git a/lib/chip-types/access-strategy.js b/lib/chip-types/access-strategy.js --- a/lib/chip-types/access-strategy.js +++ b/lib/chip-types/access-strategy.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const AccessStrategyType = locreq("lib/chip-types/access-strategy-type.js"); diff --git a/lib/chip-types/aggregated-field.js b/lib/chip-types/aggregated-field.js --- a/lib/chip-types/aggregated-field.js +++ b/lib/chip-types/aggregated-field.js @@ -8,12 +8,11 @@ AggregatedField.prototype.get_aggregation_stages = function(context, item) { const self = this; return Promise.all( - self.aggregations.map(function(e) { + self.aggregations.map(e => { if (e instanceof Function) { return e(context, item); - } else { - return e; } + return e; }) ); }; diff --git a/lib/chip-types/calculated-field-type.js b/lib/chip-types/calculated-field-type.js --- a/lib/chip-types/calculated-field-type.js +++ b/lib/chip-types/calculated-field-type.js @@ -12,7 +12,7 @@ CalculatedFieldType.type_name = "calculated_field_type"; CalculatedFieldType.pure = { - get_value: function(declaration, context, params, item, db_document) { + get_value(declaration, context, params, item, db_document) { return Promise.resolve( declaration.calculate(context, params, item, db_document) ); @@ -31,7 +31,7 @@ const pure = CalculatedFieldType.pure; CalculatedFieldType.prototype = { - get_value: function(context, params, item, raw_db_entry) { + get_value(context, params, item, raw_db_entry) { return pure.get_value( this.declaration, context, diff --git a/lib/chip-types/calculated-field.js b/lib/chip-types/calculated-field.js --- a/lib/chip-types/calculated-field.js +++ b/lib/chip-types/calculated-field.js @@ -7,8 +7,8 @@ type_params ) { this.app = App; - (this.name = field_name), - (this.type = new CalculatedFieldType(App, type_declaration)); + this.name = field_name; + this.type = new CalculatedFieldType(App, type_declaration); this.params = type_params; }; diff --git a/lib/chip-types/channel.js b/lib/chip-types/channel.js --- a/lib/chip-types/channel.js +++ b/lib/chip-types/channel.js @@ -1,6 +1,3 @@ -"use strict"; -const locreq = require("locreq")(__dirname); - const channel = function(app, declaration) { this.name = declaration.name; this.longid = `channel.${declaration.name}`; diff --git a/lib/chip-types/chip.js b/lib/chip-types/chip.js --- a/lib/chip-types/chip.js +++ b/lib/chip-types/chip.js @@ -1,8 +1,5 @@ -"use strict"; const Promise = require("bluebird"); -let ChipManager; - const Chip = function(type, name) { this.type = type; this.name = name; diff --git a/lib/chip-types/collection.js b/lib/chip-types/collection.js --- a/lib/chip-types/collection.js +++ b/lib/chip-types/collection.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const assert = require("assert"); @@ -18,8 +17,6 @@ } else if (declaration instanceof Collection) { return declaration; } - - const self = this; Chip.call(this, "collection", declaration.name); this.app = app; this.name = declaration.name; @@ -73,13 +70,7 @@ Collection.type_name = "collection"; Collection.pure = { - add_field: function( - app, - field_type, - fields, - field_declaration, - collection - ) { + add_field(app, field_type, fields, field_declaration, collection) { const field_object = new Field( app, field_declaration, @@ -87,23 +78,23 @@ collection ); const field_name = field_object.name; - if (!fields[field_name]) { - fields[field_name] = field_object; - } else { + if (fields[field_name]) { throw new Errors.DeveloperError( `Duplicate field names: "${field_name}" in collection: "${ field_type.name }"` ); + } else { + fields[field_name] = field_object; } }, - add_fields: function(app, field_type, fields, field_declarations_array) { + add_fields(app, field_type, fields, field_declarations_array) { for (const i in field_declarations_array) { const declaration = field_declarations_array[i]; Collection.pure.add_field(app, field_type, fields, declaration); } }, - add_calculated_field: function( + add_calculated_field( app, collection, calc_field_name, @@ -117,10 +108,11 @@ calc_field_type_params ); }, + /* eslint-disable no-shadow */ add_special_filters(Collection, named_filters) { Collection.named_filters = named_filters; }, - get_unknown_field_errors: function(field_type_name, fields, values) { + get_unknown_field_errors(field_type_name, fields, values) { const validation_errors = {}; for (const field_name in values) { if (fields[field_name] === undefined) { @@ -131,7 +123,7 @@ } return validation_errors; }, - get_missing_values_checker: function( + get_missing_values_checker( fields, values, assume_delete_value_on_missing_key, @@ -144,17 +136,16 @@ values[field_name] === undefined ); }; - } else { - return function(field_name) { - return ( - fields[field_name].required && - values[field_name] === undefined && - old_values[field_name] === undefined - ); - }; } + return function(field_name) { + return ( + fields[field_name].required && + values[field_name] === undefined && + old_values[field_name] === undefined + ); + }; }, - get_missing_field_values_errors: function( + get_missing_field_values_errors( fields, values, assume_delete_value_on_missing_key, @@ -169,21 +160,16 @@ ); return Promise.filter(Object.keys(fields), checker_fn) - .each(function(field_name) { + .each(field_name => { errors[field_name] = new Errors.ValidationError( `Missing value for field '${field_name}'` ); }) - .then(function() { + .then(() => { return errors; }); }, - get_invalid_field_values_errors: function( - fields, - context, - values, - old_values - ) { + get_invalid_field_values_errors(fields, context, values, old_values) { const errors = {}; const promises = []; for (const field_name in values) { @@ -195,7 +181,7 @@ : undefined; const promise = fields[field_name] .is_proper_value(context, value, old_value) - .catch(function(error) { + .catch(error => { if ( typeof error === "string" || error.type === "validation" @@ -210,11 +196,11 @@ promises.push(promise); } } - return Promise.all(promises).then(function() { + return Promise.all(promises).then(() => { return errors; }); }, - get_missing_required_field_values: function(fields, new_values) { + get_missing_required_field_values(fields, new_values) { const errors = {}; for (const field_name in new_values) { if ( @@ -229,7 +215,7 @@ } return errors; }, - validate_field_values: function( + validate_field_values( field_type_name, fields, context, @@ -263,7 +249,7 @@ return Promise.all(errors_array) .reduce(merge) - .then(function(errors) { + .then(errors => { const user_errors = {}; const non_user_errors = {}; for (const field_name in errors) { @@ -288,7 +274,7 @@ } }); }, - encode_field_values: async function(fields, context, body, old_body) { + async encode_field_values(fields, context, body, old_body) { const promises = {}; for (let field_name in fields) { const field = fields[field_name]; @@ -316,7 +302,7 @@ } return Promise.props(promises); }, - get_specification: function( + get_specification( name, human_readable_name, summary, @@ -333,14 +319,14 @@ } const specification = { - name: name, - human_readable_name: human_readable_name, - summary: summary, + name, + human_readable_name, + summary, fields: collection_specification, }; return specification; }, - set_access_strategy: function(app, collection, strategy_declaration) { + set_access_strategy(app, collection, strategy_declaration) { if ( typeof strategy_declaration === "string" || strategy_declaration instanceof AccessStrategyType || @@ -359,12 +345,12 @@ } } }, - get_access_strategy: function(access_strategy_map, action_name) { + get_access_strategy(access_strategy_map, action_name) { const ret = - access_strategy_map[action_name] || access_strategy_map["default"]; + access_strategy_map[action_name] || access_strategy_map.default; return ret; }, - has_large_data_fields: function(fields) { + has_large_data_fields(fields) { for (const i in fields) { const field = fields[i]; if (field.type.handles_large_data) { @@ -373,7 +359,7 @@ } return false; }, - is_old_value_sensitive: function(fields, action_name) { + is_old_value_sensitive(fields, action_name) { for (const i in fields) { if (fields[i].type.is_old_value_sensitive(action_name)) { return true; @@ -381,7 +367,7 @@ } return false; }, - decode_values: function(fields, context, values) { + decode_values(fields, context, values) { const decoded_values = {}; for (const key in fields) { const value = values[key]; @@ -393,7 +379,7 @@ } return Promise.props(decoded_values); }, - format_decoded_values: function(fields, context, decoded_values, format) { + format_decoded_values(fields, context, decoded_values, format) { const formatted_values = clone(decoded_values); for (const field_name in formatted_values) { const field_format = format[field_name] || undefined; @@ -406,7 +392,7 @@ } return Promise.props(formatted_values); }, - _get_body: async function(fields, context, db_document, format) { + async _get_body(fields, context, db_document, format) { const decoded_values = await Collection.pure.decode_values( fields, context, @@ -419,7 +405,7 @@ format || {} ); }, - _get_calculated_fields: function( + _get_calculated_fields( context, calculated_fields, representation, @@ -438,16 +424,15 @@ } return Promise.props(ret); }, - get_resource_representation: async function( + async get_resource_representation( fields, field_type_name, context, db_document, format, calculated_fields, - calculate + calculate = true ) { - if (calculate === undefined) calculate = true; const representation = await Collection.pure._get_body( fields, context, @@ -468,7 +453,7 @@ } return representation; }, - check_if_action_is_allowed: function( + check_if_action_is_allowed( access_strategy_map, context, action_name, @@ -481,11 +466,11 @@ return access_strategy .check(context, resource_representation) - .then(function(results) { + .then(results => { return results; }); }, - get_aggregation_stages: function( + get_aggregation_stages( collection, context, action_name, @@ -572,13 +557,13 @@ type_params ); }, - add_special_filters: function(named_filters = []) { + add_special_filters(named_filters = []) { return pure.add_special_filters(this, named_filters); }, - get_named_filter: function(filter_name) { + get_named_filter(filter_name) { return this.named_filters[filter_name]; }, - add_named_filter: function(filter_name, filter) { + add_named_filter(filter_name, filter) { this.named_filters[filter_name] = filter; }, validate_field_values( diff --git a/lib/chip-types/datastore.js b/lib/chip-types/datastore.js --- a/lib/chip-types/datastore.js +++ b/lib/chip-types/datastore.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const assert = require("assert"); const Chip = require("./chip.js"); @@ -15,8 +14,6 @@ Datastore.prototype = new Chip(); -const needs_to_implement = ["find", "insert", "update", "remove"]; - Datastore.prototype.return_not_implemented = function(fn_name) { return function() { throw new Errors.DeveloperError( @@ -40,7 +37,7 @@ const test_collection_name = "_test"; return Promise.resolve() - .then(function() { + .then(() => { // .insert method should respond with the created document const to_insert = { value: 1, @@ -48,7 +45,7 @@ }; return self .insert(test_collection_name, to_insert) - .then(function(response) { + .then(response => { assert.deepEqual( to_insert, response, @@ -57,22 +54,17 @@ return Promise.resolve(); }); }) - .then(function() { + .then(() => // check if find resolves with an array - - return self - .find(test_collection_name, {}, {}) - .then(function(documents) { - assert( - documents instanceof Array, - `datastore.${ - self.name - }.find should resolve with an array` - ); - return Promise.resolve(); - }); - }) - .then(function() { + self.find(test_collection_name, {}, {}).then(documents => { + assert( + documents instanceof Array, + `datastore.${self.name}.find should resolve with an array` + ); + return Promise.resolve(); + }) + ) + .then(() => { // check if amount of created documents checks out const creates = [ self.insert(test_collection_name, { @@ -91,10 +83,8 @@ const created_so_far = 4; return Promise.all(creates) - .then(function() { - return self.find(test_collection_name, {}, {}); - }) - .then(function(documents) { + .then(() => self.find(test_collection_name, {}, {})) + .then(documents => { assert( documents.length === created_so_far, `Inserted ${created_so_far} documents so far, but ${ @@ -104,7 +94,7 @@ return Promise.resolve(created_so_far); }); }) - .then(function(created_so_far) { + .then(created_so_far => { // check if there is a proper amount of documents with random value set to rand const documents_with_rand = created_so_far - 1; return self @@ -115,7 +105,7 @@ }, {} ) - .then(function(documents) { + .then(documents => { assert( documents.length === documents_with_rand, `Inserted ${documents_with_rand} documents with "random" set to "${rand}" so far, but ${ @@ -125,7 +115,7 @@ return Promise.resolve(); }); }) - .then(function() { + .then(() => { // Should store a complex object const complex_object = { id: "aseoifaoeina", @@ -136,7 +126,7 @@ }; return self .insert(test_collection_name, complex_object) - .then(function(response) { + .then(response => { assert.deepEqual( complex_object, response, @@ -146,7 +136,7 @@ id: complex_object.id, }); }) - .then(function(response) { + .then(response => { assert.deepEqual( complex_object, response[0], @@ -155,13 +145,13 @@ return Promise.resolve(complex_object); }); }) - .then(function(complex_object) { + .then(complex_object => { // Should handle dot-notation nested queries return self .find(test_collection_name, { name: complex_object.name, }) - .then(function(response) { + .then(response => { assert.deepEqual( complex_object, response[0], @@ -170,23 +160,23 @@ return Promise.resolve(complex_object); }); }) - .then(function(complex_object) { - return self + .then(complex_object => + self .find(test_collection_name, { body: { name: complex_object.name, }, }) - .then(function(response) { + .then(response => { assert.deepEqual( complex_object, response[0], ".find method should handle nested object queries" ); return Promise.resolve(complex_object); - }); - }) - .then(function(complex_object) { + }) + ) + .then(complex_object => { // .update should modify document values with dot notation complex_object.name = "Hanna"; return self @@ -199,12 +189,12 @@ name: complex_object.name, } ) - .then(function() { - return self.find(test_collection_name, { + .then(() => + self.find(test_collection_name, { id: complex_object.id, - }); - }) - .then(function(results) { + }) + ) + .then(results => { assert.deepEqual( complex_object, results[0], @@ -213,7 +203,7 @@ return Promise.resolve(complex_object); }); }) - .then(function(complex_object) { + .then(complex_object => { // .update should modify document values using nested object as a query complex_object.name = "Marzanna"; return self @@ -228,12 +218,12 @@ }, } ) - .then(function() { - return self.find(test_collection_name, { + .then(() => + self.find(test_collection_name, { id: complex_object.id, - }); - }) - .then(function(results) { + }) + ) + .then(results => { assert.deepEqual( complex_object, results[0], @@ -242,7 +232,7 @@ return Promise.resolve(complex_object); }); }) - .then(function(complex_object) { + .then(complex_object => { // .update should insert new value to a field that previously had no value (undefined) complex_object.other = "Focca"; return self @@ -257,12 +247,12 @@ }, } ) - .then(function() { - return self.find(test_collection_name, { + .then(() => + self.find(test_collection_name, { id: complex_object.id, - }); - }) - .then(function(results) { + }) + ) + .then(results => { assert.deepEqual( complex_object, results[0], @@ -271,29 +261,29 @@ return Promise.resolve(complex_object); }); }) - .then(function(complex_object) { + .then(complex_object => { // .remove should remove only one document when "just_one" is set to true return Promise.all([ self.insert(test_collection_name, complex_object), self.insert(test_collection_name, complex_object), self.insert(test_collection_name, complex_object), ]) - .then(function() { + .then(() => // all the "complex_object" documents have the same id - return self.remove( + self.remove( test_collection_name, { id: complex_object.id, }, true - ); - }) - .then(function() { - return self.find(test_collection_name, { + ) + ) + .then(() => + self.find(test_collection_name, { id: complex_object.id, - }); - }) - .then(function(results) { + }) + ) + .then(results => { assert( results.length === 3, ".remove should remove only *one* document when `just_one` argument is set to true" @@ -301,29 +291,29 @@ return Promise.resolve(complex_object); }); }) - .then(function(complex_object) { + .then(complex_object => { // .remove should remove all matching documents when "just_one" is falsy return Promise.all([ self.insert(test_collection_name, complex_object), self.insert(test_collection_name, complex_object), self.insert(test_collection_name, complex_object), ]) - .then(function() { + .then(() => // all the "complex_object" documents have the same id - return self.remove( + self.remove( test_collection_name, { id: complex_object.id, }, false - ); - }) - .then(function() { - return self.find(test_collection_name, { + ) + ) + .then(() => + self.find(test_collection_name, { id: complex_object.id, - }); - }) - .then(function(results) { + }) + ) + .then(results => { assert( results.length === 0, ".remove should remove all matching documents when 'just_one' is falsy" @@ -331,10 +321,10 @@ return Promise.resolve(complex_object); }); }) - .then(function() { + .then(() => { self.clear_collection(test_collection_name); }) - .catch(function() { + .catch(() => { self.clear_collection(test_collection_name); return Promise.reject("Compatibility test unsuccesfull"); }); diff --git a/lib/chip-types/field-structures.js b/lib/chip-types/field-structures.js --- a/lib/chip-types/field-structures.js +++ b/lib/chip-types/field-structures.js @@ -1,4 +1,3 @@ -"use strict"; const FieldStructures = { single: require("./field-structures/single.js"), }; diff --git a/lib/chip-types/field-type-default-methods.js b/lib/chip-types/field-type-default-methods.js --- a/lib/chip-types/field-type-default-methods.js +++ b/lib/chip-types/field-type-default-methods.js @@ -1,44 +1,41 @@ -"use strict"; const Promise = require("bluebird"); const expandHash = require("expand-hash"); const FieldTypeDescription = require("../data-structures/field-type-description.js"); const default_methods = { - init: function() { + init() { return null; }, - has_index: function(params) { + has_index(params) { return false; }, - is_proper_value: function(context, params, new_value, old_value) { + is_proper_value(context, params, new_value, old_value) { return Promise.resolve(); }, - format: function(context, params, decoded_value, format_params) { + format(context, params, decoded_value, format_params) { return decoded_value; }, - encode: function(context, params, value_in_code) { + encode(context, params, value_in_code) { return value_in_code; }, - get_description: function(context, params) { + get_description(context, params) { return new FieldTypeDescription(this.name); }, - decode: function(context, params, value_in_database) { + decode(context, params, value_in_database) { return value_in_database; }, - filter_to_query: function(context, params, query) { + filter_to_query(context, params, query) { return Promise.resolve(this.encode(context, params, query)).then( - function(encoded_value) { - return { - $eq: encoded_value, - }; - } + encoded_value => ({ + $eq: encoded_value, + }) ); }, - full_text_search_enabled: function() { + full_text_search_enabled() { return false; }, - get_aggregation_stages: async function( + async get_aggregation_stages( context, params, field_name, @@ -64,7 +61,7 @@ let new_filter = null; if (field_filter instanceof Array) { new_filter = await Promise.all( - field_filter.map(function(element) { + field_filter.map(element => { return self.encode(context, params, element); }) ).then(filters => { diff --git a/lib/chip-types/field-type.js b/lib/chip-types/field-type.js --- a/lib/chip-types/field-type.js +++ b/lib/chip-types/field-type.js @@ -1,8 +1,4 @@ -"use strict"; -const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); - -const Errors = locreq("lib/response/error.js"); const default_methods = require("./field-type-default-methods.js"); function wrap_method_in_promise(context, declaration, method_name) { diff --git a/lib/chip-types/field.js b/lib/chip-types/field.js --- a/lib/chip-types/field.js +++ b/lib/chip-types/field.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const default_methods = require("./field-type-default-methods.js"); const FieldType = locreq("lib/chip-types/field-type.js"); @@ -15,11 +14,14 @@ const self = this; for (const method_name in default_methods) { - this[method_name] = (function(method_name) { + this[method_name] = (function(_method_name) { return function() { const arguments_array = Array.from(arguments); arguments_array.splice(1, 0, self.params); - return self.type[method_name].apply(self.type, arguments_array); + return self.type[_method_name].apply( + self.type, + arguments_array + ); }; })(method_name); } diff --git a/lib/chip-types/special-filter.js b/lib/chip-types/special-filter.js --- a/lib/chip-types/special-filter.js +++ b/lib/chip-types/special-filter.js @@ -3,7 +3,7 @@ const Collection = locreq("lib/chip-types/collection"); -module.exports = app => { +module.exports = App => { class SpecialFilter { constructor(params) { this.params = params; diff --git a/lib/context.js b/lib/context.js --- a/lib/context.js +++ b/lib/context.js @@ -1,12 +1,11 @@ -"use strict"; const locreq = require("locreq")(__dirname); const promisify = require("bluebird-events"); const EventEmitter = require("events"); function Context( - timestamp, + _timestamp, ip, - user_id, + _user_id, session_id, anonymous_session_id, anon_session_is_new, @@ -39,14 +38,11 @@ value: anon_session_is_new || false, }); // to make it non-enumerable and non-writeable - if (user_id === undefined || user_id === false) { - user_id = null; - } + const user_id = + _user_id === undefined || _user_id === false ? null : _user_id; - if (timestamp === undefined) { - const d = new Date(); - timestamp = d.getTime(); - } + const timestamp = + _timestamp === undefined ? new Date().getTime() : _timestamp; this.timestamp = timestamp; this.ip = ip || null; @@ -70,19 +66,18 @@ const c = new SuperContext(self); return app .run_action(c, ["collections", "users", this.user_id], "show") - .then(function(user_data) { + .then(user_data => { self._cached_user_data = user_data; self.loading_user_data = false; self.e.emit("loaded_user_data", user_data); return user_data; }) - .catch(function(error) { + .catch(error => { self.e.emit("error"); throw error; }); - } else { - return Promise.resolve(self._cached_user_data); } + return Promise.resolve(self._cached_user_data); }; module.exports = Context; diff --git a/lib/data-structures/field-type-description.js b/lib/data-structures/field-type-description.js --- a/lib/data-structures/field-type-description.js +++ b/lib/data-structures/field-type-description.js @@ -1,6 +1,3 @@ -"use strict"; -"use strict"; - const FieldTypeDescription = function(summary, raw_params, extra_info) { this.summary = summary; this.raw_params = raw_params; diff --git a/lib/data-structures/file.js b/lib/data-structures/file.js --- a/lib/data-structures/file.js +++ b/lib/data-structures/file.js @@ -1,9 +1,5 @@ -"use strict"; -const locreq = require("locreq")(__dirname); const mime = require("mime-types"); -const Promise = require("bluebird"); - function File(creation_context, filename, data, id, file_mime) { this.filename = filename; this.data = data; diff --git a/lib/data-structures/subject-path.js b/lib/data-structures/subject-path.js --- a/lib/data-structures/subject-path.js +++ b/lib/data-structures/subject-path.js @@ -1,5 +1,3 @@ -"use strict"; - const clone = require("clone"); const SubjectPath = function(subject_path) { diff --git a/lib/data-structures/virtual-file.js b/lib/data-structures/virtual-file.js --- a/lib/data-structures/virtual-file.js +++ b/lib/data-structures/virtual-file.js @@ -1,6 +1,3 @@ -"use strict"; -"use strict"; - const VirtualFile = function(content, mime) { this.content = content; this.mime = mime || "text/plain"; diff --git a/lib/datastore/db.js b/lib/datastore/db.js --- a/lib/datastore/db.js +++ b/lib/datastore/db.js @@ -1,33 +1,29 @@ -"use strict"; -var Promise = require("bluebird"); -var MongoClient = require("mongodb").MongoClient; -var DbsCommonPart = require("./mongo-api-abstract"); +const Promise = require("bluebird"); +const MongoClient = require("mongodb").MongoClient; +const DbsCommonPart = require("./mongo-api-abstract"); module.exports = function(App) { const priv = { db: null }; let client = null; - var DatastoreMongo = App.createChip(App.Sealious.Datastore, { + const DatastoreMongo = App.createChip(App.Sealious.Datastore, { name: "mongo", }); DatastoreMongo.start = function() { - var self = this; - var config = App.ConfigManager.get("datastore_mongo"); + const self = this; + const config = App.ConfigManager.get("datastore_mongo"); - var url = `mongodb://${config.host}:${config.port}/${config.db_name}`; - return Promise.promisify(MongoClient.connect)(url).then(function( - _client - ) { + const url = `mongodb://${config.host}:${config.port}/${config.db_name}`; + return Promise.promisify(MongoClient.connect)(url).then(_client => { if (_client === null) { return Promise.reject( "MongoDB was not found, please make sure it's installed. Check https://docs.mongodb.org/manual/tutorial/ for more info." ); - } else { - client = _client; - priv.db = _client.db(config.db_name); - return self.post_start(); } + client = _client; + priv.db = _client.db(config.db_name); + return self.post_start(); }); }; diff --git a/lib/datastore/graph.js b/lib/datastore/graph.js --- a/lib/datastore/graph.js +++ b/lib/datastore/graph.js @@ -5,6 +5,7 @@ this.nodes = []; this.indexes = []; } + addNode(id, priority) { this.adjacency_matrix.push(Array(this.getNoOfNodes()).fill(0)); for (const row of this.adjacency_matrix) { @@ -14,20 +15,25 @@ this.nodes.push({ id, priority }); this.indexes.push(this.nodes.length - 1); } + getNoOfNodes() { return this.nodes.length; } + addEdge(id_i, id_j) { const [i, j] = this._getIndexesOfNodePair(id_i, id_j); this.adjacency_matrix[i][j] = 1; } + _getIndexesOfNodePair(id_i, id_j) { return [this.node_ids.indexOf(id_i), this.node_ids.indexOf(id_j)]; } + pathExists(id_i, id_j) { const [i, j] = this._getIndexesOfNodePair(id_i, id_j); return this._pathExists(i, j); } + _pathExists(i, j) { if (this.adjacency_matrix[i][j]) { return true; @@ -39,6 +45,7 @@ } return false; } + bestFirstSearch() { this.front = []; this.visited = []; @@ -59,6 +66,7 @@ } return this.visited.map(i => this.nodes[i].id); } + _areAllSuccessorsVisited(i) { for (let j = 0; j < this.nodes.length; ++j) { if (this.adjacency_matrix[i][j] && !this._isVisited(j)) { @@ -67,9 +75,11 @@ } return true; } + _isVisited(i) { return this.visited.includes(i); } + _isNodeWithoutPredecessors(i) { for (let j = 0; j < this.nodes.length; ++j) { if (this.adjacency_matrix[j][i]) { @@ -78,6 +88,7 @@ } return true; } + _getNextNode() { const nodesWithoutPredecessorsYetToBeVisited = this.indexes.filter( i => this._isNodeWithoutPredecessors(i) && !this._isVisited(i) @@ -119,6 +130,7 @@ ); return { front_node, next_node: candidate2.index }; } + _lookForNextNodeInCandidates(candidates) { let next_node = null, best_priority = Infinity, @@ -146,6 +158,7 @@ mean_priority_of_succcessors: best_mean, }; } + _meanPriorityOfSuccessors(i) { let sum = 0, length = 0; diff --git a/lib/datastore/mongo-api-abstract.js b/lib/datastore/mongo-api-abstract.js --- a/lib/datastore/mongo-api-abstract.js +++ b/lib/datastore/mongo-api-abstract.js @@ -1,5 +1,4 @@ -"use strict"; -var Promise = require("bluebird"); +const Promise = require("bluebird"); const merge = require("merge"); function createIndex(db_collection, index) { @@ -9,16 +8,16 @@ ); } -var DatabasesCommonPart = function(app, datastore, _private) { +const DatabasesCommonPart = function(app, datastore, _private) { datastore.post_start = function() { datastore.client = _private.db; const collection_names = app.ChipManager.get_all_collections(); const collections = collection_names.map(name => app.ChipManager.get_chip("collection", name) ); - return Promise.map(collections, function(collection) { - let indexes = [["sealious_id", 1]]; - for (var field_name in collection.fields) { + return Promise.map(collections, collection => { + const indexes = [["sealious_id", 1]]; + for (const field_name in collection.fields) { indexes.push( Promise.all([ field_name, @@ -28,19 +27,18 @@ } const db_collection = _private.db.collection(collection.name); return Promise.all(indexes) - .then(function(collection_indexes) { + .then(collection_indexes => { const all_indexes = collection_indexes .filter(e => e[1] !== false) - .map(function(index) { + .map(index => { if (index[1] instanceof Object) { const ret = []; for (const i in index[1]) { - ret.push([index[0] + "." + i, index[1][i]]); + ret.push([`${index[0]}.${i}`, index[1][i]]); } return ret; - } else { - return [index]; } + return [index]; }) .reduce((a, b) => a.concat(b), []); @@ -60,7 +58,7 @@ {} ), ]; - if (Object.keys(text_indexes[0]).length == 0) { + if (!Object.keys(text_indexes[0]).length) { text_indexes = []; } @@ -70,12 +68,12 @@ return merged_indexes; }) - .each(function(index) { + .each(index => { return createIndex(db_collection, index).catch( - e => e.code == 85, - function(error) { + e => e.code === 85, + error => { const index_name = error.message - .match(/name: \"([^\"]+)\"/g)[1] + .match(/name: "([^"]+)"/g)[1] .replace('name: "', "") .replace('"', ""); return Promise.promisify(db_collection.dropIndex) @@ -91,34 +89,37 @@ if (!query) { return {}; } - var new_query = {}; - for (var attribute_name in query) { - if (attribute_name == "sealious_id") { + let new_query = {}; + for (let attribute_name in query) { + if (attribute_name === "sealious_id") { new_query[attribute_name] = query[attribute_name]; - } else { - if (query[attribute_name] instanceof Object) { - if (attribute_name[0] === "$") { - new_query[attribute_name] = query[attribute_name]; - } else { - for (var i in query[attribute_name]) { - new_query[attribute_name + "." + i] = - query[attribute_name][i]; - } - } - } else { + } else if (query[attribute_name] instanceof Object) { + if (attribute_name[0] === "$") { new_query[attribute_name] = query[attribute_name]; + } else { + for (let i in query[attribute_name]) { + new_query[`${attribute_name}.${i}`] = + query[attribute_name][i]; + } } + } else { + new_query[attribute_name] = query[attribute_name]; } } return new_query; } - datastore.find = function(collection_name, query, options, output_options) { + datastore.find = function( + collection_name, + query, + _options, + _output_options + ) { //console.log("FIND", collection_name, query); //query = process_query(query); // - needed, ResourceCollection subject handles that now - options = options || {}; - output_options = output_options || {}; - var cursor = _private.db + const options = _options || {}; + const output_options = _output_options || {}; + let cursor = _private.db .collection(collection_name) .find(query, options); if (output_options.sort) { @@ -137,11 +138,10 @@ collection_name, pipeline, options, - output_options + _output_options ) { //console.log("aggregate", collection_name, JSON.stringify(pipeline)); - options = options || {}; - output_options = output_options || {}; + const output_options = _output_options || {}; const cursor = _private.db .collection(collection_name) .aggregate(pipeline); @@ -162,17 +162,17 @@ datastore.insert = function(collection_name, to_insert, options) { return Promise.promisify(_private.db.collection(collection_name).insert) .bind(_private.db.collection(collection_name))(to_insert, options) - .then(function(result) { + .then(result => { return result.ops[0]; }); }; - datastore.update = function(collection_name, query, new_value) { - query = process_query(query); - return new Promise(function(resolve, reject) { + datastore.update = function(collection_name, _query, new_value) { + const query = process_query(_query); + return new Promise((resolve, reject) => { _private.db .collection(collection_name) - .update(query, new_value, function(err, WriteResult) { + .update(query, new_value, (err, WriteResult) => { if (err) { reject(err); } else { @@ -182,16 +182,14 @@ }); }; - datastore.remove = function(collection_name, query, just_one) { - query = process_query(query); - return new Promise(function(resolve, reject) { - if (just_one === undefined) { - just_one = 0; - } + datastore.remove = function(collection_name, _query, _just_one) { + const query = process_query(_query); + return new Promise((resolve, reject) => { + let just_one = _just_one === undefined ? 0 : _just_one; just_one = just_one ? 1 : 0; _private.db .collection(collection_name) - .remove(query, just_one, function(err, delete_response) { + .remove(query, just_one, (err, delete_response) => { if (err) { reject(err); } else { diff --git a/lib/datastore/negate_stage.js b/lib/datastore/negate_stage.js --- a/lib/datastore/negate_stage.js +++ b/lib/datastore/negate_stage.js @@ -9,12 +9,10 @@ negated_stage.$or = stage[key].map(expression => negate_stage(expression) ); + } else if (stage[key].$not) { + negated_stage[key] = stage[key].$not; } else { - if (stage[key].$not) { - negated_stage[key] = stage[key].$not; - } else { - negated_stage[key] = { $not: stage[key] }; - } + negated_stage[key] = { $not: stage[key] }; } } return negated_stage; diff --git a/lib/datastore/query-step.js b/lib/datastore/query-step.js --- a/lib/datastore/query-step.js +++ b/lib/datastore/query-step.js @@ -4,13 +4,16 @@ class QueryStep { constructor(body) { this.body = body; + this.cost = 8; } + hash() { return QueryStep.hashBody(this.body); } + static fromStage(stage, unwind = true) { if (stage.$lookup) { - const clonedStageBody = Object.assign({}, stage.$lookup); + const clonedStageBody = { ...stage.$lookup }; clonedStageBody.unwind = unwind; return [new QueryStep.Lookup(clonedStageBody)]; } else if (stage.$match) { @@ -18,19 +21,22 @@ field => new QueryStep.Match({ [field]: stage.$match[field] }) ); } - throw new Error("Unsupported stage: " + JSON.stringify(stage)); + throw new Error(`Unsupported stage: ${JSON.stringify(stage)}`); } + pushDump(dumps) { dumps.push(this.body); return dumps; } + static hashBody(body) { return object_hash(body, { algorithm: "md5", excludeKeys: key => key === "as", }); } - getUsedFields() { + + static getUsedFields() { throw new Error("Cannot be used on base QueryStep class"); } } @@ -46,22 +52,27 @@ super(cleared_body); this.unwind = body.unwind; } + hash() { return this.body.as; } + pushStage(pipeline) { pipeline.push({ $lookup: this.body }); if (this.unwind) { - pipeline.push({ $unwind: "$" + this.body.as }); + pipeline.push({ $unwind: `$${this.body.as}` }); } return pipeline; } + getUsedFields() { return this.body.localField.split("."); } + getCost() { - return 8; + return this.cost; } + negate() { return this; } @@ -72,6 +83,7 @@ pipeline.push({ $match: this.body }); return pipeline; } + getUsedFields() { return getAllKeys(this.body) .map(path => path.split(".")) @@ -79,9 +91,11 @@ acc.concat(fields.filter(field => !field.startsWith("$"))) ); } + getCost() { return this.body.$or ? 2 : 0; } + negate() { return new QueryStep.Match(negate_stage(this.body)); } diff --git a/lib/datastore/query.js b/lib/datastore/query.js --- a/lib/datastore/query.js +++ b/lib/datastore/query.js @@ -1,6 +1,3 @@ -"use strict"; - -const object_hash = require("object-hash"); const QueryStep = require("./query-step.js"); const transformObject = require("../utils/transform-object.js"); @@ -8,30 +5,36 @@ constructor() { this.steps = []; } + lookup(body) { const lookup_step = new QueryStep.Lookup(body); this.steps.push(lookup_step); return lookup_step.hash(); } + match(body) { for (let key of Object.keys(body)) { this.steps.push(new QueryStep.Match({ [key]: body[key] })); } } + dump() { return this.steps; } + toPipeline() { return this.steps.reduce( (pipeline, query_step) => query_step.pushStage(pipeline), [] ); } + static fromSingleMatch(body) { const query = new Query(); query.match(body); return query; } + static fromCustomPipeline(stages) { const query = new Query(); let steps; @@ -78,6 +81,8 @@ } return query; } + + /* eslint-disable */ _isUnwindStage(stages, i) { if (!stages[i].$lookup) { return false; @@ -93,10 +98,12 @@ super(); super.match({ _id: { $exists: false } }); } - lookup() { + + static lookup() { throw new Error("The query is not mutable!"); } - match() { + + static match() { throw new Error("The query is not mutable!"); } }; @@ -106,10 +113,12 @@ super(); super.match({ _id: { $exists: true } }); } - lookup() { + + static lookup() { throw new Error("The query is not mutable!"); } - match() { + + static match() { throw new Error("The query is not mutable!"); } }; diff --git a/lib/datastore/query.test.js b/lib/datastore/query.test.js --- a/lib/datastore/query.test.js +++ b/lib/datastore/query.test.js @@ -55,7 +55,7 @@ }, }, { - $unwind: "$" + authors_hash, + $unwind: `$${authors_hash}`, }, { $match: { @@ -72,7 +72,7 @@ as: states_hash, }, }, - { $unwind: "$" + states_hash }, + { $unwind: `$${states_hash}` }, { $match: { $or: [ @@ -493,6 +493,6 @@ } function hashLookup({ $lookup }) { - const { as, ...lookup_without_as } = $lookup; + const { ...lookup_without_as } = $lookup; return QueryStep.hashBody(lookup_without_as); } diff --git a/lib/datastore/query_and.js b/lib/datastore/query_and.js --- a/lib/datastore/query_and.js +++ b/lib/datastore/query_and.js @@ -10,11 +10,13 @@ this.addQuery(query); } } + _reset() { this.graph = new Graph(); this.aggregation_steps = {}; this.received_deny_all = false; } + addQuery(query) { if (this.received_deny_all) { return; @@ -34,13 +36,16 @@ this._addDependenciesInGraph(id, step); } } + _isInGraph(key) { return key.length === 32 && this.graph.node_ids.includes(key); } + _addToAggregationSteps(id, step) { this.graph.addNode(id, step.getCost()); this.aggregation_steps[id] = step; } + _addDependenciesInGraph(id, step) { let dependencies = step .getUsedFields() @@ -56,11 +61,13 @@ this.graph.addEdge(dependency, id); } } + _isNotDependencyForAnyInGroup(id, nodeGroup) { return !nodeGroup.some( node => id !== node && this.graph.pathExists(id, node) ); } + dump() { const sortedStepIds = this.graph.bestFirstSearch(); return sortedStepIds.reduce((steps, id) => { @@ -72,6 +79,7 @@ return steps; }, []); } + toPipeline() { const sortedStepIds = this.graph.bestFirstSearch(); return sortedStepIds.reduce((pipeline, id) => { diff --git a/lib/datastore/query_not.js b/lib/datastore/query_not.js --- a/lib/datastore/query_not.js +++ b/lib/datastore/query_not.js @@ -1,18 +1,20 @@ const Query = require("./query.js"); -const QueryStep = require("./query-step.js"); module.exports = class extends Query { constructor(query) { super(); this.addQuery(query); } + addQuery(query) { const steps = query.dump(); this.steps.push(...steps); } + dump() { return this.steps.map(step => step.negate()); } + toPipeline() { return this.steps.reduce( (acc, step) => step.negate().pushStage(acc), diff --git a/lib/datastore/query_or.js b/lib/datastore/query_or.js --- a/lib/datastore/query_or.js +++ b/lib/datastore/query_or.js @@ -9,6 +9,7 @@ this.addQuery(query); } } + addQuery(query) { const steps = query.dump(); this.lookup_steps.push( @@ -25,11 +26,13 @@ : match_stage_bodies[0]; this.steps.push(new QueryStep.Match(match_stage)); } + dump() { return this.lookup_steps.concat( new QueryStep.Match({ $or: this._getMatchExpressions() }) ); } + toPipeline() { const lookups = this.lookup_steps.reduce( (acc, step) => step.pushStage(acc), @@ -38,6 +41,7 @@ return lookups.concat({ $match: { $or: this._getMatchExpressions() } }); } + _getMatchExpressions() { return this.steps.reduce((acc, step) => step.pushDump(acc), []); } diff --git a/lib/email/logger-mailer.js b/lib/email/logger-mailer.js --- a/lib/email/logger-mailer.js +++ b/lib/email/logger-mailer.js @@ -1,10 +1,13 @@ class LoggerMailer { constructor(app) { this.logger = app.Logger; + this.verify_msg = "ok"; } + verify() { - return "ok"; + return this.verify_msg; } + sendEmail({ to, subject, text, html }) { this.logger.info({ message: "Would send an email here", diff --git a/lib/email/message.js b/lib/email/message.js --- a/lib/email/message.js +++ b/lib/email/message.js @@ -8,6 +8,7 @@ assert(attachments === undefined || Array.isArray(attachments)); Object.assign(this, { to, subject, html, attachments, text }); } + async send(app) { return app.Mail.send(this); } diff --git a/lib/email/smtp-mailer.js b/lib/email/smtp-mailer.js --- a/lib/email/smtp-mailer.js +++ b/lib/email/smtp-mailer.js @@ -4,10 +4,10 @@ class SmtpMailer { constructor(app) { const config = app.ConfigManager.get("smtp"); - assert(typeof config.host == "string"); - assert(typeof config.port == "number"); - assert(typeof config.user == "string"); - assert(typeof config.password == "string"); + assert(typeof config.host === "string"); + assert(typeof config.port === "number"); + assert(typeof config.user === "string"); + assert(typeof config.password === "string"); this.mail_config = app.ConfigManager.get("email"); this.transport = nodemailer.createTransport({ host: config.host, @@ -18,9 +18,11 @@ }, }); } + async verify() { return this.transport.verify(); } + async sendEmail({ to, subject, text, html, from_name, attachments }) { return this.transport.sendMail({ from: `${from_name || this.config.from_name} <${ diff --git a/lib/email/templates/simple.js b/lib/email/templates/simple.js --- a/lib/email/templates/simple.js +++ b/lib/email/templates/simple.js @@ -19,7 +19,7 @@ html = "dummy"; } - const text = data.text + "\n\n" + buttons_to_text(data.buttons); + const text = `${data.text}\n\n${buttons_to_text(data.buttons)}`; return new Message({ to: data.to, subject: data.subject, diff --git a/lib/http/error-to-boom.js b/lib/http/error-to-boom.js --- a/lib/http/error-to-boom.js +++ b/lib/http/error-to-boom.js @@ -1,5 +1,3 @@ -"use strict"; -const Sealious = require("../../lib/main"); const Boom = require("boom"); const error_code_map = { diff --git a/lib/http/extract-context.js b/lib/http/extract-context.js --- a/lib/http/extract-context.js +++ b/lib/http/extract-context.js @@ -1,4 +1,3 @@ -"use strict"; const Sealious = require("../../lib/main"); function create_anonymous_session(app) { @@ -20,12 +19,11 @@ filter: { "anonymous-session-id": anon_session_id }, } ) - .then(function({ items: anon_sessions }) { + .then(({ items: anon_sessions }) => { if (anon_sessions.length === 0) { return create_anonymous_session(app); - } else { - return anon_sessions[0]; } + return anon_sessions[0]; }); } @@ -49,7 +47,7 @@ let anonymous_user_id = null; - await get_anonymous_data.then(function(anon_session) { + await get_anonymous_data.then(anon_session => { anonymous_session_id = anon_session["anonymous-session-id"]; anonymous_user_id = anon_session["anonymous-user-id"]; }); diff --git a/lib/http/get-request-body.js b/lib/http/get-request-body.js --- a/lib/http/get-request-body.js +++ b/lib/http/get-request-body.js @@ -1,26 +1,24 @@ -"use strict"; -const merge = require("merge"); const Sealious = require("../../lib/main"); const squares = { - set: function(obj, key, value) { - const keys = key.split(/[\]\[]{1,2}/g); + set(obj, key, value) { + const keys = key.split(/[\][]{1,2}/g); if (keys.length > 1) { keys.splice(-1); //to remove the trailing empty string; } const last_key = keys[keys.length - 1]; let current = obj; for (let i = 0; i < keys.length - 1; i++) { - const key = keys[i]; + const _key = keys[i]; const next_key = keys[i + 1]; - if (current[key] === undefined) { + if (current[_key] === undefined) { if (next_key === "") { - current[key] = []; + current[_key] = []; } else { - current[key] = {}; + current[_key] = {}; } } - current = current[key]; + current = current[_key]; } if (last_key === "") { current.push(value); @@ -38,14 +36,14 @@ for (const i in request.payload) { squares.set(parsed_query, i, request.payload[i]); } - for (var i in request.payload) { + for (const i in request.payload) { if ( request.payload[i].payload && request.payload[i].payload instanceof Buffer ) { let filename = request.payload[i].filename; - var mime_type = request.payload[i].headers["content-type"]; - var data = request.payload[i].payload; + const mime_type = request.payload[i].headers["content-type"]; + const data = request.payload[i].payload; parsed_query[i] = new Sealious.File( context, filename, @@ -58,6 +56,4 @@ return parsed_query; } -const a = {}; - module.exports = get_request_body; diff --git a/lib/http/handle-error.js b/lib/http/handle-error.js --- a/lib/http/handle-error.js +++ b/lib/http/handle-error.js @@ -1,4 +1,3 @@ -"use strict"; const error_to_boom = require("./error-to-boom.js"); module.exports = function(app, h) { @@ -6,8 +5,7 @@ app.Logger.error(error); if (error instanceof app.Sealious.Error && error.is_user_fault) { return error_to_boom(error); - } else { - return error; } + return error; }; }; diff --git a/lib/http/handle-request.js b/lib/http/handle-request.js --- a/lib/http/handle-request.js +++ b/lib/http/handle-request.js @@ -1,21 +1,18 @@ -"use strict"; -const Sealious = require("../../lib/main"); const get_request_body = require("./get-request-body.js"); const http_to_subject_method = require("./http-to-method-name.js"); -const error_to_boom = require("./error-to-boom.js"); const extract_context = require("./extract-context.js"); const handle_response = require("./handle-response.js"); const handle_error = require("./handle-error.js"); function handle_request(app, request, h) { try { - const config = app.ConfigManager.get("www-server"); - var path_elements = request.params.elements.split("/"); - var action_name = http_to_subject_method[request.method.toUpperCase()]; + const path_elements = request.params.elements.split("/"); + const action_name = + http_to_subject_method[request.method.toUpperCase()]; let context = null; return extract_context(app, request) - .then(function(_context) { + .then(_context => { context = _context; let body = get_request_body(context, request); return app.run_action( diff --git a/lib/http/handle-response.js b/lib/http/handle-response.js --- a/lib/http/handle-response.js +++ b/lib/http/handle-response.js @@ -1,5 +1,3 @@ -"use strict"; - module.exports = function(app, context, h) { const config = app.ConfigManager.get("www-server"); return function(response) { diff --git a/lib/http/http.js b/lib/http/http.js --- a/lib/http/http.js +++ b/lib/http/http.js @@ -1,12 +1,5 @@ -"use strict"; -const stream = require("stream"); -const http = require("http"); -const Promise = require("bluebird"); const Sealious = require("../../lib/main"); const Hapi = require("hapi"); -const Boom = require("boom"); -const merge = require("merge"); - const handle_request = require("./handle-request.js"); const get_request_body = require("./get-request-body.js"); const extract_context = require("./extract-context.js"); @@ -49,13 +42,13 @@ }); }; - channel.custom_route = async function(method, path, handler) { + channel.custom_route = async function(method, _path, handler) { await server.register(require("inert")); server.route({ - method: method, - path: path, - handler: async function(request, h) { + method, + path: _path, + async handler(request, h) { let context = null; try { context = await extract_context(app, request); @@ -76,13 +69,13 @@ server.route({ method: ["GET", "DELETE"], - path: path, + path, handler: handle_request.bind({}, app), }); server.route({ method: ["PATCH", "PUT", "POST"], - path: path, + path, config: { payload: { multipart: { diff --git a/lib/http/routes/account-creation-details.js b/lib/http/routes/account-creation-details.js --- a/lib/http/routes/account-creation-details.js +++ b/lib/http/routes/account-creation-details.js @@ -87,8 +87,8 @@ `; -module.exports = app => { - app.WwwServer.custom_route( +module.exports = App => { + App.WwwServer.custom_route( "GET", "/account-creation-details", async (app, context, { token, email }) => { diff --git a/lib/http/routes/confirm-password-reset.js b/lib/http/routes/confirm-password-reset.js --- a/lib/http/routes/confirm-password-reset.js +++ b/lib/http/routes/confirm-password-reset.js @@ -1,23 +1,16 @@ const assert = require("assert"); const locreq = require("locreq")(__dirname); const fs = require("fs"); +const { promisify } = require("util"); +const readFile = promisify(fs.readFile); let css; let get_css = async () => { if (!css) { - css = await new Promise((resolve, reject) => { - fs.readFile( - locreq.resolve("lib/assets/vertical-rhythm.css"), - (err, data) => { - if (err) reject(err); - else resolve(data); - } - ); - }); + css = await readFile(locreq.resolve("lib/assets/vertical-rhythm.css")); } return css; }; - let render_form = async (app, token, email) => ` @@ -71,8 +64,8 @@ `; -module.exports = app => { - app.WwwServer.custom_route( +module.exports = App => { + App.WwwServer.custom_route( "GET", "/confirm-password-reset", async (app, context, params) => { diff --git a/lib/http/routes/confirm-password-reset.subtest.js b/lib/http/routes/confirm-password-reset.subtest.js --- a/lib/http/routes/confirm-password-reset.subtest.js +++ b/lib/http/routes/confirm-password-reset.subtest.js @@ -1,12 +1,11 @@ const locreq = require("locreq")(__dirname); const axios = require("axios"); -const assert = require("assert"); const { with_running_app } = locreq("test_utils/with-test-app.js"); describe("confirm-password-reset", () => { it("displays an html form", async () => with_running_app(async ({ app, base_url }) => { - const response = await axios.get( + await axios.get( `${base_url}/confirm-password-reset?token=kupcia&email=dupcia` ); })); diff --git a/lib/http/routes/finalize-password-reset.js b/lib/http/routes/finalize-password-reset.js --- a/lib/http/routes/finalize-password-reset.js +++ b/lib/http/routes/finalize-password-reset.js @@ -1,7 +1,7 @@ const assert = require("assert"); -module.exports = app => { - app.WwwServer.custom_route( +module.exports = App => { + App.WwwServer.custom_route( "POST", "/finalize-password-reset", async (app, context, params) => { @@ -13,7 +13,7 @@ "show", { filter: { token: params.token } } ); - if (matches.length === 0) { + if (!matches.length) { throw new Error("Incorrect token"); } else if (matches.length > 1) { throw new Error("Something went wrong."); diff --git a/lib/http/routes/finalize-password-reset.subtest.js b/lib/http/routes/finalize-password-reset.subtest.js --- a/lib/http/routes/finalize-password-reset.subtest.js +++ b/lib/http/routes/finalize-password-reset.subtest.js @@ -1,10 +1,8 @@ const locreq = require("locreq")(__dirname); const assert = require("assert"); const tough = require("tough-cookie"); -const { promise_timeout, assert_throws_async } = locreq("test_utils"); -const { with_running_app, with_running_app_prod } = locreq( - "test_utils/with-test-app.js" -); +const { assert_throws_async } = locreq("test_utils"); +const { with_running_app_prod } = locreq("test_utils/with-test-app.js"); describe("finalize password reset", () => { async function create_a_user(app) { @@ -40,7 +38,7 @@ }); const message_metadata = (await mail_api.get_messages()).filter( - message => message.recipients[0] == "" + message => message.recipients[0] === "" )[0]; assert(message_metadata.subject); diff --git a/lib/http/routes/finalize-registration-intent.js b/lib/http/routes/finalize-registration-intent.js --- a/lib/http/routes/finalize-registration-intent.js +++ b/lib/http/routes/finalize-registration-intent.js @@ -1,7 +1,7 @@ const assert = require("assert"); -module.exports = app => { - app.WwwServer.custom_route( +module.exports = App => { + App.WwwServer.custom_route( "POST", "/finalize-registration-intent", async (app, context, params) => { @@ -14,7 +14,7 @@ "show", { filter: { token: params.token } } ); - if (matches.length === 0) { + if (!matches.length) { throw new Error("Incorrect token"); } else if (matches.length > 1) { throw new Error("Something went wrong."); diff --git a/lib/http/routes/finalize-registration-intent.subtest.js b/lib/http/routes/finalize-registration-intent.subtest.js --- a/lib/http/routes/finalize-registration-intent.subtest.js +++ b/lib/http/routes/finalize-registration-intent.subtest.js @@ -1,7 +1,6 @@ const locreq = require("locreq")(__dirname); const assert = require("assert"); const tough = require("tough-cookie"); -const { promise_timeout, assert_throws_async } = locreq("test_utils"); const { with_stopped_app_prod } = locreq("test_utils/with-test-app.js"); describe("finalize registration", () => { @@ -21,7 +20,7 @@ options ); const message_metadata = (await mail_api.get_messages()).filter( - message => message.recipients[0] == "" + message => message.recipients[0] === "" )[0]; assert(message_metadata.subject); diff --git a/lib/http/setup-routes.js b/lib/http/setup-routes.js --- a/lib/http/setup-routes.js +++ b/lib/http/setup-routes.js @@ -3,8 +3,7 @@ function setup_routes(App, express_app) { const router = express.Router({ mergeParams: true }); - router.all("/*", function(req, res, next) { - const elements = req.url.split("/").slice(1); + router.all("/*", (req, res, next) => { res.send(); }); diff --git a/lib/main.js b/lib/main.js --- a/lib/main.js +++ b/lib/main.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Sealious = {}; const { diff --git a/lib/response/error.js b/lib/response/error.js --- a/lib/response/error.js +++ b/lib/response/error.js @@ -1,10 +1,7 @@ -"use strict"; -const Response = require("./response.js"); - const SealiousErrors = {}; -SealiousErrors.Error = function(message, params, data) { - params = params || {}; +SealiousErrors.Error = function(message, _params, data) { + const params = _params || {}; this.is_user_fault = params.is_user_fault === undefined ? false : params.is_user_fault; this.type = params.type === undefined ? "error" : params.type; @@ -79,9 +76,9 @@ for (const full_name in error_types) { const params = error_types[full_name]; - SealiousErrors[full_name] = (function(params) { + SealiousErrors[full_name] = (function(_params) { return function(message, data) { - SealiousErrors.Error.call(this, message, params, data); + SealiousErrors.Error.call(this, message, _params, data); }; })(params); SealiousErrors[full_name].prototype = Object.create( diff --git a/lib/response/response.js b/lib/response/response.js --- a/lib/response/response.js +++ b/lib/response/response.js @@ -1,6 +1,3 @@ -"use strict"; -"use strict"; - function Response(data, is_error, type, status_message) { this.status = is_error ? "error" : "success"; this.type = type || "response"; diff --git a/lib/response/responses.js b/lib/response/responses.js --- a/lib/response/responses.js +++ b/lib/response/responses.js @@ -1,12 +1,10 @@ -"use strict"; - const SealiousResponses = {}; SealiousResponses.NewSession = function(session_id) { this.status = "success"; this.message = "Logged in!"; Object.defineProperty(this, "metadata", { - value: { session_id: session_id }, + value: { session_id }, }); this.data = {}; }; diff --git a/lib/subject/predefined-subjects/collections-subject.js b/lib/subject/predefined-subjects/collections-subject.js --- a/lib/subject/predefined-subjects/collections-subject.js +++ b/lib/subject/predefined-subjects/collections-subject.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); diff --git a/lib/subject/predefined-subjects/formatted-images.js b/lib/subject/predefined-subjects/formatted-images.js --- a/lib/subject/predefined-subjects/formatted-images.js +++ b/lib/subject/predefined-subjects/formatted-images.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); diff --git a/lib/subject/predefined-subjects/me-subject.js b/lib/subject/predefined-subjects/me-subject.js --- a/lib/subject/predefined-subjects/me-subject.js +++ b/lib/subject/predefined-subjects/me-subject.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Subject = locreq("lib/subject/subject.js"); const Errors = locreq("lib/response/error.js"); @@ -15,7 +14,7 @@ action_name, params ) - .catch({ type: "not_found" }, function(error) { + .catch({ type: "not_found" }, error => { throw new Errors.InvalidCredentials("You're not logged in!"); }); }; diff --git a/lib/subject/predefined-subjects/root-subject.js b/lib/subject/predefined-subjects/root-subject.js --- a/lib/subject/predefined-subjects/root-subject.js +++ b/lib/subject/predefined-subjects/root-subject.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Errors = locreq("lib/response/error.js"); @@ -33,9 +32,8 @@ throw new Errors.BadSubjectPath( `No child subject with key '${key}' in RootSubject` ); - } else { - return ret; } + return ret; }; }; diff --git a/lib/subject/predefined-subjects/sessions-subject.js b/lib/subject/predefined-subjects/sessions-subject.js --- a/lib/subject/predefined-subjects/sessions-subject.js +++ b/lib/subject/predefined-subjects/sessions-subject.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const CurrentSessionSubject = require("../subject-types/current-session-subject.js"); @@ -53,8 +52,8 @@ } const SessionsSubject = function(app) { - this.perform_action = function(context, action_name, params) { - params = params || {}; + this.perform_action = function(context, action_name, _params) { + const params = _params || {}; switch (action_name) { case "create": return try_to_login(app, context, params); diff --git a/lib/subject/predefined-subjects/specifications.js b/lib/subject/predefined-subjects/specifications.js --- a/lib/subject/predefined-subjects/specifications.js +++ b/lib/subject/predefined-subjects/specifications.js @@ -1,15 +1,12 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Subject = locreq("lib/subject/subject.js"); -const Errors = locreq("lib/response/error.js"); - const SingleSpecificationSubject = locreq( "lib/subject/subject-types/single-specification-subject.js" ); const SpecificationsSubject = function(app) { const actions = { - show: function(params) { + show(params) { const collections = app.ChipManager.get_chips_by_type("collection"); return Object.keys(collections).map(collection_name => collections[collection_name].get_specification(false) diff --git a/lib/subject/predefined-subjects/uploaded-files.js b/lib/subject/predefined-subjects/uploaded-files.js --- a/lib/subject/predefined-subjects/uploaded-files.js +++ b/lib/subject/predefined-subjects/uploaded-files.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); diff --git a/lib/subject/predefined-subjects/users-subject.js b/lib/subject/predefined-subjects/users-subject.js --- a/lib/subject/predefined-subjects/users-subject.js +++ b/lib/subject/predefined-subjects/users-subject.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); @@ -11,8 +10,8 @@ const SuperContext = locreq("lib/super-context.js"); const UsersSubject = function(app) { - this.perform_action = function(context, action_name, params) { - params = params || {}; + this.perform_action = function(context, action_name, _params) { + const params = _params || {}; switch (action_name) { case "create": return app.run_action( @@ -38,32 +37,28 @@ }; this.get_child_subject = function(key) { - if (me_synonyms.indexOf(key) !== -1) { + if (me_synonyms.includes(key)) { return new MeSubject(app); - } else { - const username = key; - return app - .run_action( - new SuperContext(), - ["collections", "users"], - "show", - { filter: { username: username } } - ) - .then(function(result) { - if (result.length === 0) { - throw new Errors.BadSubjectPath( - `Unknown username: '${username}'` - ); - } else { - const user = result[0]; - return RootSubject.get_subject([ - "collections", - "users", - user.id, - ]); - } - }); } + const username = key; + return app + .run_action(new SuperContext(), ["collections", "users"], "show", { + filter: { username }, + }) + .then(result => { + if (result.length === 0) { + throw new Errors.BadSubjectPath( + `Unknown username: '${username}'` + ); + } else { + const user = result[0]; + return RootSubject.get_subject([ + "collections", + "users", + user.id, + ]); + } + }); }; }; diff --git a/lib/subject/subject-types/_batch_action.js b/lib/subject/subject-types/_batch_action.js --- a/lib/subject/subject-types/_batch_action.js +++ b/lib/subject/subject-types/_batch_action.js @@ -1,4 +1,3 @@ -"use strict"; const Promise = require("bluebird"); const locreq = require("locreq")(__dirname); const ArrayCartesian = locreq("lib/utils/array-cartesian.js"); @@ -35,18 +34,17 @@ "show", { filter } ) - .then(function({ items: resources }) { - for (const i in map_to) { - const field_in_collection = fields[i]; - const field_name = map_to[i]; + .then(({ items: resources }) => { + for (const j in map_to) { + const field_in_collection = fields[j]; + const field_name = map_to[j]; field_names.push(field_name); possible_field_values.push( resources.map(resource => { if (field_in_collection === "id") { return resource.id; - } else { - return resource[field_in_collection]; } + return resource[field_in_collection]; }) ); } @@ -54,10 +52,10 @@ to_await.push(promise); } } - return Promise.all(to_await).then(function() { + return Promise.all(to_await).then(() => { return PromiseIterateGenerator( new ArrayCartesian(possible_field_values), - function(values) { + values => { const body = {}; for (const i in field_names) { body[field_names[i]] = values[i]; diff --git a/lib/subject/subject-types/collection-field-subject.js b/lib/subject/subject-types/collection-field-subject.js --- a/lib/subject/subject-types/collection-field-subject.js +++ b/lib/subject/subject-types/collection-field-subject.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const merge = require("merge"); @@ -20,9 +19,9 @@ CollectionFieldSubject.prototype.perform_action = function( context, action_name, - params + _params ) { - params = params || {}; + const params = _params || {}; merge(params, { resource_id: this.resource_id, field_name: this.field_name, @@ -32,14 +31,13 @@ return Promise.resolve( this.field_type.actions[action_name](context, params) ); - } else { - throw new Errors.DeveloperError(`Unknown action: '${action_name}'`); } + throw new Errors.DeveloperError(`Unknown action: '${action_name}'`); }; CollectionFieldSubject.prototype.get_child_subject = function(key) { const self = this; - return Promise.try(function() { + return Promise.try(() => { return self.field_type.get_child_subject(key); }); }; diff --git a/lib/subject/subject-types/collection-subject.js b/lib/subject/subject-types/collection-subject.js --- a/lib/subject/subject-types/collection-subject.js +++ b/lib/subject/subject-types/collection-subject.js @@ -1,4 +1,3 @@ -"use strict"; const assert = require("assert"); const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); @@ -63,9 +62,9 @@ * map_to[] */ const self = this; - return batch_action(app, context, params, function(context, body) { + return batch_action(app, context, params, (_context, body) => { return app.run_action( - context, + _context, ["collections", self.collection.name], "create", body @@ -75,19 +74,19 @@ this.delete_many = function(context, params) { const self = this; - return batch_action(app, context, params, function(context, body) { + return batch_action(app, context, params, (_context, body) => { return app .run_action( - context, + _context, ["collections", self.collection.name], "show", { filter: body, } ) - .each(function(resource) { + .each(resource => { return app.run_action( - context, + _context, ["collections", self.collection.name, resource.id], "delete" ); @@ -98,11 +97,10 @@ this.delete = function(context, params) { if (params.__multiple) { return this.delete_many(context, params); - } else { - throw new app.Sealious.Errors.NotFound( - "Cannot delete a collection. Try using the '__multiple: true' mode" - ); } + throw new app.Sealious.Errors.NotFound( + "Cannot delete a collection. Try using the '__multiple: true' mode" + ); }; this.get_child_subject = async function(key) { @@ -111,15 +109,14 @@ ...named_filters, key.slice(1), ]); - } else { - const resource_id = key; - const single_resource_subject = new SingleResource( - app, - this.collection, - resource_id - ); - return single_resource_subject; } + const resource_id = key; + const single_resource_subject = new SingleResource( + app, + this.collection, + resource_id + ); + return single_resource_subject; }; } @@ -133,13 +130,13 @@ ) { return collection .check_if_action_is_allowed(context, "create", body) - .then(function() { + .then(() => { return collection.validate_field_values(context, true, body); }) - .then(function() { + .then(() => { return collection.encode_field_values(context, body); }) - .then(function(encoded_body) { + .then(encoded_body => { const newID = shortid(); const resource_data = { _metadata: { @@ -152,13 +149,13 @@ }; return datastore.insert(collection.name, resource_data, {}); }) - .then(function(database_entry) { + .then(database_entry => { return collection.get_resource_representation( context, database_entry ); }) - .then(function(representation) { + .then(representation => { return new Sealious.Responses.ResourceCreated(representation); }); }; @@ -166,9 +163,9 @@ CollectionSubject.prototype.__preprocess_resource_filter = function( collection, context, - filter + _filter ) { - filter = clone(filter) || {}; + const filter = clone(_filter) || {}; const expanded_filter = expandHash(filter); const processed_filter = {}; for (const field_name in expanded_filter) { @@ -207,13 +204,14 @@ ); const must_be_int = ["items", "page"]; - must_be_int.forEach(function(attribute_name) { - if (isNaN(parseInt(full_pagination_params[attribute_name]))) { + must_be_int.forEach(attribute_name => { + if (isNaN(parseInt(full_pagination_params[attribute_name], 10))) { full_pagination_params[attribute_name] = default_pagination_params[attribute_name]; } else { full_pagination_params[attribute_name] = parseInt( - full_pagination_params[attribute_name] + full_pagination_params[attribute_name], + 10 ); } }); @@ -221,14 +219,14 @@ output_options.skip = (full_pagination_params.page - 1) * full_pagination_params.items; output_options.amount = - parseInt(full_pagination_params.items) + - (parseInt(full_pagination_params.forward_buffer) || 0); + parseInt(full_pagination_params.items, 10) + + (parseInt(full_pagination_params.forward_buffer, 10) || 0); } else { if (params.skip) { - output_options.skip = parseInt(params.skip); + output_options.skip = parseInt(params.skip, 10); } if (params.amount) { - output_options.amount = parseInt(params.count); + output_options.amount = parseInt(params.count, 10); } } @@ -256,12 +254,10 @@ datastore, collection, context, - params, + _params, named_filters ) { - if (params === undefined || params === null) { - params = {}; - } + const params = _params === undefined || _params === null ? {} : _params; if (params.calculate === "false" || params.calculate === false) { params.calculate = false; @@ -291,18 +287,16 @@ const is_item_sensitive = await access_strategy.is_item_sensitive(); for (let document of documents) { - try { - let item = await collection.get_resource_representation( - context, - document, - params.format, - params.calculate - ); - if (is_item_sensitive) { - await access_strategy.check(context, item); - } - decoded_items.push(item); - } catch (e) {} + let item = await collection.get_resource_representation( + context, + document, + params.format, + params.calculate + ); + if (is_item_sensitive) { + await access_strategy.check(context, item); + } + decoded_items.push(item); } return { attachments: {}, items: decoded_items }; }; @@ -316,9 +310,9 @@ case "create": if (args.__multiple) { return this.create_many(context, args); - } else { - return this.create_resource(context, args); } + return this.create_resource(context, args); + case "show": return this.list_resources(context, args); case "delete": diff --git a/lib/subject/subject-types/current-session-subject.js b/lib/subject/subject-types/current-session-subject.js --- a/lib/subject/subject-types/current-session-subject.js +++ b/lib/subject/subject-types/current-session-subject.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); @@ -59,7 +58,6 @@ "delete" ) ); - return new Response({}, false, "logged_out", "You've been logged out"); } catch (e) { return Promise.reject(new Errors.BadContext("Invalid session id!")); diff --git a/lib/subject/subject-types/image-format.js b/lib/subject/subject-types/image-format.js --- a/lib/subject/subject-types/image-format.js +++ b/lib/subject/subject-types/image-format.js @@ -1,105 +1,96 @@ -"use strict"; const locreq = require("locreq")(__dirname); -const Subject = locreq("lib/subject/subject.js"); -const Errors = locreq("lib/response/error.js"); const Promise = require("bluebird"); - -const gm = require("gm").subClass({ imageMagick: true }); const fs = require("fs"); +const gm = require("gm").subClass({ imageMagick: true }); +const Subject = locreq("lib/subject/subject.js"); +const Errors = locreq("lib/response/error.js"); const QUALITY = 80; function format_hash(format_obj) { - return format_obj.size[0] + ":" + format_obj.size[1] + "(" + QUALITY + ")"; + return `${format_obj.size[0]}:${format_obj.size[1]}(${QUALITY})`; } function format_filename(original_filename, format_name) { - return ( - original_filename - .split(".") - .slice(0, -1) - .join(".") + - "-" + - format_name + - ".jpg" - ); + return `${original_filename + .split(".") + .slice(0, -1) + .join(".")}-${format_name}.jpg`; } const ImageFormat = function(app, file_id, format_name) { this.name = "ImageFormats"; this.file_id = file_id; - function get_hdd_path(file_id) { - return locreq.resolve(app.FileManager.upload_path + "/" + file_id); + function get_hdd_path(_file_id) { + return locreq.resolve(`${app.FileManager.upload_path}/${_file_id}`); } - function create_formatted_version(file_id, format_name) { - const format_obj = app.ConfigManager.get("image_formats")[format_name]; - return app.Datastore.find("files", { id: file_id }).then(function( - matches - ) { - const original_file = matches[0]; - const file_path = get_hdd_path(original_file.id); - const width = format_obj.size[0]; - const height = format_obj.size[1]; - const filename = format_filename( - original_file.original_name, - format_name - ); - const temp_file_path = - "/tmp/" + Math.floor(Math.random() * Math.pow(10, 7)) + ".jpg"; - const resize_request = gm(file_path) - .resize(width, height, "^") - .quality(QUALITY); - return Promise.promisify(resize_request.write, { - context: resize_request, - })(temp_file_path) - .then(function() { - return Promise.promisify(fs.readFile)(temp_file_path); - }) - .then(function(buffer) { - return app.FileManager.save_file( - new app.Sealious.File( - new app.Sealious.SuperContext(), - filename, - buffer + function create_formatted_version(formatted_file_id, _format_name) { + const format_obj = app.ConfigManager.get("image_formats")[_format_name]; + return app.Datastore.find("files", { id: formatted_file_id }).then( + matches => { + const original_file = matches[0]; + const file_path = get_hdd_path(original_file.id); + const width = format_obj.size[0]; + const height = format_obj.size[1]; + const filename = format_filename( + original_file.original_name, + _format_name + ); + const temp_file_path = `/tmp/${Math.floor( + Math.random() * Math.pow(10, 7) + )}.jpg`; + const resize_request = gm(file_path) + .resize(width, height, "^") + .quality(QUALITY); + return Promise.promisify(resize_request.write, { + context: resize_request, + })(temp_file_path) + .then(() => Promise.promisify(fs.readFile)(temp_file_path)) + .then(buffer => + app.FileManager.save_file( + new app.Sealious.File( + new app.Sealious.SuperContext(), + filename, + buffer + ) ) - ); - }) - .then(function(sealious_file) { - return app - .run_action( - new app.Sealious.SuperContext(), - ["collections", "formatted-images"], - "create", - { - original_photo_file: original_file.id, - formatted_photo_file: sealious_file.id, - format: format_hash(format_obj), - } + ) + .then(sealious_file => + app + .run_action( + new app.Sealious.SuperContext(), + ["collections", "formatted-images"], + "create", + { + original_photo_file: original_file.id, + formatted_photo_file: sealious_file.id, + format: format_hash(format_obj), + } + ) + .then(() => sealious_file) + ) + .then(file => + Promise.promisify(fs.unlink)(temp_file_path).then( + () => file ) - .then(() => sealious_file); - }) - .then(function(file) { - return Promise.promisify(fs.unlink)(temp_file_path).then( - () => file ); - }); - }); + } + ); } function get_formatted_version( - file_id, - file_name, - format_name, + formatted_file_id, + formatted_file_name, + _format_name, format_obj ) { - const random = Math.random(); const hash = format_hash(format_obj); return app.Datastore.aggregate("formatted-images", [ { $match: { - original_photo_file: { $eq: file_id }, + original_photo_file: { $eq: formatted_file_id }, }, }, { @@ -107,20 +98,22 @@ $or: [{ "format.original": hash }, { "format.safe": hash }], }, }, - ]).then(function(results) { - return ( + ]).then( + results => results[0] && results[0] && { id: results[0].formatted_photo_file, - original_name: format_filename(file_name, format_name), + original_name: format_filename( + formatted_file_name, + _format_name + ), } - ); - }); + ); } - const ImageFormatFile = function(file_id, format_name, file_name) { + const ImageFormatFile = function(_file_id, _format_name, file_name) { this.name = "SingleFile"; - this.file_id = file_id; + this.file_id = _file_id; this.file_name = file_name; ImageFormatFile.prototype.perform_action = function( @@ -128,31 +121,30 @@ action_name, args ) { + const format_obj = app.ConfigManager.get("image_formats")[ + _format_name + ]; switch (action_name) { case "show": - const format_obj = app.ConfigManager.get("image_formats")[ - format_name - ]; if (format_obj === undefined) { throw new Errors.BadSubjectPath( - "Unknown image format: " + format_name + `Unknown image format: ${_format_name}` ); } return get_formatted_version( file_id, file_name, - format_name, + _format_name, format_obj ) - .then(function(result) { + .then(result => { if (result !== undefined) { return result; - } else { - return create_formatted_version( - file_id, - format_name - ); } + return create_formatted_version( + file_id, + _format_name + ); }) .then(file_description => { let ret = new app.Sealious.File.from_db_entry( diff --git a/lib/subject/subject-types/image-formats.js b/lib/subject/subject-types/image-formats.js --- a/lib/subject/subject-types/image-formats.js +++ b/lib/subject/subject-types/image-formats.js @@ -1,14 +1,10 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Subject = locreq("lib/subject/subject.js"); -const Errors = locreq("lib/response/error.js"); - const ImageFormat = locreq("lib/subject/subject-types/image-format.js"); const ImageFormats = function(app, file_id) { this.name = "ImageFormats"; this.file_id = file_id; - this.get_child_subject = function(format_name) { return new ImageFormat(app, file_id, format_name); }; diff --git a/lib/subject/subject-types/single-file-subject.js b/lib/subject/subject-types/single-file-subject.js --- a/lib/subject/subject-types/single-file-subject.js +++ b/lib/subject/subject-types/single-file-subject.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Subject = locreq("lib/subject/subject.js"); const Errors = locreq("lib/response/error.js"); @@ -7,9 +6,9 @@ this.name = "FileHash"; this.file_id = file_id; - const SingleFileSubject = function(file_id, file_name) { + const SingleFileSubject = function(single_file_id, file_name) { this.name = "SingleFile"; - this.file_id = file_id; + this.single_file_id = single_file_id; this.file_name = file_name; SingleFileSubject.prototype.perform_action = function( @@ -20,8 +19,8 @@ switch (action_name) { case "show": return app.FileManager.find(context, { - id: this.file_id, - }).then(function(results) { + id: this.single_file_id, + }).then(results => { return results[0]; }); default: diff --git a/lib/subject/subject-types/single-resource-subject.js b/lib/subject/subject-types/single-resource-subject.js --- a/lib/subject/subject-types/single-resource-subject.js +++ b/lib/subject/subject-types/single-resource-subject.js @@ -1,4 +1,3 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const Subject = locreq("lib/subject/subject.js"); @@ -59,36 +58,32 @@ collection, resource_id, context, - args + _args ) { - args = args || {}; - + const args = _args || {}; return datastore .find(collection.name, { sealious_id: resource_id }, {}) - .then(function(db_entries) { + .then(db_entries => { if (db_entries[0] === undefined) { throw new Errors.NotFound( `${collection.name}: id ${resource_id} not found` ); - } else { - return collection.get_resource_representation( - context, - db_entries[0], - args.format - ); } + return collection.get_resource_representation( + context, + db_entries[0], + args.format + ); }) - .then(function(resource_representation) { - return collection + .then(resource_representation => + collection .check_if_action_is_allowed( context, "show", resource_representation ) - .then(function() { - return resource_representation; - }); - }); + .then(() => resource_representation) + ); }; SingleResource.prototype.__edit_resource = function( @@ -97,18 +92,15 @@ resource_id, context, values_to_patch, - delete_empty_values + delete_empty_values = false ) { // replaces just the provided values. Equivalent of PATCH request - delete_empty_values = - delete_empty_values === undefined ? false : delete_empty_values; - let resource_representation; return SingleResource.prototype .__get_resource(datastore, collection, resource_id, context, {}) - .then(function(resource_data) { + .then(resource_data => { resource_representation = resource_data; return collection.check_if_action_is_allowed( context, @@ -116,22 +108,22 @@ resource_representation ); }) - .then(function() { - return collection.validate_field_values( + .then(() => + collection.validate_field_values( context, delete_empty_values, values_to_patch, resource_representation - ); - }) - .then(function() { - return collection.encode_field_values( + ) + ) + .then(() => + collection.encode_field_values( context, values_to_patch, resource_representation - ); - }) - .then(function(encoded_values) { + ) + ) + .then(encoded_values => { const query = { _metadata: resource_representation._metadata }; query._metadata.last_modified_context = context; for (const field_name in encoded_values) { @@ -143,7 +135,7 @@ { $set: query } ); }) - .then(function(patch_result) { + .then(patch_result => { if (patch_result.result.n !== 1) { throw new Error("Wrong amount of resources (!=1) modified"); } @@ -165,28 +157,25 @@ args ) { // abstraction seems to be leaking here: should we use context or SuperContext here? - return SingleResource.prototype .__get_resource(datastore, collection, resource_id, context, {}) - .then(function(resource_representation) { - return collection.check_if_action_is_allowed( + .then(resource_representation => + collection.check_if_action_is_allowed( context, "delete", resource_representation - ); - }) - .then(function() { - return datastore.remove( + ) + ) + .then(() => + datastore.remove( collection.name, { sealious_id: resource_id, }, {} - ); - }) - .then(function(data) { - return Promise.resolve(); - }); + ) + ) + .then(data => Promise.resolve()); }; SingleResource.prototype.perform_action = function(context, action_name, args) { diff --git a/lib/subject/subject-types/single-specification-subject.js b/lib/subject/subject-types/single-specification-subject.js --- a/lib/subject/subject-types/single-specification-subject.js +++ b/lib/subject/subject-types/single-specification-subject.js @@ -1,11 +1,10 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Subject = locreq("lib/subject/subject.js"); const Errors = locreq("lib/response/error.js"); const SingleSpecificationsSubject = function(app, collection_name) { const actions = { - show: function(params) { + show(params) { const collection = app.ChipManager.get_chip( "collection", collection_name diff --git a/lib/subject/subject.js b/lib/subject/subject.js --- a/lib/subject/subject.js +++ b/lib/subject/subject.js @@ -1,21 +1,19 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Promise = require("bluebird"); const SubjectPath = locreq("lib/data-structures/subject-path.js"); function Subject() {} -Subject.prototype.get_subject = function(subject_path) { +Subject.prototype.get_subject = function(_subject_path) { // This is a recursive function. It traverses the subject tree and returns // the subject referenced by subject_path - subject_path = new SubjectPath(subject_path); + const subject_path = new SubjectPath(_subject_path); return Promise.resolve(this.get_child_subject(subject_path.head())).then( - function(child_subject) { + child_subject => { if (subject_path.elements.length === 1) { return child_subject; - } else { - return child_subject.get_subject(subject_path.tail()); } + return child_subject.get_subject(subject_path.tail()); } ); }; diff --git a/lib/super-context.js b/lib/super-context.js --- a/lib/super-context.js +++ b/lib/super-context.js @@ -1,12 +1,7 @@ -"use strict"; const locreq = require("locreq")(__dirname); const Context = locreq("lib/context.js"); -function SuperContext(regular_context) { - if (regular_context === undefined) { - regular_context = new Context(); - } - +function SuperContext(regular_context = new Context()) { const ret = Object.create(regular_context); Object.defineProperty(ret, "is_super", { value: true }); diff --git a/lib/utils/array-cartesian.js b/lib/utils/array-cartesian.js --- a/lib/utils/array-cartesian.js +++ b/lib/utils/array-cartesian.js @@ -1,4 +1,3 @@ -"use strict"; const IntegerCartesian = require("./integer-cartesian.js"); const ArrayCartesian = function(sources) { @@ -6,16 +5,16 @@ let current_int_state = null; return { - next: function() { + next() { const int_next_element = IntegerCartesian.next( int_sources, current_int_state ); current_int_state = int_next_element; if (int_next_element === null) return null; - return int_next_element.map((index, source_number) => { - return sources[source_number][index]; - }); + return int_next_element.map( + (index, source_number) => sources[source_number][index] + ); }, }; }; diff --git a/lib/utils/flatten-object-to-dot-notation.js b/lib/utils/flatten-object-to-dot-notation.js --- a/lib/utils/flatten-object-to-dot-notation.js +++ b/lib/utils/flatten-object-to-dot-notation.js @@ -1,5 +1,5 @@ module.exports = function(context, obj) { - const prefix = typeof context === "string" ? context + "." : ""; + const prefix = typeof context === "string" ? `${context}.` : ""; return flattenObjectToDotNotation(prefix, obj); }; @@ -9,7 +9,7 @@ if (obj[prop] && typeof obj[prop] === "object") { Object.assign( flattened, - flattenObjectToDotNotation(new_prop + ".", obj[prop]) + flattenObjectToDotNotation(`${new_prop}.`, obj[prop]) ); } else { flattened[new_prop] = obj[prop]; diff --git a/lib/utils/get-datetime.js b/lib/utils/get-datetime.js --- a/lib/utils/get-datetime.js +++ b/lib/utils/get-datetime.js @@ -1,4 +1,3 @@ -"use strict"; const prettyMs = require("pretty-ms"); const dateFormatters = { @@ -31,13 +30,12 @@ return formats .reduce((date_string, format) => { if (dateFormats.includes(format)) { - return date_string + " " + dateFormatters[format](date); + return `${date_string} ${dateFormatters[format](date)}`; } else if (timeFormats.includes(format)) { const parsed_time = date.toISOString().split("T")[1]; - return date_string + " " + timeFormatters[format](parsed_time); - } else { - throw new Error("Unknown format: " + format); + return `${date_string} ${timeFormatters[format](parsed_time)}`; } + throw new Error(`Unknown format: ${format}`); }, "") .trimLeft(); } diff --git a/lib/utils/get-main-app-dir.js b/lib/utils/get-main-app-dir.js --- a/lib/utils/get-main-app-dir.js +++ b/lib/utils/get-main-app-dir.js @@ -1,4 +1,3 @@ -"use strict"; const path = require("path"); function get_main_app_dir() { diff --git a/lib/utils/integer-cartesian.js b/lib/utils/integer-cartesian.js --- a/lib/utils/integer-cartesian.js +++ b/lib/utils/integer-cartesian.js @@ -1,9 +1,8 @@ -"use strict"; const clone = require("clone"); const IntegerCartesian = { // integer-only - next: function(sources, element) { + next(sources, element) { for (const i in sources) { if (sources[i] <= 0) { return null; @@ -12,29 +11,28 @@ const new_element = clone(element); if (element === null) { return sources.map(() => 0); - } else { - let i = element.length - 1; - while (i >= 0) { - if (element[i] >= sources[i]) { - throw new Error( - `Invalid element. Max value on index '${i.toString()}' is '${( - sources[i] - 1 - ).toString()}'` - ); - } - if (element[i] === sources[i] - 1) { - new_element[i] = 0; - } else { - break; - } - i--; + } + let i = element.length - 1; + while (i >= 0) { + if (element[i] >= sources[i]) { + throw new Error( + `Invalid element. Max value on index '${i.toString()}' is '${( + sources[i] - 1 + ).toString()}'` + ); } - if (i === -1) { - return null; + if (element[i] === sources[i] - 1) { + new_element[i] = 0; + } else { + break; } - new_element[i] = new_element[i] + 1; - return new_element; + i--; + } + if (i === -1) { + return null; } + new_element[i] = new_element[i] + 1; + return new_element; }, }; diff --git a/lib/utils/promise-iterate-generator.js b/lib/utils/promise-iterate-generator.js --- a/lib/utils/promise-iterate-generator.js +++ b/lib/utils/promise-iterate-generator.js @@ -2,11 +2,8 @@ const current = generator.next(); if (current === null) { return Promise.resolve(); - } else { - return fn(current).then(function() { - return PromiseIterateGenerator(generator, fn); - }); } + return fn(current).then(() => PromiseIterateGenerator(generator, fn)); }; module.exports = PromiseIterateGenerator; diff --git a/lib/utils/secure-hasher.js b/lib/utils/secure-hasher.js --- a/lib/utils/secure-hasher.js +++ b/lib/utils/secure-hasher.js @@ -22,7 +22,6 @@ const [iterations, key_length, salt, hash] = hash_with_params.split( "." ); - return pbkdf2( value, salt, diff --git a/package.json b/package.json --- a/package.json +++ b/package.json @@ -7,7 +7,9 @@ "scripts": { "test": "mocha --timeout=10000 setup-test.js \"./lib/**/*.test.js\"", "build": "rm -rf cosealious/* && babel cosealious-src --out-dir cosealious", - "prepare": "npm run build" + "prepare": "npm run build", + "lint": "eslint lib/ --ext .js,.jsx --ignore-pattern node_modules/", + "lint:fix": "eslint lib/ --ext .js,.jsx --ignore-pattern node_modules/ --fix" }, "repository": { "type": "git", @@ -56,12 +58,14 @@ "react": "^16.3.2" }, "devDependencies": { - "mocha": "*", - "sinon": "^5.0.7", - "eslint": "^3.1.1", + "babel-cli": "^6.26.0", "babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-preset-env": "^1.7.0", "babel-preset-react": "^6.24.1", - "babel-cli": "^6.26.0" + "eslint": "^5.6.1", + "eslint-config-sealcode": "github:sealcode/eslint-config-sealcode#master", + "mocha": "*", + "prettier": "^1.14.3", + "sinon": "^5.0.7" } } diff --git a/test_utils/assert_throws_async.js b/test_utils/assert_throws_async.js --- a/test_utils/assert_throws_async.js +++ b/test_utils/assert_throws_async.js @@ -1,7 +1,6 @@ const assert = require("assert"); module.exports = async function assertThrowsAsync(fn, error_handler) { - let f = () => {}; let error = null; try { await fn();