@workflow/next 5.0.0-beta.4 → 5.0.0-beta.41

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.
Files changed (40) hide show
  1. package/dist/builder-eager.d.ts +1 -1
  2. package/dist/builder-eager.d.ts.map +1 -1
  3. package/dist/builder-eager.js +377 -220
  4. package/dist/builder.d.ts +1 -4
  5. package/dist/builder.d.ts.map +1 -1
  6. package/dist/builder.js +2 -28
  7. package/dist/index.d.ts +8 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +333 -55
  10. package/dist/loader.d.ts +5 -0
  11. package/dist/loader.d.ts.map +1 -1
  12. package/dist/loader.js +15 -341
  13. package/dist/runtime.d.ts +1 -1
  14. package/dist/runtime.d.ts.map +1 -1
  15. package/dist/runtime.js +2 -2
  16. package/dist/swc-plugin-cache.d.ts +7 -0
  17. package/dist/swc-plugin-cache.d.ts.map +1 -0
  18. package/dist/swc-plugin-cache.js +23 -0
  19. package/dist/watch-ignore.d.ts +51 -0
  20. package/dist/watch-ignore.d.ts.map +1 -0
  21. package/dist/watch-ignore.js +264 -0
  22. package/dist/watch-rebuild.d.ts +63 -0
  23. package/dist/watch-rebuild.d.ts.map +1 -0
  24. package/dist/watch-rebuild.js +399 -0
  25. package/docs/api-reference/with-workflow.mdx +56 -2
  26. package/docs/next.mdx +12 -6
  27. package/package.json +10 -7
  28. package/dist/builder-deferred.d.ts +0 -2
  29. package/dist/builder-deferred.d.ts.map +0 -1
  30. package/dist/builder-deferred.js +0 -1401
  31. package/dist/builder-deferred.js.map +0 -1
  32. package/dist/builder-eager.js.map +0 -1
  33. package/dist/builder.js.map +0 -1
  34. package/dist/index.js.map +0 -1
  35. package/dist/loader.js.map +0 -1
  36. package/dist/runtime.js.map +0 -1
  37. package/dist/socket-server.d.ts +0 -48
  38. package/dist/socket-server.d.ts.map +0 -1
  39. package/dist/socket-server.js +0 -154
  40. package/dist/socket-server.js.map +0 -1
@@ -0,0 +1,399 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.classifyRebuild = exports.replaceSourceSnapshots = exports.getRelevantFiles = exports.createSourceSnapshot = exports.createSourceSnapshotFromSource = exports.extractDefinitionSignature = exports.extractImportSignature = exports.stripCommentsFromSource = void 0;
4
+ const promises_1 = require("node:fs/promises");
5
+ const importSpecifierPatterns = [
6
+ /\bfrom\s+['"]([^'"]+)['"]/g,
7
+ /(?:^|[;\n])\s*import\s+['"]([^'"]+)['"]/g,
8
+ /\bimport\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
9
+ /\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
10
+ ];
11
+ const directiveFunctionPatterns = [
12
+ /\b(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)[^{]*\{\s*['"]use\s+(workflow|step)['"]/g,
13
+ /\b(?:export\s+)?const\s+([A-Za-z_$][\w$]*)\s*=\s*(?:async\s*)?(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*=>\s*\{\s*['"]use\s+(workflow|step)['"]/g,
14
+ ];
15
+ const serdeClassPattern = /\bclass\s+([A-Za-z_$][\w$]*)[\s\S]*?(?:static\s+classId\s*=\s*['"]([^'"]+)['"]|Symbol\.for\s*\(\s*['"]workflow-(?:serialize|deserialize)['"]\s*\)|\[\s*WORKFLOW_(?:SERIALIZE|DESERIALIZE)\s*\])/g;
16
+ const defaultNormalizePath = (pathname) => pathname.replace(/\\/g, '/');
17
+ const REGEX_PREFIX_CHARS = new Set([
18
+ '(',
19
+ '{',
20
+ '[',
21
+ '=',
22
+ ':',
23
+ ',',
24
+ ';',
25
+ '!',
26
+ '?',
27
+ '&',
28
+ '|',
29
+ '+',
30
+ '-',
31
+ '*',
32
+ '~',
33
+ '^',
34
+ '<',
35
+ '>',
36
+ '%',
37
+ ]);
38
+ const REGEX_PREFIX_KEYWORDS = /\b(?:return|throw|case|delete|void|typeof|instanceof|in|yield|await)$/;
39
+ const canStartRegexLiteral = (output) => {
40
+ const previous = output.trimEnd();
41
+ if (previous.length === 0) {
42
+ return true;
43
+ }
44
+ const previousChar = previous[previous.length - 1];
45
+ return (REGEX_PREFIX_CHARS.has(previousChar) || REGEX_PREFIX_KEYWORDS.test(previous));
46
+ };
47
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Keep the string/comment/regex scanner local and allocation-light.
48
+ const stripCommentsFromSource = (source) => {
49
+ let output = '';
50
+ let index = 0;
51
+ let quote;
52
+ let regex = false;
53
+ let regexCharClass = false;
54
+ let escaped = false;
55
+ while (index < source.length) {
56
+ const char = source[index];
57
+ const next = source[index + 1];
58
+ if (quote || regex) {
59
+ output += char;
60
+ index++;
61
+ if (escaped) {
62
+ escaped = false;
63
+ }
64
+ else if (char === '\\') {
65
+ escaped = true;
66
+ }
67
+ else if (quote && char === quote) {
68
+ quote = undefined;
69
+ }
70
+ else if (regex && char === '[') {
71
+ regexCharClass = true;
72
+ }
73
+ else if (regex && char === ']') {
74
+ regexCharClass = false;
75
+ }
76
+ else if (regex && char === '/' && !regexCharClass) {
77
+ regex = false;
78
+ }
79
+ continue;
80
+ }
81
+ if (char === '"' || char === "'" || char === '`') {
82
+ quote = char;
83
+ output += char;
84
+ index++;
85
+ continue;
86
+ }
87
+ if (char === '/' &&
88
+ next !== '/' &&
89
+ next !== '*' &&
90
+ canStartRegexLiteral(output)) {
91
+ regex = true;
92
+ output += char;
93
+ index++;
94
+ continue;
95
+ }
96
+ if (char === '/' && next === '/') {
97
+ output += ' ';
98
+ index += 2;
99
+ while (index < source.length && source[index] !== '\n') {
100
+ output += ' ';
101
+ index++;
102
+ }
103
+ continue;
104
+ }
105
+ if (char === '/' && next === '*') {
106
+ output += ' ';
107
+ index += 2;
108
+ while (index < source.length) {
109
+ const blockChar = source[index];
110
+ const blockNext = source[index + 1];
111
+ if (blockChar === '*' && blockNext === '/') {
112
+ output += ' ';
113
+ index += 2;
114
+ break;
115
+ }
116
+ output += blockChar === '\n' ? '\n' : ' ';
117
+ index++;
118
+ }
119
+ continue;
120
+ }
121
+ output += char;
122
+ index++;
123
+ }
124
+ return output;
125
+ };
126
+ exports.stripCommentsFromSource = stripCommentsFromSource;
127
+ const sourceMayContainImportSpecifiers = (source) => source.includes('import') ||
128
+ source.includes('require') ||
129
+ source.includes('from');
130
+ const collectImportSpecifiers = (source) => {
131
+ const specifiers = new Set();
132
+ for (const pattern of importSpecifierPatterns) {
133
+ pattern.lastIndex = 0;
134
+ for (const match of source.matchAll(pattern)) {
135
+ if (match[1]) {
136
+ specifiers.add(match[1]);
137
+ }
138
+ }
139
+ }
140
+ return [...specifiers].sort().join('\n');
141
+ };
142
+ const extractImportSignature = (source) => sourceMayContainImportSpecifiers(source)
143
+ ? collectImportSpecifiers(source)
144
+ : '';
145
+ exports.extractImportSignature = extractImportSignature;
146
+ const extractDefinitionSignature = (source) => {
147
+ const definitions = [];
148
+ for (const pattern of directiveFunctionPatterns) {
149
+ pattern.lastIndex = 0;
150
+ for (const match of source.matchAll(pattern)) {
151
+ definitions.push(`${match[2]}:${match[1]}`);
152
+ }
153
+ }
154
+ serdeClassPattern.lastIndex = 0;
155
+ for (const match of source.matchAll(serdeClassPattern)) {
156
+ definitions.push(`serde:${match[2] ?? match[1]}`);
157
+ }
158
+ return definitions.sort().join('\n');
159
+ };
160
+ exports.extractDefinitionSignature = extractDefinitionSignature;
161
+ const createSourceSnapshotFromSource = (source, detectWorkflowPatterns) => {
162
+ const sourceWithoutComments = (0, exports.stripCommentsFromSource)(source);
163
+ const patterns = detectWorkflowPatterns(sourceWithoutComments);
164
+ return {
165
+ importSignature: (0, exports.extractImportSignature)(sourceWithoutComments),
166
+ definitionSignature: (0, exports.extractDefinitionSignature)(sourceWithoutComments),
167
+ hasDirective: patterns.hasDirective,
168
+ hasSerde: patterns.hasSerde,
169
+ };
170
+ };
171
+ exports.createSourceSnapshotFromSource = createSourceSnapshotFromSource;
172
+ const createSourceSnapshot = async ({ file, detectWorkflowPatterns, }) => (0, exports.createSourceSnapshotFromSource)(await (0, promises_1.readFile)(file, 'utf8'), detectWorkflowPatterns);
173
+ exports.createSourceSnapshot = createSourceSnapshot;
174
+ const getRelevantFiles = ({ discoveredEntries, inputFiles, normalizePath = defaultNormalizePath, }) => new Set([
175
+ ...inputFiles,
176
+ ...discoveredEntries.discoveredSteps,
177
+ ...discoveredEntries.discoveredWorkflows,
178
+ ...discoveredEntries.discoveredSerdeFiles,
179
+ ...(discoveredEntries.discoveredFiles || []),
180
+ ].map(normalizePath));
181
+ exports.getRelevantFiles = getRelevantFiles;
182
+ const replaceSourceSnapshots = async ({ discoveredEntries, inputFiles, normalizePath = defaultNormalizePath, readSnapshot, sourceSnapshots, }) => {
183
+ sourceSnapshots.clear();
184
+ await Promise.all([
185
+ ...(0, exports.getRelevantFiles)({
186
+ discoveredEntries,
187
+ inputFiles,
188
+ normalizePath,
189
+ }),
190
+ ].map(async (file) => {
191
+ try {
192
+ sourceSnapshots.set(file, await readSnapshot(file));
193
+ }
194
+ catch {
195
+ sourceSnapshots.delete(file);
196
+ }
197
+ }));
198
+ };
199
+ exports.replaceSourceSnapshots = replaceSourceSnapshots;
200
+ const didSourceSnapshotChange = (previousSnapshot, nextSnapshot) => previousSnapshot.importSignature !== nextSnapshot.importSignature ||
201
+ previousSnapshot.definitionSignature !== nextSnapshot.definitionSignature ||
202
+ previousSnapshot.hasDirective !== nextSnapshot.hasDirective ||
203
+ previousSnapshot.hasSerde !== nextSnapshot.hasSerde;
204
+ const unique = (paths) => [...new Set(paths)];
205
+ const snapshotChangedFile = async ({ file, nextSnapshots, readSnapshot, sourceSnapshots, }) => {
206
+ const previousSnapshot = sourceSnapshots.get(file);
207
+ if (!previousSnapshot) {
208
+ return false;
209
+ }
210
+ const nextSnapshot = await readSnapshot(file);
211
+ if (didSourceSnapshotChange(previousSnapshot, nextSnapshot)) {
212
+ return false;
213
+ }
214
+ nextSnapshots.set(file, nextSnapshot);
215
+ return true;
216
+ };
217
+ const removedFilesRequireFullRebuild = ({ discoveredEntries, inputFiles, normalizePath, removedFiles, }) => {
218
+ const relevantFiles = (0, exports.getRelevantFiles)({
219
+ discoveredEntries,
220
+ inputFiles,
221
+ normalizePath,
222
+ });
223
+ return removedFiles.some((file) => relevantFiles.has(file));
224
+ };
225
+ const addedFilesRequireFullRebuild = async ({ addedFiles, readSnapshot, }) => {
226
+ for (const file of addedFiles) {
227
+ try {
228
+ const snapshot = await readSnapshot(file);
229
+ if (snapshot.hasDirective || snapshot.hasSerde) {
230
+ return true;
231
+ }
232
+ }
233
+ catch {
234
+ return true;
235
+ }
236
+ }
237
+ return false;
238
+ };
239
+ const pruneStaleAddedFiles = async ({ addedFiles, readSnapshot, sourceSnapshots, }) => {
240
+ const nextAddedFiles = [];
241
+ const snapshots = new Map();
242
+ for (const file of unique(addedFiles)) {
243
+ const previousSnapshot = sourceSnapshots.get(file);
244
+ if (!previousSnapshot) {
245
+ nextAddedFiles.push(file);
246
+ continue;
247
+ }
248
+ try {
249
+ const nextSnapshot = await readSnapshot(file);
250
+ if (didSourceSnapshotChange(previousSnapshot, nextSnapshot)) {
251
+ nextAddedFiles.push(file);
252
+ continue;
253
+ }
254
+ snapshots.set(file, nextSnapshot);
255
+ }
256
+ catch {
257
+ nextAddedFiles.push(file);
258
+ }
259
+ }
260
+ return { addedFiles: nextAddedFiles, snapshots };
261
+ };
262
+ const modifiedFilesRequireFullRebuild = async ({ modifiedFiles, readSnapshot, sourceSnapshots, }) => {
263
+ for (const file of unique(modifiedFiles)) {
264
+ try {
265
+ const nextSnapshot = await readSnapshot(file);
266
+ const previousSnapshot = sourceSnapshots.get(file);
267
+ if (!previousSnapshot) {
268
+ if (nextSnapshot.importSignature ||
269
+ nextSnapshot.definitionSignature ||
270
+ nextSnapshot.hasDirective ||
271
+ nextSnapshot.hasSerde) {
272
+ return true;
273
+ }
274
+ continue;
275
+ }
276
+ if (didSourceSnapshotChange(previousSnapshot, nextSnapshot)) {
277
+ return true;
278
+ }
279
+ }
280
+ catch {
281
+ return true;
282
+ }
283
+ }
284
+ return false;
285
+ };
286
+ const getChangedRelevantFiles = ({ discoveredEntries, fileChanges, inputFiles, normalizePath, }) => {
287
+ const relevantFiles = (0, exports.getRelevantFiles)({
288
+ discoveredEntries,
289
+ inputFiles,
290
+ normalizePath,
291
+ });
292
+ return unique(fileChanges.modifiedFiles).filter((file) => relevantFiles.has(file));
293
+ };
294
+ const collectHotRebuildSnapshots = async ({ changedFiles, readSnapshot, sourceSnapshots, }) => {
295
+ const snapshots = new Map();
296
+ for (const file of changedFiles) {
297
+ if (!(await snapshotChangedFile({
298
+ file,
299
+ nextSnapshots: snapshots,
300
+ readSnapshot,
301
+ sourceSnapshots,
302
+ }))) {
303
+ return;
304
+ }
305
+ }
306
+ return snapshots;
307
+ };
308
+ const workflowEntryFilesChanged = ({ changedFiles, discoveredEntries, normalizePath, parentHasChild, }) => {
309
+ const workflowEntryFiles = [
310
+ ...discoveredEntries.discoveredWorkflows,
311
+ ...discoveredEntries.discoveredSerdeFiles,
312
+ ].map(normalizePath);
313
+ const stepEntryFiles = [...discoveredEntries.discoveredSteps].map(normalizePath);
314
+ return changedFiles.some((changedFile) => {
315
+ if (workflowEntryFiles.includes(changedFile)) {
316
+ return true;
317
+ }
318
+ if (stepEntryFiles.includes(changedFile)) {
319
+ return false;
320
+ }
321
+ return workflowEntryFiles.some((workflowFile) => parentHasChild(workflowFile, changedFile, {
322
+ excludedRoots: stepEntryFiles,
323
+ }));
324
+ });
325
+ };
326
+ const stepRegistrationsNeedRefresh = ({ changedFiles, discoveredEntries, normalizePath, }) => {
327
+ const serdeFiles = new Set([...discoveredEntries.discoveredSerdeFiles].map(normalizePath));
328
+ return changedFiles.some((file) => serdeFiles.has(file));
329
+ };
330
+ const classifyRebuild = async ({ discoveredEntries, fileChanges, inputFiles, normalizePath = defaultNormalizePath, parentHasChild, readSnapshot, sourceSnapshots, }) => {
331
+ const prunedAddedFiles = await pruneStaleAddedFiles({
332
+ addedFiles: fileChanges.addedFiles,
333
+ readSnapshot,
334
+ sourceSnapshots,
335
+ });
336
+ const normalizedFileChanges = {
337
+ ...fileChanges,
338
+ addedFiles: prunedAddedFiles.addedFiles,
339
+ };
340
+ if (removedFilesRequireFullRebuild({
341
+ discoveredEntries,
342
+ inputFiles,
343
+ normalizePath,
344
+ removedFiles: normalizedFileChanges.removedFiles,
345
+ }) ||
346
+ (await addedFilesRequireFullRebuild({
347
+ addedFiles: normalizedFileChanges.addedFiles,
348
+ readSnapshot,
349
+ })) ||
350
+ (await modifiedFilesRequireFullRebuild({
351
+ modifiedFiles: normalizedFileChanges.modifiedFiles,
352
+ readSnapshot,
353
+ sourceSnapshots,
354
+ }))) {
355
+ return { kind: 'full' };
356
+ }
357
+ const changedRelevantFiles = getChangedRelevantFiles({
358
+ discoveredEntries,
359
+ fileChanges: normalizedFileChanges,
360
+ inputFiles,
361
+ normalizePath,
362
+ });
363
+ if (changedRelevantFiles.length === 0) {
364
+ return prunedAddedFiles.snapshots.size > 0
365
+ ? { kind: 'none', snapshots: prunedAddedFiles.snapshots }
366
+ : { kind: 'none' };
367
+ }
368
+ try {
369
+ const snapshots = await collectHotRebuildSnapshots({
370
+ changedFiles: changedRelevantFiles,
371
+ readSnapshot,
372
+ sourceSnapshots,
373
+ });
374
+ if (!snapshots) {
375
+ return { kind: 'full' };
376
+ }
377
+ return workflowEntryFilesChanged({
378
+ changedFiles: changedRelevantFiles,
379
+ discoveredEntries,
380
+ normalizePath,
381
+ parentHasChild,
382
+ })
383
+ ? {
384
+ kind: 'hot',
385
+ refreshStepRegistrations: stepRegistrationsNeedRefresh({
386
+ changedFiles: changedRelevantFiles,
387
+ discoveredEntries,
388
+ normalizePath,
389
+ }),
390
+ snapshots,
391
+ }
392
+ : { kind: 'none', snapshots };
393
+ }
394
+ catch {
395
+ return { kind: 'full' };
396
+ }
397
+ };
398
+ exports.classifyRebuild = classifyRebuild;
399
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F0Y2gtcmVidWlsZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy93YXRjaC1yZWJ1aWxkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtDQUE0QztBQW9DNUMsTUFBTSx1QkFBdUIsR0FBRztJQUM5Qiw0QkFBNEI7SUFDNUIsMENBQTBDO0lBQzFDLHdDQUF3QztJQUN4Qyx5Q0FBeUM7Q0FDMUMsQ0FBQztBQUNGLE1BQU0seUJBQXlCLEdBQUc7SUFDaEMsb0dBQW9HO0lBQ3BHLHlJQUF5STtDQUMxSSxDQUFDO0FBQ0YsTUFBTSxpQkFBaUIsR0FDckIsa01BQWtNLENBQUM7QUFFck0sTUFBTSxvQkFBb0IsR0FBRyxDQUFDLFFBQWdCLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBRWhGLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDakMsR0FBRztJQUNILEdBQUc7SUFDSCxHQUFHO0lBQ0gsR0FBRztJQUNILEdBQUc7SUFDSCxHQUFHO0lBQ0gsR0FBRztJQUNILEdBQUc7SUFDSCxHQUFHO0lBQ0gsR0FBRztJQUNILEdBQUc7SUFDSCxHQUFHO0lBQ0gsR0FBRztJQUNILEdBQUc7SUFDSCxHQUFHO0lBQ0gsR0FBRztJQUNILEdBQUc7SUFDSCxHQUFHO0lBQ0gsR0FBRztDQUNKLENBQUMsQ0FBQztBQUNILE1BQU0scUJBQXFCLEdBQ3pCLHVFQUF1RSxDQUFDO0FBRTFFLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxNQUFjLEVBQUUsRUFBRTtJQUM5QyxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbEMsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzFCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELE1BQU0sWUFBWSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFH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aUJBQWlCO1lBQ2pCLGFBQWE7WUFDYixjQUFjO1NBQ2YsQ0FBQztZQUNBLENBQUMsQ0FBQztnQkFDRSxJQUFJLEVBQUUsS0FBSztnQkFDWCx3QkFBd0IsRUFBRSw0QkFBNEIsQ0FBQztvQkFDckQsWUFBWSxFQUFFLG9CQUFvQjtvQkFDbEMsaUJBQWlCO29CQUNqQixhQUFhO2lCQUNkLENBQUM7Z0JBQ0YsU0FBUzthQUNWO1lBQ0gsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQztJQUMxQixDQUFDO0FBQ0gsQ0FBQyxDQUFDO0FBM0ZXLFFBQUEsZUFBZSxtQkEyRjFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVhZEZpbGUgfSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcblxuZXhwb3J0IGludGVyZmFjZSBEaXNjb3ZlcmVkRW50cmllc0xpa2Uge1xuICBkaXNjb3ZlcmVkU3RlcHM6IFNldDxzdHJpbmc+O1xuICBkaXNjb3ZlcmVkV29ya2Zsb3dzOiBTZXQ8c3RyaW5nPjtcbiAgZGlzY292ZXJlZFNlcmRlRmlsZXM6IFNldDxzdHJpbmc+O1xuICBkaXNjb3ZlcmVkRmlsZXM/OiBTZXQ8c3RyaW5nPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGaWxlQ2hhbmdlcyB7XG4gIGFkZGVkRmlsZXM6IHN0cmluZ1tdO1xuICBtb2RpZmllZEZpbGVzOiBzdHJpbmdbXTtcbiAgcmVtb3ZlZEZpbGVzOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTb3VyY2VTbmFwc2hvdCB7XG4gIGltcG9ydFNpZ25hdHVyZTogc3RyaW5nO1xuICBkZWZpbml0aW9uU2lnbmF0dXJlOiBzdHJpbmc7XG4gIGhhc0RpcmVjdGl2ZTogYm9vbGVhbjtcbiAgaGFzU2VyZGU6IGJvb2xlYW47XG59XG5cbmV4cG9ydCB0eXBlIFJlYnVpbGREZWNpc2lvbiA9XG4gIHwgeyBraW5kOiAnbm9uZSc7IHNuYXBzaG90cz86IE1hcDxzdHJpbmcsIFNvdXJjZVNuYXBzaG90PiB9XG4gIHwge1xuICAgICAga2luZDogJ2hvdCc7XG4gICAgICByZWZyZXNoU3RlcFJlZ2lzdHJhdGlvbnM6IGJvb2xlYW47XG4gICAgICBzbmFwc2hvdHM6IE1hcDxzdHJpbmcsIFNvdXJjZVNuYXBzaG90PjtcbiAgICB9XG4gIHwgeyBraW5kOiAnZnVsbCcgfTtcblxuZXhwb3J0IHR5cGUgU291cmNlUGF0dGVybkRldGVjdG9yID0gKHNvdXJjZTogc3RyaW5nKSA9PiB7XG4gIGhhc0RpcmVjdGl2ZTogYm9vbGVhbjtcbiAgaGFzU2VyZGU6IGJvb2xlYW47XG59O1xuXG5jb25zdCBpbXBvcnRTcGVjaWZpZXJQYXR0ZXJucyA9IFtcbiAgL1xcYmZyb21cXHMrWydcIl0oW14nXCJdKylbJ1wiXS9nLFxuICAvKD86XnxbO1xcbl0pXFxzKmltcG9ydFxccytbJ1wiXShbXidcIl0rKVsnXCJdL2csXG4gIC9cXGJpbXBvcnRcXHMqXFwoXFxzKlsnXCJdKFteJ1wiXSspWydcIl1cXHMqXFwpL2csXG4gIC9cXGJyZXF1aXJlXFxzKlxcKFxccypbJ1wiXShbXidcIl0rKVsnXCJdXFxzKlxcKS9nLFxuXTtcbmNvbnN0IGRpcmVjdGl2ZUZ1bmN0aW9uUGF0dGVybnMgPSBbXG4gIC9cXGIoPzpleHBvcnRcXHMrKT8oPzphc3luY1xccyspP2Z1bmN0aW9uXFxzKyhbQS1aYS16XyRdW1xcdyRdKilbXntdKlxce1xccypbJ1wiXXVzZVxccysod29ya2Zsb3d8c3RlcClbJ1wiXS9nLFxuICAvXFxiKD86ZXhwb3J0XFxzKyk/Y29uc3RcXHMrKFtBLVphLXpfJF1bXFx3JF0qKVxccyo9XFxzKig/OmFzeW5jXFxzKik/KD86XFwoW14pXSpcXCl8W0EtWmEtel8kXVtcXHckXSopXFxzKj0+XFxzKlxce1xccypbJ1wiXXVzZVxccysod29ya2Zsb3d8c3RlcClbJ1wiXS9nLFxuXTtcbmNvbnN0IHNlcmRlQ2xhc3NQYXR0ZXJuID1cbiAgL1xcYmNsYXNzXFxzKyhbQS1aYS16XyRdW1xcdyRdKilbXFxzXFxTXSo/KD86c3RhdGljXFxzK2NsYXNzSWRcXHMqPVxccypbJ1wiXShbXidcIl0rKVsnXCJdfFN5bWJvbFxcLmZvclxccypcXChcXHMqWydcIl13b3JrZmxvdy0oPzpzZXJpYWxpemV8ZGVzZXJpYWxpemUpWydcIl1cXHMqXFwpfFxcW1xccypXT1JLRkxPV18oPzpTRVJJQUxJWkV8REVTRVJJQUxJWkUpXFxzKlxcXSkvZztcblxuY29uc3QgZGVmYXVsdE5vcm1hbGl6ZVBhdGggPSAocGF0aG5hbWU6IHN0cmluZykgPT4gcGF0aG5hbWUucmVwbGFjZSgvXFxcXC9nLCAnLycpO1xuXG5jb25zdCBSRUdFWF9QUkVGSVhfQ0hBUlMgPSBuZXcgU2V0KFtcbiAgJygnLFxuICAneycsXG4gICdbJyxcbiAgJz0nLFxuICAnOicsXG4gICcsJyxcbiAgJzsnLFxuICAnIScsXG4gICc/JyxcbiAgJyYnLFxuICAnfCcsXG4gICcrJyxcbiAgJy0nLFxuICAnKicsXG4gICd+JyxcbiAgJ14nLFxuICAnPCcsXG4gICc+JyxcbiAgJyUnLFxuXSk7XG5jb25zdCBSRUdFWF9QUkVGSVhfS0VZV09SRFMgPVxuICAvXFxiKD86cmV0dXJufHRocm93fGNhc2V8ZGVsZXRlfHZvaWR8dHlwZW9mfGluc3RhbmNlb2Z8aW58eWllbGR8YXdhaXQpJC87XG5cbmNvbnN0IGNhblN0YXJ0UmVnZXhMaXRlcmFsID0gKG91dHB1dDogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IHByZXZpb3VzID0gb3V0cHV0LnRyaW1FbmQoKTtcbiAgaWYgKHByZXZpb3VzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGNvbnN0IHByZXZpb3VzQ2hhciA9IHByZXZpb3VzW3ByZXZpb3VzLmxlbmd0aCAtIDFdO1xuICByZXR1cm4gKFxuICAgIFJFR0VYX1BSRUZJWF9DSEFSUy5oYXMocHJldmlvdXNDaGFyKSB8fCBSRUdFWF9QUkVGSVhfS0VZV09SRFMudGVzdChwcmV2aW91cylcbiAgKTtcbn07XG5cbi8vIGJpb21lLWlnbm9yZSBsaW50L2NvbXBsZXhpdHkvbm9FeGNlc3NpdmVDb2duaXRpdmVDb21wbGV4aXR5OiBLZWVwIHRoZSBzdHJpbmcvY29tbWVudC9yZWdleCBzY2FubmVyIGxvY2FsIGFuZCBhbGxvY2F0aW9uLWxpZ2h0LlxuZXhwb3J0IGNvbnN0IHN0cmlwQ29tbWVudHNGcm9tU291cmNlID0gKHNvdXJjZTogc3RyaW5nKSA9PiB7XG4gIGxldCBvdXRwdXQgPSAnJztcbiAgbGV0IGluZGV4ID0gMDtcbiAgbGV0IHF1b3RlOiAnXCInIHwgXCInXCIgfCAnYCcgfCB1bmRlZmluZWQ7XG4gIGxldCByZWdleCA9IGZhbHNlO1xuICBsZXQgcmVnZXhDaGFyQ2xhc3MgPSBmYWxzZTtcbiAgbGV0IGVzY2FwZWQgPSBmYWxzZTtcblxuICB3aGlsZSAoaW5kZXggPCBzb3VyY2UubGVuZ3RoKSB7XG4gICAgY29uc3QgY2hhciA9IHNvdXJjZVtpbmRleF07XG4gICAgY29uc3QgbmV4dCA9IHNvdXJjZVtpbmRleCArIDFdO1xuXG4gICAgaWYgKHF1b3RlIHx8IHJlZ2V4KSB7XG4gICAgICBvdXRwdXQgKz0gY2hhcjtcbiAgICAgIGluZGV4Kys7XG5cbiAgICAgIGlmIChlc2NhcGVkKSB7XG4gICAgICAgIGVzY2FwZWQgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSBpZiAoY2hhciA9PT0gJ1xcXFwnKSB7XG4gICAgICAgIGVzY2FwZWQgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmIChxdW90ZSAmJiBjaGFyID09PSBxdW90ZSkge1xuICAgICAgICBxdW90ZSA9IHVuZGVmaW5lZDtcbiAgICAgIH0gZWxzZSBpZiAocmVnZXggJiYgY2hhciA9PT0gJ1snKSB7XG4gICAgICAgIHJlZ2V4Q2hhckNsYXNzID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSBpZiAocmVnZXggJiYgY2hhciA9PT0gJ10nKSB7XG4gICAgICAgIHJlZ2V4Q2hhckNsYXNzID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKHJlZ2V4ICYmIGNoYXIgPT09ICcvJyAmJiAhcmVnZXhDaGFyQ2xhc3MpIHtcbiAgICAgICAgcmVnZXggPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChjaGFyID09PSAnXCInIHx8IGNoYXIgPT09IFwiJ1wiIHx8IGNoYXIgPT09ICdgJykge1xuICAgICAgcXVvdGUgPSBjaGFyO1xuICAgICAgb3V0cHV0ICs9IGNoYXI7XG4gICAgICBpbmRleCsrO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgY2hhciA9PT0gJy8nICYmXG4gICAgICBuZXh0ICE9PSAnLycgJiZcbiAgICAgIG5leHQgIT09ICcqJyAmJlxuICAgICAgY2FuU3RhcnRSZWdleExpdGVyYWwob3V0cHV0KVxuICAgICkge1xuICAgICAgcmVnZXggPSB0cnVlO1xuICAgICAgb3V0cHV0ICs9IGNoYXI7XG4gICAgICBpbmRleCsrO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGNoYXIgPT09ICcvJyAmJiBuZXh0ID09PSAnLycpIHtcbiAgICAgIG91dHB1dCArPSAnICAnO1xuICAgICAgaW5kZXggKz0gMjtcbiAgICAgIHdoaWxlIChpbmRleCA8IHNvdXJjZS5sZW5ndGggJiYgc291cmNlW2luZGV4XSAhPT0gJ1xcbicpIHtcbiAgICAgICAgb3V0cHV0ICs9ICcgJztcbiAgICAgICAgaW5kZXgrKztcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChjaGFyID09PSAnLycgJiYgbmV4dCA9PT0gJyonKSB7XG4gICAgICBvdXRwdXQgKz0gJyAgJztcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgICB3aGlsZSAoaW5kZXggPCBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IGJsb2NrQ2hhciA9IHNvdXJjZVtpbmRleF07XG4gICAgICAgIGNvbnN0IGJsb2NrTmV4dCA9IHNvdXJjZVtpbmRleCArIDFdO1xuICAgICAgICBpZiAoYmxvY2tDaGFyID09PSAnKicgJiYgYmxvY2tOZXh0ID09PSAnLycpIHtcbiAgICAgICAgICBvdXRwdXQgKz0gJyAgJztcbiAgICAgICAgICBpbmRleCArPSAyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIG91dHB1dCArPSBibG9ja0NoYXIgPT09ICdcXG4nID8gJ1xcbicgOiAnICc7XG4gICAgICAgIGluZGV4Kys7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBvdXRwdXQgKz0gY2hhcjtcbiAgICBpbmRleCsrO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbmNvbnN0IHNvdXJjZU1heUNvbnRhaW5JbXBvcnRTcGVjaWZpZXJzID0gKHNvdXJjZTogc3RyaW5nKSA9PlxuICBzb3VyY2UuaW5jbHVkZXMoJ2ltcG9ydCcpIHx8XG4gIHNvdXJjZS5pbmNsdWRlcygncmVxdWlyZScpIHx8XG4gIHNvdXJjZS5pbmNsdWRlcygnZnJvbScpO1xuXG5jb25zdCBjb2xsZWN0SW1wb3J0U3BlY2lmaWVycyA9IChzb3VyY2U6IHN0cmluZykgPT4ge1xuICBjb25zdCBzcGVjaWZpZXJzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGZvciAoY29uc3QgcGF0dGVybiBvZiBpbXBvcnRTcGVjaWZpZXJQYXR0ZXJucykge1xuICAgIHBhdHRlcm4ubGFzdEluZGV4ID0gMDtcbiAgICBmb3IgKGNvbnN0IG1hdGNoIG9mIHNvdXJjZS5tYXRjaEFsbChwYXR0ZXJuKSkge1xuICAgICAgaWYgKG1hdGNoWzFdKSB7XG4gICAgICAgIHNwZWNpZmllcnMuYWRkKG1hdGNoWzFdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIFsuLi5zcGVjaWZpZXJzXS5zb3J0KCkuam9pbignXFxuJyk7XG59O1xuXG5leHBvcnQgY29uc3QgZXh0cmFjdEltcG9ydFNpZ25hdHVyZSA9IChzb3VyY2U6IHN0cmluZykgPT5cbiAgc291cmNlTWF5Q29udGFpbkltcG9ydFNwZWNpZmllcnMoc291cmNlKVxuICAgID8gY29sbGVjdEltcG9ydFNwZWNpZmllcnMoc291cmNlKVxuICAgIDogJyc7XG5cbmV4cG9ydCBjb25zdCBleHRyYWN0RGVmaW5pdGlvblNpZ25hdHVyZSA9IChzb3VyY2U6IHN0cmluZykgPT4ge1xuICBjb25zdCBkZWZpbml0aW9uczogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChjb25zdCBwYXR0ZXJuIG9mIGRpcmVjdGl2ZUZ1bmN0aW9uUGF0dGVybnMpIHtcbiAgICBwYXR0ZXJuLmxhc3RJbmRleCA9IDA7XG4gICAgZm9yIChjb25zdCBtYXRjaCBvZiBzb3VyY2UubWF0Y2hBbGwocGF0dGVybikpIHtcbiAgICAgIGRlZmluaXRpb25zLnB1c2goYCR7bWF0Y2hbMl19OiR7bWF0Y2hbMV19YCk7XG4gICAgfVxuICB9XG4gIHNlcmRlQ2xhc3NQYXR0ZXJuLmxhc3RJbmRleCA9IDA7XG4gIGZvciAoY29uc3QgbWF0Y2ggb2Ygc291cmNlLm1hdGNoQWxsKHNlcmRlQ2xhc3NQYXR0ZXJuKSkge1xuICAgIGRlZmluaXRpb25zLnB1c2goYHNlcmRlOiR7bWF0Y2hbMl0gPz8gbWF0Y2hbMV19YCk7XG4gIH1cbiAgcmV0dXJuIGRlZmluaXRpb25zLnNvcnQoKS5qb2luKCdcXG4nKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVTb3VyY2VTbmFwc2hvdEZyb21Tb3VyY2UgPSAoXG4gIHNvdXJjZTogc3RyaW5nLFxuICBkZXRlY3RXb3JrZmxvd1BhdHRlcm5zOiBTb3VyY2VQYXR0ZXJuRGV0ZWN0b3Jcbik6IFNvdXJjZVNuYXBzaG90ID0+IHtcbiAgY29uc3Qgc291cmNlV2l0aG91dENvbW1lbnRzID0gc3RyaXBDb21tZW50c0Zyb21Tb3VyY2Uoc291cmNlKTtcbiAgY29uc3QgcGF0dGVybnMgPSBkZXRlY3RXb3JrZmxvd1BhdHRlcm5zKHNvdXJjZVdpdGhvdXRDb21tZW50cyk7XG5cbiAgcmV0dXJuIHtcbiAgICBpbXBvcnRTaWduYXR1cmU6IGV4dHJhY3RJbXBvcnRTaWduYXR1cmUoc291cmNlV2l0aG91dENvbW1lbnRzKSxcbiAgICBkZWZpbml0aW9uU2lnbmF0dXJlOiBleHRyYWN0RGVmaW5pdGlvblNpZ25hdHVyZShzb3VyY2VXaXRob3V0Q29tbWVudHMpLFxuICAgIGhhc0RpcmVjdGl2ZTogcGF0dGVybnMuaGFzRGlyZWN0aXZlLFxuICAgIGhhc1NlcmRlOiBwYXR0ZXJucy5oYXNTZXJkZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVTb3VyY2VTbmFwc2hvdCA9IGFzeW5jICh7XG4gIGZpbGUsXG4gIGRldGVjdFdvcmtmbG93UGF0dGVybnMsXG59OiB7XG4gIGZpbGU6IHN0cmluZztcbiAgZGV0ZWN0V29ya2Zsb3dQYXR0ZXJuczogU291cmNlUGF0dGVybkRldGVjdG9yO1xufSk6IFByb21pc2U8U291cmNlU25hcHNob3Q+ID0+XG4gIGNyZWF0ZVNvdXJjZVNuYXBzaG90RnJvbVNvdXJjZShcbiAgICBhd2FpdCByZWFkRmlsZShmaWxlLCAndXRmOCcpLFxuICAgIGRldGVjdFdvcmtmbG93UGF0dGVybnNcbiAgKTtcblxuZXhwb3J0IGNvbnN0IGdldFJlbGV2YW50RmlsZXMgPSAoe1xuICBkaXNjb3ZlcmVkRW50cmllcyxcbiAgaW5wdXRGaWxlcyxcbiAgbm9ybWFsaXplUGF0aCA9IGRlZmF1bHROb3JtYWxpemVQYXRoLFxufToge1xuICBkaXNjb3ZlcmVkRW50cmllczogRGlzY292ZXJlZEVudHJpZXNMaWtlO1xuICBpbnB1dEZpbGVzOiBzdHJpbmdbXTtcbiAgbm9ybWFsaXplUGF0aD86IChwYXRoOiBzdHJpbmcpID0+IHN0cmluZztcbn0pID0+XG4gIG5ldyBTZXQoXG4gICAgW1xuICAgICAgLi4uaW5wdXRGaWxlcyxcbiAgICAgIC4uLmRpc2NvdmVyZWRFbnRyaWVzLmRpc2NvdmVyZWRTdGVwcyxcbiAgICAgIC4uLmRpc2NvdmVyZWRFbnRyaWVzLmRpc2NvdmVyZWRXb3JrZmxvd3MsXG4gICAgICAuLi5kaXNjb3ZlcmVkRW50cmllcy5kaXNjb3ZlcmVkU2VyZGVGaWxlcyxcbiAgICAgIC4uLihkaXNjb3ZlcmVkRW50cmllcy5kaXNjb3ZlcmVkRmlsZXMgfHwgW10pLFxuICAgIF0ubWFwKG5vcm1hbGl6ZVBhdGgpXG4gICk7XG5cbmV4cG9ydCBjb25zdCByZXBsYWNlU291cmNlU25hcHNob3RzID0gYXN5bmMgKHtcbiAgZGlzY292ZXJlZEVudHJpZXMsXG4gIGlucHV0RmlsZXMsXG4gIG5vcm1hbGl6ZVBhdGggPSBkZWZhdWx0Tm9ybWFsaXplUGF0aCxcbiAgcmVhZFNuYXBzaG90LFxuICBzb3VyY2VTbmFwc2hvdHMsXG59OiB7XG4gIGRpc2NvdmVyZWRFbnRyaWVzOiBEaXNjb3ZlcmVkRW50cmllc0xpa2U7XG4gIGlucHV0RmlsZXM6IHN0cmluZ1tdO1xuICBub3JtYWxpemVQYXRoPzogKHBhdGg6IHN0cmluZykgPT4gc3RyaW5nO1xuICByZWFkU25hcHNob3Q6IChmaWxlOiBzdHJpbmcpID0+IFByb21pc2U8U291cmNlU25hcHNob3Q+O1xuICBzb3VyY2VTbmFwc2hvdHM6IE1hcDxzdHJpbmcsIFNvdXJjZVNuYXBzaG90Pjtcbn0pID0+IHtcbiAgc291cmNlU25hcHNob3RzLmNsZWFyKCk7XG4gIGF3YWl0IFByb21pc2UuYWxsKFxuICAgIFtcbiAgICAgIC4uLmdldFJlbGV2YW50RmlsZXMoe1xuICAgICAgICBkaXNjb3ZlcmVkRW50cmllcyxcbiAgICAgICAgaW5wdXRGaWxlcyxcbiAgICAgICAgbm9ybWFsaXplUGF0aCxcbiAgICAgIH0pLFxuICAgIF0ubWFwKGFzeW5jIChmaWxlKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBzb3VyY2VTbmFwc2hvdHMuc2V0KGZpbGUsIGF3YWl0IHJlYWRTbmFwc2hvdChmaWxlKSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgc291cmNlU25hcHNob3RzLmRlbGV0ZShmaWxlKTtcbiAgICAgIH1cbiAgICB9KVxuICApO1xufTtcblxuY29uc3QgZGlkU291cmNlU25hcHNob3RDaGFuZ2UgPSAoXG4gIHByZXZpb3VzU25hcHNob3Q6IFNvdXJjZVNuYXBzaG90LFxuICBuZXh0U25hcHNob3Q6IFNvdXJjZVNuYXBzaG90XG4pID0+XG4gIHByZXZpb3VzU25hcHNob3QuaW1wb3J0U2lnbmF0dXJlICE9PSBuZXh0U25hcHNob3QuaW1wb3J0U2lnbmF0dXJlIHx8XG4gIHByZXZpb3VzU25hcHNob3QuZGVmaW5pdGlvblNpZ25hdHVyZSAhPT0gbmV4dFNuYXBzaG90LmRlZmluaXRpb25TaWduYXR1cmUgfHxcbiAgcHJldmlvdXNTbmFwc2hvdC5oYXNEaXJlY3RpdmUgIT09IG5leHRTbmFwc2hvdC5oYXNEaXJlY3RpdmUgfHxcbiAgcHJldmlvdXNTbmFwc2hvdC5oYXNTZXJkZSAhPT0gbmV4dFNuYXBzaG90Lmhhc1NlcmRlO1xuXG5jb25zdCB1bmlxdWUgPSAocGF0aHM6IHN0cmluZ1tdKSA9PiBbLi4ubmV3IFNldChwYXRocyldO1xuXG5jb25zdCBzbmFwc2hvdENoYW5nZWRGaWxlID0gYXN5bmMgKHtcbiAgZmlsZSxcbiAgbmV4dFNuYXBzaG90cyxcbiAgcmVhZFNuYXBzaG90LFxuICBzb3VyY2VTbmFwc2hvdHMsXG59OiB7XG4gIGZpbGU6IHN0cmluZztcbiAgbmV4dFNuYXBzaG90czogTWFwPHN0cmluZywgU291cmNlU25hcHNob3Q+O1xuICByZWFkU25hcHNob3Q6IChmaWxlOiBzdHJpbmcpID0+IFByb21pc2U8U291cmNlU25hcHNob3Q+O1xuICBzb3VyY2VTbmFwc2hvdHM6IE1hcDxzdHJpbmcsIFNvdXJjZVNuYXBzaG90Pjtcbn0pID0+IHtcbiAgY29uc3QgcHJldmlvdXNTbmFwc2hvdCA9IHNvdXJjZVNuYXBzaG90cy5nZXQoZmlsZSk7XG4gIGlmICghcHJldmlvdXNTbmFwc2hvdCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IG5leHRTbmFwc2hvdCA9IGF3YWl0IHJlYWRTbmFwc2hvdChmaWxlKTtcbiAgaWYgKGRpZFNvdXJjZVNuYXBzaG90Q2hhbmdlKHByZXZpb3VzU25hcHNob3QsIG5leHRTbmFwc2hvdCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBuZXh0U25hcHNob3RzLnNldChmaWxlLCBuZXh0U25hcHNob3QpO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmNvbnN0IHJlbW92ZWRGaWxlc1JlcXVpcmVGdWxsUmVidWlsZCA9ICh7XG4gIGRpc2NvdmVyZWRFbnRyaWVzLFxuICBpbnB1dEZpbGVzLFxuICBub3JtYWxpemVQYXRoLFxuICByZW1vdmVkRmlsZXMsXG59OiB7XG4gIGRpc2NvdmVyZWRFbnRyaWVzOiBEaXNjb3ZlcmVkRW50cmllc0xpa2U7XG4gIGlucHV0RmlsZXM6IHN0cmluZ1tdO1xuICBub3JtYWxpemVQYXRoOiAocGF0aDogc3RyaW5nKSA9PiBzdHJpbmc7XG4gIHJlbW92ZWRGaWxlczogc3RyaW5nW107XG59KSA9PiB7XG4gIGNvbnN0IHJlbGV2YW50RmlsZXMgPSBnZXRSZWxldmFudEZpbGVzKHtcbiAgICBkaXNjb3ZlcmVkRW50cmllcyxcbiAgICBpbnB1dEZpbGVzLFxuICAgIG5vcm1hbGl6ZVBhdGgsXG4gIH0pO1xuICByZXR1cm4gcmVtb3ZlZEZpbGVzLnNvbWUoKGZpbGUpID0+IHJlbGV2YW50RmlsZXMuaGFzKGZpbGUpKTtcbn07XG5cbmNvbnN0IGFkZGVkRmlsZXNSZXF1aXJlRnVsbFJlYnVpbGQgPSBhc3luYyAoe1xuICBhZGRlZEZpbGVzLFxuICByZWFkU25hcHNob3QsXG59OiB7XG4gIGFkZGVkRmlsZXM6IHN0cmluZ1tdO1xuICByZWFkU25hcHNob3Q6IChmaWxlOiBzdHJpbmcpID0+IFByb21pc2U8U291cmNlU25hcHNob3Q+O1xufSkgPT4ge1xuICBmb3IgKGNvbnN0IGZpbGUgb2YgYWRkZWRGaWxlcykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHJlYWRTbmFwc2hvdChmaWxlKTtcbiAgICAgIGlmIChzbmFwc2hvdC5oYXNEaXJlY3RpdmUgfHwgc25hcHNob3QuaGFzU2VyZGUpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuY29uc3QgcHJ1bmVTdGFsZUFkZGVkRmlsZXMgPSBhc3luYyAoe1xuICBhZGRlZEZpbGVzLFxuICByZWFkU25hcHNob3QsXG4gIHNvdXJjZVNuYXBzaG90cyxcbn06IHtcbiAgYWRkZWRGaWxlczogc3RyaW5nW107XG4gIHJlYWRTbmFwc2hvdDogKGZpbGU6IHN0cmluZykgPT4gUHJvbWlzZTxTb3VyY2VTbmFwc2hvdD47XG4gIHNvdXJjZVNuYXBzaG90czogTWFwPHN0cmluZywgU291cmNlU25hcHNob3Q+O1xufSkgPT4ge1xuICBjb25zdCBuZXh0QWRkZWRGaWxlczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgc25hcHNob3RzID0gbmV3IE1hcDxzdHJpbmcsIFNvdXJjZVNuYXBzaG90PigpO1xuXG4gIGZvciAoY29uc3QgZmlsZSBvZiB1bmlxdWUoYWRkZWRGaWxlcykpIHtcbiAgICBjb25zdCBwcmV2aW91c1NuYXBzaG90ID0gc291cmNlU25hcHNob3RzLmdldChmaWxlKTtcbiAgICBpZiAoIXByZXZpb3VzU25hcHNob3QpIHtcbiAgICAgIG5leHRBZGRlZEZpbGVzLnB1c2goZmlsZSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgbmV4dFNuYXBzaG90ID0gYXdhaXQgcmVhZFNuYXBzaG90KGZpbGUpO1xuICAgICAgaWYgKGRpZFNvdXJjZVNuYXBzaG90Q2hhbmdlKHByZXZpb3VzU25hcHNob3QsIG5leHRTbmFwc2hvdCkpIHtcbiAgICAgICAgbmV4dEFkZGVkRmlsZXMucHVzaChmaWxlKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBzbmFwc2hvdHMuc2V0KGZpbGUsIG5leHRTbmFwc2hvdCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBuZXh0QWRkZWRGaWxlcy5wdXNoKGZpbGUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGFkZGVkRmlsZXM6IG5leHRBZGRlZEZpbGVzLCBzbmFwc2hvdHMgfTtcbn07XG5cbmNvbnN0IG1vZGlmaWVkRmlsZXNSZXF1aXJlRnVsbFJlYnVpbGQgPSBhc3luYyAoe1xuICBtb2RpZmllZEZpbGVzLFxuICByZWFkU25hcHNob3QsXG4gIHNvdXJjZVNuYXBzaG90cyxcbn06IHtcbiAgbW9kaWZpZWRGaWxlczogc3RyaW5nW107XG4gIHJlYWRTbmFwc2hvdDogKGZpbGU6IHN0cmluZykgPT4gUHJvbWlzZTxTb3VyY2VTbmFwc2hvdD47XG4gIHNvdXJjZVNuYXBzaG90czogTWFwPHN0cmluZywgU291cmNlU25hcHNob3Q+O1xufSkgPT4ge1xuICBmb3IgKGNvbnN0IGZpbGUgb2YgdW5pcXVlKG1vZGlmaWVkRmlsZXMpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG5leHRTbmFwc2hvdCA9IGF3YWl0IHJlYWRTbmFwc2hvdChmaWxlKTtcbiAgICAgIGNvbnN0IHByZXZpb3VzU25hcHNob3QgPSBzb3VyY2VTbmFwc2hvdHMuZ2V0KGZpbGUpO1xuICAgICAgaWYgKCFwcmV2aW91c1NuYXBzaG90KSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBuZXh0U25hcHNob3QuaW1wb3J0U2lnbmF0dXJlIHx8XG4gICAgICAgICAgbmV4dFNuYXBzaG90LmRlZmluaXRpb25TaWduYXR1cmUgfHxcbiAgICAgICAgICBuZXh0U25hcHNob3QuaGFzRGlyZWN0aXZlIHx8XG4gICAgICAgICAgbmV4dFNuYXBzaG90Lmhhc1NlcmRlXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGRpZFNvdXJjZVNuYXBzaG90Q2hhbmdlKHByZXZpb3VzU25hcHNob3QsIG5leHRTbmFwc2hvdCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuY29uc3QgZ2V0Q2hhbmdlZFJlbGV2YW50RmlsZXMgPSAoe1xuICBkaXNjb3ZlcmVkRW50cmllcyxcbiAgZmlsZUNoYW5nZXMsXG4gIGlucHV0RmlsZXMsXG4gIG5vcm1hbGl6ZVBhdGgsXG59OiB7XG4gIGRpc2NvdmVyZWRFbnRyaWVzOiBEaXNjb3ZlcmVkRW50cmllc0xpa2U7XG4gIGZpbGVDaGFuZ2VzOiBGaWxlQ2hhbmdlcztcbiAgaW5wdXRGaWxlczogc3RyaW5nW107XG4gIG5vcm1hbGl6ZVBhdGg6IChwYXRoOiBzdHJpbmcpID0+IHN0cmluZztcbn0pID0+IHtcbiAgY29uc3QgcmVsZXZhbnRGaWxlcyA9IGdldFJlbGV2YW50RmlsZXMoe1xuICAgIGRpc2NvdmVyZWRFbnRyaWVzLFxuICAgIGlucHV0RmlsZXMsXG4gICAgbm9ybWFsaXplUGF0aCxcbiAgfSk7XG4gIHJldHVybiB1bmlxdWUoZmlsZUNoYW5nZXMubW9kaWZpZWRGaWxlcykuZmlsdGVyKChmaWxlKSA9PlxuICAgIHJlbGV2YW50RmlsZXMuaGFzKGZpbGUpXG4gICk7XG59O1xuXG5jb25zdCBjb2xsZWN0SG90UmVidWlsZFNuYXBzaG90cyA9IGFzeW5jICh7XG4gIGNoYW5nZWRGaWxlcyxcbiAgcmVhZFNuYXBzaG90LFxuICBzb3VyY2VTbmFwc2hvdHMsXG59OiB7XG4gIGNoYW5nZWRGaWxlczogc3RyaW5nW107XG4gIHJlYWRTbmFwc2hvdDogKGZpbGU6IHN0cmluZykgPT4gUHJvbWlzZTxTb3VyY2VTbmFwc2hvdD47XG4gIHNvdXJjZVNuYXBzaG90czogTWFwPHN0cmluZywgU291cmNlU25hcHNob3Q+O1xufSkgPT4ge1xuICBjb25zdCBzbmFwc2hvdHMgPSBuZXcgTWFwPHN0cmluZywgU291cmNlU25hcHNob3Q+KCk7XG4gIGZvciAoY29uc3QgZmlsZSBvZiBjaGFuZ2VkRmlsZXMpIHtcbiAgICBpZiAoXG4gICAgICAhKGF3YWl0IHNuYXBzaG90Q2hhbmdlZEZpbGUoe1xuICAgICAgICBmaWxlLFxuICAgICAgICBuZXh0U25hcHNob3RzOiBzbmFwc2hvdHMsXG4gICAgICAgIHJlYWRTbmFwc2hvdCxcbiAgICAgICAgc291cmNlU25hcHNob3RzLFxuICAgICAgfSkpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG4gIHJldHVybiBzbmFwc2hvdHM7XG59O1xuXG5jb25zdCB3b3JrZmxvd0VudHJ5RmlsZXNDaGFuZ2VkID0gKHtcbiAgY2hhbmdlZEZpbGVzLFxuICBkaXNjb3ZlcmVkRW50cmllcyxcbiAgbm9ybWFsaXplUGF0aCxcbiAgcGFyZW50SGFzQ2hpbGQsXG59OiB7XG4gIGNoYW5nZWRGaWxlczogc3RyaW5nW107XG4gIGRpc2NvdmVyZWRFbnRyaWVzOiBEaXNjb3ZlcmVkRW50cmllc0xpa2U7XG4gIG5vcm1hbGl6ZVBhdGg6IChwYXRoOiBzdHJpbmcpID0+IHN0cmluZztcbiAgcGFyZW50SGFzQ2hpbGQ6IChcbiAgICBwYXJlbnQ6IHN0cmluZyxcbiAgICBjaGlsZDogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiB7IGV4Y2x1ZGVkUm9vdHM/OiBJdGVyYWJsZTxzdHJpbmc+IH1cbiAgKSA9PiBib29sZWFuO1xufSkgPT4ge1xuICBjb25zdCB3b3JrZmxvd0VudHJ5RmlsZXMgPSBbXG4gICAgLi4uZGlzY292ZXJlZEVudHJpZXMuZGlzY292ZXJlZFdvcmtmbG93cyxcbiAgICAuLi5kaXNjb3ZlcmVkRW50cmllcy5kaXNjb3ZlcmVkU2VyZGVGaWxlcyxcbiAgXS5tYXAobm9ybWFsaXplUGF0aCk7XG4gIGNvbnN0IHN0ZXBFbnRyeUZpbGVzID0gWy4uLmRpc2NvdmVyZWRFbnRyaWVzLmRpc2NvdmVyZWRTdGVwc10ubWFwKFxuICAgIG5vcm1hbGl6ZVBhdGhcbiAgKTtcblxuICByZXR1cm4gY2hhbmdlZEZpbGVzLnNvbWUoKGNoYW5nZWRGaWxlKSA9PiB7XG4gICAgaWYgKHdvcmtmbG93RW50cnlGaWxlcy5pbmNsdWRlcyhjaGFuZ2VkRmlsZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoc3RlcEVudHJ5RmlsZXMuaW5jbHVkZXMoY2hhbmdlZEZpbGUpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB3b3JrZmxvd0VudHJ5RmlsZXMuc29tZSgod29ya2Zsb3dGaWxlKSA9PlxuICAgICAgcGFyZW50SGFzQ2hpbGQod29ya2Zsb3dGaWxlLCBjaGFuZ2VkRmlsZSwge1xuICAgICAgICBleGNsdWRlZFJvb3RzOiBzdGVwRW50cnlGaWxlcyxcbiAgICAgIH0pXG4gICAgKTtcbiAgfSk7XG59O1xuXG5jb25zdCBzdGVwUmVnaXN0cmF0aW9uc05lZWRSZWZyZXNoID0gKHtcbiAgY2hhbmdlZEZpbGVzLFxuICBkaXNjb3ZlcmVkRW50cmllcyxcbiAgbm9ybWFsaXplUGF0aCxcbn06IHtcbiAgY2hhbmdlZEZpbGVzOiBzdHJpbmdbXTtcbiAgZGlzY292ZXJlZEVudHJpZXM6IERpc2NvdmVyZWRFbnRyaWVzTGlrZTtcbiAgbm9ybWFsaXplUGF0aDogKHBhdGg6IHN0cmluZykgPT4gc3RyaW5nO1xufSkgPT4ge1xuICBjb25zdCBzZXJkZUZpbGVzID0gbmV3IFNldChcbiAgICBbLi4uZGlzY292ZXJlZEVudHJpZXMuZGlzY292ZXJlZFNlcmRlRmlsZXNdLm1hcChub3JtYWxpemVQYXRoKVxuICApO1xuICByZXR1cm4gY2hhbmdlZEZpbGVzLnNvbWUoKGZpbGUpID0+IHNlcmRlRmlsZXMuaGFzKGZpbGUpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjbGFzc2lmeVJlYnVpbGQgPSBhc3luYyAoe1xuICBkaXNjb3ZlcmVkRW50cmllcyxcbiAgZmlsZUNoYW5nZXMsXG4gIGlucHV0RmlsZXMsXG4gIG5vcm1hbGl6ZVBhdGggPSBkZWZhdWx0Tm9ybWFsaXplUGF0aCxcbiAgcGFyZW50SGFzQ2hpbGQsXG4gIHJlYWRTbmFwc2hvdCxcbiAgc291cmNlU25hcHNob3RzLFxufToge1xuICBkaXNjb3ZlcmVkRW50cmllczogRGlzY292ZXJlZEVudHJpZXNMaWtlO1xuICBmaWxlQ2hhbmdlczogRmlsZUNoYW5nZXM7XG4gIGlucHV0RmlsZXM6IHN0cmluZ1tdO1xuICBub3JtYWxpemVQYXRoPzogKHBhdGg6IHN0cmluZykgPT4gc3RyaW5nO1xuICBwYXJlbnRIYXNDaGlsZDogKFxuICAgIHBhcmVudDogc3RyaW5nLFxuICAgIGNoaWxkOiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IHsgZXhjbHVkZWRSb290cz86IEl0ZXJhYmxlPHN0cmluZz4gfVxuICApID0+IGJvb2xlYW47XG4gIHJlYWRTbmFwc2hvdDogKGZpbGU6IHN0cmluZykgPT4gUHJvbWlzZTxTb3VyY2VTbmFwc2hvdD47XG4gIHNvdXJjZVNuYXBzaG90czogTWFwPHN0cmluZywgU291cmNlU25hcHNob3Q+O1xufSk6IFByb21pc2U8UmVidWlsZERlY2lzaW9uPiA9PiB7XG4gIGNvbnN0IHBydW5lZEFkZGVkRmlsZXMgPSBhd2FpdCBwcnVuZVN0YWxlQWRkZWRGaWxlcyh7XG4gICAgYWRkZWRGaWxlczogZmlsZUNoYW5nZXMuYWRkZWRGaWxlcyxcbiAgICByZWFkU25hcHNob3QsXG4gICAgc291cmNlU25hcHNob3RzLFxuICB9KTtcbiAgY29uc3Qgbm9ybWFsaXplZEZpbGVDaGFuZ2VzID0ge1xuICAgIC4uLmZpbGVDaGFuZ2VzLFxuICAgIGFkZGVkRmlsZXM6IHBydW5lZEFkZGVkRmlsZXMuYWRkZWRGaWxlcyxcbiAgfTtcblxuICBpZiAoXG4gICAgcmVtb3ZlZEZpbGVzUmVxdWlyZUZ1bGxSZWJ1aWxkKHtcbiAgICAgIGRpc2NvdmVyZWRFbnRyaWVzLFxuICAgICAgaW5wdXRGaWxlcyxcbiAgICAgIG5vcm1hbGl6ZVBhdGgsXG4gICAgICByZW1vdmVkRmlsZXM6IG5vcm1hbGl6ZWRGaWxlQ2hhbmdlcy5yZW1vdmVkRmlsZXMsXG4gICAgfSkgfHxcbiAgICAoYXdhaXQgYWRkZWRGaWxlc1JlcXVpcmVGdWxsUmVidWlsZCh7XG4gICAgICBhZGRlZEZpbGVzOiBub3JtYWxpemVkRmlsZUNoYW5nZXMuYWRkZWRGaWxlcyxcbiAgICAgIHJlYWRTbmFwc2hvdCxcbiAgICB9KSkgfHxcbiAgICAoYXdhaXQgbW9kaWZpZWRGaWxlc1JlcXVpcmVGdWxsUmVidWlsZCh7XG4gICAgICBtb2RpZmllZEZpbGVzOiBub3JtYWxpemVkRmlsZUNoYW5nZXMubW9kaWZpZWRGaWxlcyxcbiAgICAgIHJlYWRTbmFwc2hvdCxcbiAgICAgIHNvdXJjZVNuYXBzaG90cyxcbiAgICB9KSlcbiAgKSB7XG4gICAgcmV0dXJuIHsga2luZDogJ2Z1bGwnIH07XG4gIH1cblxuICBjb25zdCBjaGFuZ2VkUmVsZXZhbnRGaWxlcyA9IGdldENoYW5nZWRSZWxldmFudEZpbGVzKHtcbiAgICBkaXNjb3ZlcmVkRW50cmllcyxcbiAgICBmaWxlQ2hhbmdlczogbm9ybWFsaXplZEZpbGVDaGFuZ2VzLFxuICAgIGlucHV0RmlsZXMsXG4gICAgbm9ybWFsaXplUGF0aCxcbiAgfSk7XG4gIGlmIChjaGFuZ2VkUmVsZXZhbnRGaWxlcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gcHJ1bmVkQWRkZWRGaWxlcy5zbmFwc2hvdHMuc2l6ZSA+IDBcbiAgICAgID8geyBraW5kOiAnbm9uZScsIHNuYXBzaG90czogcHJ1bmVkQWRkZWRGaWxlcy5zbmFwc2hvdHMgfVxuICAgICAgOiB7IGtpbmQ6ICdub25lJyB9O1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBzbmFwc2hvdHMgPSBhd2FpdCBjb2xsZWN0SG90UmVidWlsZFNuYXBzaG90cyh7XG4gICAgICBjaGFuZ2VkRmlsZXM6IGNoYW5nZWRSZWxldmFudEZpbGVzLFxuICAgICAgcmVhZFNuYXBzaG90LFxuICAgICAgc291cmNlU25hcHNob3RzLFxuICAgIH0pO1xuICAgIGlmICghc25hcHNob3RzKSB7XG4gICAgICByZXR1cm4geyBraW5kOiAnZnVsbCcgfTtcbiAgICB9XG4gICAgcmV0dXJuIHdvcmtmbG93RW50cnlGaWxlc0NoYW5nZWQoe1xuICAgICAgY2hhbmdlZEZpbGVzOiBjaGFuZ2VkUmVsZXZhbnRGaWxlcyxcbiAgICAgIGRpc2NvdmVyZWRFbnRyaWVzLFxuICAgICAgbm9ybWFsaXplUGF0aCxcbiAgICAgIHBhcmVudEhhc0NoaWxkLFxuICAgIH0pXG4gICAgICA/IHtcbiAgICAgICAgICBraW5kOiAnaG90JyxcbiAgICAgICAgICByZWZyZXNoU3RlcFJlZ2lzdHJhdGlvbnM6IHN0ZXBSZWdpc3RyYXRpb25zTmVlZFJlZnJlc2goe1xuICAgICAgICAgICAgY2hhbmdlZEZpbGVzOiBjaGFuZ2VkUmVsZXZhbnRGaWxlcyxcbiAgICAgICAgICAgIGRpc2NvdmVyZWRFbnRyaWVzLFxuICAgICAgICAgICAgbm9ybWFsaXplUGF0aCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBzbmFwc2hvdHMsXG4gICAgICAgIH1cbiAgICAgIDogeyBraW5kOiAnbm9uZScsIHNuYXBzaG90cyB9O1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4geyBraW5kOiAnZnVsbCcgfTtcbiAgfVxufTtcbiJdfQ==
@@ -27,6 +27,39 @@ const workflowConfig = {}
27
27
  export default withWorkflow(nextConfig, workflowConfig); // [!code highlight]
28
28
  ```
29
29
 
30
+ <Callout type="warn">
31
+ If a package in `serverExternalPackages` contains workflow code (`"use step"`,
32
+ `"use workflow"`, or serialization classes), `withWorkflow()` automatically
33
+ removes it from `serverExternalPackages` for the current build and prints a
34
+ warning. Workflow still compiles the package so its directives are transformed.
35
+ Remove that package from `serverExternalPackages` in your
36
+ `next.config` to silence the warning.
37
+ </Callout>
38
+
39
+ ### Workflow Discovery in Next.js
40
+
41
+ `withWorkflow()` discovers workflows by scanning your Next.js entrypoints — App
42
+ Router `route`, `page`, and `layout` files (under `app/` or `src/app/`) and any
43
+ file under `pages/` or `src/pages/` — for `start()` calls imported from
44
+ `workflow/api`. The workflow and step files themselves can live anywhere (for
45
+ example `src/workflows/`); they are discovered transitively through imports, as
46
+ long as a `start()` call in an entrypoint statically reaches them.
47
+
48
+ <Callout type="info">
49
+ Call `start()` from server-side entrypoints, including Route Handlers and Server
50
+ Actions. Don't call workflow functions directly — that bypasses the workflow
51
+ runtime.
52
+ </Callout>
53
+
54
+ ### Next.js Server Actions and `"use server"`
55
+
56
+ Don't put a top-level `"use server"` directive in modules imported by workflow
57
+ or step functions. Workflow transformation wraps imported modules in synchronous
58
+ initializers, and Next.js rejects a `"use server"` directive inside that wrapper
59
+ with errors like `Server Actions must be async functions`. Keep `"use server"`
60
+ on the files that define your Server Actions, and move shared logic into
61
+ separate modules that don't carry the directive.
62
+
30
63
  ### Monorepos and Workspace Imports
31
64
 
32
65
  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:
@@ -59,18 +92,38 @@ const nextConfig: NextConfig = {};
59
92
 
60
93
  export default withWorkflow(nextConfig, {
61
94
  workflows: {
62
- lazyDiscovery: true,
63
95
  local: {
64
96
  port: 4000,
65
97
  },
98
+ sourcemap: false,
66
99
  },
67
100
  });
68
101
  ```
69
102
 
70
103
  | Option | Type | Default | Description |
71
104
  | --- | --- | --- | --- |
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
105
  | `workflows.local.port` | `number` | — | Overrides the `PORT` environment variable for local development. Has no effect when deployed to Vercel. |
106
+ | `workflows.sourcemap` | `boolean \| 'inline' \| 'linked' \| 'external' \| 'both'` | `'inline'` (dev) / `false` (prod) | Controls source maps on generated workflow bundles. See [Source maps](#source-maps) below. |
107
+
108
+ ### Source maps
109
+
110
+ The step bundle and intermediate workflow bundle default to `'inline'` source maps **in development** — so stack traces from step errors and workflow VM errors point at your source files — and to **`false` in production**, so function bundles stay small. The `sourcemap` option lets you change that:
111
+
112
+ | Value | Behavior |
113
+ | --- | --- |
114
+ | `true` / `'inline'` | Base64-encode the source map and append it to the bundle (default in development). |
115
+ | `'linked'` | Write a separate `.map` file and add a `sourceMappingURL` comment. |
116
+ | `'external'` | Write a separate `.map` file without the comment. |
117
+ | `'both'` | Emit both inline and external source maps. |
118
+ | `false` | Omit source maps entirely. |
119
+
120
+ In production, source maps are already off by default. Setting `sourcemap: false` explicitly also turns them off in development, and it drops the inline source map from every bundle while skipping the source-map-support runtime shim on the Vercel step function (the same behavior production gets by default) — the main lever for staying under the Vercel 250MB function size limit. The tradeoff is that workflow VM stack traces will reference generated code (e.g. `evalmachine.<anonymous>`) rather than your source files.
121
+
122
+ <Callout type="info">
123
+ Setting `sourcemap` explicitly affects **all** generated bundles (steps, workflows, webhook). The legacy `WORKFLOW_EMIT_SOURCEMAPS_FOR_DEBUGGING=1` environment variable is narrower — it only toggles source maps on the final workflow wrapper and webhook bundle (which default to off). It continues to work, but new code should use the `sourcemap` option or the `WORKFLOW_SOURCEMAP` environment variable instead.
124
+ </Callout>
125
+
126
+ The option can also be set via the `WORKFLOW_SOURCEMAP` environment variable, which accepts the same values plus `'0'` / `'1'` as aliases for `false` / `true`. Precedence is: explicit config > `WORKFLOW_SOURCEMAP` > the environment-aware default (`'inline'` in development, `false` in production). Development is detected from `next dev` / `NODE_ENV=development`, so the config option and the env var both let you force either behavior in either environment.
74
127
 
75
128
  <Callout type="info">
76
129
  The `workflows.local` options only affect local development. When deployed to Vercel, the runtime ignores `local` settings and uses the Vercel world automatically.
@@ -78,6 +131,7 @@ The `workflows.local` options only affect local development. When deployed to Ve
78
131
 
79
132
  ## Exporting a Function
80
133
 
134
+
81
135
  If you are exporting a function in your `next.config` you will need to ensure you call the function returned from `withWorkflow`.
82
136
 
83
137
  ```typescript title="next.config.ts" lineNumbers
package/docs/next.mdx CHANGED
@@ -7,9 +7,13 @@ prerequisites:
7
7
  - /docs/getting-started
8
8
  related:
9
9
  - /docs/api-reference/workflow-next
10
- - /docs/deploying/world/vercel-world
10
+ - /worlds/vercel
11
11
  ---
12
12
 
13
+ <CopyPrompt
14
+ text="In this Next.js app, run `npm i workflow`. Wrap `next.config.ts` with `withWorkflow` from `workflow/next`. If the app has `proxy.ts` or middleware, exclude `.well-known/workflow/` from its matcher. Add `workflows/user-signup.ts` exporting `handleUserSignup(email)` with `&quot;use workflow&quot;`, `sleep` from `workflow`, and `&quot;use step&quot;` helper functions that create a user, send a welcome email, and send an onboarding email. Add `app/api/signup/route.ts` with a POST handler that reads `{ email }`, calls `start(handleUserSignup, [email])` from `workflow/api`, and returns JSON. Run `npm run dev`, trigger `curl -X POST --json '{&quot;email&quot;:&quot;hello@example.com&quot;}' http://localhost:3000/api/signup`, and inspect with `npx workflow web` or `npx workflow inspect runs`."
15
+ />
16
+
13
17
  <Steps>
14
18
 
15
19
  <Step>
@@ -75,9 +79,9 @@ To enable helpful hints in your IDE, setup the workflow plugin in `tsconfig.json
75
79
  </Accordion>
76
80
 
77
81
  <Accordion type="single" collapsible>
78
- <AccordionItem value="typescript-intellisense" className="[&_h3]:my-0">
82
+ <AccordionItem value="configure-proxy-handler" className="[&_h3]:my-0">
79
83
  <AccordionTrigger className="text-sm">
80
- ### Configure Proxy Handler (if applicable)
84
+ <h3 id="configure-proxy-handler">Configure Proxy Handler (if applicable)</h3>
81
85
  </AccordionTrigger>
82
86
  <AccordionContent className="[&_p]:my-2">
83
87
 
@@ -85,7 +89,9 @@ If your Next.js app has a [proxy handler](https://nextjs.org/docs/app/api-refere
85
89
  (formerly known as "middleware"), you'll need to update the matcher pattern to exclude Workflow's
86
90
  internal paths to prevent the proxy handler from running on them.
87
91
 
88
- Add `.well-known/workflow/*` to your middleware's exclusion list:
92
+ If you see `[local world] Queue operation failed` with `Cannot perform ArrayBuffer.prototype.slice on a detached ArrayBuffer`, your proxy matcher is still intercepting Workflow's internal `POST /.well-known/workflow/v1/flow` request. This is especially easy to miss in Next.js 16, where `proxy.ts` replaced `middleware.ts`.
93
+
94
+ Add `.well-known/workflow/*` to your matcher exclusion list:
89
95
 
90
96
  ```typescript title="proxy.ts" lineNumbers
91
97
  import { NextResponse } from "next/server";
@@ -186,7 +192,7 @@ async function sendOnboardingEmail(user: { id: string; email: string}) {
186
192
 
187
193
  Taking a look at this code:
188
194
 
189
- * Business logic lives inside **steps**. When a step is invoked inside a **workflow**, it gets enqueued to run on a separate request while the workflow is suspended, just like `sleep`.
195
+ * Business logic lives inside **steps**. When a workflow invokes a step, the workflow suspends while the step runs with full Node.js access. The combined handler may execute it inline; queued retries and continuations return through the same flow route.
190
196
  * If a step throws an error, like in `sendWelcomeEmail`, the step will automatically be retried until it succeeds (or hits the step's max retry count).
191
197
  * Steps can throw a `FatalError` if an error is intentional and should not be retried.
192
198
 
@@ -310,7 +316,7 @@ Without this configuration, you may experience intermittent issues where workflo
310
316
  If you see this error:
311
317
 
312
318
  ```
313
- 'start' received an invalid workflow function. Ensure the Workflow Development Kit is configured correctly and the function includes a 'use workflow' directive.
319
+ 'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
314
320
  ```
315
321
 
316
322
  Check both of these first:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workflow/next",
3
- "version": "5.0.0-beta.4",
3
+ "version": "5.0.0-beta.41",
4
4
  "description": "Next.js integration for Workflow SDK",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.js",
@@ -27,17 +27,19 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@swc/core": "1.15.3",
30
+ "chokidar": "4.0.3",
31
+ "ignore": "7.0.5",
30
32
  "semver": "7.7.4",
31
- "watchpack": "2.5.1",
32
- "@workflow/builders": "5.0.0-beta.4",
33
- "@workflow/core": "5.0.0-beta.4",
34
- "@workflow/swc-plugin": "5.0.0-beta.3"
33
+ "@workflow/builders": "5.0.0-beta.41",
34
+ "@workflow/core": "5.0.0-beta.41",
35
+ "@workflow/swc-plugin": "5.0.0-beta.5"
35
36
  },
36
37
  "devDependencies": {
37
38
  "@types/node": "22.19.0",
38
39
  "@types/semver": "7.7.1",
39
- "@types/watchpack": "2.4.4",
40
- "next": "16.2.1",
40
+ "next": "16.2.11",
41
+ "typescript": "^6.0.3",
42
+ "vitest": "^4.1.10",
41
43
  "@workflow/tsconfig": "5.0.0-beta.0"
42
44
  },
43
45
  "peerDependencies": {
@@ -51,6 +53,7 @@
51
53
  "scripts": {
52
54
  "build": "tsc",
53
55
  "dev": "tsc --watch",
56
+ "test": "vitest run src",
54
57
  "clean": "tsc --build --clean && rm -rf dist docs"
55
58
  }
56
59
  }