1{
2 lib,
3 json-schema-catalog-rs,
4 runCommand,
5 jq,
6}:
7let
8
9 /**
10 A somewhat opinionated method for constructing a JSON Schema Catalog from files in a Nix store.
11
12 The input is a slightly simpler format:
13
14 ```nix
15 {
16 name = "my-catalog"; # derivation name, default displayName
17 displayName = "My Catalog"; # optional
18 groups = {
19 "Group One" = {
20 "https://example.com/schemas/one-v1.json" = pkgs.fetchurl { ... };
21 "https://example.com/schemas/one-v2.json" = pkgs.fetchurl { ... };
22 "https://example.com/schemas/one-common.json" = pkgs.fetchurl { ... };
23 };
24 "Group Two" = {
25 "https://example.com/schemas/two-v1.json" = ./two-v1.json; # Files can be local
26 };
27 };
28 }
29 ```
30 */
31 newCatalog =
32 {
33 name,
34 displayName ? name,
35 groups,
36 version ? null,
37 extraDescription ? null,
38 meta ? { },
39 }:
40 let
41 # lazyDerivation tidies up the package attributes
42 package = lib.lazyDerivation {
43 derivation = drv;
44 passthru = {
45 name = "catalog-${name}";
46 internals = drv;
47 }
48 // lib.optionalAttrs (version != null) {
49 inherit version;
50 };
51 meta = {
52 description = "JSON Schema Catalog for ${displayName}";
53 longDescription =
54 let
55 licenses = lib.toList meta.license;
56 show = license: license.fullName or license;
57 theLicensesApply =
58 if lib.length licenses == 1 then
59 "The package license, ${show (lib.head licenses)}, applies"
60 else
61 "The package licenses, ${lib.concatMapStringsSep " / " show licenses}, apply";
62 in
63 ''
64 A JSON Schema Catalog is a mapping from URIs to JSON Schema documents.
65 It enables offline use, e.g. in build processes, and therefore it improves performance, robustness and safety.
66 ${lib.optionalString (extraDescription != null) "\n${extraDescription}\n"}
67 ${theLicensesApply} to the schemas in this catalog. The catalog file itself is licensed under the terms of the Nix expression that governs it, e.g. MIT in the case of Nixpkgs.
68 '';
69 }
70 // meta;
71 };
72
73 drvArgs = {
74 pname = name;
75 catalogJson = builtins.toJSON {
76 name = displayName;
77 groups = lib.mapAttrsToList (name: group: {
78 inherit name;
79 # TODO dedup the longest common prefix by putting it in baseLocation
80 baseLocation = "/";
81 schemas = lib.mapAttrsToList (id: location: {
82 inherit id;
83 inherit location;
84 }) group;
85 }) groups;
86 };
87 passAsFile = [ "catalogJson" ];
88 passthru = {
89 inherit groups;
90 };
91 nativeBuildInputs = [
92 jq
93 json-schema-catalog-rs
94 ];
95 }
96 // lib.optionalAttrs (version != null) {
97 inherit version;
98 };
99
100 drv = runCommand "${package.name}${lib.optionalString (version != null) "-${version}"}" drvArgs ''
101 out_dir="$out/share/json-schema-catalogs"
102 out_file="$out_dir/$name.json"
103
104 mkdir -p "$out_dir"
105
106 # Write the catalog JSON. `jq` formats it nicely.
107 jq . <"$catalogJsonPath" >"$out_file"
108
109 json-schema-catalog check "$out_file"
110 '';
111 in
112 package;
113in
114{
115 lib =
116 # Exported as part of `pkgs.jsonSchemaCatalogs`
117 {
118 inherit newCatalog;
119 };
120}