mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-22 09:32:41 +00:00
10
package-lock.json
generated
10
package-lock.json
generated
@@ -403,6 +403,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.4.tgz",
|
||||
"integrity": "sha512-Set5ZdrAaKI/qHdFlVMgm/GsAv/wkXhSTuZFkJ+JI7HK+wIkIlOaUXSXieIvJ0+OvGIqtREFoE+NHJtEq0gtEw=="
|
||||
},
|
||||
"@types/traverse": {
|
||||
"version": "0.6.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/traverse/-/traverse-0.6.32.tgz",
|
||||
"integrity": "sha512-RBz2uRZVCXuMg93WD//aTS5B120QlT4lR/gL+935QtGsKHLS6sCtZBaKfWjIfk7ZXv/r8mtGbwjVIee6/3XTow=="
|
||||
},
|
||||
"@types/uuid": {
|
||||
"version": "3.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.4.tgz",
|
||||
@@ -5227,6 +5232,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"traverse": {
|
||||
"version": "0.6.6",
|
||||
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
|
||||
"integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc="
|
||||
},
|
||||
"trim-newlines": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz",
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
"@types/cli-progress": "1.8.1",
|
||||
"@types/node": "10.14.4",
|
||||
"@types/request": "2.48.1",
|
||||
"@types/traverse": "0.6.32",
|
||||
"@types/uuid": "3.4.4",
|
||||
"cli-progress": "2.1.1",
|
||||
"commander": "2.19.0",
|
||||
"moment": "2.24.0",
|
||||
"request": "2.88.0",
|
||||
"traverse": "0.6.6",
|
||||
"uuid": "3.3.2"
|
||||
},
|
||||
"license": "GPL-3.0-only",
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
*/
|
||||
import {asyncPool} from '@krlwlfrt/async-pool';
|
||||
import {
|
||||
isThing,
|
||||
SCAssociatedThingWithoutReferences,
|
||||
SCBulkResponse,
|
||||
SCBulkRoute,
|
||||
SCLicensePlate,
|
||||
@@ -68,6 +70,76 @@ export class ConnectorClient extends Client {
|
||||
return v5(uid.toString(), SCNamespaces[namespaceId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove fields from a thing that are references
|
||||
*
|
||||
* This effectively turns a thing into a thing without references, e.g. SCDish into SCDishWithoutReferences.
|
||||
*
|
||||
* @param thing Thing to remove references from
|
||||
*/
|
||||
static removeReferences<THING extends SCThings>(thing: THING): SCAssociatedThingWithoutReferences<THING> {
|
||||
const thingWithoutReferences: any = {
|
||||
...{},
|
||||
...thing,
|
||||
};
|
||||
|
||||
// iterate over all properties
|
||||
for (const key in thingWithoutReferences) {
|
||||
/* istanbul ignore if */
|
||||
if (!thingWithoutReferences.hasOwnProperty(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const property = thingWithoutReferences[key];
|
||||
|
||||
// check if property itself is a thing
|
||||
if (isThing(property)) {
|
||||
// delete said property
|
||||
delete thingWithoutReferences[key];
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if property is an array
|
||||
if (Array.isArray(property)) {
|
||||
if (property.every(isThing)) {
|
||||
// delete property if every item in it is a thing
|
||||
delete thingWithoutReferences[key];
|
||||
} else {
|
||||
// check every item in array
|
||||
for (const item of property) {
|
||||
if (['boolean', 'number', 'string'].indexOf(typeof item) >= 0) {
|
||||
// skip primitives
|
||||
continue;
|
||||
}
|
||||
|
||||
// check every property
|
||||
for (const itemKey in item) {
|
||||
/* istanbul ignore if */
|
||||
if (!item.hasOwnProperty(itemKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isThing(item[itemKey])) {
|
||||
// delete properties that are things
|
||||
delete item[itemKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (typeof property === 'object') {
|
||||
// iterate over all properties in nested objects
|
||||
for (const nestedKey in property) {
|
||||
if (isThing(property[nestedKey])) {
|
||||
// delete properties that are things
|
||||
delete property[nestedKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return thingWithoutReferences as SCAssociatedThingWithoutReferences<THING>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a bulk transfer to the backend
|
||||
*
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {asyncPool} from '@krlwlfrt/async-pool';
|
||||
import {
|
||||
isThing,
|
||||
SCBulkAddResponse,
|
||||
SCBulkAddRoute,
|
||||
SCBulkDoneResponse,
|
||||
@@ -20,17 +22,22 @@ import {
|
||||
SCBulkResponse,
|
||||
SCBulkRoute,
|
||||
SCMessage,
|
||||
SCThing,
|
||||
SCThingOriginType,
|
||||
SCThingType,
|
||||
SCThingUpdateResponse,
|
||||
SCThingUpdateRoute,
|
||||
SCThingType,
|
||||
SCThingOriginType,
|
||||
} from '@openstapps/core';
|
||||
import * as chai from 'chai';
|
||||
import {expect} from 'chai';
|
||||
import * as chaiAsPromised from 'chai-as-promised';
|
||||
import * as chaiSpies from 'chai-spies';
|
||||
import {readdir, readFile} from 'fs';
|
||||
import {suite, test} from 'mocha-typescript';
|
||||
import * as moment from 'moment';
|
||||
import {join, resolve} from 'path';
|
||||
import * as traverse from 'traverse';
|
||||
import {promisify} from 'util';
|
||||
import {ConnectorClient} from '../src/connectorClient';
|
||||
import {EmptyBulkError, NamespaceNotDefinedError} from '../src/errors';
|
||||
import {HttpClient} from '../src/httpClient';
|
||||
@@ -47,8 +54,27 @@ const bulkDoneRoute = new SCBulkDoneRoute();
|
||||
const bulkRoute = new SCBulkRoute();
|
||||
const thingUpdateRoute = new SCThingUpdateRoute();
|
||||
|
||||
const readdirPromisified = promisify(readdir);
|
||||
const readFilePromisified = promisify(readFile);
|
||||
|
||||
const httpClient = new HttpClient();
|
||||
|
||||
/**
|
||||
* Check if something contains things
|
||||
*
|
||||
* @param thing Thing to check
|
||||
*/
|
||||
function doesContainThings<T extends SCThing>(thing: T): boolean {
|
||||
/* tslint:disable-next-line:only-arrow-functions */
|
||||
return traverse(thing).reduce(function(sum, item) {
|
||||
if (this.isRoot) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return sum || (item === null) ? false : isThing(item);
|
||||
}, false);
|
||||
}
|
||||
|
||||
@suite()
|
||||
export class ConnectorClientSpec {
|
||||
async after() {
|
||||
@@ -305,6 +331,36 @@ export class ConnectorClientSpec {
|
||||
}).to.throw(NamespaceNotDefinedError);
|
||||
}
|
||||
|
||||
@test
|
||||
async removeReferences() {
|
||||
const pathToTestFiles = resolve(
|
||||
__dirname,
|
||||
'..',
|
||||
'node_modules',
|
||||
'@openstapps',
|
||||
'core',
|
||||
'test',
|
||||
'resources',
|
||||
);
|
||||
|
||||
const testFiles = await readdirPromisified(pathToTestFiles);
|
||||
|
||||
const testInstances = await asyncPool(5, testFiles, async (testFile) => {
|
||||
const buffer = await readFilePromisified(join(pathToTestFiles, testFile));
|
||||
const content = JSON.parse(buffer.toString());
|
||||
return content.instance;
|
||||
});
|
||||
|
||||
for (const testInstance of testInstances) {
|
||||
const testInstanceWithoutReferences = ConnectorClient.removeReferences(testInstance);
|
||||
expect(doesContainThings(testInstanceWithoutReferences)).to.be.equal(false, JSON.stringify(
|
||||
[testInstance, testInstanceWithoutReferences],
|
||||
null,
|
||||
2,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
async update() {
|
||||
const message: SCMessage = {
|
||||
|
||||
Reference in New Issue
Block a user