Line data Source code
1 : /*
2 : * Copyright (C) 2018 Red Hat, Inc.
3 : * SPDX-License-Identifier: LGPL-2.1-or-later
4 : */
5 :
6 628 : import React from "react";
7 :
8 628 : import cockpit from "cockpit";
9 :
10 42 : export function fmt_to_fragments(format: string, ...args: React.ReactNode[]) {
11 42 : const fragments = format.split(/(\$[0-9]+)/g).map(part => {
12 42 : if (part[0] == "$") {
13 42 : return args[parseInt(part.slice(1))]; // placeholder, from `args`
14 42 : } else
15 42 : return part; // literal string content
16 42 : });
17 :
18 42 : return React.createElement(React.Fragment, { }, ...fragments);
19 42 : }
20 :
21 : /**
22 : * Checks if a JsonValue is a JsonObject, and acts as a type guard.
23 : *
24 : * This function produces correct results for any possible JsonValue, and also
25 : * for undefined. If you pass other types of values to this function it may
26 : * return an incorrect result (ie: it doesn't check deeply, so anything that
27 : * looks like a "simple object" will pass the check).
28 : */
29 111 : export function is_json_dict(value: cockpit.JsonValue | undefined): value is cockpit.JsonObject {
30 111 : return value?.constructor === Object;
31 111 : }
32 :
33 111 : function try_fields(
34 111 : dict: cockpit.JsonObject, fields: (string | undefined)[], def: cockpit.JsonValue
35 111 : ): cockpit.JsonValue {
36 111 : for (const field of fields)
37 111 : if (field && field in dict)
38 109 : return dict[field];
39 21 : return def;
40 111 : }
41 :
42 : /**
43 : * Get an entry from a manifest's ".config[config_name]" field.
44 : *
45 : * This can either be a direct value, e.g.
46 : *
47 : * "config": { "color": "yellow" }
48 : *
49 : * Or an object indexed by any value in "matches". Commonly these are fields
50 : * from os-release(5) like PLATFORM_ID or ID; e.g.
51 : *
52 : * "config": {
53 : * "fedora": { "color": "blue" },
54 : * "platform:el9": { "color": "red" }
55 : * }
56 : */
57 :
58 : /** Parse `sessionStorage.cockpit_anaconda` as JSON (storaged uses the object when present). */
59 113 : export function read_anaconda_session_storage(): cockpit.JsonValue | null {
60 113 : try {
61 113 : const value = JSON.parse(
62 113 : window.sessionStorage.getItem("cockpit_anaconda") as string
63 113 : ) as cockpit.JsonValue;
64 113 : if (value)
65 24 : console.log("ANACONDA", value);
66 113 : return value;
67 22 : } catch {
68 22 : console.warn("Can't parse cockpit_anaconda configuration as JSON");
69 22 : return null;
70 22 : }
71 113 : }
72 :
73 : /** True when embedded in Anaconda (parent sets JSON in sessionStorage `cockpit_anaconda`). */
74 148 : export function in_anaconda_mode(): boolean {
75 148 : try {
76 148 : const raw = window.sessionStorage.getItem("cockpit_anaconda");
77 143 : return !!JSON.parse(raw ?? "null");
78 25 : } catch {
79 25 : return false;
80 25 : }
81 148 : }
82 :
83 111 : export function get_manifest_config_matchlist(
84 111 : manifest_name: string, config_name: string, default_value: cockpit.JsonValue, matches: (string | undefined)[]
85 111 : ): cockpit.JsonValue {
86 111 : const config = cockpit.manifests[manifest_name]?.config;
87 :
88 111 : if (is_json_dict(config)) {
89 111 : const val = config[config_name];
90 111 : if (is_json_dict(val))
91 9 : return try_fields(val, matches, default_value);
92 : else
93 5 : return val !== undefined ? val : default_value;
94 5 : } else {
95 5 : return default_value;
96 5 : }
97 111 : }
|