@workflow/next 4.0.1-beta.9 → 5.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/builder-deferred.d.ts +2 -0
- package/dist/builder-deferred.d.ts.map +1 -0
- package/dist/builder-deferred.js +1413 -0
- package/dist/builder-deferred.js.map +1 -0
- package/dist/builder-eager.d.ts +2 -0
- package/dist/builder-eager.d.ts.map +1 -0
- package/dist/builder-eager.js +392 -0
- package/dist/builder-eager.js.map +1 -0
- package/dist/builder.d.ts +4 -10
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +25 -311
- package/dist/builder.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +118 -26
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +7 -2
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +410 -38
- package/dist/loader.js.map +1 -1
- package/dist/socket-server.d.ts +48 -0
- package/dist/socket-server.d.ts.map +1 -0
- package/dist/socket-server.js +154 -0
- package/dist/socket-server.js.map +1 -0
- package/dist/step-copy-utils.d.ts +19 -0
- package/dist/step-copy-utils.d.ts.map +1 -0
- package/dist/step-copy-utils.js +101 -0
- package/dist/step-copy-utils.js.map +1 -0
- package/docs/api-reference/index.mdx +18 -0
- package/docs/api-reference/with-workflow.mdx +107 -0
- package/docs/next.mdx +303 -0
- package/package.json +16 -12
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serializeMessage = serializeMessage;
|
|
4
|
+
exports.parseMessage = parseMessage;
|
|
5
|
+
exports.createSocketServer = createSocketServer;
|
|
6
|
+
const node_crypto_1 = require("node:crypto");
|
|
7
|
+
const promises_1 = require("node:fs/promises");
|
|
8
|
+
const node_net_1 = require("node:net");
|
|
9
|
+
const node_path_1 = require("node:path");
|
|
10
|
+
/**
|
|
11
|
+
* Magic preamble that must prefix all messages to authenticate them as workflow messages.
|
|
12
|
+
* This prevents accidental processing of messages from port scanners or other local processes.
|
|
13
|
+
*/
|
|
14
|
+
const MESSAGE_PREAMBLE = 'WF:';
|
|
15
|
+
/**
|
|
16
|
+
* Generate a random authentication token for this server session.
|
|
17
|
+
* Clients must include this token in all messages.
|
|
18
|
+
*/
|
|
19
|
+
function generateAuthToken() {
|
|
20
|
+
return (0, node_crypto_1.randomBytes)(16).toString('hex');
|
|
21
|
+
}
|
|
22
|
+
function getDefaultSocketInfoFilePath() {
|
|
23
|
+
return (0, node_path_1.join)(process.cwd(), '.next', 'cache', 'workflow-socket.json');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Serialize a message with authentication preamble
|
|
27
|
+
*/
|
|
28
|
+
function serializeMessage(message, authToken) {
|
|
29
|
+
return `${MESSAGE_PREAMBLE}${authToken}:${JSON.stringify(message)}\n`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse and authenticate a message from the socket
|
|
33
|
+
* Returns the parsed message if valid, null otherwise
|
|
34
|
+
*/
|
|
35
|
+
function parseMessage(line, authToken) {
|
|
36
|
+
const trimmed = line.trim();
|
|
37
|
+
if (!trimmed) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
// Check for preamble
|
|
41
|
+
if (!trimmed.startsWith(MESSAGE_PREAMBLE)) {
|
|
42
|
+
console.warn('Received message without valid preamble, ignoring');
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
// Extract auth token and payload
|
|
46
|
+
const withoutPreamble = trimmed.slice(MESSAGE_PREAMBLE.length);
|
|
47
|
+
const colonIndex = withoutPreamble.indexOf(':');
|
|
48
|
+
if (colonIndex === -1) {
|
|
49
|
+
console.warn('Received message without auth token separator, ignoring');
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
const messageToken = withoutPreamble.slice(0, colonIndex);
|
|
53
|
+
const payload = withoutPreamble.slice(colonIndex + 1);
|
|
54
|
+
// Verify auth token
|
|
55
|
+
if (messageToken !== authToken) {
|
|
56
|
+
console.warn('Received message with invalid auth token, ignoring');
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
// Parse JSON payload
|
|
60
|
+
try {
|
|
61
|
+
return JSON.parse(payload);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error('Failed to parse socket message JSON:', error);
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create a TCP socket server for loader<->builder communication.
|
|
70
|
+
* Returns a SocketIO interface for broadcasting messages and the auth token.
|
|
71
|
+
*
|
|
72
|
+
* SECURITY: Server listens on 127.0.0.1 (localhost only) and uses
|
|
73
|
+
* message authentication to prevent processing of unauthorized messages.
|
|
74
|
+
*/
|
|
75
|
+
async function createSocketServer(config) {
|
|
76
|
+
const authToken = generateAuthToken();
|
|
77
|
+
const clients = new Set();
|
|
78
|
+
let buildTriggered = false;
|
|
79
|
+
const server = (0, node_net_1.createServer)((socket) => {
|
|
80
|
+
socket.setNoDelay(true);
|
|
81
|
+
clients.add(socket);
|
|
82
|
+
// Send build-complete if build already finished (production mode)
|
|
83
|
+
if (buildTriggered && !config.isDevServer) {
|
|
84
|
+
socket.write(serializeMessage({ type: 'build-complete' }, authToken));
|
|
85
|
+
}
|
|
86
|
+
let buffer = '';
|
|
87
|
+
socket.on('data', (data) => {
|
|
88
|
+
buffer += data.toString();
|
|
89
|
+
// Process complete messages (newline-delimited)
|
|
90
|
+
let newlineIndex = buffer.indexOf('\n');
|
|
91
|
+
while (newlineIndex !== -1) {
|
|
92
|
+
const line = buffer.slice(0, newlineIndex);
|
|
93
|
+
buffer = buffer.slice(newlineIndex + 1);
|
|
94
|
+
newlineIndex = buffer.indexOf('\n');
|
|
95
|
+
const message = parseMessage(line, authToken);
|
|
96
|
+
if (!message) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (message.type === 'file-discovered') {
|
|
100
|
+
config.onFileDiscovered(message.filePath, message.hasWorkflow, message.hasStep, message.hasSerde);
|
|
101
|
+
}
|
|
102
|
+
else if (message.type === 'trigger-build') {
|
|
103
|
+
config.onTriggerBuild();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
socket.on('end', () => {
|
|
108
|
+
clients.delete(socket);
|
|
109
|
+
});
|
|
110
|
+
socket.on('error', (err) => {
|
|
111
|
+
console.error('Socket error:', err);
|
|
112
|
+
clients.delete(socket);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
// Listen on random available port (localhost only)
|
|
116
|
+
await new Promise((resolve, reject) => {
|
|
117
|
+
server.once('error', reject);
|
|
118
|
+
server.listen(0, '127.0.0.1', () => {
|
|
119
|
+
const address = server.address();
|
|
120
|
+
if (address && typeof address === 'object') {
|
|
121
|
+
const socketInfoFilePath = config.socketInfoFilePath || getDefaultSocketInfoFilePath();
|
|
122
|
+
void (async () => {
|
|
123
|
+
try {
|
|
124
|
+
await (0, promises_1.mkdir)((0, node_path_1.dirname)(socketInfoFilePath), { recursive: true });
|
|
125
|
+
await (0, promises_1.writeFile)(socketInfoFilePath, JSON.stringify({
|
|
126
|
+
port: address.port,
|
|
127
|
+
authToken,
|
|
128
|
+
}, null, 2));
|
|
129
|
+
process.env.WORKFLOW_SOCKET_INFO_PATH = socketInfoFilePath;
|
|
130
|
+
process.env.WORKFLOW_SOCKET_PORT = String(address.port);
|
|
131
|
+
process.env.WORKFLOW_SOCKET_AUTH = authToken;
|
|
132
|
+
resolve();
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
reject(error);
|
|
136
|
+
}
|
|
137
|
+
})();
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
reject(new Error('Failed to obtain workflow socket server address'));
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
emit: (_event) => {
|
|
145
|
+
buildTriggered = true;
|
|
146
|
+
const message = serializeMessage({ type: 'build-complete' }, authToken);
|
|
147
|
+
for (const client of clients) {
|
|
148
|
+
client.write(message);
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
getAuthToken: () => authToken,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=socket-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket-server.js","sourceRoot":"","sources":["../src/socket-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const DEFERRED_STEP_COPY_DIR_NAME = "__workflow_step_files__";
|
|
2
|
+
export declare const DEFERRED_STEP_SOURCE_METADATA_PREFIX = "WORKFLOW_STEP_SOURCE_B64:";
|
|
3
|
+
export interface DeferredStepSourceMetadata {
|
|
4
|
+
relativeFilename: string;
|
|
5
|
+
absolutePath: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function isDeferredStepCopyFilePath(filePath: string): boolean;
|
|
8
|
+
export declare function createDeferredStepSourceMetadataComment(metadata: DeferredStepSourceMetadata): string;
|
|
9
|
+
export declare function createDeferredStepCopyInlineSourceMapComment({ sourcePath, sourceContent, generatedContent, }: {
|
|
10
|
+
sourcePath: string;
|
|
11
|
+
sourceContent: string;
|
|
12
|
+
generatedContent?: string;
|
|
13
|
+
}): string;
|
|
14
|
+
export declare function parseInlineSourceMapComment(source: string): {
|
|
15
|
+
sourceWithoutMapComment: string;
|
|
16
|
+
sourceMap: string | null;
|
|
17
|
+
};
|
|
18
|
+
export declare function parseDeferredStepSourceMetadata(source: string): DeferredStepSourceMetadata | null;
|
|
19
|
+
//# sourceMappingURL=step-copy-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-copy-utils.d.ts","sourceRoot":"","sources":["../src/step-copy-utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B,4BAA4B,CAAC;AACrE,eAAO,MAAM,oCAAoC,8BAA8B,CAAC;AAIhF,MAAM,WAAW,0BAA0B;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAUD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAKpE;AAED,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,0BAA0B,GACnC,MAAM,CAKR;AAiBD,wBAAgB,4CAA4C,CAAC,EAC3D,UAAU,EACV,aAAa,EACb,gBAAgB,GACjB,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GAAG,MAAM,CAiBT;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG;IAC3D,uBAAuB,EAAE,MAAM,CAAC;IAChC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAuBA;AAED,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,MAAM,GACb,0BAA0B,GAAG,IAAI,CA8BnC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFERRED_STEP_SOURCE_METADATA_PREFIX = exports.DEFERRED_STEP_COPY_DIR_NAME = void 0;
|
|
4
|
+
exports.isDeferredStepCopyFilePath = isDeferredStepCopyFilePath;
|
|
5
|
+
exports.createDeferredStepSourceMetadataComment = createDeferredStepSourceMetadataComment;
|
|
6
|
+
exports.createDeferredStepCopyInlineSourceMapComment = createDeferredStepCopyInlineSourceMapComment;
|
|
7
|
+
exports.parseInlineSourceMapComment = parseInlineSourceMapComment;
|
|
8
|
+
exports.parseDeferredStepSourceMetadata = parseDeferredStepSourceMetadata;
|
|
9
|
+
exports.DEFERRED_STEP_COPY_DIR_NAME = '__workflow_step_files__';
|
|
10
|
+
exports.DEFERRED_STEP_SOURCE_METADATA_PREFIX = 'WORKFLOW_STEP_SOURCE_B64:';
|
|
11
|
+
const INLINE_SOURCE_MAP_PATTERN = /(?:^|\r?\n)\s*\/\/[#@]\s*sourceMappingURL=data:application\/json(?:;charset=[^;,]+)?;base64,([A-Za-z0-9+/=]+)\s*$/;
|
|
12
|
+
function escapeRegExp(input) {
|
|
13
|
+
return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
14
|
+
}
|
|
15
|
+
function normalizePath(filePath) {
|
|
16
|
+
return filePath.replace(/\\/g, '/');
|
|
17
|
+
}
|
|
18
|
+
function isDeferredStepCopyFilePath(filePath) {
|
|
19
|
+
const normalizedPath = normalizePath(filePath);
|
|
20
|
+
return normalizedPath.includes(`/.well-known/workflow/v1/step/${exports.DEFERRED_STEP_COPY_DIR_NAME}/`);
|
|
21
|
+
}
|
|
22
|
+
function createDeferredStepSourceMetadataComment(metadata) {
|
|
23
|
+
const encoded = Buffer.from(JSON.stringify(metadata), 'utf-8').toString('base64');
|
|
24
|
+
return `// ${exports.DEFERRED_STEP_SOURCE_METADATA_PREFIX}${encoded}`;
|
|
25
|
+
}
|
|
26
|
+
function getLineCount(source) {
|
|
27
|
+
if (source.length === 0) {
|
|
28
|
+
return 1;
|
|
29
|
+
}
|
|
30
|
+
const lineBreakMatches = source.match(/\r\n|\r|\n/g);
|
|
31
|
+
return (lineBreakMatches?.length ?? 0) + 1;
|
|
32
|
+
}
|
|
33
|
+
function createIdentityLineMappings(lineCount) {
|
|
34
|
+
if (lineCount <= 1) {
|
|
35
|
+
return 'AAAA';
|
|
36
|
+
}
|
|
37
|
+
return `AAAA${';AACA'.repeat(lineCount - 1)}`;
|
|
38
|
+
}
|
|
39
|
+
function createDeferredStepCopyInlineSourceMapComment({ sourcePath, sourceContent, generatedContent, }) {
|
|
40
|
+
const normalizedSourcePath = normalizePath(sourcePath);
|
|
41
|
+
const sourceMap = {
|
|
42
|
+
version: 3,
|
|
43
|
+
file: normalizedSourcePath.split('/').pop() ?? normalizedSourcePath,
|
|
44
|
+
sources: [normalizedSourcePath],
|
|
45
|
+
sourcesContent: [sourceContent],
|
|
46
|
+
names: [],
|
|
47
|
+
mappings: createIdentityLineMappings(getLineCount(generatedContent ?? sourceContent)),
|
|
48
|
+
};
|
|
49
|
+
const encodedSourceMap = Buffer.from(JSON.stringify(sourceMap), 'utf-8').toString('base64');
|
|
50
|
+
return `//# sourceMappingURL=data:application/json;base64,${encodedSourceMap}`;
|
|
51
|
+
}
|
|
52
|
+
function parseInlineSourceMapComment(source) {
|
|
53
|
+
const mapMatch = source.match(INLINE_SOURCE_MAP_PATTERN);
|
|
54
|
+
if (!mapMatch?.[1]) {
|
|
55
|
+
return {
|
|
56
|
+
sourceWithoutMapComment: source,
|
|
57
|
+
sourceMap: null,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const sourceWithoutMapComment = source.replace(INLINE_SOURCE_MAP_PATTERN, '');
|
|
61
|
+
try {
|
|
62
|
+
const decodedMap = Buffer.from(mapMatch[1], 'base64').toString('utf-8');
|
|
63
|
+
JSON.parse(decodedMap);
|
|
64
|
+
return {
|
|
65
|
+
sourceWithoutMapComment,
|
|
66
|
+
sourceMap: decodedMap,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return {
|
|
71
|
+
sourceWithoutMapComment,
|
|
72
|
+
sourceMap: null,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function parseDeferredStepSourceMetadata(source) {
|
|
77
|
+
const pattern = new RegExp(`^\\s*//\\s*${escapeRegExp(exports.DEFERRED_STEP_SOURCE_METADATA_PREFIX)}([A-Za-z0-9+/=]+)\\s*$`, 'm');
|
|
78
|
+
const match = source.match(pattern);
|
|
79
|
+
const encoded = match?.[1];
|
|
80
|
+
if (!encoded) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
|
|
85
|
+
const parsed = JSON.parse(decoded);
|
|
86
|
+
if (typeof parsed.relativeFilename !== 'string' ||
|
|
87
|
+
parsed.relativeFilename.length === 0 ||
|
|
88
|
+
typeof parsed.absolutePath !== 'string' ||
|
|
89
|
+
parsed.absolutePath.length === 0) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
relativeFilename: parsed.relativeFilename,
|
|
94
|
+
absolutePath: normalizePath(parsed.absolutePath),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=step-copy-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-copy-utils.js","sourceRoot":"","sources":["../src/step-copy-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "workflow/next"
|
|
3
|
+
description: Next.js integration for automatic bundling and runtime configuration.
|
|
4
|
+
type: overview
|
|
5
|
+
summary: Explore the Next.js integration for automatic workflow bundling and runtime support.
|
|
6
|
+
related:
|
|
7
|
+
- /docs/getting-started/next
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Next.js integration for Workflow SDK that automatically configures bundling and runtime support.
|
|
11
|
+
|
|
12
|
+
## Functions
|
|
13
|
+
|
|
14
|
+
<Cards>
|
|
15
|
+
<Card title="withWorkflow" href="/docs/api-reference/workflow-next/with-workflow">
|
|
16
|
+
Configures webpack/turbopack loaders to transform workflow code (`"use step"`/`"use workflow"` directives)
|
|
17
|
+
</Card>
|
|
18
|
+
</Cards>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: withWorkflow
|
|
3
|
+
description: Configure webpack/turbopack to transform workflow directives in Next.js.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Wrap your Next.js config with withWorkflow to enable workflow directive transformation.
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /docs/getting-started/next
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Configures webpack/turbopack loaders to transform workflow code (`"use step"`/`"use workflow"` directives)
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
To enable `"use step"` and `"use workflow"` directives while developing locally or deploying to production, wrap your `nextConfig` with `withWorkflow`.
|
|
15
|
+
|
|
16
|
+
```typescript title="next.config.ts" lineNumbers
|
|
17
|
+
import { withWorkflow } from "workflow/next"; // [!code highlight]
|
|
18
|
+
import type { NextConfig } from "next";
|
|
19
|
+
|
|
20
|
+
const nextConfig: NextConfig = {
|
|
21
|
+
// … rest of your Next.js config
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// not required but allows configuring workflow options
|
|
25
|
+
const workflowConfig = {}
|
|
26
|
+
|
|
27
|
+
export default withWorkflow(nextConfig, workflowConfig); // [!code highlight]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Monorepos and Workspace Imports
|
|
31
|
+
|
|
32
|
+
By default, Next.js detects the correct workspace root automatically. If your Next.js app lives in a subdirectory such as `apps/web` and workspace resolution is not working correctly, you can set `outputFileTracingRoot` as a workaround:
|
|
33
|
+
|
|
34
|
+
```typescript title="apps/web/next.config.ts" lineNumbers
|
|
35
|
+
import { resolve } from "node:path";
|
|
36
|
+
import type { NextConfig } from "next";
|
|
37
|
+
import { withWorkflow } from "workflow/next";
|
|
38
|
+
|
|
39
|
+
const nextConfig: NextConfig = {
|
|
40
|
+
outputFileTracingRoot: resolve(process.cwd(), "../.."),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export default withWorkflow(nextConfig);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
<Callout type="info">
|
|
47
|
+
Use the smallest directory that contains every workspace package imported by your workflows. If your app already lives at the repository root, you do not need to set `outputFileTracingRoot`.
|
|
48
|
+
</Callout>
|
|
49
|
+
|
|
50
|
+
## Options
|
|
51
|
+
|
|
52
|
+
`withWorkflow` accepts an optional second argument to configure the Next.js integration.
|
|
53
|
+
|
|
54
|
+
```typescript title="next.config.ts" lineNumbers
|
|
55
|
+
import type { NextConfig } from "next";
|
|
56
|
+
import { withWorkflow } from "workflow/next";
|
|
57
|
+
|
|
58
|
+
const nextConfig: NextConfig = {};
|
|
59
|
+
|
|
60
|
+
export default withWorkflow(nextConfig, {
|
|
61
|
+
workflows: {
|
|
62
|
+
lazyDiscovery: true,
|
|
63
|
+
local: {
|
|
64
|
+
port: 4000,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Option | Type | Default | Description |
|
|
71
|
+
| --- | --- | --- | --- |
|
|
72
|
+
| `workflows.lazyDiscovery` | `boolean` | `false` | When `true`, defers workflow discovery until files are requested instead of scanning eagerly at startup. Useful for large projects where startup time matters. |
|
|
73
|
+
| `workflows.local.port` | `number` | — | Overrides the `PORT` environment variable for local development. Has no effect when deployed to Vercel. |
|
|
74
|
+
|
|
75
|
+
<Callout type="info">
|
|
76
|
+
The `workflows.local` options only affect local development. When deployed to Vercel, the runtime ignores `local` settings and uses the Vercel world automatically.
|
|
77
|
+
</Callout>
|
|
78
|
+
|
|
79
|
+
## Exporting a Function
|
|
80
|
+
|
|
81
|
+
If you are exporting a function in your `next.config` you will need to ensure you call the function returned from `withWorkflow`.
|
|
82
|
+
|
|
83
|
+
```typescript title="next.config.ts" lineNumbers
|
|
84
|
+
import { NextConfig } from "next";
|
|
85
|
+
import { withWorkflow } from "workflow/next";
|
|
86
|
+
import createNextIntlPlugin from "next-intl/plugin";
|
|
87
|
+
|
|
88
|
+
const withNextIntl = createNextIntlPlugin();
|
|
89
|
+
|
|
90
|
+
export default async function config(
|
|
91
|
+
phase: string,
|
|
92
|
+
ctx: {
|
|
93
|
+
defaultConfig: NextConfig
|
|
94
|
+
}
|
|
95
|
+
): Promise<NextConfig> {
|
|
96
|
+
let nextConfig: NextConfig | typeof config = {};
|
|
97
|
+
|
|
98
|
+
for (const configModifier of [withNextIntl, withWorkflow]) {
|
|
99
|
+
nextConfig = configModifier(nextConfig);
|
|
100
|
+
|
|
101
|
+
if (typeof nextConfig === "function") {
|
|
102
|
+
nextConfig = await nextConfig(phase, ctx);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return nextConfig;
|
|
106
|
+
}
|
|
107
|
+
```
|