refactor(scaffolder): wrap full field schema and prop type def in helper

Signed-off-by: Phil Kuang <pkuang@factset.com>
This commit is contained in:
Phil Kuang
2022-11-11 14:11:42 -05:00
parent 3e4a2ee779
commit da25293910
22 changed files with 169 additions and 201 deletions
@@ -212,7 +212,7 @@ export const MyCustomExtensionWithOptions = ({
rawErrors,
required,
formData,
}: FieldProps<string, { focused?: boolean }>) => {
}: FieldExtensionComponentProps<string, { focused?: boolean }>) => {
return (
<FormControl
margin="normal"
@@ -240,16 +240,17 @@ export const MyCustomFieldWithOptionsExtension = scaffolderPlugin.provide(
```
We recommend using a library like [zod](https://github.com/colinhacks/zod) to define your schema
and the provided `makeJsonSchemaFromZod` helper utility function to generate both the JSON schema
and types for your field input/output to preventing having to duplicate the definitions:
and the provided `makeFieldSchemaFromZod` helper utility function to generate both the JSON schema
and type for your field props to preventing having to duplicate the definitions:
```tsx
//packages/app/src/scaffolder/MyCustomExtensionWithOptions/MyCustomExtensionWithOptions.tsx
...
import { z } from 'zod';
import { makeJsonSchemaFromZod } from '@backstage/plugin-scaffolder';
import { makeFieldSchemaFromZod } from '@backstage/plugin-scaffolder';
const MyCustomExtensionWithOptionsUiOptionsSchema = makeJsonSchemaFromZod(
const MyCustomExtensionWithOptionsFieldSchema = makeFieldSchemaFromZod(
z.string(),
z.object({
focused: z
.boolean()
@@ -258,24 +259,16 @@ const MyCustomExtensionWithOptionsUiOptionsSchema = makeJsonSchemaFromZod(
}),
);
const MyCustomExtensionWithOptionsReturnValueSchema = makeJsonSchemaFromZod(
z.string(),
);
export const MyCustomExtensionWithOptionsSchema = MyCustomExtensionWithOptionsFieldSchema.schema;
export const MyCustomExtensionWithOptionsSchema = {
uiOptions: MyCustomExtensionWithOptionsUiOptionsSchema.schema,
returnValue: MyCustomExtensionWithOptionsReturnValueSchema.schema,
};
type MyCustomExtensionWithOptionsProps = typeof MyCustomExtensionWithOptionsFieldSchema.type;
export const MyCustomExtensionWithOptions = ({
onChange,
rawErrors,
required,
formData,
}: FieldProps<
typeof MyCustomExtensionWithOptionsReturnValueSchema.type,
typeof MyCustomExtensionWithOptionsUiOptionsSchema.type
>) => {
}: MyCustomExtensionWithOptionsProps) => {
return (
<FormControl
margin="normal"
+67 -49
View File
@@ -60,8 +60,8 @@ export function createScaffolderLayout<TInputProps = unknown>(
// @public
export type CustomFieldExtensionSchema = {
returnValue: JSONSchema7;
uiOptions?: JSONSchema7;
returnValue?: JSONSchema7;
};
// @public
@@ -90,19 +90,20 @@ export const EntityPickerFieldExtension: FieldExtensionComponent<
}
>;
// @public
export type EntityPickerUiOptions = typeof EntityPickerUiOptionsSchema.type;
// @public (undocumented)
export const EntityPickerUiOptionsSchema: {
schema: JSONSchema7;
type: {
export const EntityPickerFieldSchema: FieldSchema<
string,
{
defaultKind?: string | undefined;
defaultNamespace?: string | false | undefined;
allowedKinds?: string[] | undefined;
allowArbitraryValues?: boolean | undefined;
};
};
}
>;
// @public
export type EntityPickerUiOptions =
typeof EntityPickerFieldSchema.uiOptionsType;
// @public
export const EntityTagsPickerFieldExtension: FieldExtensionComponent<
@@ -114,19 +115,19 @@ export const EntityTagsPickerFieldExtension: FieldExtensionComponent<
}
>;
// @public
export type EntityTagsPickerUiOptions =
typeof EntityTagsPickerUiOptionsSchema.type;
// @public (undocumented)
export const EntityTagsPickerUiOptionsSchema: {
schema: JSONSchema7;
type: {
export const EntityTagsPickerFieldSchema: FieldSchema<
string[],
{
showCounts?: boolean | undefined;
kinds?: string[] | undefined;
helperText?: string | undefined;
};
};
}
>;
// @public
export type EntityTagsPickerUiOptions =
typeof EntityTagsPickerFieldSchema.uiOptionsType;
// @public
export type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null;
@@ -155,6 +156,16 @@ export type FieldExtensionOptions<
schema?: CustomFieldExtensionSchema;
};
// @public
export interface FieldSchema<TReturn, TUiOptions> {
// (undocumented)
readonly schema: CustomFieldExtensionSchema;
// (undocumented)
readonly type: FieldExtensionComponentProps<TReturn, TUiOptions>;
// (undocumented)
readonly uiOptionsType: TUiOptions;
}
// @public
export type LayoutComponent<_TInputProps> = () => null;
@@ -193,12 +204,18 @@ export type LogEvent = {
};
// @public
export function makeJsonSchemaFromZod<T extends z.ZodType>(
schema: T,
): {
schema: JSONSchema7;
type: T extends z.ZodType<any, any, infer I> ? I : never;
};
export function makeFieldSchemaFromZod<
TReturnSchema extends z.ZodType,
TUiOptionsSchema extends z.ZodType = z.ZodType<any, any, {}>,
>(
returnSchema: TReturnSchema,
uiOptionsSchema?: TUiOptionsSchema,
): FieldSchema<
TReturnSchema extends z.ZodType<any, any, infer IReturn> ? IReturn : never,
TUiOptionsSchema extends z.ZodType<any, any, infer IUiOptions>
? IUiOptions
: never
>;
// @alpha
export type NextCustomFieldValidator<TFieldReturnValue> = (
@@ -268,20 +285,20 @@ export const OwnedEntityPickerFieldExtension: FieldExtensionComponent<
}
>;
// @public
export type OwnedEntityPickerUiOptions =
typeof OwnedEntityPickerUiOptionsSchema.type;
// @public (undocumented)
export const OwnedEntityPickerUiOptionsSchema: {
schema: JSONSchema7;
type: {
export const OwnedEntityPickerFieldSchema: FieldSchema<
string,
{
defaultKind?: string | undefined;
defaultNamespace?: string | false | undefined;
allowedKinds?: string[] | undefined;
allowArbitraryValues?: boolean | undefined;
};
};
}
>;
// @public
export type OwnedEntityPickerUiOptions =
typeof OwnedEntityPickerFieldSchema.uiOptionsType;
// @public
export const OwnerPickerFieldExtension: FieldExtensionComponent<
@@ -293,18 +310,18 @@ export const OwnerPickerFieldExtension: FieldExtensionComponent<
}
>;
// @public
export type OwnerPickerUiOptions = typeof OwnerPickerUiOptionsSchema.type;
// @public (undocumented)
export const OwnerPickerUiOptionsSchema: {
schema: JSONSchema7;
type: {
export const OwnerPickerFieldSchema: FieldSchema<
string,
{
defaultNamespace?: string | false | undefined;
allowedKinds?: string[] | undefined;
allowArbitraryValues?: boolean | undefined;
};
};
}
>;
// @public
export type OwnerPickerUiOptions = typeof OwnerPickerFieldSchema.uiOptionsType;
// @public
export const repoPickerValidation: (
@@ -340,13 +357,10 @@ export const RepoUrlPickerFieldExtension: FieldExtensionComponent<
}
>;
// @public
export type RepoUrlPickerUiOptions = typeof RepoUrlPickerUiOptionsSchema.type;
// @public (undocumented)
export const RepoUrlPickerUiOptionsSchema: {
schema: JSONSchema7;
type: {
export const RepoUrlPickerFieldSchema: FieldSchema<
string,
{
allowedOwners?: string[] | undefined;
allowedOrganizations?: string[] | undefined;
allowedRepos?: string[] | undefined;
@@ -365,8 +379,12 @@ export const RepoUrlPickerUiOptionsSchema: {
secretsKey: string;
}
| undefined;
};
};
}
>;
// @public
export type RepoUrlPickerUiOptions =
typeof RepoUrlPickerFieldSchema.uiOptionsType;
// @public (undocumented)
export const rootRouteRef: RouteRef<undefined>;
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import React from 'react';
import { FieldExtensionComponentProps } from '../../../extensions';
import { EntityNamePickerReturnValue } from './schema';
import { EntityNamePickerProps } from './schema';
import { TextField } from '@material-ui/core';
export { EntityNamePickerSchema } from './schema';
@@ -23,9 +22,7 @@ export { EntityNamePickerSchema } from './schema';
/**
* EntityName Picker
*/
export const EntityNamePicker = (
props: FieldExtensionComponentProps<EntityNamePickerReturnValue>,
) => {
export const EntityNamePicker = (props: EntityNamePickerProps) => {
const {
onChange,
required,
@@ -14,13 +14,10 @@
* limitations under the License.
*/
import { z } from 'zod';
import { makeJsonSchemaFromZod } from '../utils';
import { makeFieldSchemaFromZod } from '../utils';
const EntityNamePickerReturnValueSchema = makeJsonSchemaFromZod(z.string());
const EntityNamePickerFieldSchema = makeFieldSchemaFromZod(z.string());
export type EntityNamePickerReturnValue =
typeof EntityNamePickerReturnValueSchema.type;
export const EntityNamePickerSchema = EntityNamePickerFieldSchema.schema;
export const EntityNamePickerSchema = {
returnValue: EntityNamePickerReturnValueSchema.schema,
};
export type EntityNamePickerProps = typeof EntityNamePickerFieldSchema.type;
@@ -23,8 +23,7 @@ import FormControl from '@material-ui/core/FormControl';
import Autocomplete from '@material-ui/lab/Autocomplete';
import React, { useCallback, useEffect } from 'react';
import useAsync from 'react-use/lib/useAsync';
import { FieldExtensionComponentProps } from '../../../extensions';
import { EntityPickerReturnValue, EntityPickerUiOptions } from './schema';
import { EntityPickerProps } from './schema';
export { EntityPickerSchema } from './schema';
@@ -34,12 +33,7 @@ export { EntityPickerSchema } from './schema';
*
* @public
*/
export const EntityPicker = (
props: FieldExtensionComponentProps<
EntityPickerReturnValue,
EntityPickerUiOptions
>,
) => {
export const EntityPicker = (props: EntityPickerProps) => {
const {
onChange,
schema: { title = 'Entity', description = 'An entity from the catalog' },
@@ -13,7 +13,4 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {
type EntityPickerUiOptions,
EntityPickerUiOptionsSchema,
} from './schema';
export { EntityPickerFieldSchema, type EntityPickerUiOptions } from './schema';
@@ -14,12 +14,13 @@
* limitations under the License.
*/
import { z } from 'zod';
import { makeJsonSchemaFromZod } from '../utils';
import { makeFieldSchemaFromZod } from '../utils';
/**
* @public
*/
export const EntityPickerUiOptionsSchema = makeJsonSchemaFromZod(
export const EntityPickerFieldSchema = makeFieldSchemaFromZod(
z.string(),
z.object({
allowedKinds: z
.array(z.string())
@@ -44,19 +45,15 @@ export const EntityPickerUiOptionsSchema = makeJsonSchemaFromZod(
}),
);
const EntityPickerReturnValueSchema = makeJsonSchemaFromZod(z.string());
/**
* The input props that can be specified under `ui:options` for the
* `EntityPicker` field extension.
*
* @public
*/
export type EntityPickerUiOptions = typeof EntityPickerUiOptionsSchema.type;
export type EntityPickerUiOptions =
typeof EntityPickerFieldSchema.uiOptionsType;
export type EntityPickerReturnValue = typeof EntityPickerReturnValueSchema.type;
export type EntityPickerProps = typeof EntityPickerFieldSchema.type;
export const EntityPickerSchema = {
uiOptions: EntityPickerUiOptionsSchema.schema,
returnValue: EntityPickerReturnValueSchema.schema,
};
export const EntityPickerSchema = EntityPickerFieldSchema.schema;
@@ -22,11 +22,7 @@ import { useApi } from '@backstage/core-plugin-api';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { FormControl, TextField } from '@material-ui/core';
import { Autocomplete } from '@material-ui/lab';
import { FieldExtensionComponentProps } from '../../../extensions';
import {
EntityTagsPickerReturnValue,
EntityTagsPickerUiOptions,
} from './schema';
import { EntityTagsPickerProps } from './schema';
export { EntityTagsPickerSchema } from './schema';
@@ -36,12 +32,7 @@ export { EntityTagsPickerSchema } from './schema';
*
* @public
*/
export const EntityTagsPicker = (
props: FieldExtensionComponentProps<
EntityTagsPickerReturnValue,
EntityTagsPickerUiOptions
>,
) => {
export const EntityTagsPicker = (props: EntityTagsPickerProps) => {
const { formData, onChange, uiSchema } = props;
const catalogApi = useApi(catalogApiRef);
const [tagOptions, setTagOptions] = useState<string[]>([]);
@@ -14,6 +14,6 @@
* limitations under the License.
*/
export {
EntityTagsPickerFieldSchema,
type EntityTagsPickerUiOptions,
EntityTagsPickerUiOptionsSchema,
} from './schema';
@@ -14,12 +14,13 @@
* limitations under the License.
*/
import { z } from 'zod';
import { makeJsonSchemaFromZod } from '../utils';
import { makeFieldSchemaFromZod } from '../utils';
/**
* @public
*/
export const EntityTagsPickerUiOptionsSchema = makeJsonSchemaFromZod(
export const EntityTagsPickerFieldSchema = makeFieldSchemaFromZod(
z.array(z.string()),
z.object({
kinds: z
.array(z.string())
@@ -33,9 +34,9 @@ export const EntityTagsPickerUiOptionsSchema = makeJsonSchemaFromZod(
}),
);
const EntityTagsPickerReturnValueSchema = makeJsonSchemaFromZod(
z.array(z.string()),
);
export const EntityTagsPickerSchema = EntityTagsPickerFieldSchema.schema;
export type EntityTagsPickerProps = typeof EntityTagsPickerFieldSchema.type;
/**
* The input props that can be specified under `ui:options` for the
@@ -44,12 +45,4 @@ const EntityTagsPickerReturnValueSchema = makeJsonSchemaFromZod(
* @public
*/
export type EntityTagsPickerUiOptions =
typeof EntityTagsPickerUiOptionsSchema.type;
export type EntityTagsPickerReturnValue =
typeof EntityTagsPickerReturnValueSchema.type;
export const EntityTagsPickerSchema = {
uiOptions: EntityTagsPickerUiOptionsSchema.schema,
returnValue: EntityTagsPickerReturnValueSchema.schema,
};
typeof EntityTagsPickerFieldSchema.uiOptionsType;
@@ -26,25 +26,17 @@ import Autocomplete from '@material-ui/lab/Autocomplete';
import React, { useMemo } from 'react';
import useAsync from 'react-use/lib/useAsync';
import { FieldExtensionComponentProps } from '../../../extensions';
import {
OwnedEntityPickerReturnValue,
OwnedEntityPickerUiOptions,
} from './schema';
import { OwnedEntityPickerProps } from './schema';
export { OwnedEntityPickerSchema } from './schema';
/**
* The underlying component that is rendered in the form for the `OwnedEntityPicker`
* field extension.
*
* @public
*/
export const OwnedEntityPicker = (
props: FieldExtensionComponentProps<
OwnedEntityPickerReturnValue,
OwnedEntityPickerUiOptions
>,
) => {
export const OwnedEntityPicker = (props: OwnedEntityPickerProps) => {
const {
onChange,
schema: { title = 'Entity', description = 'An entity from the catalog' },
@@ -14,6 +14,6 @@
* limitations under the License.
*/
export {
OwnedEntityPickerFieldSchema,
type OwnedEntityPickerUiOptions,
OwnedEntityPickerUiOptionsSchema,
} from './schema';
@@ -14,12 +14,13 @@
* limitations under the License.
*/
import { z } from 'zod';
import { makeJsonSchemaFromZod } from '../utils';
import { makeFieldSchemaFromZod } from '../utils';
/**
* @public
*/
export const OwnedEntityPickerUiOptionsSchema = makeJsonSchemaFromZod(
export const OwnedEntityPickerFieldSchema = makeFieldSchemaFromZod(
z.string(),
z.object({
allowedKinds: z
.array(z.string())
@@ -44,8 +45,6 @@ export const OwnedEntityPickerUiOptionsSchema = makeJsonSchemaFromZod(
}),
);
const OwnedEntityPickerReturnValueSchema = makeJsonSchemaFromZod(z.string());
/**
* The input props that can be specified under `ui:options` for the
* `OwnedEntityPicker` field extension.
@@ -53,12 +52,8 @@ const OwnedEntityPickerReturnValueSchema = makeJsonSchemaFromZod(z.string());
* @public
*/
export type OwnedEntityPickerUiOptions =
typeof OwnedEntityPickerUiOptionsSchema.type;
typeof OwnedEntityPickerFieldSchema.uiOptionsType;
export type OwnedEntityPickerReturnValue =
typeof OwnedEntityPickerReturnValueSchema.type;
export type OwnedEntityPickerProps = typeof OwnedEntityPickerFieldSchema.type;
export const OwnedEntityPickerSchema = {
uiOptions: OwnedEntityPickerUiOptionsSchema.schema,
returnValue: OwnedEntityPickerReturnValueSchema.schema,
};
export const OwnedEntityPickerSchema = OwnedEntityPickerFieldSchema.schema;
@@ -15,8 +15,7 @@
*/
import React from 'react';
import { EntityPicker } from '../EntityPicker/EntityPicker';
import { FieldExtensionComponentProps } from '../../../extensions';
import { OwnerPickerReturnValue, OwnerPickerUiOptions } from './schema';
import { OwnerPickerProps } from './schema';
export { OwnerPickerSchema } from './schema';
@@ -26,12 +25,7 @@ export { OwnerPickerSchema } from './schema';
*
* @public
*/
export const OwnerPicker = (
props: FieldExtensionComponentProps<
OwnerPickerReturnValue,
OwnerPickerUiOptions
>,
) => {
export const OwnerPicker = (props: OwnerPickerProps) => {
const {
schema: { title = 'Owner', description = 'The owner of the component' },
uiSchema,
@@ -13,7 +13,4 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {
type OwnerPickerUiOptions,
OwnerPickerUiOptionsSchema,
} from './schema';
export { OwnerPickerFieldSchema, type OwnerPickerUiOptions } from './schema';
@@ -14,12 +14,13 @@
* limitations under the License.
*/
import { z } from 'zod';
import { makeJsonSchemaFromZod } from '../utils';
import { makeFieldSchemaFromZod } from '../utils';
/**
* @public
*/
export const OwnerPickerUiOptionsSchema = makeJsonSchemaFromZod(
export const OwnerPickerFieldSchema = makeFieldSchemaFromZod(
z.string(),
z.object({
allowedKinds: z
.array(z.string())
@@ -41,19 +42,14 @@ export const OwnerPickerUiOptionsSchema = makeJsonSchemaFromZod(
}),
);
const OwnerPickerReturnValueSchema = makeJsonSchemaFromZod(z.string());
/**
* The input props that can be specified under `ui:options` for the
* `OwnerPicker` field extension.
*
* @public
*/
export type OwnerPickerUiOptions = typeof OwnerPickerUiOptionsSchema.type;
export type OwnerPickerUiOptions = typeof OwnerPickerFieldSchema.uiOptionsType;
export type OwnerPickerReturnValue = typeof OwnerPickerReturnValueSchema.type;
export type OwnerPickerProps = typeof OwnerPickerFieldSchema.type;
export const OwnerPickerSchema = {
uiOptions: OwnerPickerUiOptionsSchema.schema,
returnValue: OwnerPickerReturnValueSchema.schema,
};
export const OwnerPickerSchema = OwnerPickerFieldSchema.schema;
@@ -24,11 +24,10 @@ import { GitlabRepoPicker } from './GitlabRepoPicker';
import { AzureRepoPicker } from './AzureRepoPicker';
import { BitbucketRepoPicker } from './BitbucketRepoPicker';
import { GerritRepoPicker } from './GerritRepoPicker';
import { FieldExtensionComponentProps } from '../../../extensions';
import { RepoUrlPickerHost } from './RepoUrlPickerHost';
import { RepoUrlPickerRepoName } from './RepoUrlPickerRepoName';
import { parseRepoPickerUrl, serializeRepoPickerUrl } from './utils';
import { RepoUrlPickerReturnValue, RepoUrlPickerUiOptions } from './schema';
import { RepoUrlPickerProps } from './schema';
import { RepoUrlPickerState } from './types';
import useDebounce from 'react-use/lib/useDebounce';
import { useTemplateSecrets } from '../../secrets';
@@ -41,12 +40,7 @@ export { RepoUrlPickerSchema } from './schema';
*
* @public
*/
export const RepoUrlPicker = (
props: FieldExtensionComponentProps<
RepoUrlPickerReturnValue,
RepoUrlPickerUiOptions
>,
) => {
export const RepoUrlPicker = (props: RepoUrlPickerProps) => {
const { uiSchema, onChange, rawErrors, formData } = props;
const [state, setState] = useState<RepoUrlPickerState>(
parseRepoPickerUrl(formData),
@@ -14,7 +14,7 @@
* limitations under the License.
*/
export {
RepoUrlPickerFieldSchema,
type RepoUrlPickerUiOptions,
RepoUrlPickerUiOptionsSchema,
} from './schema';
export { repoPickerValidation } from './validation';
@@ -14,12 +14,13 @@
* limitations under the License.
*/
import { z } from 'zod';
import { makeJsonSchemaFromZod } from '../utils';
import { makeFieldSchemaFromZod } from '../utils';
/**
* @public
*/
export const RepoUrlPickerUiOptionsSchema = makeJsonSchemaFromZod(
export const RepoUrlPickerFieldSchema = makeFieldSchemaFromZod(
z.string(),
z.object({
allowedHosts: z
.array(z.string())
@@ -77,23 +78,18 @@ export const RepoUrlPickerUiOptionsSchema = makeJsonSchemaFromZod(
}),
);
const RepoUrlPickerReturnValueSchema = makeJsonSchemaFromZod(z.string());
/**
* The input props that can be specified under `ui:options` for the
* `RepoUrlPicker` field extension.
*
* @public
*/
export type RepoUrlPickerUiOptions = typeof RepoUrlPickerUiOptionsSchema.type;
export type RepoUrlPickerUiOptions =
typeof RepoUrlPickerFieldSchema.uiOptionsType;
export type RepoUrlPickerReturnValue =
typeof RepoUrlPickerReturnValueSchema.type;
export type RepoUrlPickerProps = typeof RepoUrlPickerFieldSchema.type;
// NOTE: There is a bug with this failing validation in the custom field explorer due
// to https://github.com/rjsf-team/react-jsonschema-form/issues/675 even if
// requestUserCredentials is not defined
export const RepoUrlPickerSchema = {
uiOptions: RepoUrlPickerUiOptionsSchema.schema,
returnValue: RepoUrlPickerReturnValueSchema.schema,
};
export const RepoUrlPickerSchema = RepoUrlPickerFieldSchema.schema;
@@ -18,4 +18,4 @@ export * from './OwnerPicker';
export * from './RepoUrlPicker';
export * from './OwnedEntityPicker';
export * from './EntityTagsPicker';
export { makeJsonSchemaFromZod } from './utils';
export { type FieldSchema, makeFieldSchemaFromZod } from './utils';
@@ -16,20 +16,47 @@
import { JSONSchema7 } from 'json-schema';
import { z } from 'zod';
import zodToJsonSchema from 'zod-to-json-schema';
import {
CustomFieldExtensionSchema,
FieldExtensionComponentProps,
} from '../../extensions';
/**
* @public
* Utility function to convert zod schemas to JSON schemas with
* type inference extraction that abstracts away zod typings
* FieldSchema encapsulates a JSONSchema7 along with the
* matching FieldExtensionComponentProps type for a field extension.
*/
export function makeJsonSchemaFromZod<T extends z.ZodType>(
schema: T,
): {
schema: JSONSchema7;
type: T extends z.ZodType<any, any, infer I> ? I : never;
} {
export interface FieldSchema<TReturn, TUiOptions> {
readonly schema: CustomFieldExtensionSchema;
readonly type: FieldExtensionComponentProps<TReturn, TUiOptions>;
readonly uiOptionsType: TUiOptions;
}
/**
* @public
* Utility function to convert zod return and UI options schemas to a
* CustomFieldExtensionSchema with FieldExtensionComponentProps type inference
*/
export function makeFieldSchemaFromZod<
TReturnSchema extends z.ZodType,
TUiOptionsSchema extends z.ZodType = z.ZodType<any, any, {}>,
>(
returnSchema: TReturnSchema,
uiOptionsSchema?: TUiOptionsSchema,
): FieldSchema<
TReturnSchema extends z.ZodType<any, any, infer IReturn> ? IReturn : never,
TUiOptionsSchema extends z.ZodType<any, any, infer IUiOptions>
? IUiOptions
: never
> {
return {
schema: zodToJsonSchema(schema) as JSONSchema7,
schema: {
returnValue: zodToJsonSchema(returnSchema) as JSONSchema7,
uiOptions: uiOptionsSchema
? (zodToJsonSchema(uiOptionsSchema) as JSONSchema7)
: undefined,
},
type: null as any,
uiOptionsType: null as any,
};
}
+1 -1
View File
@@ -41,8 +41,8 @@ export type CustomFieldValidator<TFieldReturnValue> = (
* @public
*/
export type CustomFieldExtensionSchema = {
returnValue: JSONSchema7;
uiOptions?: JSONSchema7;
returnValue?: JSONSchema7;
};
/**