Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/create-builders-package.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@workflow/builders": patch
"@workflow/cli": patch
"@workflow/nitro": patch
---

Create @workflow/builders package with shared builder infrastructure
5 changes: 5 additions & 0 deletions .changeset/famous-jeans-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@workflow/cli": patch
---

Rename vercel-static builder to standalone
43 changes: 43 additions & 0 deletions packages/builders/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# @workflow/builders

Shared builder infrastructure for Workflow DevKit. This package provides the base builder class and utilities used by framework-specific integrations.

## Overview

This package contains the core build logic for transforming workflow source files into deployable bundles. It is used by:

- `@workflow/cli` - For standalone/basic builds
- `@workflow/next` - For Next.js integration
- `@workflow/nitro` - For Nitro/Nuxt integration

## Key Components

- **BaseBuilder**: Abstract base class providing common build logic
- **Build plugins**: esbuild plugins for workflow transformations
- **SWC integration**: Compiler plugin integration for workflow directives

## Usage

This package is typically not used directly. Instead, use one of the framework-specific packages that extend `BaseBuilder`:

```typescript
import { BaseBuilder } from '@workflow/builders';

class MyBuilder extends BaseBuilder {
async build(): Promise<void> {
// Implement builder-specific logic
}
}
```

## Architecture

The builder system uses:

1. **esbuild** for bundling and tree-shaking
2. **SWC** for transforming workflow directives (`"use workflow"`, `"use step"`)
3. **Enhanced resolve** for TypeScript path mapping

## License

MIT
54 changes: 54 additions & 0 deletions packages/builders/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"name": "@workflow/builders",
"version": "4.0.1-beta.3",
"description": "Shared builder infrastructure for Workflow DevKit",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./base-builder": {
"types": "./dist/base-builder.d.ts",
"default": "./dist/base-builder.js"
}
},
"files": [
"dist"
],
"publishConfig": {
"access": "public"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/vercel/workflow.git",
"directory": "packages/builders"
},
"scripts": {
"build": "tsc",
"clean": "tsc --build --clean && rm -r dist ||:",
"dev": "tsc --watch",
"test": "vitest run src",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@types/node": "catalog:",
"@workflow/tsconfig": "workspace:*"
},
"dependencies": {
"@swc/core": "1.11.24",
"@workflow/swc-plugin": "workspace:*",
"@workflow/errors": "workspace:*",
"@workflow/core": "workspace:*",
"builtin-modules": "^5.0.0",
"chalk": "^5.6.2",
"comment-json": "4.2.5",
"enhanced-resolve": "5.18.2",
"esbuild": "catalog:",
"find-up": "7.0.0",
"tinyglobby": "^0.2.14"
}
}
76 changes: 76 additions & 0 deletions packages/builders/src/apply-swc-transform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { transform } from '@swc/core';
import { createRequire } from 'module';

const require = createRequire(import.meta.filename);

export type WorkflowManifest = {
steps?: {
[relativeFileName: string]: {
[functionName: string]: {
stepId: string;
};
};
};
workflows?: {
[relativeFileName: string]: {
[functionName: string]: {
workflowId: string;
};
};
};
};

export async function applySwcTransform(
filename: string,
source: string,
mode: 'workflow' | 'step' | 'client' | false,
jscConfig?: {
paths?: Record<string, string[]>;
// this must be absolute path
baseUrl?: string;
}
): Promise<{
code: string;
workflowManifest: WorkflowManifest;
}> {
// Determine if this is a TypeScript file
const isTypeScript = filename.endsWith('.ts') || filename.endsWith('.tsx');
const isTsx = filename.endsWith('.tsx');

// Transform with SWC to support syntax esbuild doesn't
const result = await transform(source, {
filename,
swcrc: false,
jsc: {
parser: {
syntax: isTypeScript ? 'typescript' : 'ecmascript',
tsx: isTsx,
},
target: 'es2022',
experimental: mode
? {
plugins: [[require.resolve('@workflow/swc-plugin'), { mode }]],
}
: undefined,
...jscConfig,
},
// TODO: investigate proper source map support as they
// won't even be used in Node.js by default unless we
// intercept errors and apply them ourselves
sourceMaps: false,
minify: false,
});

const workflowCommentMatch = result.code.match(
/\/\*\*__internal_workflows({.*?})\*\//s
);

const parsedWorkflows = JSON.parse(
workflowCommentMatch?.[1] || '{}'
) as WorkflowManifest;

return {
code: result.code,
workflowManifest: parsedWorkflows || {},
};
}
Loading