Make form attribute conversion type-safe (#3823)

This commit is contained in:
Jon Koops 2022-11-24 16:48:22 +01:00 committed by GitHub
parent 5239fc30af
commit 0e04f088e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 13 deletions

View file

@ -1,16 +1,16 @@
import { cloneDeep } from "lodash-es";
import { saveAs } from "file-saver";
import type { IFormatter, IFormatterValueType } from "@patternfly/react-table";
import { flatten } from "flat";
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation"; import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
import type { ProviderRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation"; import type { ProviderRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation";
import type { IFormatter, IFormatterValueType } from "@patternfly/react-table";
import { saveAs } from "file-saver";
import { flatten } from "flat";
import { cloneDeep } from "lodash-es";
import { import {
keyValueToArray,
arrayToKeyValue, arrayToKeyValue,
keyValueToArray,
KeyValueType, KeyValueType,
} from "./components/key-value-form/key-value-convert"; } from "./components/key-value-form/key-value-convert";
import { ReplaceString } from "./utils/types";
export const sortProviders = (providers: { export const sortProviders = (providers: {
[index: string]: ProviderRepresentation; [index: string]: ProviderRepresentation;
@ -84,13 +84,14 @@ const isEmpty = (obj: any) => Object.keys(obj).length === 0;
export const convertAttributeNameToForm = (name: string) => { export const convertAttributeNameToForm = (name: string) => {
const index = name.indexOf("."); const index = name.indexOf(".");
return `${name.substring(0, index)}.${convertAttribute( return `${name.substring(0, index)}.${beerify(name.substring(index + 1))}`;
name.substring(index + 1)
)}`;
}; };
const convertAttribute = (name: string) => name.replace(/\./g, "🍺"); const beerify = <T extends string>(name: T) =>
const convertFormNameToAttribute = (name: string) => name.replace(/🍺/g, "."); name.replaceAll(".", "🍺") as ReplaceString<T, ".", "🍺">;
const debeerify = <T extends string>(name: T) =>
name.replaceAll("🍺", ".") as ReplaceString<T, "🍺", ".">;
export const convertToFormValues = ( export const convertToFormValues = (
obj: any, obj: any,
@ -107,7 +108,7 @@ export const convertToFormValues = (
); );
convertedValues.forEach(([k, v]) => convertedValues.forEach(([k, v]) =>
setValue(`${key}.${convertAttribute(k)}`, v) setValue(`${key}.${beerify(k)}`, v)
); );
} else { } else {
setValue(key, undefined); setValue(key, undefined);
@ -128,7 +129,7 @@ export function convertFormValuesToObject<T extends Record<string, any>, G = T>(
} else if (key === "config" || key === "attributes") { } else if (key === "config" || key === "attributes") {
result[key] = Object.fromEntries( result[key] = Object.fromEntries(
Object.entries(value as Record<string, unknown>).map(([k, v]) => [ Object.entries(value as Record<string, unknown>).map(([k, v]) => [
convertFormNameToAttribute(k), debeerify(k),
v, v,
]) ])
); );

View file

@ -0,0 +1,14 @@
export type ReplaceStringOptions = {
skipFirst?: boolean;
};
export type ReplaceString<
Input extends string,
Search extends string,
Replacement extends string,
Options extends ReplaceStringOptions = {}
> = Input extends `${infer Head}${Search}${infer Tail}`
? Options["skipFirst"] extends true
? `${Head}${Search}${ReplaceString<Tail, Search, Replacement>}`
: `${Head}${Replacement}${ReplaceString<Tail, Search, Replacement>}`
: Input;