Improve type-check for scaffolder output parameters
If an action uses zod to define the actions output schema, it is now ensured that `ctx.output` is using only the defined properties Signed-off-by: Andreas Berger <andreas@berger-ecommerce.com>
This commit is contained in:
@@ -33,7 +33,14 @@ export type TemplateActionOptions<
|
||||
input?: TInputSchema;
|
||||
output?: TOutputSchema;
|
||||
};
|
||||
handler: (ctx: ActionContext<TActionInput>) => Promise<void>;
|
||||
handler: (
|
||||
ctx: ActionContext<
|
||||
TActionInput,
|
||||
TOutputSchema extends z.ZodType<any, any, infer IReturn>
|
||||
? IReturn
|
||||
: undefined
|
||||
>,
|
||||
) => Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -48,9 +55,12 @@ export const createTemplateAction = <
|
||||
TActionInput = TInputSchema extends z.ZodType<any, any, infer IReturn>
|
||||
? IReturn
|
||||
: TParams,
|
||||
TActionOutput = TOutputSchema extends z.ZodType<any, any, infer IReturn>
|
||||
? IReturn
|
||||
: undefined,
|
||||
>(
|
||||
action: TemplateActionOptions<TActionInput, TInputSchema, TOutputSchema>,
|
||||
): TemplateAction<TActionInput> => {
|
||||
): TemplateAction<TActionInput, TActionOutput> => {
|
||||
const inputSchema =
|
||||
action.schema?.input && 'safeParseAsync' in action.schema.input
|
||||
? zodToJsonSchema(action.schema.input)
|
||||
@@ -61,7 +71,7 @@ export const createTemplateAction = <
|
||||
? zodToJsonSchema(action.schema.output)
|
||||
: action.schema?.output;
|
||||
|
||||
const templateAction = {
|
||||
return {
|
||||
...action,
|
||||
schema: {
|
||||
...action.schema,
|
||||
@@ -69,6 +79,4 @@ export const createTemplateAction = <
|
||||
output: outputSchema,
|
||||
},
|
||||
};
|
||||
|
||||
return templateAction;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import { Logger } from 'winston';
|
||||
import { Writable } from 'stream';
|
||||
import { JsonObject, JsonValue } from '@backstage/types';
|
||||
import { TaskSecrets } from '../tasks/types';
|
||||
import { TaskSecrets } from '../tasks';
|
||||
import { TemplateInfo } from '@backstage/plugin-scaffolder-common';
|
||||
import { UserEntity } from '@backstage/catalog-model';
|
||||
import { Schema } from 'jsonschema';
|
||||
@@ -26,13 +26,19 @@ import { Schema } from 'jsonschema';
|
||||
* ActionContext is passed into scaffolder actions.
|
||||
* @public
|
||||
*/
|
||||
export type ActionContext<TActionInput extends JsonObject> = {
|
||||
export type ActionContext<
|
||||
TActionInput extends JsonObject,
|
||||
TActionOutput extends JsonObject | undefined = undefined,
|
||||
> = {
|
||||
logger: Logger;
|
||||
logStream: Writable;
|
||||
secrets?: TaskSecrets;
|
||||
workspacePath: string;
|
||||
input: TActionInput;
|
||||
output(name: string, value: JsonValue): void;
|
||||
output<KEY extends keyof TActionOutput>(
|
||||
name: TActionOutput extends undefined ? string : KEY,
|
||||
value: TActionOutput extends undefined ? JsonValue : TActionOutput[KEY],
|
||||
): void;
|
||||
|
||||
/**
|
||||
* Creates a temporary directory for use by the action, which is then cleaned up automatically.
|
||||
@@ -68,7 +74,10 @@ export type ActionContext<TActionInput extends JsonObject> = {
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export type TemplateAction<TActionInput = unknown> = {
|
||||
export type TemplateAction<
|
||||
TActionInput = unknown,
|
||||
TActionOutput = undefined,
|
||||
> = {
|
||||
id: string;
|
||||
description?: string;
|
||||
examples?: { description: string; example: string }[];
|
||||
@@ -77,5 +86,5 @@ export type TemplateAction<TActionInput = unknown> = {
|
||||
input?: Schema;
|
||||
output?: Schema;
|
||||
};
|
||||
handler: (ctx: ActionContext<TActionInput>) => Promise<void>;
|
||||
handler: (ctx: ActionContext<TActionInput, TActionOutput>) => Promise<void>;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user