diff --git a/.changeset/add-type-safety.md b/.changeset/add-type-safety.md new file mode 100644 index 000000000..4594af007 --- /dev/null +++ b/.changeset/add-type-safety.md @@ -0,0 +1,5 @@ +--- +"@workflow/builders": patch +--- + +Add type safety for builder configurations with discriminated unions diff --git a/packages/builders/src/index.ts b/packages/builders/src/index.ts index a305ca58a..344f785bc 100644 --- a/packages/builders/src/index.ts +++ b/packages/builders/src/index.ts @@ -1,7 +1,14 @@ export { BaseBuilder } from './base-builder.js'; export { StandaloneBuilder } from './standalone.js'; export { VercelBuildOutputAPIBuilder } from './vercel-build-output-api.js'; -export type { WorkflowConfig, BuildTarget } from './types.js'; +export type { + WorkflowConfig, + BuildTarget, + StandaloneConfig, + VercelBuildOutputConfig, + NextConfig, + SvelteKitConfig, +} from './types.js'; export { validBuildTargets, isValidBuildTarget } from './types.js'; export type { WorkflowManifest } from './apply-swc-transform.js'; export { applySwcTransform } from './apply-swc-transform.js'; diff --git a/packages/builders/src/types.ts b/packages/builders/src/types.ts index 4bb99785c..5c514142f 100644 --- a/packages/builders/src/types.ts +++ b/packages/builders/src/types.ts @@ -6,14 +6,13 @@ export const validBuildTargets = [ ] as const; export type BuildTarget = (typeof validBuildTargets)[number]; -export interface WorkflowConfig { +/** + * Common configuration options shared across all builder types. + */ +interface BaseWorkflowConfig { watch?: boolean; dirs: string[]; workingDir: string; - buildTarget: BuildTarget; - stepsBundlePath: string; - workflowsBundlePath: string; - webhookBundlePath: string; // Optionally generate a client library for workflow execution. The preferred // method of using workflow is to use a loader within a framework (like @@ -25,6 +24,57 @@ export interface WorkflowConfig { workflowManifestPath?: string; } +/** + * Configuration for standalone (CLI-based) builds. + */ +export interface StandaloneConfig extends BaseWorkflowConfig { + buildTarget: 'standalone'; + stepsBundlePath: string; + workflowsBundlePath: string; + webhookBundlePath: string; +} + +/** + * Configuration for Vercel Build Output API builds. + */ +export interface VercelBuildOutputConfig extends BaseWorkflowConfig { + buildTarget: 'vercel-build-output-api'; + stepsBundlePath: string; + workflowsBundlePath: string; + webhookBundlePath: string; +} + +/** + * Configuration for Next.js builds. + */ +export interface NextConfig extends BaseWorkflowConfig { + buildTarget: 'next'; + // Next.js builder computes paths dynamically, so these are not used + stepsBundlePath: string; + workflowsBundlePath: string; + webhookBundlePath: string; +} + +/** + * Configuration for SvelteKit builds. + */ +export interface SvelteKitConfig extends BaseWorkflowConfig { + buildTarget: 'sveltekit'; + // SvelteKit builder computes paths dynamically, so these are not used + stepsBundlePath: string; + workflowsBundlePath: string; + webhookBundlePath: string; +} + +/** + * Discriminated union of all builder configuration types. + */ +export type WorkflowConfig = + | StandaloneConfig + | VercelBuildOutputConfig + | NextConfig + | SvelteKitConfig; + export function isValidBuildTarget( target: string | undefined ): target is BuildTarget { diff --git a/packages/sveltekit/src/builder.ts b/packages/sveltekit/src/builder.ts index 90409d3df..c49fa67bf 100644 --- a/packages/sveltekit/src/builder.ts +++ b/packages/sveltekit/src/builder.ts @@ -1,7 +1,7 @@ import { constants } from 'node:fs'; import { access, mkdir, readFile, stat, writeFile } from 'node:fs/promises'; import { join, resolve } from 'node:path'; -import { BaseBuilder, type WorkflowConfig } from '@workflow/builders'; +import { BaseBuilder, type SvelteKitConfig } from '@workflow/builders'; // Helper function code for converting SvelteKit requests to standard Request objects const SVELTEKIT_REQUEST_CONVERTER = ` @@ -18,7 +18,7 @@ async function convertSvelteKitRequest(request) { `; export class SvelteKitBuilder extends BaseBuilder { - constructor(config?: Partial) { + constructor(config?: Partial) { super({ ...config, dirs: ['workflows'],