frontend-plugin-api: widen config schema constraint to accept Standard Schema
Widens the TConfigSchema generic constraint in createExtension, createExtensionBlueprint, and their override/makeWithOverrides methods to accept both the existing zod factory form and direct Standard Schema instances via the new ConfigFieldSchema union type. Existing consumers are unaffected — the factory form continues to infer concrete types through z.infer<ReturnType<...>>. Direct Standard Schema values are accepted but infer as any in the current iteration. Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Made-with: Cursor
This commit is contained in:
@@ -14,7 +14,8 @@ import { FilterPredicate } from '@backstage/filter-predicates';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { JSX as JSX_2 } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
import type { z } from 'zod/v3';
|
||||
import { z } from 'zod/v3';
|
||||
import { ZodType } from 'zod/v3';
|
||||
|
||||
// @public
|
||||
export type AnyRouteRefParams =
|
||||
@@ -160,10 +161,11 @@ export interface ExtensionBlueprint<
|
||||
inputs: T['inputs'];
|
||||
params: T['params'];
|
||||
}>;
|
||||
// Warning: (ae-forgotten-export) The symbol "ConfigFieldSchema" needs to be exported by the entry point alpha.d.ts
|
||||
makeWithOverrides<
|
||||
TName extends string | undefined,
|
||||
TExtensionConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
[key in string]: ConfigFieldSchema;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UNewOutput extends ExtensionDataRef,
|
||||
@@ -212,7 +214,7 @@ export interface ExtensionBlueprint<
|
||||
apis: ApiHolder;
|
||||
config: T['config'] & {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
|
||||
@@ -230,7 +232,9 @@ export interface ExtensionBlueprint<
|
||||
? {}
|
||||
: {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
ReturnType<
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
>
|
||||
>;
|
||||
}) &
|
||||
T['config']
|
||||
@@ -241,7 +245,7 @@ export interface ExtensionBlueprint<
|
||||
: z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TExtensionConfigSchema]: ReturnType<
|
||||
TExtensionConfigSchema[key]
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>) &
|
||||
@@ -473,7 +477,7 @@ export interface OverridableExtensionDefinition<
|
||||
// (undocumented)
|
||||
override<
|
||||
TExtensionConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
[key in string]: ConfigFieldSchema;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UNewOutput extends ExtensionDataRef,
|
||||
@@ -531,7 +535,9 @@ export interface OverridableExtensionDefinition<
|
||||
apis: ApiHolder;
|
||||
config: T['config'] & {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
ReturnType<
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
|
||||
@@ -560,14 +566,14 @@ export interface OverridableExtensionDefinition<
|
||||
inputs: T['inputs'] & TExtraInputs;
|
||||
config: T['config'] & {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
configInput: T['configInput'] &
|
||||
z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TExtensionConfigSchema]: ReturnType<
|
||||
TExtensionConfigSchema[key]
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>;
|
||||
|
||||
@@ -23,7 +23,8 @@ import { Observable } from '@backstage/types';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
import { SwappableComponentRef as SwappableComponentRef_2 } from '@backstage/frontend-plugin-api';
|
||||
import type { z } from 'zod/v3';
|
||||
import { z } from 'zod/v3';
|
||||
import { ZodType } from 'zod/v3';
|
||||
|
||||
// @public @deprecated
|
||||
export type AlertApi = {
|
||||
@@ -388,6 +389,16 @@ export const configApiRef: ApiRef_2<Config, 'core.config'> & {
|
||||
readonly $$type: '@backstage/ApiRef';
|
||||
};
|
||||
|
||||
// @public
|
||||
export type ConfigFieldSchema =
|
||||
| StandardSchemaV1
|
||||
| ((zImpl: typeof z) => ZodType);
|
||||
|
||||
// @public
|
||||
export type ConfigSchemaRecord = {
|
||||
[key: string]: ConfigFieldSchema;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export interface ConfigurableExtensionDataRef<
|
||||
TData,
|
||||
@@ -464,7 +475,7 @@ export function createExtension<
|
||||
[inputName in string]: ExtensionInput;
|
||||
},
|
||||
TConfigSchema extends {
|
||||
[key: string]: (zImpl: typeof z) => z.ZodType;
|
||||
[key: string]: ConfigFieldSchema;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
const TKind extends string | undefined = undefined,
|
||||
@@ -484,13 +495,17 @@ export function createExtension<
|
||||
config: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: {
|
||||
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
configInput: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
|
||||
[key in keyof TConfigSchema]: ReturnType<
|
||||
((...args: any[]) => any) & TConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>;
|
||||
output: UOutput extends ExtensionDataRef<
|
||||
@@ -514,7 +529,7 @@ export function createExtensionBlueprint<
|
||||
[inputName in string]: ExtensionInput;
|
||||
},
|
||||
TConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
[key in string]: ConfigFieldSchema;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
TKind extends string,
|
||||
@@ -547,13 +562,17 @@ export function createExtensionBlueprint<
|
||||
config: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: {
|
||||
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
configInput: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
|
||||
[key in keyof TConfigSchema]: ReturnType<
|
||||
((...args: any[]) => any) & TConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>;
|
||||
dataRefs: TDataRefs;
|
||||
@@ -568,7 +587,7 @@ export type CreateExtensionBlueprintOptions<
|
||||
[inputName in string]: ExtensionInput;
|
||||
},
|
||||
TConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
[key in string]: ConfigFieldSchema;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
TDataRefs extends {
|
||||
@@ -597,7 +616,9 @@ export type CreateExtensionBlueprintOptions<
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
@@ -657,7 +678,7 @@ export type CreateExtensionOptions<
|
||||
[inputName in string]: ExtensionInput;
|
||||
},
|
||||
TConfigSchema extends {
|
||||
[key: string]: (zImpl: typeof z) => z.ZodType;
|
||||
[key: string]: ConfigFieldSchema;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
@@ -677,7 +698,9 @@ export type CreateExtensionOptions<
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
}): Iterable<UFactoryOutput>;
|
||||
@@ -1042,7 +1065,7 @@ export interface ExtensionBlueprint<
|
||||
makeWithOverrides<
|
||||
TName extends string | undefined,
|
||||
TExtensionConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
[key in string]: ConfigFieldSchema;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UNewOutput extends ExtensionDataRef,
|
||||
@@ -1091,7 +1114,7 @@ export interface ExtensionBlueprint<
|
||||
apis: ApiHolder;
|
||||
config: T['config'] & {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
|
||||
@@ -1109,7 +1132,9 @@ export interface ExtensionBlueprint<
|
||||
? {}
|
||||
: {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
ReturnType<
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
>
|
||||
>;
|
||||
}) &
|
||||
T['config']
|
||||
@@ -1120,7 +1145,7 @@ export interface ExtensionBlueprint<
|
||||
: z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TExtensionConfigSchema]: ReturnType<
|
||||
TExtensionConfigSchema[key]
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>) &
|
||||
@@ -1682,7 +1707,7 @@ export interface OverridableExtensionDefinition<
|
||||
// (undocumented)
|
||||
override<
|
||||
TExtensionConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
[key in string]: ConfigFieldSchema;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UNewOutput extends ExtensionDataRef,
|
||||
@@ -1740,7 +1765,9 @@ export interface OverridableExtensionDefinition<
|
||||
apis: ApiHolder;
|
||||
config: T['config'] & {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
ReturnType<
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
|
||||
@@ -1769,14 +1796,14 @@ export interface OverridableExtensionDefinition<
|
||||
inputs: T['inputs'] & TExtraInputs;
|
||||
config: T['config'] & {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
configInput: T['configInput'] &
|
||||
z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TExtensionConfigSchema]: ReturnType<
|
||||
TExtensionConfigSchema[key]
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>;
|
||||
@@ -2119,6 +2146,76 @@ export namespace SessionState {
|
||||
export type SignedOut = typeof SessionState.SignedOut;
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface StandardSchemaV1<Input = unknown, Output = Input> {
|
||||
// (undocumented)
|
||||
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export namespace StandardSchemaV1 {
|
||||
// (undocumented)
|
||||
export interface FailureResult {
|
||||
// (undocumented)
|
||||
readonly issues: ReadonlyArray<Issue>;
|
||||
}
|
||||
// (undocumented)
|
||||
export type InferInput<Schema extends StandardSchemaV1> = NonNullable<
|
||||
Schema['~standard']['types']
|
||||
>['input'];
|
||||
// (undocumented)
|
||||
export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<
|
||||
Schema['~standard']['types']
|
||||
>['output'];
|
||||
// (undocumented)
|
||||
export interface Issue {
|
||||
// (undocumented)
|
||||
readonly message: string;
|
||||
// (undocumented)
|
||||
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
||||
}
|
||||
// (undocumented)
|
||||
export interface Options {
|
||||
// (undocumented)
|
||||
readonly libraryOptions?: Record<string, unknown> | undefined;
|
||||
}
|
||||
// (undocumented)
|
||||
export interface PathSegment {
|
||||
// (undocumented)
|
||||
readonly key: PropertyKey;
|
||||
}
|
||||
// (undocumented)
|
||||
export interface Props<Input = unknown, Output = Input> {
|
||||
// (undocumented)
|
||||
readonly types?: Types<Input, Output> | undefined;
|
||||
// (undocumented)
|
||||
readonly validate: (
|
||||
value: unknown,
|
||||
options?: Options | undefined,
|
||||
) => Result<Output> | Promise<Result<Output>>;
|
||||
// (undocumented)
|
||||
readonly vendor: string;
|
||||
// (undocumented)
|
||||
readonly version: 1;
|
||||
}
|
||||
// (undocumented)
|
||||
export type Result<Output> = SuccessResult<Output> | FailureResult;
|
||||
// (undocumented)
|
||||
export interface SuccessResult<Output> {
|
||||
// (undocumented)
|
||||
readonly issues?: undefined;
|
||||
// (undocumented)
|
||||
readonly value: Output;
|
||||
}
|
||||
// (undocumented)
|
||||
export interface Types<Input = unknown, Output = Input> {
|
||||
// (undocumented)
|
||||
readonly input: Input;
|
||||
// (undocumented)
|
||||
readonly output: Output;
|
||||
}
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface StorageApi {
|
||||
forBucket(name: string): StorageApi;
|
||||
|
||||
@@ -44,13 +44,19 @@ import { PortableSchema } from './types';
|
||||
// See: https://github.com/standard-schema/standard-schema
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** The Standard Schema interface. */
|
||||
interface StandardSchemaV1<Input = unknown, Output = Input> {
|
||||
/**
|
||||
* The Standard Schema interface.
|
||||
* @public
|
||||
*/
|
||||
export interface StandardSchemaV1<Input = unknown, Output = Input> {
|
||||
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace StandardSchemaV1 {
|
||||
export namespace StandardSchemaV1 {
|
||||
export interface Props<Input = unknown, Output = Input> {
|
||||
readonly version: 1;
|
||||
readonly vendor: string;
|
||||
@@ -106,38 +112,82 @@ namespace StandardSchemaV1 {
|
||||
/**
|
||||
* A single config field schema. Accepts any Standard Schema implementation,
|
||||
* or the legacy factory form for backward compat and zod-based composition.
|
||||
* @public
|
||||
*/
|
||||
type ConfigFieldSchema = StandardSchemaV1 | ((zImpl: typeof zodV3) => ZodType);
|
||||
export type ConfigFieldSchema =
|
||||
| StandardSchemaV1
|
||||
| ((zImpl: typeof zodV3) => ZodType);
|
||||
|
||||
/** A record of per-field config schemas. */
|
||||
type ConfigSchemaRecord = { [key: string]: ConfigFieldSchema };
|
||||
|
||||
/** Resolves a field entry to its StandardSchemaV1 form for type inference. */
|
||||
type ResolveField<T extends ConfigFieldSchema> = T extends (
|
||||
...args: any[]
|
||||
) => infer R
|
||||
? R extends StandardSchemaV1
|
||||
? R
|
||||
: never
|
||||
: T extends StandardSchemaV1
|
||||
? T
|
||||
: never;
|
||||
/**
|
||||
* A record of per-field config schemas.
|
||||
* @public
|
||||
*/
|
||||
export type ConfigSchemaRecord = { [key: string]: ConfigFieldSchema };
|
||||
|
||||
/**
|
||||
* Infers the parsed output type of a config schema record.
|
||||
* Replaces: `{ [key in keyof T]: z.infer<ReturnType<T[key]>> }`
|
||||
*
|
||||
* Split into two mapped types joined by intersection to avoid conditional
|
||||
* types in the value position, which TypeScript defers in declaration emit.
|
||||
* Factory-form fields use `ReturnType<...>['_output']` (eagerly evaluated),
|
||||
* Standard Schema fields use `['~standard']['types']['output']`.
|
||||
* @ignore
|
||||
*/
|
||||
type InferConfigOutput<T extends ConfigSchemaRecord> = {
|
||||
[K in keyof T]: StandardSchemaV1.InferOutput<ResolveField<T[K]>>;
|
||||
[K in keyof T as T[K] extends (...args: any[]) => any
|
||||
? K
|
||||
: never]: ReturnType<T[K] & ((...args: any[]) => any)>['_output'];
|
||||
} & {
|
||||
[K in keyof T as T[K] extends (...args: any[]) => any
|
||||
? never
|
||||
: K]: NonNullable<
|
||||
(T[K] & StandardSchemaV1)['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
|
||||
/**
|
||||
* Infers the raw input type (before defaults/transforms) of a config
|
||||
* schema record.
|
||||
* Replaces: `z.input<z.ZodObject<{ ... }>>`
|
||||
*
|
||||
* Fields whose input type includes `undefined` are made optional keys,
|
||||
* matching the behavior of `z.input<z.ZodObject<...>>` for ZodDefault
|
||||
* and ZodOptional fields.
|
||||
* @ignore
|
||||
*/
|
||||
type InferConfigInput<T extends ConfigSchemaRecord> = {
|
||||
[K in keyof T]: StandardSchemaV1.InferInput<ResolveField<T[K]>>;
|
||||
type InferConfigInput<T extends ConfigSchemaRecord> = _RequiredInput<T> &
|
||||
_OptionalInput<T>;
|
||||
|
||||
type _FactoryInput<T extends (...args: any[]) => any> = ReturnType<T>['_input'];
|
||||
type _SchemaInput<T extends StandardSchemaV1> = NonNullable<
|
||||
T['~standard']['types']
|
||||
>['input'];
|
||||
|
||||
/** @ignore */
|
||||
type _RequiredInput<T extends ConfigSchemaRecord> = {
|
||||
[K in keyof T as T[K] extends (...args: any[]) => any
|
||||
? undefined extends _FactoryInput<T[K] & ((...args: any[]) => any)>
|
||||
? never
|
||||
: K
|
||||
: undefined extends _SchemaInput<T[K] & StandardSchemaV1>
|
||||
? never
|
||||
: K]: T[K] extends (...args: any[]) => any
|
||||
? _FactoryInput<T[K] & ((...args: any[]) => any)>
|
||||
: _SchemaInput<T[K] & StandardSchemaV1>;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
type _OptionalInput<T extends ConfigSchemaRecord> = {
|
||||
[K in keyof T as T[K] extends (...args: any[]) => any
|
||||
? undefined extends _FactoryInput<T[K] & ((...args: any[]) => any)>
|
||||
? K
|
||||
: never
|
||||
: undefined extends _SchemaInput<T[K] & StandardSchemaV1>
|
||||
? K
|
||||
: never]?: T[K] extends (...args: any[]) => any
|
||||
? _FactoryInput<T[K] & ((...args: any[]) => any)>
|
||||
: _SchemaInput<T[K] & StandardSchemaV1>;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -161,7 +211,7 @@ interface FieldValidator {
|
||||
* public PortableSchema surface. The brand field is used to detect whether
|
||||
* a PortableSchema came from this utility (and thus supports merging).
|
||||
*/
|
||||
interface MergeablePortableSchema<TOutput = any, TInput = any>
|
||||
export interface MergeablePortableSchema<TOutput = any, TInput = any>
|
||||
extends PortableSchema<TOutput, TInput> {
|
||||
/** @internal */
|
||||
readonly _fields: Record<string, FieldValidator>;
|
||||
@@ -171,7 +221,7 @@ interface MergeablePortableSchema<TOutput = any, TInput = any>
|
||||
// createPortableSchema — builds from a field record
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function createPortableSchema<T extends ConfigSchemaRecord>(
|
||||
export function createPortableSchema<T extends ConfigSchemaRecord>(
|
||||
fields: T,
|
||||
): MergeablePortableSchema<InferConfigOutput<T>, InferConfigInput<T>> {
|
||||
const fieldValidators: Record<string, FieldValidator> = {};
|
||||
@@ -193,7 +243,7 @@ function createPortableSchema<T extends ConfigSchemaRecord>(
|
||||
// no need to mix schema types within a single validator.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function mergePortableSchemas<A, B>(
|
||||
export function mergePortableSchemas<A, B>(
|
||||
a: MergeablePortableSchema<A> | undefined,
|
||||
b: MergeablePortableSchema<B> | undefined,
|
||||
): MergeablePortableSchema<A & B> | undefined {
|
||||
@@ -437,18 +487,3 @@ function formatStandardIssue(
|
||||
: fieldKey;
|
||||
return `${message} at '${path}'`;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Exports
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
createPortableSchema,
|
||||
mergePortableSchemas,
|
||||
type MergeablePortableSchema,
|
||||
type ConfigFieldSchema,
|
||||
type ConfigSchemaRecord,
|
||||
type InferConfigOutput,
|
||||
type InferConfigInput,
|
||||
type StandardSchemaV1,
|
||||
};
|
||||
|
||||
@@ -15,3 +15,8 @@
|
||||
*/
|
||||
|
||||
export { type PortableSchema } from './types';
|
||||
export {
|
||||
type StandardSchemaV1,
|
||||
type ConfigFieldSchema,
|
||||
type ConfigSchemaRecord,
|
||||
} from './createPortableSchema';
|
||||
|
||||
@@ -28,6 +28,7 @@ import { ExtensionDataRef, ExtensionDataValue } from './createExtensionDataRef';
|
||||
import { ExtensionInput } from './createExtensionInput';
|
||||
import type { z } from 'zod/v3';
|
||||
import { createSchemaFromZod } from '../schema/createSchemaFromZod';
|
||||
import type { ConfigFieldSchema } from '../schema/createPortableSchema';
|
||||
import { OpaqueExtensionDefinition } from '@internal/frontend';
|
||||
import { ExtensionDataContainer } from './types';
|
||||
import {
|
||||
@@ -166,7 +167,7 @@ export type CreateExtensionOptions<
|
||||
TName extends string | undefined,
|
||||
UOutput extends ExtensionDataRef,
|
||||
TInputs extends { [inputName in string]: ExtensionInput },
|
||||
TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },
|
||||
TConfigSchema extends { [key: string]: ConfigFieldSchema },
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
> = {
|
||||
@@ -185,7 +186,9 @@ export type CreateExtensionOptions<
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
}): Iterable<UFactoryOutput>;
|
||||
@@ -239,7 +242,7 @@ export interface OverridableExtensionDefinition<
|
||||
|
||||
override<
|
||||
TExtensionConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
[key in string]: ConfigFieldSchema;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UNewOutput extends ExtensionDataRef,
|
||||
@@ -295,7 +298,9 @@ export interface OverridableExtensionDefinition<
|
||||
apis: ApiHolder;
|
||||
config: T['config'] & {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
ReturnType<
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
|
||||
@@ -324,14 +329,14 @@ export interface OverridableExtensionDefinition<
|
||||
inputs: T['inputs'] & TExtraInputs;
|
||||
config: T['config'] & {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
configInput: T['configInput'] &
|
||||
z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TExtensionConfigSchema]: ReturnType<
|
||||
TExtensionConfigSchema[key]
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>;
|
||||
@@ -400,7 +405,7 @@ function bindInputs(
|
||||
export function createExtension<
|
||||
UOutput extends ExtensionDataRef,
|
||||
TInputs extends { [inputName in string]: ExtensionInput },
|
||||
TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },
|
||||
TConfigSchema extends { [key: string]: ConfigFieldSchema },
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
const TKind extends string | undefined = undefined,
|
||||
const TName extends string | undefined = undefined,
|
||||
@@ -419,16 +424,19 @@ export function createExtension<
|
||||
config: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: {
|
||||
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
configInput: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
|
||||
[key in keyof TConfigSchema]: ReturnType<
|
||||
((...args: any[]) => any) & TConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>;
|
||||
// This inference and remapping back to ExtensionDataRef eliminates any occurrences ConfigurationExtensionDataRef
|
||||
output: UOutput extends ExtensionDataRef<
|
||||
infer IData,
|
||||
infer IId,
|
||||
@@ -447,8 +455,11 @@ export function createExtension<
|
||||
createSchemaFromZod(innerZ =>
|
||||
innerZ.object(
|
||||
Object.fromEntries(
|
||||
Object.entries(schemaDeclaration).map(([k, v]) => [k, v(innerZ)]),
|
||||
),
|
||||
Object.entries(schemaDeclaration).map(([k, v]) => [
|
||||
k,
|
||||
typeof v === 'function' ? v(innerZ) : v,
|
||||
]),
|
||||
) as Record<string, z.ZodTypeAny>,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -458,14 +469,16 @@ export function createExtension<
|
||||
? {}
|
||||
: {
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<TConfigSchema[key]>
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
configInput: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
|
||||
[key in keyof TConfigSchema]: ReturnType<
|
||||
((...args: any[]) => any) & TConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>;
|
||||
output: UOutput;
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
} from './createExtension';
|
||||
import type { z } from 'zod/v3';
|
||||
import { ExtensionInput } from './createExtensionInput';
|
||||
import type { ConfigFieldSchema } from '../schema/createPortableSchema';
|
||||
import { ExtensionDataRef, ExtensionDataValue } from './createExtensionDataRef';
|
||||
import { createExtensionDataContainer } from '@internal/frontend';
|
||||
import {
|
||||
@@ -106,7 +107,7 @@ export type CreateExtensionBlueprintOptions<
|
||||
TParams extends object | ExtensionBlueprintDefineParams,
|
||||
UOutput extends ExtensionDataRef,
|
||||
TInputs extends { [inputName in string]: ExtensionInput },
|
||||
TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },
|
||||
TConfigSchema extends { [key in string]: ConfigFieldSchema },
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
TDataRefs extends { [name in string]: ExtensionDataRef },
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
@@ -170,7 +171,9 @@ export type CreateExtensionBlueprintOptions<
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
@@ -248,7 +251,7 @@ export interface ExtensionBlueprint<
|
||||
makeWithOverrides<
|
||||
TName extends string | undefined,
|
||||
TExtensionConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
[key in string]: ConfigFieldSchema;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UNewOutput extends ExtensionDataRef,
|
||||
@@ -295,7 +298,7 @@ export interface ExtensionBlueprint<
|
||||
apis: ApiHolder;
|
||||
config: T['config'] & {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
|
||||
@@ -313,7 +316,9 @@ export interface ExtensionBlueprint<
|
||||
? {}
|
||||
: {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
ReturnType<
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
>
|
||||
>;
|
||||
}) &
|
||||
T['config']
|
||||
@@ -324,7 +329,7 @@ export interface ExtensionBlueprint<
|
||||
: z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TExtensionConfigSchema]: ReturnType<
|
||||
TExtensionConfigSchema[key]
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>) &
|
||||
@@ -461,7 +466,7 @@ export function createExtensionBlueprint<
|
||||
TParams extends object | ExtensionBlueprintDefineParams,
|
||||
UOutput extends ExtensionDataRef,
|
||||
TInputs extends { [inputName in string]: ExtensionInput },
|
||||
TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },
|
||||
TConfigSchema extends { [key in string]: ConfigFieldSchema },
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
TKind extends string,
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
@@ -491,12 +496,18 @@ export function createExtensionBlueprint<
|
||||
inputs: string extends keyof TInputs ? {} : TInputs;
|
||||
config: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: { [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>> };
|
||||
: {
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
configInput: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
|
||||
[key in keyof TConfigSchema]: ReturnType<
|
||||
((...args: any[]) => any) & TConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>;
|
||||
dataRefs: TDataRefs;
|
||||
@@ -592,13 +603,17 @@ export function createExtensionBlueprint<
|
||||
config: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: {
|
||||
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
configInput: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
|
||||
[key in keyof TConfigSchema]: ReturnType<
|
||||
((...args: any[]) => any) & TConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>;
|
||||
dataRefs: TDataRefs;
|
||||
|
||||
Reference in New Issue
Block a user