"use strict"; const Promise = require("bluebird"); const dlayer = require("."); const syncpipe = require("syncpipe"); let fakeDriveTree = { one: [ "/dev/1a", "/dev/1b" ], two: [ "/dev/2a" ] }; let invertedTree = { "/dev/1a": "one", "/dev/1b": "one", "/dev/2a": "two" }; let contextCounter = 1; // FIXME: Disallow type name conflicts! let moduleDrives = { name: "Drives", types: { "sysquery.core.Drive": function ({ name }) { return { name: name }; } }, extensions: { "sysquery.core.BlockDevice": { drive: async function (_, { counter, $getProperty, $make }) { console.log(`[context ${counter}] BlockDevice::drive`); return $make("sysquery.core.Drive", { name: invertedTree[await $getProperty(this, "path")] }); } } }, root: { hardware: { drives: function ({ names }, { counter, $make }) { console.log(`[context ${counter}] root::drives`); return syncpipe(fakeDriveTree, [ _ => Object.entries(_), _ => (names != null) ? _.filter(([ name, _devices ]) => names.includes(name)) : _, _ => _.map(([ name, _devices ]) => $make("sysquery.core.Drive", { name })) ]); } } }, makeContext: () => { return { counter: contextCounter++ }; } }; let moduleBlockDevices = { name: "Block Devices", types: { "sysquery.core.BlockDevice": function ({ path }) { return { path: path }; } }, extensions: { "sysquery.core.Drive": { blockDevices: async function (_, { counter, $getProperty, $make }) { console.log(`[context ${counter}] Drive::blockDevices`); return fakeDriveTree[await $getProperty(this, "name")].map((path) => { return $make("sysquery.core.BlockDevice", { path }); }); } } }, root: { hardware: { blockDevices: function ({ paths }, { counter, $make }) { console.log(`[context ${counter}] root::blockDevices`); return syncpipe(fakeDriveTree, [ _ => Object.values(_), _ => _.flat(), _ => (paths != null) ? _.filter((path) => paths.includes(path)) : _, _ => _.map((path) => $make("sysquery.core.BlockDevice", { path })) ]); } } }, makeContext: () => { return { counter: contextCounter++ }; } }; let api = dlayer({ schema: { foo: { bar: "baz" } }, modules: [ moduleBlockDevices, moduleDrives ] }); return Promise.try(() => { return api.query({ hardware: { blockDevices: { $arguments: { paths: [ "/dev/1b" ] }, path: true, drive: { name: true, blockDevices: { path: true } } } } }); }).then((result) => { console.log("-- result:"); console.dir(result, {depth: null}); }).catch((error) => { console.log("Unhandled error:"); console.dir(error); });