diff --git a/lib/inventory/spec/cue.mod/module.cue b/lib/inventory/spec/cue.mod/module.cue deleted file mode 100644 index 773cae9d3..000000000 --- a/lib/inventory/spec/cue.mod/module.cue +++ /dev/null @@ -1,2 +0,0 @@ -module: "clan.lol/inventory" -language: version: "v0.8.2" \ No newline at end of file diff --git a/lib/inventory/spec/root.cue b/lib/inventory/spec/root.cue deleted file mode 100644 index da64c1b2c..000000000 --- a/lib/inventory/spec/root.cue +++ /dev/null @@ -1,23 +0,0 @@ -package inventory - -import ( - "clan.lol/inventory/schema" -) - -@jsonschema(schema="http://json-schema.org/schema#") -#Root: { - meta: { - // A name of the clan (primarily shown by the UI) - name: string - // A description of the clan - description?: string - // The icon path - icon?: string - } - - // // A map of services - schema.#service - - // // A map of machines - schema.#machine -} diff --git a/lib/inventory/spec/schema/schema.cue b/lib/inventory/spec/schema/schema.cue deleted file mode 100644 index eded84e29..000000000 --- a/lib/inventory/spec/schema/schema.cue +++ /dev/null @@ -1,40 +0,0 @@ -package schema - -#machine: machines: [string]: { - name: string, - description?: string, - icon?: string - tags: [...string] - system?: string -} - -#role: string - -#service: services: [string]: [string]: { - // Required meta fields - meta: { - name: string, - icon?: string - description?: string, - }, - // We moved the machine sepcific config to "machines". - // It may be moved back depending on what makes more sense in the future. - roles: [#role]: { - machines: [...string], - tags: [...string], - } - machines?: { - [string]: { - config?: { - ... - } - } - }, - - // Global Configuration for the service - config?: { - // Schema depends on the module. - // It declares the interface how the service can be configured. - ... - } -} \ No newline at end of file diff --git a/lib/jsonschema/default.nix b/lib/jsonschema/default.nix index 0a92da9b6..fabf4f81f 100644 --- a/lib/jsonschema/default.nix +++ b/lib/jsonschema/default.nix @@ -47,22 +47,35 @@ rec { let evaled = lib.evalModules { modules = [ module ]; }; in - { "$schema" = "http://json-schema.org/draft-07/schema#"; } // parseOptions evaled.options; + parseOptions evaled.options { }; + + parseOptions' = lib.flip parseOptions { addHeader = false; }; # parses a set of evaluated nixos options to a jsonschema parseOptions = - options': + options: + { + # The top-level header object should specify at least the schema version + # Can be customized if needed + header ? { + "$schema" = "http://json-schema.org/draft-07/schema#"; + }, + # By default the header is not added to the schema + addHeader ? true, + }: let - options = filterInvisibleOpts (filterExcludedAttrs (clean options')); + options' = filterInvisibleOpts (filterExcludedAttrs (clean options)); # parse options to jsonschema properties - properties = lib.mapAttrs (_name: option: parseOption option) options; + properties = lib.mapAttrs (_name: option: parseOption option) options'; # TODO: figure out how to handle if prop.anyOf is used isRequired = prop: !(prop ? default || prop.type or null == "object"); requiredProps = lib.filterAttrs (_: prop: isRequired prop) properties; required = lib.optionalAttrs (requiredProps != { }) { required = lib.attrNames requiredProps; }; + header' = if addHeader then header else { }; in # return jsonschema - required + header' + // required // { type = "object"; inherit properties; @@ -108,7 +121,7 @@ rec { # handle nested options (not a submodule) else if !option ? _type then - parseOptions option + parseOptions' option # throw if not an option else if option._type != "option" && option._type != "option-type" then @@ -231,7 +244,7 @@ rec { // description // { type = "array"; - items = parseOptions (option.type.functor.wrapped.getSubOptions option.loc); + items = parseOptions' (option.type.functor.wrapped.getSubOptions option.loc); } # parse list @@ -271,7 +284,7 @@ rec { // description // { type = "object"; - additionalProperties = parseOptions (option.type.nestedTypes.elemType.getSubOptions option.loc); + additionalProperties = parseOptions' (option.type.nestedTypes.elemType.getSubOptions option.loc); } # parse attrs @@ -322,7 +335,7 @@ rec { # return jsonschema property definition for submodule # then (lib.attrNames (option.type.getSubOptions option.loc).opt) then - parseOptions (option.type.getSubOptions option.loc) + parseOptions' (option.type.getSubOptions option.loc) # throw error if option type is not supported else diff --git a/lib/jsonschema/test_parseOptions.nix b/lib/jsonschema/test_parseOptions.nix index 9467160f6..c1c8cc1cc 100644 --- a/lib/jsonschema/test_parseOptions.nix +++ b/lib/jsonschema/test_parseOptions.nix @@ -17,8 +17,9 @@ }; in { - expr = slib.parseOptions evaled.options; + expr = slib.parseOptions evaled.options { }; expected = { + "$schema" = "http://json-schema.org/draft-07/schema#"; additionalProperties = false; properties = { foo = { diff --git a/pkgs/schemas/flake-module.nix b/pkgs/schemas/flake-module.nix index 59c25d013..195b5c6dd 100644 --- a/pkgs/schemas/flake-module.nix +++ b/pkgs/schemas/flake-module.nix @@ -18,13 +18,13 @@ if (eval.options.clan ? "${mName}") then eval.options.clan.${mName} else { }; clanModuleSchemas = lib.mapAttrs ( - modulename: _: self.lib.jsonschema.parseOptions (optionsFromModule modulename) + modulename: _: self.lib.jsonschema.parseOptions (optionsFromModule modulename) { } ) clanModules; clanModuleFunctionSchemas = lib.mapAttrsFlatten (modulename: _: { name = modulename; description = self.lib.modules.getShortDescription modulename; - parameters = self.lib.jsonschema.parseOptions (optionsFromModule modulename); + parameters = self.lib.jsonschema.parseOptions (optionsFromModule modulename) { }; }) clanModules; in rec {