chore: steps to making outputs and factories look pretty
Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
@@ -148,7 +148,9 @@ export interface LegacyCreateExtensionOptions<
|
||||
/** @ignore */
|
||||
export type VerifyExtensionFactoryOutput<
|
||||
UDeclaredOutput extends AnyExtensionDataRef,
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UFactoryOutput extends
|
||||
| ExtensionDataValue<any, any>
|
||||
| ExtensionDataContainer<any>,
|
||||
> = (
|
||||
UDeclaredOutput extends any
|
||||
? UDeclaredOutput['config']['optional'] extends true
|
||||
@@ -156,21 +158,29 @@ export type VerifyExtensionFactoryOutput<
|
||||
: UDeclaredOutput['id']
|
||||
: never
|
||||
) extends infer IRequiredOutputIds
|
||||
? [IRequiredOutputIds] extends [UFactoryOutput['id']]
|
||||
? [UFactoryOutput['id']] extends [UDeclaredOutput['id']]
|
||||
? {}
|
||||
? (
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>
|
||||
? UFactoryOutput['id']
|
||||
: UFactoryOutput extends ExtensionDataContainer<infer IDataRefs>
|
||||
? IDataRefs['id']
|
||||
: never
|
||||
) extends infer IFactoryOutputIds
|
||||
? [IRequiredOutputIds] extends [IFactoryOutputIds]
|
||||
? [IFactoryOutputIds] extends [UDeclaredOutput['id']]
|
||||
? {}
|
||||
: {
|
||||
'Error: The extension factory has undeclared output(s)': Exclude<
|
||||
IFactoryOutputIds,
|
||||
UDeclaredOutput['id']
|
||||
>;
|
||||
}
|
||||
: {
|
||||
'Error: The extension factory has undeclared output(s)': Exclude<
|
||||
UFactoryOutput['id'],
|
||||
UDeclaredOutput['id']
|
||||
'Error: The extension factory is missing the following output(s)': Exclude<
|
||||
IRequiredOutputIds,
|
||||
IFactoryOutputIds
|
||||
>;
|
||||
}
|
||||
: {
|
||||
'Error: The extension factory is missing the following output(s)': Exclude<
|
||||
IRequiredOutputIds,
|
||||
UFactoryOutput['id']
|
||||
>;
|
||||
}
|
||||
: never
|
||||
: never;
|
||||
|
||||
/** @public */
|
||||
|
||||
@@ -21,6 +21,7 @@ import { createExtensionTester } from '@backstage/frontend-test-utils';
|
||||
import { createExtensionDataRef } from './createExtensionDataRef';
|
||||
import { createExtensionInput } from './createExtensionInput';
|
||||
import { RouteRef } from '../routing';
|
||||
import { toInternalExtensionDefinition } from './createExtension';
|
||||
|
||||
function unused(..._any: any[]) {}
|
||||
|
||||
@@ -450,4 +451,79 @@ describe('createExtensionBlueprint', () => {
|
||||
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
|
||||
it('should replace the outputs when provided through make', () => {
|
||||
const testDataRef1 = createExtensionDataRef<string>().with({ id: 'test1' });
|
||||
const testDataRef2 = createExtensionDataRef<string>().with({ id: 'test2' });
|
||||
|
||||
const blueprint = createExtensionBlueprint({
|
||||
kind: 'test-extension',
|
||||
attachTo: { id: 'test', input: 'default' },
|
||||
output: [testDataRef1],
|
||||
factory() {
|
||||
return [testDataRef1('foo')];
|
||||
},
|
||||
});
|
||||
|
||||
const ext = toInternalExtensionDefinition(
|
||||
blueprint.make({
|
||||
output: [testDataRef2],
|
||||
factory(origFactory) {
|
||||
const parent = origFactory({});
|
||||
return [testDataRef2(`${parent.get(testDataRef1)}bar`)];
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
expect(ext.output).toEqual([testDataRef2]);
|
||||
});
|
||||
|
||||
it('should allow returning of the parent data container', () => {
|
||||
const testDataRef1 = createExtensionDataRef<string>().with({ id: 'test1' });
|
||||
const testDataRef2 = createExtensionDataRef<string>().with({ id: 'test2' });
|
||||
|
||||
const blueprint = createExtensionBlueprint({
|
||||
kind: 'test-extension',
|
||||
attachTo: { id: 'test', input: 'default' },
|
||||
output: [testDataRef1],
|
||||
factory() {
|
||||
return [testDataRef1('foo')];
|
||||
},
|
||||
});
|
||||
|
||||
blueprint.make({
|
||||
output: [testDataRef1, testDataRef2],
|
||||
*factory(origFactory) {
|
||||
yield origFactory({});
|
||||
yield testDataRef2('bar');
|
||||
},
|
||||
});
|
||||
|
||||
expect(true).toBe(true);
|
||||
// todo: test that the data is actually available
|
||||
});
|
||||
|
||||
it('should not allow returning parent output if outputs are overridden', () => {
|
||||
const testDataRef1 = createExtensionDataRef<string>().with({ id: 'test1' });
|
||||
const testDataRef2 = createExtensionDataRef<string>().with({ id: 'test2' });
|
||||
|
||||
const blueprint = createExtensionBlueprint({
|
||||
kind: 'test-extension',
|
||||
attachTo: { id: 'test', input: 'default' },
|
||||
output: [testDataRef1.optional()],
|
||||
factory() {
|
||||
return [testDataRef1('foo')];
|
||||
},
|
||||
});
|
||||
|
||||
blueprint.make({
|
||||
output: [testDataRef2.optional()],
|
||||
*factory(origFactory) {
|
||||
// yield testDataRef1('bar');
|
||||
yield testDataRef2('bar');
|
||||
},
|
||||
});
|
||||
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -204,7 +204,7 @@ class ExtensionBlueprintImpl<
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
UExtraOutput extends AnyExtensionDataRef,
|
||||
UNewOutput extends AnyExtensionDataRef,
|
||||
TExtraInputs extends {
|
||||
[inputName in string]: ExtensionInput<
|
||||
AnyExtensionDataRef,
|
||||
@@ -220,7 +220,7 @@ class ExtensionBlueprintImpl<
|
||||
[KName in keyof TInputs]?: `Error: Input '${KName &
|
||||
string}' is already defined in parent definition`;
|
||||
};
|
||||
output?: Array<UExtraOutput>;
|
||||
output?: Array<UNewOutput>;
|
||||
params?: TParams;
|
||||
config?: {
|
||||
schema: TExtensionConfigSchema;
|
||||
@@ -296,7 +296,7 @@ class ExtensionBlueprintImpl<
|
||||
attachTo: args.attachTo ?? this.options.attachTo,
|
||||
disabled: args.disabled ?? this.options.disabled,
|
||||
inputs: { ...args.inputs, ...this.options.inputs },
|
||||
output: [...(args.output ?? []), ...this.options.output],
|
||||
output: args.output ?? this.options.output,
|
||||
config: Object.keys(schema).length === 0 ? undefined : { schema },
|
||||
factory: ({ node, config, inputs }) => {
|
||||
if (args.factory) {
|
||||
|
||||
Reference in New Issue
Block a user