chore: more work towards supporting extensions

Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com>
Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com>
Co-authored-by: Camila Belo <camilaibs@users.noreply.github.com>
Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2024-08-07 17:11:24 +02:00
parent 4a6d9dc85e
commit 9fdbbd0889
11 changed files with 250 additions and 280 deletions
@@ -48,6 +48,7 @@ describe('createApiExtension', () => {
},
factory: expect.any(Function),
toString: expect.any(Function),
override: expect.any(Function),
});
});
@@ -85,6 +86,7 @@ describe('createApiExtension', () => {
},
factory: expect.any(Function),
toString: expect.any(Function),
override: expect.any(Function),
});
});
});
@@ -41,6 +41,7 @@ describe('createAppRootElementExtension', () => {
},
factory: expect.any(Function),
toString: expect.any(Function),
override: expect.any(Function),
});
createExtensionTester(extension).render();
@@ -88,6 +89,7 @@ describe('createAppRootElementExtension', () => {
},
factory: expect.any(Function),
toString: expect.any(Function),
override: expect.any(Function),
});
createExtensionTester(extension, { config: { name: 'Robin' } })
@@ -42,6 +42,7 @@ describe('createAppRootWrapperExtension', () => {
},
factory: expect.any(Function),
toString: expect.any(Function),
override: expect.any(Function),
});
createExtensionTester(
@@ -94,6 +95,7 @@ describe('createAppRootWrapperExtension', () => {
component: expect.anything(),
},
factory: expect.any(Function),
override: expect.any(Function),
toString: expect.any(Function),
});
@@ -41,6 +41,7 @@ describe('createNavLogoExtension', () => {
logos: expect.anything(),
},
factory: expect.any(Function),
override: expect.any(Function),
toString: expect.any(Function),
});
});
@@ -56,6 +56,7 @@ describe('createPageExtension', () => {
},
factory: expect.any(Function),
toString: expect.any(Function),
override: expect.any(Function),
});
expect(
@@ -78,6 +79,7 @@ describe('createPageExtension', () => {
kind: 'page',
attachTo: { id: 'other', input: 'place' },
configSchema: expect.anything(),
override: expect.any(Function),
disabled: true,
inputs: {
first: createExtensionInput({
@@ -115,6 +117,7 @@ describe('createPageExtension', () => {
},
factory: expect.any(Function),
toString: expect.any(Function),
override: expect.any(Function),
});
});
@@ -50,6 +50,7 @@ describe('createRouterExtension', () => {
component: expect.anything(),
},
factory: expect.any(Function),
override: expect.any(Function),
toString: expect.any(Function),
});
@@ -119,6 +120,7 @@ describe('createRouterExtension', () => {
component: expect.anything(),
},
factory: expect.any(Function),
override: expect.any(Function),
toString: expect.any(Function),
});
@@ -46,6 +46,7 @@ describe('createTranslationExtension', () => {
namespace: 'test',
attachTo: { id: 'app', input: 'translations' },
disabled: false,
override: expect.any(Function),
inputs: {},
output: {
resource: createTranslationExtension.translationDataRef,
@@ -84,6 +85,7 @@ describe('createTranslationExtension', () => {
namespace: 'test',
attachTo: { id: 'app', input: 'translations' },
disabled: false,
override: expect.any(Function),
inputs: {},
output: {
resource: createTranslationExtension.translationDataRef,
@@ -120,6 +122,7 @@ describe('createTranslationExtension', () => {
version: 'v1',
kind: 'translation',
namespace: 'test',
override: expect.any(Function),
name: 'sv',
attachTo: { id: 'app', input: 'translations' },
disabled: false,
@@ -15,7 +15,6 @@
*/
import { createExtensionTester } from '@backstage/frontend-test-utils';
import { coreExtensionData } from './coreExtensionData';
import { createExtension } from './createExtension';
import { createExtensionDataRef } from './createExtensionDataRef';
import { createExtensionInput } from './createExtensionInput';
@@ -306,9 +305,7 @@ describe('createExtension', () => {
baz: z => z.string().optional(),
},
},
output: {
foo: stringDataRef,
},
output: [stringDataRef],
factory({ config }) {
const a1: string = config.foo;
const a2: string = config.bar;
@@ -322,12 +319,10 @@ describe('createExtension', () => {
const c3: number = config.baz;
unused(a1, a2, a3, c1, c2, c3);
return {
foo: 'bar',
};
return [stringDataRef('bar')];
},
});
expect(extension).toMatchObject({ version: 'v1', namespace: 'test' });
expect(extension).toMatchObject({ version: 'v2', namespace: 'test' });
expect(String(extension)).toBe(
'ExtensionDefinition{namespace=test,attachTo=root@default}',
);
@@ -614,18 +609,7 @@ describe('createExtension', () => {
},
});
const override = testExtension.override({
output: [numberDataRef],
factory(_, { inputs }) {
return [
numberDataRef(inputs.test.get(stringDataRef).length),
stringDataRef('default'),
];
},
});
// @ts-expect-error - should fail as the string output from previous is not provided
const override2 = testExtension.override({
const override1 = testExtension.override({
output: [numberDataRef],
factory(_, { inputs }) {
return [numberDataRef(inputs.test.get(stringDataRef).length)];
@@ -633,14 +617,14 @@ describe('createExtension', () => {
});
// @ts-expect-error - this should fail because string output should be merged?
const override3 = testExtension.override({
const override2 = testExtension.override({
output: [numberDataRef],
factory(_, { inputs }) {
return [stringDataRef(inputs.test.get(stringDataRef))];
},
});
unused(override, override2, override3);
unused(override1, override2);
expect(true).toBe(true);
});
@@ -14,10 +14,10 @@
* limitations under the License.
*/
import { over } from 'lodash';
import { AppNode } from '../apis';
import { PortableSchema, createSchemaFromZod } from '../schema';
import { Expand } from '../types';
import { createDataContainer } from './createExtensionBlueprint';
import {
AnyExtensionDataRef,
ExtensionDataRef,
@@ -128,7 +128,6 @@ export interface LegacyCreateExtensionOptions<
TInputs extends AnyExtensionInputMap,
TConfig,
TConfigInput,
TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },
> {
kind?: string;
namespace?: string;
@@ -137,21 +136,10 @@ export interface LegacyCreateExtensionOptions<
disabled?: boolean;
inputs?: TInputs;
output: TOutput;
/** @deprecated - use `config.schema` instead */
configSchema?: PortableSchema<TConfig, TConfigInput>;
config?: {
schema: TConfigSchema;
};
factory(context: {
node: AppNode;
config: TConfig &
(string extends keyof TConfigSchema
? {}
: {
[key in keyof TConfigSchema]: z.infer<
ReturnType<TConfigSchema[key]>
>;
});
config: TConfig;
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
}): Expand<ExtensionDataValues<TOutput>>;
}
@@ -193,8 +181,6 @@ export type CreateExtensionOptions<
{ optional: boolean; singleton: boolean }
>;
},
TConfig,
TConfigInput,
TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },
UFactoryOutput extends ExtensionDataValue<any, any>,
> = {
@@ -205,27 +191,30 @@ export type CreateExtensionOptions<
disabled?: boolean;
inputs?: TInputs;
output: Array<UOutput>;
/** @deprecated - use `config.schema` instead */
configSchema?: PortableSchema<TConfig, TConfigInput>;
config?: {
schema: TConfigSchema;
};
factory(context: {
node: AppNode;
config: TConfig &
(string extends keyof TConfigSchema
? {}
: {
[key in keyof TConfigSchema]: z.infer<
ReturnType<TConfigSchema[key]>
>;
});
config: {
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
};
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
}): Iterable<UFactoryOutput>;
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;
/** @public */
export interface ExtensionDefinition<TConfig, TConfigInput = TConfig> {
export interface ExtensionDefinition<
TConfig,
TConfigInput = TConfig,
UOutput extends AnyExtensionDataRef = AnyExtensionDataRef,
TInputs extends {
[inputName in string]: ExtensionInput<
AnyExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
} = {},
> {
$$type: '@backstage/ExtensionDefinition';
readonly kind?: string;
readonly namespace?: string;
@@ -233,102 +222,71 @@ export interface ExtensionDefinition<TConfig, TConfigInput = TConfig> {
readonly attachTo: { id: string; input: string };
readonly disabled: boolean;
readonly configSchema?: PortableSchema<TConfig, TConfigInput>;
}
export type OverrideExtensionOptions<
UOutput extends AnyExtensionDataRef,
TInputs extends {
[inputName in string]: ExtensionInput<
AnyExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
},
TConfig,
TConfigInput,
TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },
TConfigSchemaOverrides extends {
[key: string]: (zImpl: typeof z) => z.ZodType;
},
UOutputOverrides extends AnyExtensionDataRef,
UFactoryOverrideOutput extends ExtensionDataValue<any, any>,
> = {
kind?: string;
namespace?: string;
name?: string;
attachTo?: { id: string; input: string };
disabled?: boolean;
inputs?: TInputs;
output?: Array<UOutputOverrides>;
/** @deprecated - use `config.schema` instead */
configSchema?: PortableSchema<TConfig, TConfigInput>;
config?: {
schema: TConfigSchemaOverrides & {
[KName in keyof TConfig]?: `Error: Config key '${KName &
string}' is already defined in parent schema`;
};
};
factory?(
originalFactory: (context?: {
config?: {
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
};
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
}) => ExtensionDataContainer<UOutput>,
context: {
node: AppNode;
config: TConfig &
(string extends keyof TConfigSchema
? {}
: {
[key in keyof TConfigSchemaOverrides]: z.infer<
ReturnType<TConfigSchemaOverrides[key]>
>;
} & {
[key in keyof TConfigSchema]: z.infer<
ReturnType<TConfigSchema[key]>
>;
});
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
},
): Iterable<UFactoryOverrideOutput>;
// todo(blam): need to verify that the outputs are merged and verified properly.
} & VerifyExtensionFactoryOutput<
UOutput & UOutputOverrides,
UFactoryOverrideOutput
>;
/** @public */
export type OverridableExtension<
UOutput extends AnyExtensionDataRef,
TInputs extends {
[inputName in string]: ExtensionInput<
AnyExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
},
TConfig,
TConfigInput,
TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },
> = {
override<
TConfigSchemaOverrides extends {
TExtensionConfigSchema extends {
[key in string]: (zImpl: typeof z) => z.ZodType;
},
UOutputOverrides extends AnyExtensionDataRef,
UFactoryOverrideOutput extends ExtensionDataValue<any, any>,
UFactoryOutput extends ExtensionDataValue<any, any>,
UNewOutput extends AnyExtensionDataRef,
TExtraInputs extends {
[inputName in string]: ExtensionInput<
AnyExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
},
>(
options: OverrideExtensionOptions<
UOutput,
TInputs,
TConfig,
TConfigInput,
TConfigSchema,
TConfigSchemaOverrides,
UOutputOverrides,
UFactoryOverrideOutput
args: {
attachTo?: { id: string; input: string };
disabled?: boolean;
inputs?: TExtraInputs & {
[KName in keyof TInputs]?: `Error: Input '${KName &
string}' is already defined in parent definition`;
};
output?: Array<UNewOutput>;
config?: {
schema: TExtensionConfigSchema & {
[KName in keyof TConfig]?: `Error: Config key '${KName &
string}' is already defined in parent schema`;
};
};
factory(
originalFactory: (context?: {
config?: TConfig;
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
}) => ExtensionDataContainer<UOutput>,
context: {
node: AppNode;
config: TConfig & {
[key in keyof TExtensionConfigSchema]: z.infer<
ReturnType<TExtensionConfigSchema[key]>
>;
};
inputs: Expand<ResolvedExtensionInputs<TInputs & TExtraInputs>>;
},
): Iterable<UFactoryOutput>;
} & VerifyExtensionFactoryOutput<
AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput,
UFactoryOutput
>,
): ExtensionDefinition<TConfig, TConfigInput>;
};
): ExtensionDefinition<
{
[key in keyof TExtensionConfigSchema]: z.infer<
ReturnType<TExtensionConfigSchema[key]>
>;
} & TConfig,
z.input<
z.ZodObject<{
[key in keyof TExtensionConfigSchema]: ReturnType<
TExtensionConfigSchema[key]
>;
}>
> &
TConfigInput,
AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput,
TInputs & TExtraInputs
>;
}
/** @internal */
export type InternalExtensionDefinition<TConfig, TConfigInput> =
@@ -397,36 +355,27 @@ export function createExtension<
{ optional: boolean; singleton: boolean }
>;
},
TConfig,
TConfigInput,
TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },
UFactoryOutput extends ExtensionDataValue<any, any>,
>(
options: CreateExtensionOptions<
UOutput,
TInputs,
TConfig,
TConfigInput,
TConfigSchema,
UFactoryOutput
>,
): ExtensionDefinition<
TConfig &
(string extends keyof TConfigSchema
? {}
: {
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
}),
TConfigInput &
(string extends keyof TConfigSchema
? {}
: z.input<
z.ZodObject<{
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
}>
>)
> &
OverridableExtension<UOutput, TInputs, TConfig, TConfigInput, TConfigSchema>;
{
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
},
z.input<
z.ZodObject<{
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
}>
>,
UOutput,
TInputs
>;
/**
* @public
* @deprecated - use the array format of `output` instead, see TODO-doc-link
@@ -436,31 +385,14 @@ export function createExtension<
TInputs extends AnyExtensionInputMap,
TConfig,
TConfigInput,
TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },
>(
options: LegacyCreateExtensionOptions<
TOutput,
TInputs,
TConfig,
TConfigInput,
TConfigSchema
TConfigInput
>,
): ExtensionDefinition<
TConfig &
(string extends keyof TConfigSchema
? {}
: {
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
}),
TConfigInput &
(string extends keyof TConfigSchema
? {}
: z.input<
z.ZodObject<{
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
}>
>)
>;
): ExtensionDefinition<TConfig, TConfigInput, never, never>;
export function createExtension<
UOutput extends AnyExtensionDataRef,
TInputs extends {
@@ -476,20 +408,12 @@ export function createExtension<
UFactoryOutput extends ExtensionDataValue<any, any>,
>(
options:
| CreateExtensionOptions<
UOutput,
TInputs,
TConfig,
TConfigInput,
TConfigSchema,
UFactoryOutput
>
| CreateExtensionOptions<UOutput, TInputs, TConfigSchema, UFactoryOutput>
| LegacyCreateExtensionOptions<
AnyExtensionDataMap,
TLegacyInputs,
TConfig,
TConfigInput,
TConfigSchema
TConfigInput
>,
): ExtensionDefinition<
TConfig &
@@ -505,22 +429,29 @@ export function createExtension<
z.ZodObject<{
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
}>
>)
> &
OverridableExtension<UOutput, TInputs, TConfig, TConfigInput, TConfigSchema> {
const newConfigSchema = options.config?.schema;
if (newConfigSchema && options.configSchema) {
>),
UOutput,
TInputs
> {
if ('configSchema' in options && 'config' in options) {
throw new Error(`Cannot provide both configSchema and config.schema`);
}
const configSchema = newConfigSchema
? createSchemaFromZod(innerZ =>
let configSchema: PortableSchema<any, any> | undefined;
if ('configSchema' in options) {
configSchema = options.configSchema;
}
if ('config' in options) {
const newConfigSchema = options.config?.schema;
configSchema =
newConfigSchema &&
createSchemaFromZod(innerZ =>
innerZ.object(
Object.fromEntries(
Object.entries(newConfigSchema).map(([k, v]) => [k, v(innerZ)]),
),
),
)
: options.configSchema;
);
}
return {
$$type: '@backstage/ExtensionDefinition',
@@ -548,89 +479,133 @@ export function createExtension<
parts.push(`attachTo=${options.attachTo.id}@${options.attachTo.input}`);
return `ExtensionDefinition{${parts.join(',')}}`;
},
override<
TConfigSchemaOverrides extends {
override: <
TExtensionConfigSchema extends {
[key in string]: (zImpl: typeof z) => z.ZodType;
},
UOutputOverrides extends AnyExtensionDataRef,
UFactoryOverrideOutput extends ExtensionDataValue<any, any>,
>(
overrideOptions: OverrideExtensionOptions<
UOverrideFactoryOutput extends ExtensionDataValue<any, any>,
UNewOutput extends AnyExtensionDataRef,
TExtraInputs extends {
[inputName in string]: ExtensionInput<
AnyExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
},
>(overrideOptions: {
attachTo?: { id: string; input: string };
disabled?: boolean;
inputs?: TExtraInputs;
output?: Array<UNewOutput>;
config?: {
schema: TExtensionConfigSchema;
};
factory(
originalFactory: (context?: {
config?: {
[key in keyof TConfigSchema]: z.infer<
ReturnType<TConfigSchema[key]>
>;
};
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
}) => ExtensionDataContainer<UOutput>,
context: {
node: AppNode;
config: {
[key in keyof TExtensionConfigSchema]: z.infer<
ReturnType<TExtensionConfigSchema[key]>
>;
} & {
[key in keyof TConfigSchema]: z.infer<
ReturnType<TConfigSchema[key]>
>;
};
inputs: Expand<ResolvedExtensionInputs<TInputs & TExtraInputs>>;
},
): Iterable<UOverrideFactoryOutput>;
}): ExtensionDefinition<
{
[key in keyof TExtensionConfigSchema]: z.infer<
ReturnType<TExtensionConfigSchema[key]>
>;
} & {
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
},
z.input<
z.ZodObject<
{
[key in keyof TExtensionConfigSchema]: ReturnType<
TExtensionConfigSchema[key]
>;
} & {
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
}
>
>,
AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput,
TInputs & TExtraInputs
> => {
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',
);
}
const newOptions = options as CreateExtensionOptions<
UOutput,
TInputs,
TConfig,
TConfigInput,
TConfigSchema,
TConfigSchemaOverrides,
UOutputOverrides,
UFactoryOverrideOutput
>,
) {
UFactoryOutput
>;
const overrideNewConfigSchema = overrideOptions.config?.schema;
if (overrideNewConfigSchema && overrideOptions.configSchema) {
throw new Error(`Cannot provide both configSchema and config.schema`);
}
const mergedConfigSchema = {
...options.config?.schema,
...overrideOptions.config?.schema,
};
const overrideConfigSchema = mergedConfigSchema
? createSchemaFromZod(innerZ =>
innerZ.object(
Object.fromEntries(
Object.entries(mergedConfigSchema).map(([k, v]) => [
k,
v(innerZ),
]),
),
),
)
: overrideOptions.configSchema;
const buildDataContainer = (outputs): ExtensionDataContainer<UOutput> => {
const dataMap = new Map<string, unknown>();
if (Symbol.iterator in outputs) {
for (const output of outputs) {
dataMap.set(output.id, output.value);
}
}
return {
get(ref) {
return dataMap.get(ref.id);
},
} as ExtensionDataContainer<UOutput>;
};
const schema = {
...newOptions.config?.schema,
...overrideNewConfigSchema,
} as TConfigSchema & TExtensionConfigSchema;
return createExtension({
attachTo: options.attachTo,
output: overrideOptions.output ?? options.output,
configSchema: overrideConfigSchema,
kind: newOptions.kind,
namespace: newOptions.namespace,
name: newOptions.name,
attachTo: overrideOptions.attachTo ?? newOptions.attachTo,
disabled: overrideOptions.disabled ?? newOptions.disabled,
inputs: { ...overrideOptions.inputs, ...newOptions.inputs },
output: overrideOptions.output ?? newOptions.output,
config: Object.keys(schema).length === 0 ? undefined : { schema },
factory: ({ node, config, inputs }) => {
if (overrideOptions.factory) {
return overrideOptions.factory(
innerCtx => {
const originalFactoryResponse = options.factory({
node,
config: innerCtx?.config ?? config,
inputs: innerCtx?.inputs ?? inputs,
});
return buildDataContainer(originalFactoryResponse);
},
{ node, config, inputs },
);
if (!overrideOptions.factory) {
return newOptions.factory({
node,
config,
inputs: inputs as unknown as Expand<
ResolvedExtensionInputs<TInputs>
>,
});
}
return options.factory(originalFactory, context);
return overrideOptions.factory(
(innerContext?: {
config?: {
[key in keyof TConfigSchema]: z.infer<
ReturnType<TConfigSchema[key]>
>;
};
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
}): ExtensionDataContainer<UOutput> => {
return createDataContainer<UOutput>(
newOptions.factory({
node,
config: innerContext?.config ?? config,
inputs: (innerContext?.inputs ?? inputs) as any, // TODO: Fix the way input values are overridden
}) as Iterable<any>,
);
},
{
node,
config,
inputs,
},
);
},
disabled: overrideOptions.disabled ?? options.disabled,
inputs: overrideOptions.inputs ?? options.inputs,
kind: overrideOptions.kind ?? options.kind,
name: overrideOptions.name ?? options.name,
namespace: overrideOptions.namespace ?? options.namespace,
});
} as CreateExtensionOptions<AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput, TInputs & TExtraInputs, TConfigSchema & TExtensionConfigSchema, UOverrideFactoryOutput>);
},
} as InternalExtensionDefinition<
TConfig &
@@ -69,6 +69,7 @@ describe('createExtensionBlueprint', () => {
output: [coreExtensionData.reactElement],
factory: expect.any(Function),
toString: expect.any(Function),
override: expect.any(Function),
version: 'v2',
});
@@ -108,6 +109,7 @@ describe('createExtensionBlueprint', () => {
output: [coreExtensionData.reactElement],
factory: expect.any(Function),
toString: expect.any(Function),
override: expect.any(Function),
version: 'v2',
});
@@ -389,6 +391,7 @@ describe('createExtensionBlueprint', () => {
"output": [
[Function],
],
"override": [Function],
"toString": [Function],
"version": "v2",
}
@@ -171,7 +171,7 @@ export interface ExtensionBlueprint<
}
/** @internal */
function createDataContainer<UData extends AnyExtensionDataRef>(
export function createDataContainer<UData extends AnyExtensionDataRef>(
values: Iterable<
UData extends ExtensionDataRef<infer IData, infer IId>
? ExtensionDataValue<IData, IId>
@@ -241,10 +241,7 @@ class ExtensionBlueprintImpl<
name?: string;
attachTo?: { id: string; input: string };
disabled?: boolean;
inputs?: TExtraInputs & {
[KName in keyof TInputs]?: `Error: Input '${KName &
string}' is already defined in parent definition`;
};
inputs?: TExtraInputs;
output?: Array<UNewOutput>;
params?: TParams;
config?: {
@@ -363,9 +360,7 @@ class ExtensionBlueprintImpl<
}
throw new Error('Either params or factory must be provided');
},
} as CreateExtensionOptions<
UOutput,
TInputs & TExtraInputs,
} as CreateExtensionOptions<UOutput, TInputs & TExtraInputs, TConfigSchema & TExtensionConfigSchema, UFactoryOutput>) as ExtensionDefinition<
{
[key in keyof TExtensionConfigSchema]: z.infer<
ReturnType<TExtensionConfigSchema[key]>
@@ -383,10 +378,8 @@ class ExtensionBlueprintImpl<
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
}
>
>,
TConfigSchema,
UFactoryOutput
>);
>
>;
}
}