From 07674c6c62852c688b3f82f0f7ec60f9e798ed04 Mon Sep 17 00:00:00 2001 From: Pranay Prakash Date: Sat, 25 Oct 2025 23:49:50 -0700 Subject: [PATCH 1/2] feat: add type safety for builder configurations with discriminated unions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improves type safety by creating discriminated union types for builder-specific configurations, making it clear which configuration options are required for each builder type. Changes: - Created BaseWorkflowConfig interface with common options - Created StandaloneConfig, VercelBuildOutputConfig, and NextConfig types - Made WorkflowConfig a discriminated union based on buildTarget - Added documentation for each configuration type - Exported new types from @workflow/builders This enables better IntelliSense and type checking when constructing builder configurations, preventing invalid configuration combinations at compile time. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .changeset/add-type-safety.md | 5 ++++ packages/builders/src/index.ts | 8 +++++- packages/builders/src/types.ts | 48 ++++++++++++++++++++++++++++++---- 3 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 .changeset/add-type-safety.md 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..5d9997b92 100644 --- a/packages/builders/src/index.ts +++ b/packages/builders/src/index.ts @@ -1,7 +1,13 @@ 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, +} 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..b79a23332 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,45 @@ 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; +} + +/** + * Discriminated union of all builder configuration types. + */ +export type WorkflowConfig = + | StandaloneConfig + | VercelBuildOutputConfig + | NextConfig; + export function isValidBuildTarget( target: string | undefined ): target is BuildTarget { From 9c754af4df344a2e0e80aca610549b4eb71ee46a Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Mon, 3 Nov 2025 23:14:08 -0800 Subject: [PATCH 2/2] . Signed-off-by: Nathan Rajlich --- packages/builders/src/index.ts | 1 + packages/builders/src/types.ts | 14 +++++++++++++- packages/sveltekit/src/builder.ts | 4 ++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/builders/src/index.ts b/packages/builders/src/index.ts index 5d9997b92..344f785bc 100644 --- a/packages/builders/src/index.ts +++ b/packages/builders/src/index.ts @@ -7,6 +7,7 @@ export type { StandaloneConfig, VercelBuildOutputConfig, NextConfig, + SvelteKitConfig, } from './types.js'; export { validBuildTargets, isValidBuildTarget } from './types.js'; export type { WorkflowManifest } from './apply-swc-transform.js'; diff --git a/packages/builders/src/types.ts b/packages/builders/src/types.ts index b79a23332..5c514142f 100644 --- a/packages/builders/src/types.ts +++ b/packages/builders/src/types.ts @@ -55,13 +55,25 @@ export interface NextConfig extends BaseWorkflowConfig { 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; + | NextConfig + | SvelteKitConfig; export function isValidBuildTarget( target: string | undefined 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'],