@signalk/resources-provider
Version:
Resources provider plugin for Signal K server.
253 lines (252 loc) • 9.51 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const server_api_1 = require("@signalk/server-api");
const filestorage_1 = require("./lib/filestorage");
const CONFIG_SCHEMA = {
properties: {
standard: {
type: 'object',
title: 'Resources (standard)',
description: 'ENABLE / DISABLE provider for the following SignalK resource types.',
properties: {
routes: {
type: 'boolean',
title: 'ROUTES'
},
waypoints: {
type: 'boolean',
title: 'WAYPOINTS'
},
notes: {
type: 'boolean',
title: 'NOTES'
},
regions: {
type: 'boolean',
title: 'REGIONS'
},
charts: {
type: 'boolean',
title: 'CHART SOURCES'
}
}
},
custom: {
type: 'array',
title: 'Resources (custom)',
description: 'Add provider for custom resource types.',
items: {
type: 'object',
required: ['name'],
properties: {
name: {
type: 'string',
title: 'Resource Type',
description: '/signalk/v2/api/resources/'
}
}
}
}
}
};
const CONFIG_UISCHEMA = {
standard: {
routes: {
'ui:widget': 'checkbox',
'ui:title': ' ',
'ui:help': '/signalk/v2/api/resources/routes'
},
waypoints: {
'ui:widget': 'checkbox',
'ui:title': ' ',
'ui:help': '/signalk/v2/api/resources/waypoints'
},
notes: {
'ui:widget': 'checkbox',
'ui:title': ' ',
'ui:help': '/signalk/v2/api/resources/notes'
},
regions: {
'ui:widget': 'checkbox',
'ui:title': ' ',
'ui:help': '/signalk/v2/api/resources/regions'
},
charts: {
'ui:widget': 'checkbox',
'ui:title': ' ',
'ui:help': '/signalk/v2/api/resources/charts'
}
}
};
module.exports = (server) => {
const plugin = {
id: 'resources-provider',
name: 'Resources Provider (built-in)',
schema: () => CONFIG_SCHEMA,
uiSchema: () => CONFIG_UISCHEMA,
start: (settings) => {
doStartup(settings);
},
stop: () => {
doShutdown();
}
};
const db = new filestorage_1.FileStore(plugin.id, server.debug);
let config;
const doStartup = (settings) => {
try {
server.debug(`${plugin.name} starting.......`);
config = cleanConfig(settings);
server.debug(`Applied config: ${JSON.stringify(config)}`);
// compile list of enabled resource types
let apiProviderFor = [];
Object.entries(config.standard).forEach((i) => {
if (i[1]) {
apiProviderFor.push(i[0]);
}
});
if (config.custom && Array.isArray(config.custom)) {
const customTypes = config.custom.map((i) => {
return i.name;
});
apiProviderFor = apiProviderFor.concat(customTypes);
}
server.debug(`** Enabled resource types: ${JSON.stringify(apiProviderFor)}`);
// initialise resource storage
db.init({ settings: config, basePath: server.getDataDirPath() })
.then((res) => {
if (res.error) {
const msg = `*** ERROR: ${res.message} ***`;
server.error(msg);
server.setPluginError(msg);
}
server.debug(`** ${plugin.name} started... ${!res.error ? 'OK' : 'with errors!'}`);
// register as provider for enabled resource types
const result = registerProviders(apiProviderFor);
if (result.length !== 0) {
server.setPluginError(`Error registering providers: ${result.toString()}`);
}
else {
server.setPluginStatus(`Providing: ${apiProviderFor.toString()}`);
}
})
.catch((e) => {
server.debug(e.message);
const msg = `Initialisation Error! See console for details.`;
server.setPluginError(msg);
});
}
catch (error) {
const msg = `Started with errors!`;
server.setPluginError(msg);
server.error('error: ' + error);
}
};
const doShutdown = () => {
server.debug(`${plugin.name} stopping.......`);
server.debug('** Un-registering Update Handler(s) **');
const msg = 'Stopped.';
server.setPluginStatus(msg);
};
/** process changes in config schema */
const cleanConfig = (options) => {
server.debug(`Check / Clean loaded settings...`);
const defaultConfig = {
standard: {
routes: true,
waypoints: true,
notes: true,
regions: true,
charts: true
},
custom: []
};
// set / save defaults if no saved settings
if (!(options === null || options === void 0 ? void 0 : options.standard)) {
server.savePluginOptions(defaultConfig, () => {
server.debug(`Default configuration applied...`);
});
return defaultConfig;
}
// check / clean settings
if (!Array.isArray(options === null || options === void 0 ? void 0 : options.custom)) {
options.custom = [];
}
server_api_1.SIGNALKRESOURCETYPES.forEach((r) => {
if (!(r in options.standard)) {
options.standard[r] = true;
}
});
options.custom = options.custom.filter((i) => !(i.name in defaultConfig.standard));
server.savePluginOptions(options, () => {
server.debug(`Configuration cleaned and saved...`);
});
return options;
};
const getVesselPosition = () => {
const p = server.getSelfPath('navigation.position');
return p && p.value ? [p.value.longitude, p.value.latitude] : null;
};
const registerProviders = (resTypes) => {
const failed = [];
resTypes.forEach((resType) => {
try {
server.registerResourceProvider({
type: resType,
methods: {
listResources: (params) => {
return apiGetResources(resType, params);
},
getResource: (id, property) => {
return db.getResource(resType, (0, filestorage_1.getUuid)(id), property);
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
setResource: (id, value) => {
return apiSetResource(resType, id, value);
},
deleteResource: (id) => {
return apiSetResource(resType, id, null);
}
}
});
}
catch (_error) {
failed.push(resType);
}
});
return failed;
};
// Signal K server Resource Provider interface functions
const apiGetResources = (resType,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
params = {}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
) => __awaiter(void 0, void 0, void 0, function* () {
if (typeof params.position === 'undefined') {
params.position = getVesselPosition();
}
server.debug(`*** apiGetResource: ${resType}, ${JSON.stringify(params)}`);
return yield db.getResources(resType, params);
});
const apiSetResource = (resType, id,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value) => __awaiter(void 0, void 0, void 0, function* () {
server.debug(`*** apiSetResource: ${resType}, ${id}, ${value}`);
const r = {
type: resType,
id,
value
};
return yield db.setResource(r);
});
return plugin;
};