frontend-plugin-api: add configSchema option and deprecate config.schema
Introduce a new top-level `configSchema` option for `createExtension`, `createExtensionBlueprint`, `override`, and `makeWithOverrides` that accepts Standard Schema values directly. The old `config.schema` form is deprecated via function/method overloads so that the entire call site gets editor strikethrough when matched. Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Made-with: Cursor Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Made-with: Cursor
This commit is contained in:
@@ -22,11 +22,11 @@ const examplePlugin: OverridableFrontendPlugin<
|
||||
'page:example': OverridableExtensionDefinition<{
|
||||
kind: 'page';
|
||||
name: undefined;
|
||||
config: {
|
||||
config: {} & {
|
||||
path: string | undefined;
|
||||
title: string | undefined;
|
||||
};
|
||||
configInput: {
|
||||
configInput: {} & {
|
||||
title?: string | undefined;
|
||||
path?: string | undefined;
|
||||
};
|
||||
|
||||
@@ -87,9 +87,10 @@ export interface AppTree {
|
||||
}
|
||||
|
||||
// @public
|
||||
export type ConfigFieldSchema =
|
||||
| StandardSchemaV1
|
||||
| ((zImpl: typeof z) => ZodType);
|
||||
export type ConfigFieldSchema = StandardSchemaV1 | ConfigFieldSchemaFactory;
|
||||
|
||||
// @public @deprecated
|
||||
export type ConfigFieldSchemaFactory = (zImpl: typeof z) => ZodType;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface ConfigurableExtensionDataRef<
|
||||
@@ -178,6 +179,9 @@ export interface ExtensionBlueprint<
|
||||
TExtraInputs extends {
|
||||
[inputName in string]: ExtensionInput;
|
||||
} = {},
|
||||
TNewExtensionConfigSchema extends {
|
||||
[key in string]: StandardSchemaV1;
|
||||
} = {},
|
||||
>(args: {
|
||||
name?: TName;
|
||||
attachTo?: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
@@ -194,6 +198,10 @@ export interface ExtensionBlueprint<
|
||||
string}' is already defined in parent definition`;
|
||||
};
|
||||
output?: Array<UNewOutput>;
|
||||
configSchema?: TNewExtensionConfigSchema & {
|
||||
[KName in keyof T['config']]?: `Error: Config key '${KName &
|
||||
string}' is already defined in parent schema`;
|
||||
};
|
||||
config?: {
|
||||
schema: TExtensionConfigSchema & {
|
||||
[KName in keyof T['config']]?: `Error: Config key '${KName &
|
||||
@@ -218,6 +226,10 @@ export interface ExtensionBlueprint<
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: T['config'] & {
|
||||
[key in keyof TNewExtensionConfigSchema]: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
} & {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>
|
||||
>;
|
||||
@@ -233,7 +245,11 @@ export interface ExtensionBlueprint<
|
||||
>;
|
||||
}): OverridableExtensionDefinition<{
|
||||
config: Expand<
|
||||
(string extends keyof TExtensionConfigSchema
|
||||
{
|
||||
[key in keyof TNewExtensionConfigSchema]: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
} & (string extends keyof TExtensionConfigSchema
|
||||
? {}
|
||||
: {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
@@ -245,7 +261,11 @@ export interface ExtensionBlueprint<
|
||||
T['config']
|
||||
>;
|
||||
configInput: Expand<
|
||||
(string extends keyof TExtensionConfigSchema
|
||||
{
|
||||
[key in keyof TNewExtensionConfigSchema]?: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['input'];
|
||||
} & (string extends keyof TExtensionConfigSchema
|
||||
? {}
|
||||
: z.input<
|
||||
z.ZodObject<{
|
||||
@@ -491,6 +511,9 @@ export interface OverridableExtensionDefinition<
|
||||
},
|
||||
TParamsInput extends AnyParamsInput_2<NonNullable<T['params']>>,
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
TNewExtensionConfigSchema extends {
|
||||
[key in string]: StandardSchemaV1;
|
||||
} = {},
|
||||
>(
|
||||
args: Expand<
|
||||
{
|
||||
@@ -508,6 +531,10 @@ export interface OverridableExtensionDefinition<
|
||||
string}' is already defined in parent definition`;
|
||||
};
|
||||
output?: Array<UNewOutput>;
|
||||
configSchema?: TNewExtensionConfigSchema & {
|
||||
[KName in keyof T['config']]?: `Error: Config key '${KName &
|
||||
string}' is already defined in parent schema`;
|
||||
};
|
||||
config?: {
|
||||
schema: TExtensionConfigSchema & {
|
||||
[KName in keyof T['config']]?: `Error: Config key '${KName &
|
||||
@@ -539,6 +566,10 @@ export interface OverridableExtensionDefinition<
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: T['config'] & {
|
||||
[key in keyof TNewExtensionConfigSchema]: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
} & {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
@@ -570,12 +601,19 @@ export interface OverridableExtensionDefinition<
|
||||
output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
|
||||
inputs: T['inputs'] & TExtraInputs;
|
||||
config: T['config'] & {
|
||||
[key in keyof TNewExtensionConfigSchema]: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
} & {
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TExtensionConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
configInput: T['configInput'] &
|
||||
z.input<
|
||||
configInput: T['configInput'] & {
|
||||
[key in keyof TNewExtensionConfigSchema]?: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['input'];
|
||||
} & z.input<
|
||||
z.ZodObject<{
|
||||
[key in keyof TExtensionConfigSchema]: ReturnType<
|
||||
((...args: any[]) => any) & TExtensionConfigSchema[key]
|
||||
@@ -669,5 +707,8 @@ export interface SubRouteRef<
|
||||
readonly T: TParams;
|
||||
}
|
||||
|
||||
// @public @deprecated
|
||||
export function zodField<T extends ZodType>(factory: (zImpl: typeof z) => T): T;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
|
||||
@@ -469,7 +469,69 @@ export function createApiRef<T>(): {
|
||||
};
|
||||
};
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "VerifyExtensionFactoryOutput" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// @public
|
||||
export function createExtension<
|
||||
UOutput extends ExtensionDataRef,
|
||||
TInputs extends {
|
||||
[inputName in string]: ExtensionInput;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
const TKind extends string | undefined = undefined,
|
||||
const TName extends string | undefined = undefined,
|
||||
UParentInputs extends ExtensionDataRef = ExtensionDataRef,
|
||||
TNewConfigSchema extends {
|
||||
[key: string]: StandardSchemaV1;
|
||||
} = {},
|
||||
>(
|
||||
options: {
|
||||
kind?: TKind;
|
||||
name?: TName;
|
||||
attachTo: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
VerifyExtensionAttachTo<UOutput, UParentInputs>;
|
||||
disabled?: boolean;
|
||||
if?: FilterPredicate;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
config?: never;
|
||||
configSchema?: TNewConfigSchema;
|
||||
factory(context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TNewConfigSchema]: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
}): Iterable<UFactoryOutput>;
|
||||
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>,
|
||||
): OverridableExtensionDefinition<{
|
||||
config: {
|
||||
[key in keyof TNewConfigSchema]: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
configInput: {
|
||||
[key in keyof TNewConfigSchema]?: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['input'];
|
||||
};
|
||||
output: UOutput extends ExtensionDataRef<
|
||||
infer IData,
|
||||
infer IId,
|
||||
infer IConfig
|
||||
>
|
||||
? ExtensionDataRef<IData, IId, IConfig>
|
||||
: never;
|
||||
inputs: TInputs;
|
||||
params: never;
|
||||
kind: string | undefined extends TKind ? undefined : TKind;
|
||||
name: string | undefined extends TName ? undefined : TName;
|
||||
}>;
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export function createExtension<
|
||||
UOutput extends ExtensionDataRef,
|
||||
TInputs extends {
|
||||
@@ -483,15 +545,30 @@ export function createExtension<
|
||||
const TName extends string | undefined = undefined,
|
||||
UParentInputs extends ExtensionDataRef = ExtensionDataRef,
|
||||
>(
|
||||
options: CreateExtensionOptions<
|
||||
TKind,
|
||||
TName,
|
||||
UOutput,
|
||||
TInputs,
|
||||
TConfigSchema,
|
||||
UFactoryOutput,
|
||||
UParentInputs
|
||||
>,
|
||||
options: {
|
||||
kind?: TKind;
|
||||
name?: TName;
|
||||
attachTo: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
VerifyExtensionAttachTo<UOutput, UParentInputs>;
|
||||
disabled?: boolean;
|
||||
if?: FilterPredicate;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
configSchema?: never;
|
||||
config?: {
|
||||
schema: TConfigSchema;
|
||||
};
|
||||
factory(context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
}): Iterable<UFactoryOutput>;
|
||||
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>,
|
||||
): OverridableExtensionDefinition<{
|
||||
config: string extends keyof TConfigSchema
|
||||
? {}
|
||||
@@ -522,7 +599,80 @@ export function createExtension<
|
||||
name: string | undefined extends TName ? undefined : TName;
|
||||
}>;
|
||||
|
||||
// Warning: (ae-unresolved-link) The @link reference could not be resolved: The reference is ambiguous because "createExtension" has more than one declaration; you need to add a TSDoc member reference selector
|
||||
//
|
||||
// @public
|
||||
export function createExtensionBlueprint<
|
||||
TParams extends object | ExtensionBlueprintDefineParams,
|
||||
UOutput extends ExtensionDataRef,
|
||||
TInputs extends {
|
||||
[inputName in string]: ExtensionInput;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
TKind extends string,
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
TDataRefs extends {
|
||||
[name in string]: ExtensionDataRef;
|
||||
} = never,
|
||||
TNewConfigSchema extends {
|
||||
[key in string]: StandardSchemaV1;
|
||||
} = {},
|
||||
>(
|
||||
options: {
|
||||
kind: TKind;
|
||||
attachTo: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
VerifyExtensionAttachTo<UOutput, UParentInputs>;
|
||||
disabled?: boolean;
|
||||
if?: FilterPredicate;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
config?: never;
|
||||
configSchema?: TNewConfigSchema;
|
||||
defineParams?: TParams extends ExtensionBlueprintDefineParams
|
||||
? TParams
|
||||
: 'The defineParams option must be a function if provided, see the docs for details';
|
||||
factory(
|
||||
params: TParams extends ExtensionBlueprintDefineParams
|
||||
? ReturnType<TParams>['T']
|
||||
: TParams,
|
||||
context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TNewConfigSchema]: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
): Iterable<UFactoryOutput>;
|
||||
dataRefs?: TDataRefs;
|
||||
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>,
|
||||
): ExtensionBlueprint<{
|
||||
kind: TKind;
|
||||
params: TParams;
|
||||
output: UOutput extends ExtensionDataRef<
|
||||
infer IData,
|
||||
infer IId,
|
||||
infer IConfig
|
||||
>
|
||||
? ExtensionDataRef<IData, IId, IConfig>
|
||||
: never;
|
||||
inputs: string extends keyof TInputs ? {} : TInputs;
|
||||
config: {
|
||||
[key in keyof TNewConfigSchema]: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
configInput: {
|
||||
[key in keyof TNewConfigSchema]?: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['input'];
|
||||
};
|
||||
dataRefs: TDataRefs;
|
||||
}>;
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export function createExtensionBlueprint<
|
||||
TParams extends object | ExtensionBlueprintDefineParams,
|
||||
UOutput extends ExtensionDataRef,
|
||||
@@ -539,16 +689,38 @@ export function createExtensionBlueprint<
|
||||
[name in string]: ExtensionDataRef;
|
||||
} = never,
|
||||
>(
|
||||
options: CreateExtensionBlueprintOptions<
|
||||
TKind,
|
||||
TParams,
|
||||
UOutput,
|
||||
TInputs,
|
||||
TConfigSchema,
|
||||
UFactoryOutput,
|
||||
TDataRefs,
|
||||
UParentInputs
|
||||
>,
|
||||
options: {
|
||||
kind: TKind;
|
||||
attachTo: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
VerifyExtensionAttachTo<UOutput, UParentInputs>;
|
||||
disabled?: boolean;
|
||||
if?: FilterPredicate;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
configSchema?: never;
|
||||
config?: {
|
||||
schema: TConfigSchema;
|
||||
};
|
||||
defineParams?: TParams extends ExtensionBlueprintDefineParams
|
||||
? TParams
|
||||
: 'The defineParams option must be a function if provided, see the docs for details';
|
||||
factory(
|
||||
params: TParams extends ExtensionBlueprintDefineParams
|
||||
? ReturnType<TParams>['T']
|
||||
: TParams,
|
||||
context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
): Iterable<UFactoryOutput>;
|
||||
dataRefs?: TDataRefs;
|
||||
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>,
|
||||
): ExtensionBlueprint<{
|
||||
kind: TKind;
|
||||
params: TParams;
|
||||
@@ -595,6 +767,9 @@ export type CreateExtensionBlueprintOptions<
|
||||
[name in string]: ExtensionDataRef;
|
||||
},
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
TNewConfigSchema extends {
|
||||
[key in string]: StandardSchemaV1;
|
||||
} = {},
|
||||
> = {
|
||||
kind: TKind;
|
||||
attachTo: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
@@ -603,6 +778,7 @@ export type CreateExtensionBlueprintOptions<
|
||||
if?: FilterPredicate;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
configSchema?: TNewConfigSchema;
|
||||
config?: {
|
||||
schema: TConfigSchema;
|
||||
};
|
||||
@@ -617,6 +793,10 @@ export type CreateExtensionBlueprintOptions<
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TNewConfigSchema]: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
} & {
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
@@ -683,6 +863,9 @@ export type CreateExtensionOptions<
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
TNewConfigSchema extends {
|
||||
[key: string]: StandardSchemaV1;
|
||||
} = {},
|
||||
> = {
|
||||
kind?: TKind;
|
||||
name?: TName;
|
||||
@@ -692,6 +875,7 @@ export type CreateExtensionOptions<
|
||||
if?: FilterPredicate;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
configSchema?: TNewConfigSchema;
|
||||
config?: {
|
||||
schema: TConfigSchema;
|
||||
};
|
||||
@@ -699,6 +883,10 @@ export type CreateExtensionOptions<
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TNewConfigSchema]: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
} & {
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
@@ -1063,6 +1251,91 @@ export interface ExtensionBlueprint<
|
||||
inputs: T['inputs'];
|
||||
params: T['params'];
|
||||
}>;
|
||||
makeWithOverrides<
|
||||
TName extends string | undefined,
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UNewOutput extends ExtensionDataRef,
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
TExtraInputs extends {
|
||||
[inputName in string]: ExtensionInput;
|
||||
} = {},
|
||||
TNewExtensionConfigSchema extends {
|
||||
[key in string]: StandardSchemaV1;
|
||||
} = {},
|
||||
>(args: {
|
||||
name?: TName;
|
||||
attachTo?: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
VerifyExtensionAttachTo<
|
||||
ExtensionDataRef extends UNewOutput
|
||||
? NonNullable<T['output']>
|
||||
: UNewOutput,
|
||||
UParentInputs
|
||||
>;
|
||||
disabled?: boolean;
|
||||
if?: FilterPredicate;
|
||||
inputs?: TExtraInputs & {
|
||||
[KName in keyof T['inputs']]?: `Error: Input '${KName &
|
||||
string}' is already defined in parent definition`;
|
||||
};
|
||||
output?: Array<UNewOutput>;
|
||||
config?: never;
|
||||
configSchema?: TNewExtensionConfigSchema & {
|
||||
[KName in keyof T['config']]?: `Error: Config key '${KName &
|
||||
string}' is already defined in parent schema`;
|
||||
};
|
||||
factory(
|
||||
originalFactory: <
|
||||
TParamsInput extends AnyParamsInput_2<NonNullable<T['params']>>,
|
||||
>(
|
||||
params: TParamsInput extends ExtensionBlueprintDefineParams
|
||||
? TParamsInput
|
||||
: T['params'] extends ExtensionBlueprintDefineParams
|
||||
? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`'
|
||||
: T['params'],
|
||||
context?: {
|
||||
config?: T['config'];
|
||||
inputs?: ResolvedInputValueOverrides<NonNullable<T['inputs']>>;
|
||||
},
|
||||
) => ExtensionDataContainer<NonNullable<T['output']>>,
|
||||
context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: T['config'] & {
|
||||
[key in keyof TNewExtensionConfigSchema]: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
|
||||
},
|
||||
): Iterable<UFactoryOutput> &
|
||||
VerifyExtensionFactoryOutput<
|
||||
ExtensionDataRef extends UNewOutput
|
||||
? NonNullable<T['output']>
|
||||
: UNewOutput,
|
||||
UFactoryOutput
|
||||
>;
|
||||
}): OverridableExtensionDefinition<{
|
||||
config: Expand<
|
||||
{
|
||||
[key in keyof TNewExtensionConfigSchema]: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
} & T['config']
|
||||
>;
|
||||
configInput: Expand<
|
||||
{
|
||||
[key in keyof TNewExtensionConfigSchema]?: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['input'];
|
||||
} & T['configInput']
|
||||
>;
|
||||
output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
|
||||
inputs: Expand<T['inputs'] & TExtraInputs>;
|
||||
kind: T['kind'];
|
||||
name: string | undefined extends TName ? undefined : TName;
|
||||
params: T['params'];
|
||||
}>;
|
||||
// @deprecated (undocumented)
|
||||
makeWithOverrides<
|
||||
TName extends string | undefined,
|
||||
TExtensionConfigSchema extends {
|
||||
@@ -1090,6 +1363,7 @@ export interface ExtensionBlueprint<
|
||||
string}' is already defined in parent definition`;
|
||||
};
|
||||
output?: Array<UNewOutput>;
|
||||
configSchema?: never;
|
||||
config?: {
|
||||
schema: TExtensionConfigSchema & {
|
||||
[KName in keyof T['config']]?: `Error: Config key '${KName &
|
||||
@@ -1706,6 +1980,104 @@ export interface OverridableExtensionDefinition<
|
||||
>;
|
||||
};
|
||||
// (undocumented)
|
||||
override<
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UNewOutput extends ExtensionDataRef,
|
||||
TExtraInputs extends {
|
||||
[inputName in string]: ExtensionInput;
|
||||
},
|
||||
TParamsInput extends AnyParamsInput<NonNullable<T['params']>>,
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
TNewExtensionConfigSchema extends {
|
||||
[key in string]: StandardSchemaV1;
|
||||
} = {},
|
||||
>(
|
||||
args: Expand<
|
||||
{
|
||||
attachTo?: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
VerifyExtensionAttachTo<
|
||||
ExtensionDataRef extends UNewOutput
|
||||
? NonNullable<T['output']>
|
||||
: UNewOutput,
|
||||
UParentInputs
|
||||
>;
|
||||
disabled?: boolean;
|
||||
if?: FilterPredicate;
|
||||
inputs?: TExtraInputs & {
|
||||
[KName in keyof T['inputs']]?: `Error: Input '${KName &
|
||||
string}' is already defined in parent definition`;
|
||||
};
|
||||
output?: Array<UNewOutput>;
|
||||
config?: never;
|
||||
configSchema?: TNewExtensionConfigSchema & {
|
||||
[KName in keyof T['config']]?: `Error: Config key '${KName &
|
||||
string}' is already defined in parent schema`;
|
||||
};
|
||||
factory?(
|
||||
originalFactory: <
|
||||
TFactoryParamsReturn extends AnyParamsInput<
|
||||
NonNullable<T['params']>
|
||||
>,
|
||||
>(
|
||||
context?: Expand<
|
||||
{
|
||||
config?: T['config'];
|
||||
inputs?: ResolvedInputValueOverrides<NonNullable<T['inputs']>>;
|
||||
} & ([T['params']] extends [never]
|
||||
? {}
|
||||
: {
|
||||
params?: TFactoryParamsReturn extends ExtensionBlueprintDefineParams
|
||||
? TFactoryParamsReturn
|
||||
: T['params'] extends ExtensionBlueprintDefineParams
|
||||
? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`'
|
||||
: Partial<T['params']>;
|
||||
})
|
||||
>,
|
||||
) => ExtensionDataContainer<NonNullable<T['output']>>,
|
||||
context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: T['config'] & {
|
||||
[key in keyof TNewExtensionConfigSchema]: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
|
||||
},
|
||||
): Iterable<UFactoryOutput>;
|
||||
} & ([T['params']] extends [never]
|
||||
? {}
|
||||
: {
|
||||
params?: TParamsInput extends ExtensionBlueprintDefineParams
|
||||
? TParamsInput
|
||||
: T['params'] extends ExtensionBlueprintDefineParams
|
||||
? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`'
|
||||
: Partial<T['params']>;
|
||||
})
|
||||
> &
|
||||
VerifyExtensionFactoryOutput<
|
||||
ExtensionDataRef extends UNewOutput
|
||||
? NonNullable<T['output']>
|
||||
: UNewOutput,
|
||||
UFactoryOutput
|
||||
>,
|
||||
): OverridableExtensionDefinition<{
|
||||
kind: T['kind'];
|
||||
name: T['name'];
|
||||
output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
|
||||
inputs: T['inputs'] & TExtraInputs;
|
||||
config: T['config'] & {
|
||||
[key in keyof TNewExtensionConfigSchema]: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
configInput: T['configInput'] & {
|
||||
[key in keyof TNewExtensionConfigSchema]?: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['input'];
|
||||
};
|
||||
}>;
|
||||
// @deprecated (undocumented)
|
||||
override<
|
||||
TExtensionConfigSchema extends {
|
||||
[key in string]: ConfigFieldSchema;
|
||||
@@ -1734,6 +2106,7 @@ export interface OverridableExtensionDefinition<
|
||||
string}' is already defined in parent definition`;
|
||||
};
|
||||
output?: Array<UNewOutput>;
|
||||
configSchema?: never;
|
||||
config?: {
|
||||
schema: TExtensionConfigSchema & {
|
||||
[KName in keyof T['config']]?: `Error: Config key '${KName &
|
||||
@@ -2519,4 +2892,9 @@ export function withApis<T extends {}>(
|
||||
(props: PropsWithChildren<Omit<TProps, keyof T>>): JSX_3.Element;
|
||||
displayName: string;
|
||||
};
|
||||
|
||||
// Warnings were encountered during analysis:
|
||||
//
|
||||
// src/wiring/createExtension.d.ts:280:5 - (ae-forgotten-export) The symbol "VerifyExtensionAttachTo" needs to be exported by the entry point index.d.ts
|
||||
// src/wiring/createExtension.d.ts:293:9 - (ae-forgotten-export) The symbol "ResolvedExtensionInputs" needs to be exported by the entry point index.d.ts
|
||||
```
|
||||
|
||||
@@ -46,7 +46,7 @@ import { type StandardSchemaV1 } from '@standard-schema/spec';
|
||||
|
||||
/**
|
||||
* A single config field schema. Accepts any Standard Schema implementation,
|
||||
* or the legacy factory form for backward compat and zod-based composition.
|
||||
* or the legacy factory form for backward compat.
|
||||
* @public
|
||||
*/
|
||||
export type ConfigFieldSchema =
|
||||
@@ -422,3 +422,22 @@ function formatStandardIssue(
|
||||
: fieldKey;
|
||||
return `${message} at '${path}'`;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Deprecation warning
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
let hasWarnedConfigSchemaProp = false;
|
||||
|
||||
/** @internal */
|
||||
export function warnConfigSchemaPropDeprecation() {
|
||||
if (!hasWarnedConfigSchemaProp) {
|
||||
hasWarnedConfigSchemaProp = true;
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
'DEPRECATION WARNING: The `config.schema` option for extension config is deprecated. ' +
|
||||
'Use the `configSchema` option instead with Standard Schema values, for example ' +
|
||||
'`configSchema: { title: z.string() }` using zod v3.25+ or v4.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ import { ExtensionInput } from './createExtensionInput';
|
||||
import type { z } from 'zod/v3';
|
||||
import { createSchemaFromZod } from '../schema/createSchemaFromZod';
|
||||
import type { ConfigFieldSchema } from '../schema/createPortableSchema';
|
||||
import { warnConfigSchemaPropDeprecation } from '../schema/createPortableSchema';
|
||||
import { type StandardSchemaV1 } from '@standard-schema/spec';
|
||||
import { OpaqueExtensionDefinition } from '@internal/frontend';
|
||||
import { ExtensionDataContainer } from './types';
|
||||
import {
|
||||
@@ -170,6 +172,7 @@ export type CreateExtensionOptions<
|
||||
TConfigSchema extends { [key: string]: ConfigFieldSchema },
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
TNewConfigSchema extends { [key: string]: StandardSchemaV1 } = {},
|
||||
> = {
|
||||
kind?: TKind;
|
||||
name?: TName;
|
||||
@@ -179,13 +182,24 @@ export type CreateExtensionOptions<
|
||||
if?: FilterPredicate;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
configSchema?: TNewConfigSchema;
|
||||
/**
|
||||
* @deprecated Use {@link CreateExtensionOptions.configSchema} instead.
|
||||
*/
|
||||
config?: {
|
||||
/**
|
||||
* @deprecated Use {@link CreateExtensionOptions.configSchema} instead.
|
||||
*/
|
||||
schema: TConfigSchema;
|
||||
};
|
||||
factory(context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TNewConfigSchema]: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
} & {
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
@@ -240,6 +254,105 @@ export interface OverridableExtensionDefinition<
|
||||
>;
|
||||
};
|
||||
|
||||
override<
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UNewOutput extends ExtensionDataRef,
|
||||
TExtraInputs extends { [inputName in string]: ExtensionInput },
|
||||
TParamsInput extends AnyParamsInput<NonNullable<T['params']>>,
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
TNewExtensionConfigSchema extends {
|
||||
[key in string]: StandardSchemaV1;
|
||||
} = {},
|
||||
>(
|
||||
args: Expand<
|
||||
{
|
||||
attachTo?: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
VerifyExtensionAttachTo<
|
||||
ExtensionDataRef extends UNewOutput
|
||||
? NonNullable<T['output']>
|
||||
: UNewOutput,
|
||||
UParentInputs
|
||||
>;
|
||||
disabled?: boolean;
|
||||
if?: FilterPredicate;
|
||||
inputs?: TExtraInputs & {
|
||||
[KName in keyof T['inputs']]?: `Error: Input '${KName &
|
||||
string}' is already defined in parent definition`;
|
||||
};
|
||||
output?: Array<UNewOutput>;
|
||||
config?: never;
|
||||
configSchema?: TNewExtensionConfigSchema & {
|
||||
[KName in keyof T['config']]?: `Error: Config key '${KName &
|
||||
string}' is already defined in parent schema`;
|
||||
};
|
||||
factory?(
|
||||
originalFactory: <
|
||||
TFactoryParamsReturn extends AnyParamsInput<
|
||||
NonNullable<T['params']>
|
||||
>,
|
||||
>(
|
||||
context?: Expand<
|
||||
{
|
||||
config?: T['config'];
|
||||
inputs?: ResolvedInputValueOverrides<NonNullable<T['inputs']>>;
|
||||
} & ([T['params']] extends [never]
|
||||
? {}
|
||||
: {
|
||||
params?: TFactoryParamsReturn extends ExtensionBlueprintDefineParams
|
||||
? TFactoryParamsReturn
|
||||
: T['params'] extends ExtensionBlueprintDefineParams
|
||||
? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`'
|
||||
: Partial<T['params']>;
|
||||
})
|
||||
>,
|
||||
) => ExtensionDataContainer<NonNullable<T['output']>>,
|
||||
context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: T['config'] & {
|
||||
[key in keyof TNewExtensionConfigSchema]: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
|
||||
},
|
||||
): Iterable<UFactoryOutput>;
|
||||
} & ([T['params']] extends [never]
|
||||
? {}
|
||||
: {
|
||||
params?: TParamsInput extends ExtensionBlueprintDefineParams
|
||||
? TParamsInput
|
||||
: T['params'] extends ExtensionBlueprintDefineParams
|
||||
? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`'
|
||||
: Partial<T['params']>;
|
||||
})
|
||||
> &
|
||||
VerifyExtensionFactoryOutput<
|
||||
ExtensionDataRef extends UNewOutput
|
||||
? NonNullable<T['output']>
|
||||
: UNewOutput,
|
||||
UFactoryOutput
|
||||
>,
|
||||
): OverridableExtensionDefinition<{
|
||||
kind: T['kind'];
|
||||
name: T['name'];
|
||||
output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
|
||||
inputs: T['inputs'] & TExtraInputs;
|
||||
config: T['config'] & {
|
||||
[key in keyof TNewExtensionConfigSchema]: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
configInput: T['configInput'] & {
|
||||
[key in keyof TNewExtensionConfigSchema]?: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['input'];
|
||||
};
|
||||
}>;
|
||||
|
||||
/**
|
||||
* @deprecated Use the `configSchema` option instead of `config.schema`.
|
||||
*/
|
||||
override<
|
||||
TExtensionConfigSchema extends {
|
||||
[key in string]: ConfigFieldSchema;
|
||||
@@ -266,6 +379,7 @@ export interface OverridableExtensionDefinition<
|
||||
string}' is already defined in parent definition`;
|
||||
};
|
||||
output?: Array<UNewOutput>;
|
||||
configSchema?: never;
|
||||
config?: {
|
||||
schema: TExtensionConfigSchema & {
|
||||
[KName in keyof T['config']]?: `Error: Config key '${KName &
|
||||
@@ -402,6 +516,65 @@ function bindInputs(
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function createExtension<
|
||||
UOutput extends ExtensionDataRef,
|
||||
TInputs extends { [inputName in string]: ExtensionInput },
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
const TKind extends string | undefined = undefined,
|
||||
const TName extends string | undefined = undefined,
|
||||
UParentInputs extends ExtensionDataRef = ExtensionDataRef,
|
||||
TNewConfigSchema extends { [key: string]: StandardSchemaV1 } = {},
|
||||
>(
|
||||
options: {
|
||||
kind?: TKind;
|
||||
name?: TName;
|
||||
attachTo: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
VerifyExtensionAttachTo<UOutput, UParentInputs>;
|
||||
disabled?: boolean;
|
||||
if?: FilterPredicate;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
config?: never;
|
||||
configSchema?: TNewConfigSchema;
|
||||
factory(context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TNewConfigSchema]: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
}): Iterable<UFactoryOutput>;
|
||||
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>,
|
||||
): OverridableExtensionDefinition<{
|
||||
config: {
|
||||
[key in keyof TNewConfigSchema]: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
configInput: {
|
||||
[key in keyof TNewConfigSchema]?: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['input'];
|
||||
};
|
||||
output: UOutput extends ExtensionDataRef<
|
||||
infer IData,
|
||||
infer IId,
|
||||
infer IConfig
|
||||
>
|
||||
? ExtensionDataRef<IData, IId, IConfig>
|
||||
: never;
|
||||
inputs: TInputs;
|
||||
params: never;
|
||||
kind: string | undefined extends TKind ? undefined : TKind;
|
||||
name: string | undefined extends TName ? undefined : TName;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* @deprecated Use the top-level `configSchema` option instead of `config.schema`.
|
||||
* @public
|
||||
*/
|
||||
export function createExtension<
|
||||
UOutput extends ExtensionDataRef,
|
||||
TInputs extends { [inputName in string]: ExtensionInput },
|
||||
@@ -411,15 +584,30 @@ export function createExtension<
|
||||
const TName extends string | undefined = undefined,
|
||||
UParentInputs extends ExtensionDataRef = ExtensionDataRef,
|
||||
>(
|
||||
options: CreateExtensionOptions<
|
||||
TKind,
|
||||
TName,
|
||||
UOutput,
|
||||
TInputs,
|
||||
TConfigSchema,
|
||||
UFactoryOutput,
|
||||
UParentInputs
|
||||
>,
|
||||
options: {
|
||||
kind?: TKind;
|
||||
name?: TName;
|
||||
attachTo: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
VerifyExtensionAttachTo<UOutput, UParentInputs>;
|
||||
disabled?: boolean;
|
||||
if?: FilterPredicate;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
configSchema?: never;
|
||||
config?: {
|
||||
schema: TConfigSchema;
|
||||
};
|
||||
factory(context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
}): Iterable<UFactoryOutput>;
|
||||
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>,
|
||||
): OverridableExtensionDefinition<{
|
||||
config: string extends keyof TConfigSchema
|
||||
? {}
|
||||
@@ -448,9 +636,18 @@ export function createExtension<
|
||||
params: never;
|
||||
kind: string | undefined extends TKind ? undefined : TKind;
|
||||
name: string | undefined extends TName ? undefined : TName;
|
||||
}> {
|
||||
const schemaDeclaration = options.config?.schema;
|
||||
const configSchema =
|
||||
}>;
|
||||
|
||||
/** @internal */
|
||||
export function createExtension(
|
||||
options: any,
|
||||
): OverridableExtensionDefinition<any> {
|
||||
const schemaDeclaration =
|
||||
options.configSchema ?? (options.config?.schema as any);
|
||||
if (options.config?.schema) {
|
||||
warnConfigSchemaPropDeprecation();
|
||||
}
|
||||
const resolvedConfigSchema =
|
||||
schemaDeclaration &&
|
||||
createSchemaFromZod(innerZ =>
|
||||
innerZ.object(
|
||||
@@ -464,28 +661,7 @@ export function createExtension<
|
||||
);
|
||||
|
||||
return OpaqueExtensionDefinition.createInstance('v2', {
|
||||
T: undefined as unknown as {
|
||||
config: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: {
|
||||
[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<
|
||||
((...args: any[]) => any) & TConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>;
|
||||
output: UOutput;
|
||||
inputs: TInputs;
|
||||
kind: string | undefined extends TKind ? undefined : TKind;
|
||||
name: string | undefined extends TName ? undefined : TName;
|
||||
},
|
||||
T: undefined as any,
|
||||
kind: options.kind,
|
||||
name: options.name,
|
||||
attachTo: options.attachTo,
|
||||
@@ -493,7 +669,7 @@ export function createExtension<
|
||||
if: options.if,
|
||||
inputs: bindInputs(options.inputs, options.kind, options.name),
|
||||
output: options.output,
|
||||
configSchema,
|
||||
configSchema: resolvedConfigSchema,
|
||||
factory: options.factory,
|
||||
toString() {
|
||||
const parts: string[] = [];
|
||||
@@ -540,7 +716,7 @@ export function createExtension<
|
||||
parts.push(`attachTo=${attachTo}`);
|
||||
return `ExtensionDefinition{${parts.join(',')}}`;
|
||||
},
|
||||
override(overrideOptions) {
|
||||
override(overrideOptions: any) {
|
||||
if (!Array.isArray(options.output)) {
|
||||
throw new Error(
|
||||
'Cannot override an extension that is not declared using the new format with outputs as an array',
|
||||
@@ -585,11 +761,16 @@ export function createExtension<
|
||||
output: (overrideOptions.output ??
|
||||
options.output) as ExtensionDataRef[],
|
||||
config:
|
||||
options.config || overrideOptions.config
|
||||
options.config ||
|
||||
options.configSchema ||
|
||||
overrideOptions.config ||
|
||||
overrideOptions.configSchema
|
||||
? {
|
||||
schema: {
|
||||
...options.config?.schema,
|
||||
...options.configSchema,
|
||||
...overrideOptions.config?.schema,
|
||||
...overrideOptions.configSchema,
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
@@ -604,8 +785,8 @@ export function createExtension<
|
||||
});
|
||||
}
|
||||
const parentResult = overrideOptions.factory(
|
||||
(innerContext): ExtensionDataContainer<UOutput> => {
|
||||
return createExtensionDataContainer<UOutput>(
|
||||
(innerContext: any): ExtensionDataContainer<any> => {
|
||||
return createExtensionDataContainer<any>(
|
||||
options.factory({
|
||||
node,
|
||||
apis,
|
||||
|
||||
@@ -248,6 +248,7 @@ describe('createExtensionBlueprint', () => {
|
||||
},
|
||||
});
|
||||
|
||||
// @ts-expect-error: overlapping config key 'text'
|
||||
TestExtensionBlueprint.makeWithOverrides({
|
||||
name: 'my-extension',
|
||||
params: {
|
||||
@@ -255,9 +256,8 @@ describe('createExtensionBlueprint', () => {
|
||||
},
|
||||
config: {
|
||||
schema: {
|
||||
// @ts-expect-error
|
||||
text: z => z.number(),
|
||||
something: z => z.string(),
|
||||
text: (z: any) => z.number(),
|
||||
something: (z: any) => z.string(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
import type { z } from 'zod/v3';
|
||||
import { ExtensionInput } from './createExtensionInput';
|
||||
import type { ConfigFieldSchema } from '../schema/createPortableSchema';
|
||||
import { type StandardSchemaV1 } from '@standard-schema/spec';
|
||||
import { ExtensionDataRef, ExtensionDataValue } from './createExtensionDataRef';
|
||||
import { createExtensionDataContainer } from '@internal/frontend';
|
||||
import {
|
||||
@@ -111,6 +112,7 @@ export type CreateExtensionBlueprintOptions<
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
TDataRefs extends { [name in string]: ExtensionDataRef },
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
TNewConfigSchema extends { [key in string]: StandardSchemaV1 } = {},
|
||||
> = {
|
||||
kind: TKind;
|
||||
attachTo: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
@@ -119,7 +121,14 @@ export type CreateExtensionBlueprintOptions<
|
||||
if?: FilterPredicate;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
configSchema?: TNewConfigSchema;
|
||||
/**
|
||||
* @deprecated Use {@link CreateExtensionBlueprintOptions.configSchema} instead.
|
||||
*/
|
||||
config?: {
|
||||
/**
|
||||
* @deprecated Use {@link CreateExtensionBlueprintOptions.configSchema} instead.
|
||||
*/
|
||||
schema: TConfigSchema;
|
||||
};
|
||||
/**
|
||||
@@ -171,6 +180,10 @@ export type CreateExtensionBlueprintOptions<
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TNewConfigSchema]: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
} & {
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
@@ -248,6 +261,92 @@ export interface ExtensionBlueprint<
|
||||
* You must either pass `params` directly, or define a `factory` that can
|
||||
* optionally call the original factory with the same params.
|
||||
*/
|
||||
makeWithOverrides<
|
||||
TName extends string | undefined,
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UNewOutput extends ExtensionDataRef,
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
TExtraInputs extends { [inputName in string]: ExtensionInput } = {},
|
||||
TNewExtensionConfigSchema extends {
|
||||
[key in string]: StandardSchemaV1;
|
||||
} = {},
|
||||
>(args: {
|
||||
name?: TName;
|
||||
attachTo?: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
VerifyExtensionAttachTo<
|
||||
ExtensionDataRef extends UNewOutput
|
||||
? NonNullable<T['output']>
|
||||
: UNewOutput,
|
||||
UParentInputs
|
||||
>;
|
||||
disabled?: boolean;
|
||||
if?: FilterPredicate;
|
||||
inputs?: TExtraInputs & {
|
||||
[KName in keyof T['inputs']]?: `Error: Input '${KName &
|
||||
string}' is already defined in parent definition`;
|
||||
};
|
||||
output?: Array<UNewOutput>;
|
||||
config?: never;
|
||||
configSchema?: TNewExtensionConfigSchema & {
|
||||
[KName in keyof T['config']]?: `Error: Config key '${KName &
|
||||
string}' is already defined in parent schema`;
|
||||
};
|
||||
factory(
|
||||
originalFactory: <
|
||||
TParamsInput extends AnyParamsInput<NonNullable<T['params']>>,
|
||||
>(
|
||||
params: TParamsInput extends ExtensionBlueprintDefineParams
|
||||
? TParamsInput
|
||||
: T['params'] extends ExtensionBlueprintDefineParams
|
||||
? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`'
|
||||
: T['params'],
|
||||
context?: {
|
||||
config?: T['config'];
|
||||
inputs?: ResolvedInputValueOverrides<NonNullable<T['inputs']>>;
|
||||
},
|
||||
) => ExtensionDataContainer<NonNullable<T['output']>>,
|
||||
context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: T['config'] & {
|
||||
[key in keyof TNewExtensionConfigSchema]: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
|
||||
},
|
||||
): Iterable<UFactoryOutput> &
|
||||
VerifyExtensionFactoryOutput<
|
||||
ExtensionDataRef extends UNewOutput
|
||||
? NonNullable<T['output']>
|
||||
: UNewOutput,
|
||||
UFactoryOutput
|
||||
>;
|
||||
}): OverridableExtensionDefinition<{
|
||||
config: Expand<
|
||||
{
|
||||
[key in keyof TNewExtensionConfigSchema]: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
} & T['config']
|
||||
>;
|
||||
configInput: Expand<
|
||||
{
|
||||
[key in keyof TNewExtensionConfigSchema]?: NonNullable<
|
||||
TNewExtensionConfigSchema[key]['~standard']['types']
|
||||
>['input'];
|
||||
} & T['configInput']
|
||||
>;
|
||||
output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
|
||||
inputs: Expand<T['inputs'] & TExtraInputs>;
|
||||
kind: T['kind'];
|
||||
name: string | undefined extends TName ? undefined : TName;
|
||||
params: T['params'];
|
||||
}>;
|
||||
|
||||
/**
|
||||
* @deprecated Use the `configSchema` option instead of `config.schema`.
|
||||
*/
|
||||
makeWithOverrides<
|
||||
TName extends string | undefined,
|
||||
TExtensionConfigSchema extends {
|
||||
@@ -273,6 +372,7 @@ export interface ExtensionBlueprint<
|
||||
string}' is already defined in parent definition`;
|
||||
};
|
||||
output?: Array<UNewOutput>;
|
||||
configSchema?: never;
|
||||
config?: {
|
||||
schema: TExtensionConfigSchema & {
|
||||
[KName in keyof T['config']]?: `Error: Config key '${KName &
|
||||
@@ -462,6 +562,74 @@ function unwrapParams<TParams extends object>(
|
||||
* ```
|
||||
* @public
|
||||
*/
|
||||
export function createExtensionBlueprint<
|
||||
TParams extends object | ExtensionBlueprintDefineParams,
|
||||
UOutput extends ExtensionDataRef,
|
||||
TInputs extends { [inputName in string]: ExtensionInput },
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
TKind extends string,
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
TDataRefs extends { [name in string]: ExtensionDataRef } = never,
|
||||
TNewConfigSchema extends { [key in string]: StandardSchemaV1 } = {},
|
||||
>(
|
||||
options: {
|
||||
kind: TKind;
|
||||
attachTo: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
VerifyExtensionAttachTo<UOutput, UParentInputs>;
|
||||
disabled?: boolean;
|
||||
if?: FilterPredicate;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
config?: never;
|
||||
configSchema?: TNewConfigSchema;
|
||||
defineParams?: TParams extends ExtensionBlueprintDefineParams
|
||||
? TParams
|
||||
: 'The defineParams option must be a function if provided, see the docs for details';
|
||||
factory(
|
||||
params: TParams extends ExtensionBlueprintDefineParams
|
||||
? ReturnType<TParams>['T']
|
||||
: TParams,
|
||||
context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TNewConfigSchema]: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
): Iterable<UFactoryOutput>;
|
||||
dataRefs?: TDataRefs;
|
||||
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>,
|
||||
): ExtensionBlueprint<{
|
||||
kind: TKind;
|
||||
params: TParams;
|
||||
output: UOutput extends ExtensionDataRef<
|
||||
infer IData,
|
||||
infer IId,
|
||||
infer IConfig
|
||||
>
|
||||
? ExtensionDataRef<IData, IId, IConfig>
|
||||
: never;
|
||||
inputs: string extends keyof TInputs ? {} : TInputs;
|
||||
config: {
|
||||
[key in keyof TNewConfigSchema]: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['output'];
|
||||
};
|
||||
configInput: {
|
||||
[key in keyof TNewConfigSchema]?: NonNullable<
|
||||
TNewConfigSchema[key]['~standard']['types']
|
||||
>['input'];
|
||||
};
|
||||
dataRefs: TDataRefs;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* @deprecated Use the top-level `configSchema` option instead of `config.schema`.
|
||||
* @public
|
||||
*/
|
||||
export function createExtensionBlueprint<
|
||||
TParams extends object | ExtensionBlueprintDefineParams,
|
||||
UOutput extends ExtensionDataRef,
|
||||
@@ -472,20 +640,41 @@ export function createExtensionBlueprint<
|
||||
UParentInputs extends ExtensionDataRef,
|
||||
TDataRefs extends { [name in string]: ExtensionDataRef } = never,
|
||||
>(
|
||||
options: CreateExtensionBlueprintOptions<
|
||||
TKind,
|
||||
TParams,
|
||||
UOutput,
|
||||
TInputs,
|
||||
TConfigSchema,
|
||||
UFactoryOutput,
|
||||
TDataRefs,
|
||||
UParentInputs
|
||||
>,
|
||||
options: {
|
||||
kind: TKind;
|
||||
attachTo: ExtensionDefinitionAttachTo<UParentInputs> &
|
||||
VerifyExtensionAttachTo<UOutput, UParentInputs>;
|
||||
disabled?: boolean;
|
||||
if?: FilterPredicate;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
configSchema?: never;
|
||||
config?: {
|
||||
schema: TConfigSchema;
|
||||
};
|
||||
defineParams?: TParams extends ExtensionBlueprintDefineParams
|
||||
? TParams
|
||||
: 'The defineParams option must be a function if provided, see the docs for details';
|
||||
factory(
|
||||
params: TParams extends ExtensionBlueprintDefineParams
|
||||
? ReturnType<TParams>['T']
|
||||
: TParams,
|
||||
context: {
|
||||
node: AppNode;
|
||||
apis: ApiHolder;
|
||||
config: {
|
||||
[key in keyof TConfigSchema]: z.infer<
|
||||
ReturnType<((...args: any[]) => any) & TConfigSchema[key]>
|
||||
>;
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
): Iterable<UFactoryOutput>;
|
||||
dataRefs?: TDataRefs;
|
||||
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>,
|
||||
): ExtensionBlueprint<{
|
||||
kind: TKind;
|
||||
params: TParams;
|
||||
// This inference and remapping back to ExtensionDataRef eliminates any occurrences ConfigurationExtensionDataRef
|
||||
output: UOutput extends ExtensionDataRef<
|
||||
infer IData,
|
||||
infer IId,
|
||||
@@ -511,7 +700,10 @@ export function createExtensionBlueprint<
|
||||
}>
|
||||
>;
|
||||
dataRefs: TDataRefs;
|
||||
}> {
|
||||
}>;
|
||||
|
||||
/** @internal */
|
||||
export function createExtensionBlueprint(options: any): any {
|
||||
const defineParams = options.defineParams as
|
||||
| ExtensionBlueprintDefineParams
|
||||
| undefined;
|
||||
@@ -529,14 +721,15 @@ export function createExtensionBlueprint<
|
||||
inputs: options.inputs,
|
||||
output: options.output as ExtensionDataRef[],
|
||||
config: options.config,
|
||||
configSchema: options.configSchema as any,
|
||||
factory: ctx =>
|
||||
options.factory(
|
||||
unwrapParams(args.params, ctx, defineParams, options.kind),
|
||||
ctx,
|
||||
ctx as any,
|
||||
) as Iterable<ExtensionDataValue<any, any>>,
|
||||
}) as OverridableExtensionDefinition;
|
||||
},
|
||||
makeWithOverrides(args) {
|
||||
makeWithOverrides(args: any) {
|
||||
return createExtension({
|
||||
kind: options.kind,
|
||||
name: args.name,
|
||||
@@ -555,19 +748,18 @@ export function createExtensionBlueprint<
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
configSchema:
|
||||
options.configSchema || args.configSchema
|
||||
? {
|
||||
...options.configSchema,
|
||||
...args.configSchema,
|
||||
}
|
||||
: (undefined as any),
|
||||
factory: ctx => {
|
||||
const { node, config, inputs, apis } = ctx;
|
||||
return args.factory(
|
||||
(innerParams, innerContext) => {
|
||||
return createExtensionDataContainer<
|
||||
UOutput extends ExtensionDataRef<
|
||||
infer IData,
|
||||
infer IId,
|
||||
infer IConfig
|
||||
>
|
||||
? ExtensionDataRef<IData, IId, IConfig>
|
||||
: never
|
||||
>(
|
||||
(innerParams: any, innerContext: any) => {
|
||||
return createExtensionDataContainer<any>(
|
||||
options.factory(
|
||||
unwrapParams(innerParams, ctx, defineParams, options.kind),
|
||||
{
|
||||
@@ -595,27 +787,5 @@ export function createExtensionBlueprint<
|
||||
},
|
||||
}) as OverridableExtensionDefinition;
|
||||
},
|
||||
} as ExtensionBlueprint<{
|
||||
kind: TKind;
|
||||
params: TParams;
|
||||
output: any;
|
||||
inputs: string extends keyof TInputs ? {} : TInputs;
|
||||
config: string extends keyof TConfigSchema
|
||||
? {}
|
||||
: {
|
||||
[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<
|
||||
((...args: any[]) => any) & TConfigSchema[key]
|
||||
>;
|
||||
}>
|
||||
>;
|
||||
dataRefs: TDataRefs;
|
||||
}>;
|
||||
} as ExtensionBlueprint<any>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user