feat: reworking zod integration a little bit to reduce the amount of typing you have to do

Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2023-02-14 14:31:17 +01:00
parent 7d724d8ef5
commit 10a64ff693
13 changed files with 556 additions and 425 deletions
+19 -6
View File
@@ -13,6 +13,7 @@ import { Schema } from 'jsonschema';
import { TemplateInfo } from '@backstage/plugin-scaffolder-common';
import { UserEntity } from '@backstage/catalog-model';
import { Writable } from 'stream';
import { z } from 'zod';
// @public
export type ActionContext<TInput extends JsonObject> = {
@@ -32,9 +33,12 @@ export type ActionContext<TInput extends JsonObject> = {
};
// @public
export const createTemplateAction: <TInput extends JsonObject>(
templateAction: TemplateAction<TInput>,
) => TemplateAction<TInput>;
export const createTemplateAction: <
TParams,
TInputSchema extends z.ZodType<any, z.ZodTypeDef, any> | Schema = {},
>(
templateAction: TemplateAction<TParams, TInputSchema>,
) => TemplateAction<TParams, TInputSchema>;
// @alpha
export interface ScaffolderActionsExtensionPoint {
@@ -51,7 +55,10 @@ export type TaskSecrets = Record<string, string> & {
};
// @public (undocumented)
export type TemplateAction<TInput extends JsonObject> = {
export type TemplateAction<
TParams,
TInputSchema extends Schema | z.ZodType = {},
> = {
id: string;
description?: string;
examples?: {
@@ -60,9 +67,15 @@ export type TemplateAction<TInput extends JsonObject> = {
}[];
supportsDryRun?: boolean;
schema?: {
input?: Schema;
input?: TInputSchema;
output?: Schema;
};
handler: (ctx: ActionContext<TInput>) => Promise<void>;
handler: (
ctx: ActionContext<
TInputSchema extends z.ZodType<any, any, infer IReturn>
? IReturn
: TParams
>,
) => Promise<void>;
};
```
+2 -1
View File
@@ -29,7 +29,8 @@
"@backstage/plugin-scaffolder-common": "workspace:^",
"@backstage/types": "workspace:^",
"jsonschema": "^1.2.6",
"winston": "^3.2.1"
"winston": "^3.2.1",
"zod": "~3.18.0"
},
"devDependencies": {
"@backstage/cli": "workspace:^"
@@ -14,17 +14,21 @@
* limitations under the License.
*/
import { JsonObject } from '@backstage/types';
import { TemplateAction } from './types';
import { z } from 'zod';
import { Schema } from 'jsonschema';
/**
* This function is used to create new template actions to get type safety.
*
* @public
*/
export const createTemplateAction = <TInput extends JsonObject>(
templateAction: TemplateAction<TInput>,
): TemplateAction<TInput> => {
export const createTemplateAction = <
TParams,
TInputSchema extends Schema | z.ZodType = {},
>(
templateAction: TemplateAction<TParams, TInputSchema>,
): TemplateAction<TParams, TInputSchema> => {
// TODO(blam): Can add some more validation here to validate the action later on
return templateAction;
};
+13 -4
View File
@@ -21,7 +21,7 @@ import { Schema } from 'jsonschema';
import { TaskSecrets } from '../tasks/types';
import { TemplateInfo } from '@backstage/plugin-scaffolder-common';
import { UserEntity } from '@backstage/catalog-model';
import { z } from 'zod';
/**
* ActionContext is passed into scaffolder actions.
* @public
@@ -63,14 +63,23 @@ export type ActionContext<TInput extends JsonObject> = {
};
/** @public */
export type TemplateAction<TInput extends JsonObject> = {
export type TemplateAction<
TParams,
TInputSchema extends Schema | z.ZodType = {},
> = {
id: string;
description?: string;
examples?: { description: string; example: string }[];
supportsDryRun?: boolean;
schema?: {
input?: Schema;
input?: TInputSchema;
output?: Schema;
};
handler: (ctx: ActionContext<TInput>) => Promise<void>;
handler: (
ctx: ActionContext<
TInputSchema extends z.ZodType<any, any, infer IReturn>
? IReturn
: TParams
>,
) => Promise<void>;
};