chore: wip
Signed-off-by: blam <ben@blam.sh> Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
@@ -14,42 +14,24 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { JsonObject, Prettify } from '@backstage/types';
|
||||
import type { Schema } from 'jsonschema';
|
||||
import { ActionContext, TemplateAction } from './types';
|
||||
import { z } from 'zod';
|
||||
import { Schema } from 'jsonschema';
|
||||
import zodToJsonSchema from 'zod-to-json-schema';
|
||||
import type {
|
||||
InferActionType,
|
||||
ActionContextV2,
|
||||
TemplateActionV2,
|
||||
ActionContextV1,
|
||||
TemplateActionV1,
|
||||
TemplateExample,
|
||||
} from './types';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
|
||||
/**
|
||||
* @deprecated migrate to {@link TemplateActionOptionsV2}
|
||||
* @public
|
||||
*/
|
||||
export type TemplateActionOptionsV1<
|
||||
TInputParams extends JsonObject = JsonObject,
|
||||
TOutputParams extends JsonObject = JsonObject,
|
||||
TInputSchema extends Schema | z.ZodType = Schema,
|
||||
TOutputSchema extends Schema | z.ZodType = Schema,
|
||||
TActionInput extends JsonObject = TInputSchema extends z.ZodType<
|
||||
any,
|
||||
any,
|
||||
infer IReturn
|
||||
>
|
||||
? IReturn
|
||||
: TInputParams,
|
||||
TActionOutput extends JsonObject = TOutputSchema extends z.ZodType<
|
||||
any,
|
||||
any,
|
||||
infer IReturn
|
||||
>
|
||||
? IReturn
|
||||
: TOutputParams,
|
||||
/** @public */
|
||||
export type TemplateExample = {
|
||||
description: string;
|
||||
example: string;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export type TemplateActionOptions<
|
||||
TActionInput extends JsonObject = {},
|
||||
TActionOutput extends JsonObject = {},
|
||||
TInputSchema extends Schema | z.ZodType = {},
|
||||
TOutputSchema extends Schema | z.ZodType = {},
|
||||
> = {
|
||||
id: string;
|
||||
description?: string;
|
||||
@@ -59,89 +41,15 @@ export type TemplateActionOptionsV1<
|
||||
input?: TInputSchema;
|
||||
output?: TOutputSchema;
|
||||
};
|
||||
handler: (ctx: ActionContextV1<TActionInput, TActionOutput>) => Promise<void>;
|
||||
handler: (ctx: ActionContext<TActionInput, TActionOutput>) => Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type TemplateActionOptionsV2<
|
||||
TInputParams extends Record<
|
||||
PropertyKey,
|
||||
(zod: typeof z) => z.ZodType
|
||||
> = Record<PropertyKey, (zod: typeof z) => z.ZodType>,
|
||||
TOutputParams extends Record<
|
||||
PropertyKey,
|
||||
(zod: typeof z) => z.ZodType
|
||||
> = Record<PropertyKey, (zod: typeof z) => z.ZodType>,
|
||||
> = {
|
||||
id: string;
|
||||
description?: string;
|
||||
examples?: TemplateExample[];
|
||||
supportsDryRun?: boolean;
|
||||
schema: {
|
||||
input: TInputParams;
|
||||
output: TOutputParams;
|
||||
};
|
||||
handler: (
|
||||
ctx: ActionContextV2<
|
||||
InferActionType<TInputParams>,
|
||||
InferActionType<TOutputParams>
|
||||
>,
|
||||
) => Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated migrate to {@link TemplateActionOptionsV2}
|
||||
* @public
|
||||
*/
|
||||
export type TemplateActionOptions<
|
||||
TInputParams extends JsonObject = JsonObject,
|
||||
TOutputParams extends JsonObject = JsonObject,
|
||||
TInputSchema extends Schema | z.ZodType = Schema,
|
||||
TOutputSchema extends Schema | z.ZodType = Schema,
|
||||
TActionInput extends JsonObject = TInputSchema extends z.ZodType<
|
||||
any,
|
||||
any,
|
||||
infer IReturn
|
||||
>
|
||||
? IReturn
|
||||
: TInputParams,
|
||||
TActionOutput extends JsonObject = TOutputSchema extends z.ZodType<
|
||||
any,
|
||||
any,
|
||||
infer IReturn
|
||||
>
|
||||
? IReturn
|
||||
: TOutputParams,
|
||||
> = TemplateActionOptionsV1<
|
||||
TInputParams,
|
||||
TOutputParams,
|
||||
TInputSchema,
|
||||
TOutputSchema,
|
||||
TActionInput,
|
||||
TActionOutput
|
||||
>;
|
||||
|
||||
function isZod(schema?: Schema | z.ZodType): schema is z.ZodType {
|
||||
return !!(schema && 'safeParseAsync' in schema);
|
||||
}
|
||||
|
||||
function transformZodRecordToObject(
|
||||
record: Record<PropertyKey, (zod: typeof z) => z.ZodType>,
|
||||
): z.ZodObject<Record<PropertyKey, z.ZodType>> {
|
||||
return z.object(
|
||||
Object.fromEntries(Object.entries(record).map(([k, v]) => [k, v(z)])),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used to create new template actions to get type safety.
|
||||
* Will convert zod schemas to json schemas for use throughout the system.
|
||||
* @deprecated migrate to {@link createTemplateActionV2}
|
||||
* @public
|
||||
*/
|
||||
export function createTemplateActionV1<
|
||||
export const createTemplateAction = <
|
||||
TInputParams extends JsonObject = JsonObject,
|
||||
TOutputParams extends JsonObject = JsonObject,
|
||||
TInputSchema extends Schema | z.ZodType = {},
|
||||
@@ -161,91 +69,29 @@ export function createTemplateActionV1<
|
||||
? IReturn
|
||||
: TOutputParams,
|
||||
>(
|
||||
action: TemplateActionOptionsV1<
|
||||
TInputParams,
|
||||
TOutputParams,
|
||||
TInputSchema,
|
||||
TOutputSchema,
|
||||
action: TemplateActionOptions<
|
||||
TActionInput,
|
||||
TActionOutput
|
||||
TActionOutput,
|
||||
TInputSchema,
|
||||
TOutputSchema
|
||||
>,
|
||||
): TemplateActionV1<TActionInput, TActionOutput> {
|
||||
): TemplateAction<TActionInput, TActionOutput> => {
|
||||
const inputSchema =
|
||||
action.schema && action.schema.input && isZod(action.schema.input)
|
||||
? (zodToJsonSchema(action.schema.input) as Schema)
|
||||
action.schema?.input && 'safeParseAsync' in action.schema.input
|
||||
? zodToJsonSchema(action.schema.input)
|
||||
: action.schema?.input;
|
||||
|
||||
const outputSchema =
|
||||
action.schema && action.schema.output && isZod(action.schema.output)
|
||||
? (zodToJsonSchema(action.schema.output) as Schema)
|
||||
action.schema?.output && 'safeParseAsync' in action.schema.output
|
||||
? zodToJsonSchema(action.schema.output)
|
||||
: action.schema?.output;
|
||||
|
||||
return {
|
||||
...action,
|
||||
schema: {
|
||||
...action.schema,
|
||||
input: inputSchema,
|
||||
output: outputSchema,
|
||||
input: inputSchema as TInputSchema,
|
||||
output: outputSchema as TOutputSchema,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used to create new template actions to get type safety.
|
||||
* Will convert zod schemas to json schemas for use throughout the system.
|
||||
* @public
|
||||
*/
|
||||
export function createTemplateActionV2<
|
||||
TInputParams extends Record<PropertyKey, (zod: typeof z) => z.ZodType>,
|
||||
TOutputParams extends Record<PropertyKey, (zod: typeof z) => z.ZodType>,
|
||||
>(
|
||||
action: TemplateActionOptionsV2<TInputParams, TOutputParams>,
|
||||
): TemplateActionV2<
|
||||
InferActionType<TInputParams>,
|
||||
InferActionType<TOutputParams>
|
||||
> {
|
||||
const input = transformZodRecordToObject(action.schema.input);
|
||||
const output = transformZodRecordToObject(action.schema.output);
|
||||
|
||||
return {
|
||||
...action,
|
||||
schema: {
|
||||
...action.schema,
|
||||
input: zodToJsonSchema(input) as Schema,
|
||||
output: zodToJsonSchema(output) as Schema,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function isV1Action(
|
||||
action: TemplateActionOptionsV1 | TemplateActionOptionsV2,
|
||||
): action is TemplateActionOptionsV1 {
|
||||
return (
|
||||
isZod(action.schema?.input) ||
|
||||
typeof action.schema?.input === 'string' ||
|
||||
isZod(action.schema?.output) ||
|
||||
typeof action.schema?.output === 'string'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used to create new template actions to get type safety.
|
||||
* Will convert zod schemas to json schemas for use throughout the system.
|
||||
* @public
|
||||
*/
|
||||
export function createTemplateAction<
|
||||
TInputParams extends JsonObject = JsonObject,
|
||||
TOutputParams extends JsonObject = JsonObject,
|
||||
TAction extends
|
||||
| TemplateActionOptionsV1
|
||||
| TemplateActionOptionsV2 = TemplateActionOptionsV1,
|
||||
TReturn = TAction extends TemplateActionOptionsV1
|
||||
? Prettify<TemplateActionV1<TInputParams, TOutputParams>>
|
||||
: Prettify<TemplateActionV2>,
|
||||
>(action: TAction): TReturn {
|
||||
if (isV1Action(action)) {
|
||||
return createTemplateActionV1(action) as TReturn;
|
||||
}
|
||||
|
||||
return createTemplateActionV2(action) as TReturn;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -16,31 +16,21 @@
|
||||
|
||||
export {
|
||||
createTemplateAction,
|
||||
type TemplateActionOptionsV2,
|
||||
type TemplateActionOptionsV1,
|
||||
type TemplateActionOptions,
|
||||
type TemplateExample,
|
||||
} from './createTemplateAction';
|
||||
export {
|
||||
executeShellCommand,
|
||||
type ExecuteShellCommandOptions,
|
||||
} from './executeShellCommand';
|
||||
export { fetchContents, fetchFile } from './fetch';
|
||||
export { type ActionContext, type TemplateAction } from './types';
|
||||
export {
|
||||
addFiles,
|
||||
cloneRepo,
|
||||
commitAndPushBranch,
|
||||
commitAndPushRepo,
|
||||
createBranch,
|
||||
initRepoAndPush,
|
||||
commitAndPushRepo,
|
||||
commitAndPushBranch,
|
||||
addFiles,
|
||||
createBranch,
|
||||
cloneRepo,
|
||||
} from './gitHelpers';
|
||||
export type {
|
||||
ActionContext,
|
||||
ActionContextV1,
|
||||
ActionContextV2,
|
||||
InferActionType,
|
||||
TemplateAction,
|
||||
TemplateActionV1,
|
||||
TemplateActionV2,
|
||||
TemplateExample,
|
||||
} from './types';
|
||||
export { getRepoSourceDirectory, parseRepoUrl } from './util';
|
||||
export { parseRepoUrl, getRepoSourceDirectory } from './util';
|
||||
|
||||
@@ -14,45 +14,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type {
|
||||
BackstageCredentials,
|
||||
LoggerService,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import type { UserEntity } from '@backstage/catalog-model';
|
||||
import type { TemplateInfo } from '@backstage/plugin-scaffolder-common';
|
||||
import type { JsonObject, JsonValue, Prettify } from '@backstage/types';
|
||||
import type { Schema } from 'jsonschema';
|
||||
import type { Writable } from 'stream';
|
||||
import type { Logger } from 'winston';
|
||||
import { z } from 'zod';
|
||||
import type { TaskSecrets } from '../tasks';
|
||||
import { Logger } from 'winston';
|
||||
import { Writable } from 'stream';
|
||||
import { JsonObject, JsonValue } from '@backstage/types';
|
||||
import { TaskSecrets } from '../tasks';
|
||||
import { TemplateInfo } from '@backstage/plugin-scaffolder-common';
|
||||
import { UserEntity } from '@backstage/catalog-model';
|
||||
import { Schema } from 'jsonschema';
|
||||
import { BackstageCredentials } from '@backstage/backend-plugin-api';
|
||||
|
||||
/**
|
||||
* ActionContext is passed into scaffolder actions.
|
||||
* @public
|
||||
*/
|
||||
export type TemplateExample = {
|
||||
description: string;
|
||||
example: string;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export type InferActionType<
|
||||
T extends Record<PropertyKey, (zod: typeof z) => z.ZodType>,
|
||||
> = Prettify<{
|
||||
[K in keyof T]: T[K] extends (
|
||||
zod: typeof z,
|
||||
) => z.ZodType<any, any, infer IReturn>
|
||||
? Extract<IReturn, JsonValue | undefined>
|
||||
: never;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* ActionContextV1 is passed into scaffolder actions.
|
||||
* @deprecated migrate to {@link ActionContextV2}
|
||||
* @public
|
||||
*/
|
||||
export type ActionContextV1<
|
||||
TActionInput extends JsonObject = JsonObject,
|
||||
export type ActionContext<
|
||||
TActionInput extends JsonObject,
|
||||
TActionOutput extends JsonObject = JsonObject,
|
||||
> = {
|
||||
// TODO(blam): move this to LoggerService
|
||||
@@ -67,10 +43,8 @@ export type ActionContextV1<
|
||||
fn: () => Promise<T> | T;
|
||||
}): Promise<T>;
|
||||
output(
|
||||
...params: {
|
||||
/* This maps the key to the value for type checking */
|
||||
[K in keyof TActionOutput]: [name: K, value: TActionOutput[K]];
|
||||
}[keyof TActionOutput]
|
||||
name: keyof TActionOutput,
|
||||
value: TActionOutput[keyof TActionOutput],
|
||||
): void;
|
||||
|
||||
/**
|
||||
@@ -123,123 +97,18 @@ export type ActionContextV1<
|
||||
each?: JsonObject;
|
||||
};
|
||||
|
||||
/**
|
||||
* ActionContextV2 is passed into scaffolder actions.
|
||||
* @public
|
||||
*/
|
||||
export type ActionContextV2<
|
||||
TActionInput extends JsonObject = JsonObject,
|
||||
TActionOutput extends JsonObject = JsonObject,
|
||||
> = {
|
||||
logger: LoggerService;
|
||||
secrets?: TaskSecrets;
|
||||
workspacePath: string;
|
||||
input: TActionInput;
|
||||
checkpoint<U extends JsonValue>(
|
||||
key: string,
|
||||
fn: () => Promise<U>,
|
||||
): Promise<U>;
|
||||
output(
|
||||
...params: {
|
||||
/* This maps the key to the value for type checking */
|
||||
[K in keyof TActionOutput]: [name: K, value: TActionOutput[K]];
|
||||
}[keyof TActionOutput]
|
||||
): void;
|
||||
|
||||
/**
|
||||
* Creates a temporary directory for use by the action, which is then cleaned up automatically.
|
||||
*/
|
||||
createTemporaryDirectory(): Promise<string>;
|
||||
|
||||
/**
|
||||
* Get the credentials for the current request
|
||||
*/
|
||||
getInitiatorCredentials(): Promise<BackstageCredentials>;
|
||||
|
||||
templateInfo?: TemplateInfo;
|
||||
|
||||
/**
|
||||
* Whether this action invocation is a dry-run or not.
|
||||
* This will only ever be true if the actions as marked as supporting dry-runs.
|
||||
*/
|
||||
isDryRun?: boolean;
|
||||
|
||||
/**
|
||||
* The user which triggered the action.
|
||||
*/
|
||||
user?: {
|
||||
/**
|
||||
* The decorated entity from the Catalog
|
||||
*/
|
||||
entity?: UserEntity;
|
||||
/**
|
||||
* An entity ref for the author of the task
|
||||
*/
|
||||
ref?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implement the signal to make your custom step abortable https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
|
||||
*/
|
||||
signal?: AbortSignal;
|
||||
|
||||
/**
|
||||
* Optional value of each invocation
|
||||
*/
|
||||
each?: JsonObject;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated migrate to {@link ActionContextV2}
|
||||
* @public
|
||||
*/
|
||||
export type ActionContext<
|
||||
TActionInput extends JsonObject = JsonObject,
|
||||
TActionOutput extends JsonObject = JsonObject,
|
||||
> = ActionContextV2<TActionInput, TActionOutput>;
|
||||
|
||||
/**
|
||||
* @deprecated migrate to {@link TemplateActionV2}
|
||||
* @public
|
||||
*/
|
||||
export type TemplateActionV1<
|
||||
/** @public */
|
||||
export type TemplateAction<
|
||||
TActionInput extends JsonObject = JsonObject,
|
||||
TActionOutput extends JsonObject = JsonObject,
|
||||
> = {
|
||||
id: string;
|
||||
description?: string;
|
||||
examples?: TemplateExample[];
|
||||
examples?: { description: string; example: string }[];
|
||||
supportsDryRun?: boolean;
|
||||
schema?: {
|
||||
input?: Schema;
|
||||
output?: Schema;
|
||||
};
|
||||
handler: (ctx: ActionContextV1<TActionInput, TActionOutput>) => Promise<void>;
|
||||
handler: (ctx: ActionContext<TActionInput, TActionOutput>) => Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type TemplateActionV2<
|
||||
TActionInput extends JsonObject = JsonObject,
|
||||
TActionOutput extends JsonObject = JsonObject,
|
||||
> = {
|
||||
id: string;
|
||||
description?: string;
|
||||
examples?: TemplateExample[];
|
||||
supportsDryRun?: boolean;
|
||||
schema: {
|
||||
input: Schema;
|
||||
output: Schema;
|
||||
};
|
||||
handler: (ctx: ActionContextV2<TActionInput, TActionOutput>) => Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated migrate to {@link ActionContextV2}
|
||||
* @public
|
||||
*/
|
||||
export type TemplateAction<
|
||||
TActionInput extends JsonObject = JsonObject,
|
||||
TActionOutput extends JsonObject = JsonObject,
|
||||
> = TemplateActionV1<TActionInput, TActionOutput>;
|
||||
|
||||
Reference in New Issue
Block a user