UNPKG

gpii-universal

Version:

Cross platform, core components of the GPII personalization infrastructure.

158 lines (132 loc) 6.46 kB
/* A script to generate a schema "codex" for all known solutions and generic preferences. The "codex" is a map, keyed by URI. For application settings, the URI looks like: http://registry.gpii.net/applications/com.microsoft.windows.onscreenKeyboard For "generic preference terms", the URI looks like: http://registry.gpii.net/common/fontSize Each map entry is a schema that describes all possible settings for a given solution, as shown here: { "http://registry.gpii.net/applications/my.sample.app": { properties: { setting1: { // setting1 sub-schema }, setting2: { // setting2 sub-schema } } } } This structure allows for more efficient settings/preferences validation than previous strategies. Payloads to be validated can be broken down into a series of small "per solution" validation passes, which typically take less than 5ms even for our largest sample settings payloads. */ /* eslint-env node */ "use strict"; var fluid = require("infusion"); var gpii = fluid.registerNamespace("gpii"); var mkdirp = require("mkdirp"); var fs = require("fs"); var path = require("path"); // Add the ability to require JSON5 files. require("json5/lib/register"); // Require universal so that we can resolve paths to it and any sub-modules. fluid.require("%gpii-universal"); fluid.registerNamespace("gpii.solutionsRegistry.schemaGenerator"); gpii.solutionsRegistry.schemaGenerator.generateSolutionsSchemaCodex = function (that) { // TODO: Add all solutions/settings and schemas from that.options.solutionsRegistryPath var solutionsSettings = gpii.solutionsRegistry.schemaGenerator.settingsFromSolutions(that); var genericSettings = gpii.solutionsRegistry.schemaGenerator.genericSettings(that); var allSettings = fluid.extend({}, solutionsSettings, genericSettings); // Sort the keys so that the final generated file is more readable. var orderedSettings = {}; var allSettingsKeys = fluid.keys(allSettings).sort(); fluid.each(allSettingsKeys, function (settingURI) { orderedSettings[settingURI] = allSettings[settingURI]; }); var resolvedCodexOutputPath = fluid.module.resolvePath(that.options.codexOutputPath); var settingsOutputDir = path.dirname(resolvedCodexOutputPath); if (!fs.existsSync(settingsOutputDir)) { mkdirp.sync(settingsOutputDir); } fs.writeFileSync(resolvedCodexOutputPath, JSON.stringify(orderedSettings, null, 2)); }; gpii.solutionsRegistry.schemaGenerator.settingsFromSolutions = function (that) { var settingsBySolution = {}; var resolvedSrPath = fluid.module.resolvePath(that.options.solutionsRegistryPath); var srFiles = fs.readdirSync(resolvedSrPath).filter(function (filename) { return filename.match(/\.json5?$/i); }); fluid.each(srFiles, function (filename) { var pathToFile = path.resolve(resolvedSrPath, filename); var srFileData = require(pathToFile); fluid.each(srFileData, function (solutionDef, solutionKey) { var solutionURI = "http://registry.gpii.net/applications/" + solutionKey; var solutionSchema = { "$schema": "gss-v7-full#", // Add the name as a courtesy to make reading the generated file more palatable. title: solutionDef.name, type: "object", properties: {}, additionalProperties: false }; fluid.each(fluid.get(solutionDef, "settingsHandlers"), function (settingsHandlerDef) { fluid.each(fluid.get(settingsHandlerDef, "supportedSettings"), function (settingsDef, settingsKey) { if (settingsDef.schema) { solutionSchema.properties[settingsKey] = settingsDef.schema; } }); }); // If there is not an explicit "enabled" setting for a solution, add it now. if (fluid.get(solutionSchema, "properties.enabled") === undefined) { var solutionName = fluid.get(solutionDef, "name"); var title = solutionName ? "Enable " + solutionName : "Enable"; fluid.set(solutionSchema, "properties.enabled", { title: title, description: title + ".", type: "boolean", default: false }); }; if (!fluid.jQueryStandalone.isEmptyObject(solutionSchema.properties)) { settingsBySolution[solutionURI] = solutionSchema; } }); }); return settingsBySolution; }; gpii.solutionsRegistry.schemaGenerator.genericSettings = function (that) { var allGenericSettings = {}; var resolvedPath = fluid.module.resolvePath(that.options.genericPreferenceTermsPath); var rawGenericSettings = require(resolvedPath); fluid.each(rawGenericSettings, function (settingDef, settingURI) { var schema = fluid.get(settingDef, "schema"); if (schema) { allGenericSettings[settingURI] = fluid.extend({ "$schema": "gss-v7-full#" }, schema); } }); return allGenericSettings; }; fluid.defaults("gpii.solutionsRegistry.schemaGenerator", { gradeNames: ["fluid.component"], baseSettingsSchema: "%solutionsRegistry/src/schemas/settings-base-schema.json5", codexOutputPath: "%gpii-universal/build/schemas/solution-schema-codex.json", // TODO: Move this out of test data and break down into individual solutions. solutionsRegistryPath: "%gpii-universal/testData/solutions", // TODO: Move this out of test data to a suitable location. genericPreferenceTermsPath: "%gpii-universal/testData/ontologies/flat.json5", events: { createAllSchemas: null }, listeners: { "onCreate.createAllSchemas": { funcName: "fluid.promise.fireTransformEvent", args: ["{that}.events.createAllSchemas"] }, "createAllSchemas.generateSettingsSchema": { priority: "first", funcName: "gpii.solutionsRegistry.schemaGenerator.generateSolutionsSchemaCodex", args: ["{that}"] } // TODO: Generate prefs safe schema from the settings schema. } }); gpii.solutionsRegistry.schemaGenerator();