@workflow/next 5.0.0-beta.4 → 5.0.0-beta.5
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/dist/builder-deferred.d.ts.map +1 -1
- package/dist/builder-deferred.js +227 -302
- package/dist/builder-deferred.js.map +1 -1
- package/dist/builder-eager.d.ts.map +1 -1
- package/dist/builder-eager.js +51 -75
- package/dist/builder-eager.js.map +1 -1
- package/dist/builder.d.ts +1 -1
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +2 -2
- package/dist/builder.js.map +1 -1
- package/dist/environment-flag.d.ts +2 -0
- package/dist/environment-flag.d.ts.map +1 -0
- package/dist/environment-flag.js +15 -0
- package/dist/environment-flag.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +254 -4
- package/dist/index.js.map +1 -1
- package/docs/api-reference/with-workflow.mdx +32 -0
- package/package.json +4 -4
package/dist/builder-deferred.js
CHANGED
|
@@ -7,10 +7,10 @@ exports.getNextBuilderDeferred = getNextBuilderDeferred;
|
|
|
7
7
|
const node_crypto_1 = require("node:crypto");
|
|
8
8
|
const node_fs_1 = require("node:fs");
|
|
9
9
|
const promises_1 = require("node:fs/promises");
|
|
10
|
+
const node_module_1 = require("node:module");
|
|
10
11
|
const node_os_1 = __importDefault(require("node:os"));
|
|
11
12
|
const node_path_1 = require("node:path");
|
|
12
13
|
const socket_server_js_1 = require("./socket-server.js");
|
|
13
|
-
const DEFERRED_STEP_COPY_DIR_NAME = '__workflow_step_files__';
|
|
14
14
|
const ROUTE_STUB_FILE_MARKER = 'WORKFLOW_ROUTE_STUB_FILE';
|
|
15
15
|
const ROUTE_STUB_MARKER_SCAN_BYTES = 4 * 1024;
|
|
16
16
|
let CachedNextBuilderDeferred;
|
|
@@ -21,7 +21,13 @@ async function getNextBuilderDeferred() {
|
|
|
21
21
|
if (CachedNextBuilderDeferred) {
|
|
22
22
|
return CachedNextBuilderDeferred;
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
// V2: STEP_QUEUE_TRIGGER, getImportPath, and enhanced-resolve infrastructure
|
|
25
|
+
// were removed because the V2 combined handler eliminates the separate step
|
|
26
|
+
// route/topic. The step copy import rewriting (getRelativeImportSpecifier,
|
|
27
|
+
// getStepCopyFileName, rewriteRelativeImportsForCopiedStep) from main was also
|
|
28
|
+
// removed — V2 doesn't use step copies. If step copy support is needed, it
|
|
29
|
+
// should land as a complete feature set.
|
|
30
|
+
const { BaseBuilder: BaseBuilderClass, WORKFLOW_QUEUE_TRIGGER, detectWorkflowPatterns, applySwcTransform, resolveWorkflowAliasRelativePath,
|
|
25
31
|
// biome-ignore lint/security/noGlobalEval: Need to use eval here to avoid TypeScript from transpiling the import statement into `require()`
|
|
26
32
|
} = (await eval('import("@workflow/builders")'));
|
|
27
33
|
class NextDeferredBuilder extends BaseBuilderClass {
|
|
@@ -35,7 +41,6 @@ async function getNextBuilderDeferred() {
|
|
|
35
41
|
cacheWriteTimer = null;
|
|
36
42
|
deferredRebuildTimer = null;
|
|
37
43
|
lastDeferredBuildSignature = null;
|
|
38
|
-
manifestStepResolveBaseDirs = null;
|
|
39
44
|
async build() {
|
|
40
45
|
const outputDir = await this.findAppDirectory();
|
|
41
46
|
await this.initializeDiscoveryState();
|
|
@@ -99,6 +104,14 @@ async function getNextBuilderDeferred() {
|
|
|
99
104
|
}
|
|
100
105
|
}
|
|
101
106
|
this.lastDeferredBuildSignature = buildSignature;
|
|
107
|
+
if (!this.config.watch) {
|
|
108
|
+
// Production builds can persist newly discovered deferred-entry files to
|
|
109
|
+
// the cache after the first pass completes. Reload that cache before we
|
|
110
|
+
// decide whether the input signature stabilized so staged tarball builds
|
|
111
|
+
// can immediately replay with the expanded step set.
|
|
112
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
113
|
+
await this.loadWorkflowsCache();
|
|
114
|
+
}
|
|
102
115
|
const postBuildInputFiles = this.getCurrentInputFiles(implicitStepFiles);
|
|
103
116
|
const postBuildSignature = await this.createDeferredBuildSignature(postBuildInputFiles);
|
|
104
117
|
if (postBuildSignature === buildSignature) {
|
|
@@ -115,15 +128,11 @@ async function getNextBuilderDeferred() {
|
|
|
115
128
|
const outputDir = await this.findAppDirectory();
|
|
116
129
|
const generatedRouteFiles = [
|
|
117
130
|
(0, node_path_1.join)(outputDir, '.well-known/workflow/v1/flow/route.js'),
|
|
118
|
-
(0, node_path_1.join)(outputDir, '.well-known/workflow/v1/step/route.js'),
|
|
119
131
|
(0, node_path_1.join)(outputDir, '.well-known/workflow/v1/webhook/[token]/route.js'),
|
|
120
132
|
];
|
|
121
133
|
for (const routeFilePath of generatedRouteFiles) {
|
|
122
134
|
const routeState = await this.getGeneratedRouteState(routeFilePath);
|
|
123
|
-
if (routeState === 'missing') {
|
|
124
|
-
return true;
|
|
125
|
-
}
|
|
126
|
-
if (routeState === 'stub') {
|
|
135
|
+
if (routeState === 'missing' || routeState === 'stub') {
|
|
127
136
|
return true;
|
|
128
137
|
}
|
|
129
138
|
}
|
|
@@ -341,18 +350,17 @@ async function getNextBuilderDeferred() {
|
|
|
341
350
|
...this.discoveredSerdeFiles,
|
|
342
351
|
...trackedDiscoveredEntries.discoveredSerdeFiles,
|
|
343
352
|
])).sort();
|
|
344
|
-
const discoveredStepFiles = await this.filterExistingFiles(discoveredStepFileCandidates);
|
|
345
353
|
const discoveredWorkflowFiles = await this.filterExistingFiles(discoveredWorkflowFileCandidates);
|
|
354
|
+
const existingStepFileCandidates = await this.filterExistingFiles(discoveredStepFileCandidates);
|
|
355
|
+
const discoveredStepFiles = await this.collectTransitiveStepFiles({
|
|
356
|
+
entryFiles: [...existingStepFileCandidates, ...discoveredWorkflowFiles],
|
|
357
|
+
stepFiles: existingStepFileCandidates,
|
|
358
|
+
});
|
|
346
359
|
const existingSerdeFileCandidates = await this.filterExistingFiles(discoveredSerdeFileCandidates);
|
|
347
360
|
const discoveredSerdeFiles = await this.collectTransitiveSerdeFiles({
|
|
348
361
|
entryFiles: [...discoveredStepFiles, ...discoveredWorkflowFiles],
|
|
349
362
|
serdeFiles: existingSerdeFileCandidates,
|
|
350
363
|
});
|
|
351
|
-
const discoveredEntries = {
|
|
352
|
-
discoveredSteps: new Set(discoveredStepFiles),
|
|
353
|
-
discoveredWorkflows: new Set(discoveredWorkflowFiles),
|
|
354
|
-
discoveredSerdeFiles: new Set(discoveredSerdeFiles),
|
|
355
|
-
};
|
|
356
364
|
const existingInputFiles = await this.filterExistingFiles(inputFiles);
|
|
357
365
|
const buildInputFiles = Array.from(new Set([
|
|
358
366
|
...existingInputFiles,
|
|
@@ -360,38 +368,42 @@ async function getNextBuilderDeferred() {
|
|
|
360
368
|
...discoveredWorkflowFiles,
|
|
361
369
|
...discoveredSerdeFiles,
|
|
362
370
|
])).sort();
|
|
371
|
+
const discoveredEntries = {
|
|
372
|
+
discoveredSteps: new Set(discoveredStepFiles),
|
|
373
|
+
discoveredWorkflows: new Set(discoveredWorkflowFiles),
|
|
374
|
+
discoveredSerdeFiles: new Set(discoveredSerdeFiles),
|
|
375
|
+
};
|
|
363
376
|
// Ensure output directories exist
|
|
364
377
|
await (0, promises_1.mkdir)(workflowGeneratedDir, { recursive: true });
|
|
365
378
|
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, '.gitignore'), '*');
|
|
366
379
|
const tsconfigPath = await this.findTsConfigPath();
|
|
367
|
-
|
|
380
|
+
// V2: Build combined route (replaces separate step + flow routes)
|
|
381
|
+
const flowRouteDir = (0, node_path_1.join)(workflowGeneratedDir, 'flow');
|
|
382
|
+
await (0, promises_1.mkdir)(flowRouteDir, { recursive: true });
|
|
383
|
+
// Write step registrations to final name directly (not temp) so the
|
|
384
|
+
// import path in the flow route is correct. The flow route uses temp
|
|
385
|
+
// naming to avoid HMR churn via copyFileIfChanged, but the step
|
|
386
|
+
// registrations file is a side-effect import and doesn't need that.
|
|
387
|
+
const stepsOutfile = (0, node_path_1.join)(flowRouteDir, '__step_registrations.js');
|
|
388
|
+
const combinedResult = await this.createCombinedBundle({
|
|
389
|
+
format: 'esm',
|
|
368
390
|
inputFiles: buildInputFiles,
|
|
369
|
-
|
|
391
|
+
stepsOutfile,
|
|
392
|
+
flowOutfile: (0, node_path_1.join)(flowRouteDir, tempRouteFileName),
|
|
393
|
+
bundleFinalOutput: false,
|
|
394
|
+
externalizeNonSteps: true,
|
|
370
395
|
tsconfigPath,
|
|
371
|
-
routeFileName: tempRouteFileName,
|
|
372
396
|
discoveredEntries,
|
|
373
|
-
};
|
|
374
|
-
const workflowsBundle = await this.buildWorkflowsFunction(options);
|
|
375
|
-
const { manifest: stepsManifest } = await this.buildStepsFunction({
|
|
376
|
-
...options,
|
|
377
|
-
additionalStepSourceManifest: workflowsBundle?.manifest,
|
|
378
397
|
});
|
|
379
398
|
await this.buildWebhookRoute({
|
|
380
399
|
workflowGeneratedDir,
|
|
381
400
|
routeFileName: tempRouteFileName,
|
|
382
401
|
});
|
|
383
402
|
await this.refreshTrackedDependencyFiles(workflowGeneratedDir, tempRouteFileName);
|
|
384
|
-
// Merge manifests from both bundles
|
|
385
403
|
const manifest = {
|
|
386
|
-
steps: { ...
|
|
387
|
-
workflows: {
|
|
388
|
-
|
|
389
|
-
...workflowsBundle?.manifest?.workflows,
|
|
390
|
-
},
|
|
391
|
-
classes: {
|
|
392
|
-
...stepsManifest.classes,
|
|
393
|
-
...workflowsBundle?.manifest?.classes,
|
|
394
|
-
},
|
|
404
|
+
steps: { ...combinedResult?.manifest?.steps },
|
|
405
|
+
workflows: { ...combinedResult?.manifest?.workflows },
|
|
406
|
+
classes: { ...combinedResult?.manifest?.classes },
|
|
395
407
|
};
|
|
396
408
|
const manifestFilePath = (0, node_path_1.join)(workflowGeneratedDir, 'manifest.json');
|
|
397
409
|
const manifestBuildPath = (0, node_path_1.join)(manifestBuildDir, 'manifest.json');
|
|
@@ -410,8 +422,8 @@ async function getNextBuilderDeferred() {
|
|
|
410
422
|
await (0, promises_1.rm)(manifestFilePath, { force: true });
|
|
411
423
|
}
|
|
412
424
|
await this.writeFunctionsConfig(outputDir);
|
|
425
|
+
// V2: Combined route (flow) — step registrations already at final path
|
|
413
426
|
await this.copyFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, `flow/${tempRouteFileName}`), (0, node_path_1.join)(workflowGeneratedDir, 'flow/route.js'));
|
|
414
|
-
await this.copyFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, `step/${tempRouteFileName}`), (0, node_path_1.join)(workflowGeneratedDir, 'step/route.js'));
|
|
415
427
|
await this.copyFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, `webhook/[token]/${tempRouteFileName}`), (0, node_path_1.join)(workflowGeneratedDir, 'webhook/[token]/route.js'));
|
|
416
428
|
// Expose manifest as a static file when WORKFLOW_PUBLIC_MANIFEST=1.
|
|
417
429
|
// Next.js serves files from public/ at the root URL.
|
|
@@ -432,17 +444,16 @@ async function getNextBuilderDeferred() {
|
|
|
432
444
|
(0, node_path_1.join)(flowRouteDir, 'route.js.temp'),
|
|
433
445
|
(0, node_path_1.join)(flowRouteDir, 'route.js.temp.debug.json'),
|
|
434
446
|
(0, node_path_1.join)(flowRouteDir, 'route.js.debug.json'),
|
|
435
|
-
(0, node_path_1.join)(
|
|
436
|
-
(0, node_path_1.join)(
|
|
437
|
-
|
|
438
|
-
|
|
447
|
+
(0, node_path_1.join)(flowRouteDir, '__step_registrations.route.js.temp'),
|
|
448
|
+
(0, node_path_1.join)(flowRouteDir, '__step_registrations.route.js.temp.debug.json'),
|
|
449
|
+
// V2: clean up stale V1 step route directory
|
|
450
|
+
stepRouteDir,
|
|
439
451
|
(0, node_path_1.join)(webhookRouteDir, 'route.js.temp'),
|
|
440
452
|
(0, node_path_1.join)(workflowGeneratedDir, 'manifest.json'),
|
|
441
453
|
];
|
|
442
454
|
await Promise.all(staleArtifactPaths.map((stalePath) => (0, promises_1.rm)(stalePath, { recursive: true, force: true })));
|
|
443
455
|
await Promise.all([
|
|
444
456
|
this.removeStaleDeferredTempFiles(flowRouteDir),
|
|
445
|
-
this.removeStaleDeferredTempFiles(stepRouteDir),
|
|
446
457
|
this.removeStaleDeferredTempFiles(webhookRouteDir),
|
|
447
458
|
]);
|
|
448
459
|
}
|
|
@@ -503,7 +514,11 @@ async function getNextBuilderDeferred() {
|
|
|
503
514
|
if (hasCacheTrackingChange) {
|
|
504
515
|
this.scheduleWorkflowsCacheWrite();
|
|
505
516
|
}
|
|
506
|
-
if (
|
|
517
|
+
if (hasWorkflow ||
|
|
518
|
+
hasStep ||
|
|
519
|
+
hasSerde ||
|
|
520
|
+
hasCacheTrackingChange ||
|
|
521
|
+
wasTrackedDependency) {
|
|
507
522
|
this.scheduleDeferredRebuild();
|
|
508
523
|
}
|
|
509
524
|
},
|
|
@@ -531,39 +546,66 @@ async function getNextBuilderDeferred() {
|
|
|
531
546
|
getSocketInfoFilePath() {
|
|
532
547
|
return (0, node_path_1.join)(this.config.workingDir, this.getDistDir(), 'cache', 'workflow-socket.json');
|
|
533
548
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
549
|
+
findPackageJsonPath(filePath) {
|
|
550
|
+
let currentDir = (0, node_path_1.dirname)(filePath);
|
|
551
|
+
let previousDir = '';
|
|
552
|
+
while (currentDir !== previousDir) {
|
|
553
|
+
const packageJsonPath = (0, node_path_1.join)(currentDir, 'package.json');
|
|
554
|
+
if ((0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
555
|
+
return packageJsonPath;
|
|
556
|
+
}
|
|
557
|
+
previousDir = currentDir;
|
|
558
|
+
currentDir = (0, node_path_1.dirname)(currentDir);
|
|
543
559
|
}
|
|
560
|
+
return null;
|
|
544
561
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
562
|
+
shouldPreferSourceBackedPackagePath(filePath) {
|
|
563
|
+
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
564
|
+
// Only prefer source for workspace packages (not in node_modules).
|
|
565
|
+
// For tarball-installed packages, using source-backed paths causes
|
|
566
|
+
// esbuild to bundle the full source tree (including world.ts with
|
|
567
|
+
// process.cwd()) instead of externalizing properly.
|
|
568
|
+
if (normalizedPath.includes('/packages/') &&
|
|
569
|
+
!normalizedPath.includes('/node_modules/')) {
|
|
570
|
+
return true;
|
|
548
571
|
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
resolveBaseDirs.add(this.normalizeDiscoveredFilePath(baseDir));
|
|
552
|
-
};
|
|
553
|
-
if (this.config.projectRoot) {
|
|
554
|
-
addResolveBaseDir(this.config.projectRoot);
|
|
572
|
+
if (!normalizedPath.includes('/node_modules/')) {
|
|
573
|
+
return false;
|
|
555
574
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
575
|
+
const packageJsonPath = this.findPackageJsonPath(filePath);
|
|
576
|
+
if (!packageJsonPath) {
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
try {
|
|
580
|
+
const packageJson = JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, 'utf-8'));
|
|
581
|
+
return (packageJson.name === 'workflow' ||
|
|
582
|
+
(typeof packageJson.name === 'string' &&
|
|
583
|
+
packageJson.name.startsWith('@workflow/')));
|
|
584
|
+
}
|
|
585
|
+
catch {
|
|
586
|
+
return false;
|
|
564
587
|
}
|
|
565
|
-
|
|
566
|
-
|
|
588
|
+
}
|
|
589
|
+
resolveSourceBackedPackagePath(filePath) {
|
|
590
|
+
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
591
|
+
if (!normalizedPath.includes('/dist/')) {
|
|
592
|
+
return filePath;
|
|
593
|
+
}
|
|
594
|
+
const sourceCandidate = normalizedPath.replace('/dist/', '/src/');
|
|
595
|
+
const resolvedSourceCandidate = this.resolveCopiedStepImportTargetPath(sourceCandidate);
|
|
596
|
+
if (!(0, node_fs_1.existsSync)(resolvedSourceCandidate) ||
|
|
597
|
+
!this.shouldPreferSourceBackedPackagePath(filePath)) {
|
|
598
|
+
return filePath;
|
|
599
|
+
}
|
|
600
|
+
return (0, node_fs_1.existsSync)(resolvedSourceCandidate)
|
|
601
|
+
? resolvedSourceCandidate
|
|
602
|
+
: filePath;
|
|
603
|
+
}
|
|
604
|
+
normalizeDiscoveredFilePath(filePath) {
|
|
605
|
+
const absolutePath = (0, node_path_1.isAbsolute)(filePath)
|
|
606
|
+
? filePath
|
|
607
|
+
: (0, node_path_1.resolve)(this.config.workingDir, filePath);
|
|
608
|
+
return this.resolveSourceBackedPackagePath(absolutePath);
|
|
567
609
|
}
|
|
568
610
|
async filterExistingFiles(filePaths) {
|
|
569
611
|
const normalizedFilePaths = Array.from(new Set(filePaths.map((filePath) => this.normalizeDiscoveredFilePath(filePath)))).sort();
|
|
@@ -683,9 +725,12 @@ async function getNextBuilderDeferred() {
|
|
|
683
725
|
}
|
|
684
726
|
const normalizedSourcePath = this.normalizeDiscoveredFilePath(resolvedSourcePath);
|
|
685
727
|
const normalizedSourcePathForCheck = normalizedSourcePath.replace(/\\/g, '/');
|
|
728
|
+
const isSourceBackedPackagePath = this.shouldPreferSourceBackedPackagePath(normalizedSourcePath);
|
|
686
729
|
if (normalizedSourcePathForCheck.includes('/.well-known/workflow/') ||
|
|
687
|
-
|
|
688
|
-
|
|
730
|
+
(!isSourceBackedPackagePath &&
|
|
731
|
+
normalizedSourcePathForCheck.includes('/node_modules/')) ||
|
|
732
|
+
(!isSourceBackedPackagePath &&
|
|
733
|
+
normalizedSourcePathForCheck.includes('/.pnpm/')) ||
|
|
689
734
|
normalizedSourcePathForCheck.includes('/.next/') ||
|
|
690
735
|
normalizedSourcePathForCheck.endsWith('/virtual-entry.js')) {
|
|
691
736
|
continue;
|
|
@@ -707,9 +752,6 @@ async function getNextBuilderDeferred() {
|
|
|
707
752
|
}, 50);
|
|
708
753
|
}
|
|
709
754
|
scheduleDeferredRebuild() {
|
|
710
|
-
if (!this.config.watch) {
|
|
711
|
-
return;
|
|
712
|
-
}
|
|
713
755
|
if (this.deferredRebuildTimer) {
|
|
714
756
|
clearTimeout(this.deferredRebuildTimer);
|
|
715
757
|
}
|
|
@@ -784,35 +826,61 @@ async function getNextBuilderDeferred() {
|
|
|
784
826
|
].join('\n');
|
|
785
827
|
const workflowGeneratedDir = (0, node_path_1.join)(outputDir, '.well-known/workflow/v1');
|
|
786
828
|
await (0, promises_1.mkdir)((0, node_path_1.join)(workflowGeneratedDir, 'flow'), { recursive: true });
|
|
787
|
-
await (0, promises_1.mkdir)((0, node_path_1.join)(workflowGeneratedDir, 'step'), { recursive: true });
|
|
788
829
|
await (0, promises_1.mkdir)((0, node_path_1.join)(workflowGeneratedDir, 'webhook/[token]'), {
|
|
789
830
|
recursive: true,
|
|
790
831
|
});
|
|
791
832
|
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, '.gitignore'), '*');
|
|
792
|
-
//
|
|
793
|
-
//
|
|
833
|
+
// V2: Only flow + webhook stubs needed (no separate step route).
|
|
834
|
+
// Stubs are replaced by generated output once discovery finishes.
|
|
794
835
|
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, 'flow/route.js'), routeStubContent);
|
|
795
|
-
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, 'step/route.js'), routeStubContent);
|
|
796
836
|
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, 'webhook/[token]/route.js'), routeStubContent);
|
|
797
837
|
}
|
|
838
|
+
async getInputFiles() {
|
|
839
|
+
// Read Next.js's app-paths-manifest.json from a previous build to
|
|
840
|
+
// determine which files are actual route entrypoints. This avoids
|
|
841
|
+
// predicting Next.js conventions with regexes and instead reads
|
|
842
|
+
// from Next.js's own output.
|
|
843
|
+
const nextDir = (0, node_path_1.join)(this.config.workingDir, '.next');
|
|
844
|
+
const manifestPath = (0, node_path_1.join)(nextDir, 'app-paths-manifest.json');
|
|
845
|
+
try {
|
|
846
|
+
const manifestContent = (0, node_fs_1.readFileSync)(manifestPath, 'utf-8');
|
|
847
|
+
const manifest = JSON.parse(manifestContent);
|
|
848
|
+
// The manifest maps route paths to their source files.
|
|
849
|
+
// Extract the source file paths and resolve them.
|
|
850
|
+
const manifestFiles = new Set();
|
|
851
|
+
for (const sourcePath of Object.values(manifest)) {
|
|
852
|
+
const resolved = (0, node_path_1.resolve)(nextDir, 'server', sourcePath);
|
|
853
|
+
// The manifest points to built output; find the source file
|
|
854
|
+
// by matching against the base builder's full file list.
|
|
855
|
+
manifestFiles.add(resolved);
|
|
856
|
+
}
|
|
857
|
+
// Use the manifest route paths to filter the input files.
|
|
858
|
+
// A file is included if it matches a known route segment from
|
|
859
|
+
// the manifest (e.g., app/api/route contains 'app/api/route').
|
|
860
|
+
const inputFiles = await super.getInputFiles();
|
|
861
|
+
const routeSegments = Object.keys(manifest).map((route) => route.replace(/^\//, '').replace(/\/route$/, ''));
|
|
862
|
+
return inputFiles.filter((item) => routeSegments.some((segment) => item.includes(segment)));
|
|
863
|
+
}
|
|
864
|
+
catch {
|
|
865
|
+
// No manifest from a previous build — fall back to the base
|
|
866
|
+
// builder's full file scan. This is safe but slower; subsequent
|
|
867
|
+
// builds will use the manifest.
|
|
868
|
+
return super.getInputFiles();
|
|
869
|
+
}
|
|
870
|
+
}
|
|
798
871
|
async writeFunctionsConfig(outputDir) {
|
|
799
872
|
// we don't run this in development mode as it's not needed
|
|
800
873
|
if (process.env.NODE_ENV === 'development') {
|
|
801
874
|
return;
|
|
802
875
|
}
|
|
876
|
+
// V2: Single combined trigger handles both workflow and step execution
|
|
803
877
|
const generatedConfig = {
|
|
804
878
|
version: '0',
|
|
805
|
-
steps: {
|
|
806
|
-
maxDuration: 'max',
|
|
807
|
-
experimentalTriggers: [STEP_QUEUE_TRIGGER],
|
|
808
|
-
},
|
|
809
879
|
workflows: {
|
|
810
880
|
maxDuration: 'max',
|
|
811
881
|
experimentalTriggers: [WORKFLOW_QUEUE_TRIGGER],
|
|
812
882
|
},
|
|
813
883
|
};
|
|
814
|
-
// We write this file to the generated directory for
|
|
815
|
-
// the Next.js builder to consume
|
|
816
884
|
await this.writeFileIfChanged((0, node_path_1.join)(outputDir, '.well-known/workflow/v1/config.json'), JSON.stringify(generatedConfig, null, 2));
|
|
817
885
|
}
|
|
818
886
|
async writeFileIfChanged(filePath, contents) {
|
|
@@ -859,16 +927,56 @@ async function getNextBuilderDeferred() {
|
|
|
859
927
|
// Manifest may not exist (e.g. manifest generation failed); ignore.
|
|
860
928
|
}
|
|
861
929
|
}
|
|
862
|
-
|
|
863
|
-
if (
|
|
864
|
-
|
|
930
|
+
resolveCopiedStepImportTargetPath(targetPath) {
|
|
931
|
+
if ((0, node_fs_1.existsSync)(targetPath)) {
|
|
932
|
+
return targetPath;
|
|
933
|
+
}
|
|
934
|
+
const extensionMatch = targetPath.match(/(\.[^./\\]+)$/);
|
|
935
|
+
const extension = extensionMatch?.[1]?.toLowerCase();
|
|
936
|
+
if (!extension) {
|
|
937
|
+
return targetPath;
|
|
938
|
+
}
|
|
939
|
+
const extensionFallbacks = extension === '.js'
|
|
940
|
+
? ['.ts', '.tsx', '.mts', '.cts']
|
|
941
|
+
: extension === '.mjs'
|
|
942
|
+
? ['.mts']
|
|
943
|
+
: extension === '.cjs'
|
|
944
|
+
? ['.cts']
|
|
945
|
+
: extension === '.jsx'
|
|
946
|
+
? ['.tsx']
|
|
947
|
+
: [];
|
|
948
|
+
if (extensionFallbacks.length === 0) {
|
|
949
|
+
return targetPath;
|
|
865
950
|
}
|
|
866
|
-
|
|
867
|
-
|
|
951
|
+
const targetWithoutExtension = targetPath.slice(0, -extension.length);
|
|
952
|
+
for (const fallbackExtension of extensionFallbacks) {
|
|
953
|
+
const fallbackPath = `${targetWithoutExtension}${fallbackExtension}`;
|
|
954
|
+
if ((0, node_fs_1.existsSync)(fallbackPath)) {
|
|
955
|
+
return fallbackPath;
|
|
956
|
+
}
|
|
868
957
|
}
|
|
869
|
-
|
|
870
|
-
|
|
958
|
+
return targetPath;
|
|
959
|
+
}
|
|
960
|
+
extractRelativeImportSpecifiers(source) {
|
|
961
|
+
return this.extractImportSpecifiers(source).filter((specifier) => specifier.startsWith('.'));
|
|
962
|
+
}
|
|
963
|
+
extractImportSpecifiers(source) {
|
|
964
|
+
const relativeSpecifiers = new Set();
|
|
965
|
+
const importPatterns = [
|
|
966
|
+
/from\s+['"]([^'"]+)['"]/g,
|
|
967
|
+
/import\s+['"]([^'"]+)['"]/g,
|
|
968
|
+
/import\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
969
|
+
/require\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
970
|
+
];
|
|
971
|
+
for (const importPattern of importPatterns) {
|
|
972
|
+
for (const match of source.matchAll(importPattern)) {
|
|
973
|
+
const specifier = match[1];
|
|
974
|
+
if (specifier) {
|
|
975
|
+
relativeSpecifiers.add(specifier);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
871
978
|
}
|
|
979
|
+
return Array.from(relativeSpecifiers);
|
|
872
980
|
}
|
|
873
981
|
async getRelativeFilenameForSwc(filePath) {
|
|
874
982
|
const workingDir = this.config.workingDir;
|
|
@@ -906,13 +1014,6 @@ async function getNextBuilderDeferred() {
|
|
|
906
1014
|
}
|
|
907
1015
|
return relativeFilename;
|
|
908
1016
|
}
|
|
909
|
-
getRelativeImportSpecifier(fromFilePath, toFilePath) {
|
|
910
|
-
let relativePath = (0, node_path_1.relative)((0, node_path_1.dirname)(fromFilePath), toFilePath).replace(/\\/g, '/');
|
|
911
|
-
if (!relativePath.startsWith('.')) {
|
|
912
|
-
relativePath = `./${relativePath}`;
|
|
913
|
-
}
|
|
914
|
-
return relativePath;
|
|
915
|
-
}
|
|
916
1017
|
resolveImportTargetWithExtensionFallbacks(targetPath) {
|
|
917
1018
|
if ((0, node_fs_1.existsSync)(targetPath)) {
|
|
918
1019
|
return targetPath;
|
|
@@ -943,38 +1044,35 @@ async function getNextBuilderDeferred() {
|
|
|
943
1044
|
}
|
|
944
1045
|
return targetPath;
|
|
945
1046
|
}
|
|
946
|
-
extractRelativeImportSpecifiers(source) {
|
|
947
|
-
const relativeSpecifiers = new Set();
|
|
948
|
-
const importPatterns = [
|
|
949
|
-
/from\s+['"]([^'"]+)['"]/g,
|
|
950
|
-
/import\s+['"]([^'"]+)['"]/g,
|
|
951
|
-
/import\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
952
|
-
/require\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
953
|
-
];
|
|
954
|
-
for (const importPattern of importPatterns) {
|
|
955
|
-
for (const match of source.matchAll(importPattern)) {
|
|
956
|
-
const specifier = match[1];
|
|
957
|
-
if (specifier?.startsWith('.')) {
|
|
958
|
-
relativeSpecifiers.add(specifier);
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
return Array.from(relativeSpecifiers);
|
|
963
|
-
}
|
|
964
|
-
isGeneratedWorkflowArtifact(filePath) {
|
|
965
|
-
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
966
|
-
return (normalizedPath.includes('/.well-known/workflow/') ||
|
|
967
|
-
normalizedPath.includes('/.next/'));
|
|
968
|
-
}
|
|
969
1047
|
shouldSkipTransitiveStepFile(filePath) {
|
|
970
1048
|
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
normalizedPath.includes('/.
|
|
1049
|
+
const isSourceBackedPackagePath = this.shouldPreferSourceBackedPackagePath(filePath);
|
|
1050
|
+
return (normalizedPath.includes('/.well-known/workflow/') ||
|
|
1051
|
+
normalizedPath.includes('/.next/') ||
|
|
1052
|
+
(!isSourceBackedPackagePath &&
|
|
1053
|
+
(normalizedPath.includes('/node_modules/') ||
|
|
1054
|
+
normalizedPath.includes('/.pnpm/'))));
|
|
974
1055
|
}
|
|
975
1056
|
async resolveTransitiveStepImportTargetPath(sourceFilePath, specifier) {
|
|
976
1057
|
const specifierMatch = specifier.match(/^([^?#]+)(.*)$/);
|
|
977
1058
|
const importPath = specifierMatch?.[1] ?? specifier;
|
|
1059
|
+
if (!importPath.startsWith('.')) {
|
|
1060
|
+
if (importPath !== 'workflow' && !importPath.startsWith('@workflow/')) {
|
|
1061
|
+
return null;
|
|
1062
|
+
}
|
|
1063
|
+
try {
|
|
1064
|
+
const resolvedPath = (0, node_module_1.createRequire)(sourceFilePath).resolve(importPath);
|
|
1065
|
+
const normalizedResolvedPath = this.normalizeDiscoveredFilePath(resolvedPath);
|
|
1066
|
+
if (this.shouldSkipTransitiveStepFile(normalizedResolvedPath)) {
|
|
1067
|
+
return null;
|
|
1068
|
+
}
|
|
1069
|
+
const fileStats = await (0, promises_1.stat)(normalizedResolvedPath);
|
|
1070
|
+
return fileStats.isFile() ? normalizedResolvedPath : null;
|
|
1071
|
+
}
|
|
1072
|
+
catch {
|
|
1073
|
+
return null;
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
978
1076
|
const absoluteTargetPath = (0, node_path_1.resolve)((0, node_path_1.dirname)(sourceFilePath), importPath);
|
|
979
1077
|
const candidatePaths = new Set([
|
|
980
1078
|
this.resolveImportTargetWithExtensionFallbacks(absoluteTargetPath),
|
|
@@ -1013,13 +1111,11 @@ async function getNextBuilderDeferred() {
|
|
|
1013
1111
|
}
|
|
1014
1112
|
return null;
|
|
1015
1113
|
}
|
|
1016
|
-
async collectTransitiveStepFiles({
|
|
1017
|
-
const
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
const discoveredStepFiles = new Set();
|
|
1022
|
-
const queuedFiles = [...normalizedSeedFiles];
|
|
1114
|
+
async collectTransitiveStepFiles({ entryFiles, stepFiles, }) {
|
|
1115
|
+
const normalizedEntryFiles = Array.from(new Set(entryFiles.map((entryFile) => this.normalizeDiscoveredFilePath(entryFile)))).sort();
|
|
1116
|
+
const normalizedStepSeedFiles = Array.from(new Set(stepFiles.map((stepFile) => this.normalizeDiscoveredFilePath(stepFile)))).sort();
|
|
1117
|
+
const discoveredStepFiles = new Set(normalizedStepSeedFiles);
|
|
1118
|
+
const queuedFiles = Array.from(new Set([...normalizedEntryFiles, ...normalizedStepSeedFiles]));
|
|
1023
1119
|
const visitedFiles = new Set();
|
|
1024
1120
|
const sourceCache = new Map();
|
|
1025
1121
|
const patternCache = new Map();
|
|
@@ -1060,12 +1156,8 @@ async function getNextBuilderDeferred() {
|
|
|
1060
1156
|
if (currentSource === null) {
|
|
1061
1157
|
continue;
|
|
1062
1158
|
}
|
|
1063
|
-
const
|
|
1064
|
-
|
|
1065
|
-
discoveredStepFiles.add(currentFile);
|
|
1066
|
-
}
|
|
1067
|
-
const relativeImportSpecifiers = this.extractRelativeImportSpecifiers(currentSource);
|
|
1068
|
-
for (const specifier of relativeImportSpecifiers) {
|
|
1159
|
+
const importSpecifiers = this.extractImportSpecifiers(currentSource);
|
|
1160
|
+
for (const specifier of importSpecifiers) {
|
|
1069
1161
|
const resolvedImportPath = await this.resolveTransitiveStepImportTargetPath(currentFile, specifier);
|
|
1070
1162
|
if (!resolvedImportPath) {
|
|
1071
1163
|
continue;
|
|
@@ -1177,173 +1269,6 @@ async function getNextBuilderDeferred() {
|
|
|
1177
1269
|
}));
|
|
1178
1270
|
return verifiedSerdeFiles.sort();
|
|
1179
1271
|
}
|
|
1180
|
-
async createDeferredStepsManifest({ stepFiles, workflowFiles, serdeOnlyFiles, }) {
|
|
1181
|
-
const workflowManifest = {};
|
|
1182
|
-
const filesForStepTransform = Array.from(new Set([...stepFiles, ...serdeOnlyFiles])).sort();
|
|
1183
|
-
await Promise.all(filesForStepTransform.map(async (stepFile) => {
|
|
1184
|
-
const source = await (0, promises_1.readFile)(stepFile, 'utf-8');
|
|
1185
|
-
const relativeFilename = await this.getRelativeFilenameForSwc(stepFile);
|
|
1186
|
-
const { workflowManifest: fileManifest } = await applySwcTransform(relativeFilename, source, 'step', stepFile, this.config.projectRoot || this.config.workingDir);
|
|
1187
|
-
this.mergeWorkflowManifest(workflowManifest, fileManifest);
|
|
1188
|
-
}));
|
|
1189
|
-
const stepFileSet = new Set(stepFiles);
|
|
1190
|
-
const workflowOnlyFiles = workflowFiles
|
|
1191
|
-
.filter((workflowFile) => !stepFileSet.has(workflowFile))
|
|
1192
|
-
.sort();
|
|
1193
|
-
await Promise.all(workflowOnlyFiles.map(async (workflowFile) => {
|
|
1194
|
-
try {
|
|
1195
|
-
const source = await (0, promises_1.readFile)(workflowFile, 'utf-8');
|
|
1196
|
-
const relativeFilename = await this.getRelativeFilenameForSwc(workflowFile);
|
|
1197
|
-
const { workflowManifest: fileManifest } = await applySwcTransform(relativeFilename, source, 'workflow', workflowFile, this.config.projectRoot || this.config.workingDir);
|
|
1198
|
-
this.mergeWorkflowManifest(workflowManifest, {
|
|
1199
|
-
workflows: fileManifest.workflows,
|
|
1200
|
-
classes: fileManifest.classes,
|
|
1201
|
-
});
|
|
1202
|
-
}
|
|
1203
|
-
catch (error) {
|
|
1204
|
-
console.log(`Warning: Failed to extract workflow metadata from ${workflowFile}:`, error instanceof Error ? error.message : String(error));
|
|
1205
|
-
}
|
|
1206
|
-
}));
|
|
1207
|
-
return workflowManifest;
|
|
1208
|
-
}
|
|
1209
|
-
async collectManifestStepSourceFiles(manifest) {
|
|
1210
|
-
const manifestStepEntries = Object.keys(manifest.steps || {});
|
|
1211
|
-
if (manifestStepEntries.length === 0) {
|
|
1212
|
-
return [];
|
|
1213
|
-
}
|
|
1214
|
-
const resolveBaseDirs = this.getManifestStepResolveBaseDirs();
|
|
1215
|
-
const candidateFiles = manifestStepEntries
|
|
1216
|
-
.flatMap((stepEntry) => {
|
|
1217
|
-
if ((0, node_path_1.isAbsolute)(stepEntry)) {
|
|
1218
|
-
return [this.normalizeDiscoveredFilePath(stepEntry)];
|
|
1219
|
-
}
|
|
1220
|
-
return resolveBaseDirs.map((baseDir) => this.normalizeDiscoveredFilePath((0, node_path_1.resolve)(baseDir, stepEntry)));
|
|
1221
|
-
})
|
|
1222
|
-
.filter((candidateFile) => !this.isGeneratedWorkflowArtifact(candidateFile));
|
|
1223
|
-
const existingCandidates = await this.filterExistingFiles(candidateFiles);
|
|
1224
|
-
return Array.from(new Set(existingCandidates)).sort();
|
|
1225
|
-
}
|
|
1226
|
-
/**
|
|
1227
|
-
* Resolves the path to the workflow SDK's internal response builtins
|
|
1228
|
-
* step file. Returns the file as a pair of (absolute path, import
|
|
1229
|
-
* specifier) so the caller can include it in both the manifest
|
|
1230
|
-
* (absolute path) and the generated step/route.js (as an import).
|
|
1231
|
-
*/
|
|
1232
|
-
resolveResponseBuiltinsStepSource() {
|
|
1233
|
-
let resolved;
|
|
1234
|
-
try {
|
|
1235
|
-
resolved = require.resolve('workflow/internal/builtins', {
|
|
1236
|
-
paths: [this.config.workingDir],
|
|
1237
|
-
});
|
|
1238
|
-
}
|
|
1239
|
-
catch {
|
|
1240
|
-
return null;
|
|
1241
|
-
}
|
|
1242
|
-
return {
|
|
1243
|
-
absolutePath: this.normalizeDiscoveredFilePath(resolved),
|
|
1244
|
-
importPath: 'workflow/internal/builtins',
|
|
1245
|
-
};
|
|
1246
|
-
}
|
|
1247
|
-
/**
|
|
1248
|
-
* Builds the import specifier for a given step/serde source file as it
|
|
1249
|
-
* should appear in the generated step/route.js. Package-provided files
|
|
1250
|
-
* are imported via their package specifier so the bundler resolves them
|
|
1251
|
-
* from the app's dependency graph. Local files are imported via a
|
|
1252
|
-
* relative path from the generated route.
|
|
1253
|
-
*/
|
|
1254
|
-
getStepRouteImportSpecifier(stepRouteFile, sourceFilePath) {
|
|
1255
|
-
const { importPath, isPackage } = getImportPath(sourceFilePath, this.config.workingDir);
|
|
1256
|
-
if (isPackage) {
|
|
1257
|
-
return importPath;
|
|
1258
|
-
}
|
|
1259
|
-
return this.getRelativeImportSpecifier(stepRouteFile, sourceFilePath);
|
|
1260
|
-
}
|
|
1261
|
-
async buildStepsFunction({ workflowGeneratedDir, routeFileName = 'route.js', discoveredEntries, additionalStepSourceManifest, }) {
|
|
1262
|
-
const stepsRouteDir = (0, node_path_1.join)(workflowGeneratedDir, 'step');
|
|
1263
|
-
await (0, promises_1.mkdir)(stepsRouteDir, { recursive: true });
|
|
1264
|
-
const discovered = discoveredEntries;
|
|
1265
|
-
const workflowFiles = [...discovered.discoveredWorkflows].sort();
|
|
1266
|
-
const stepFiles = await this.collectTransitiveStepFiles({
|
|
1267
|
-
stepFiles: [...discovered.discoveredSteps].sort(),
|
|
1268
|
-
// Workflow transforms can inline step IDs and remove runtime imports,
|
|
1269
|
-
// so seed transitive traversal with workflow files too.
|
|
1270
|
-
seedFiles: workflowFiles,
|
|
1271
|
-
});
|
|
1272
|
-
const serdeFiles = [...discovered.discoveredSerdeFiles].sort();
|
|
1273
|
-
const stepFileSet = new Set(stepFiles);
|
|
1274
|
-
const serdeOnlyFiles = serdeFiles.filter((file) => !stepFileSet.has(file));
|
|
1275
|
-
const additionalManifestStepFiles = additionalStepSourceManifest
|
|
1276
|
-
? await this.collectManifestStepSourceFiles(additionalStepSourceManifest)
|
|
1277
|
-
: [];
|
|
1278
|
-
const stepFilesWithManifestSources = Array.from(new Set([...stepFiles, ...additionalManifestStepFiles])).sort();
|
|
1279
|
-
const responseBuiltins = this.resolveResponseBuiltinsStepSource();
|
|
1280
|
-
const manifestStepFiles = Array.from(new Set([
|
|
1281
|
-
...stepFilesWithManifestSources,
|
|
1282
|
-
...(responseBuiltins ? [responseBuiltins.absolutePath] : []),
|
|
1283
|
-
])).sort();
|
|
1284
|
-
const manifest = await this.createDeferredStepsManifest({
|
|
1285
|
-
stepFiles: manifestStepFiles,
|
|
1286
|
-
workflowFiles,
|
|
1287
|
-
serdeOnlyFiles,
|
|
1288
|
-
});
|
|
1289
|
-
const manifestDiscoveredStepFiles = await this.collectManifestStepSourceFiles(manifest);
|
|
1290
|
-
// Step source files are imported directly from their original
|
|
1291
|
-
// locations. The workflow loader transforms every file it sees in
|
|
1292
|
-
// step mode, so package-provided sources register their step
|
|
1293
|
-
// functions as module side effects just like local sources do.
|
|
1294
|
-
const stepSourceFiles = Array.from(new Set([
|
|
1295
|
-
...stepFilesWithManifestSources,
|
|
1296
|
-
...manifestDiscoveredStepFiles,
|
|
1297
|
-
])).sort();
|
|
1298
|
-
const stepRouteFile = (0, node_path_1.join)(stepsRouteDir, routeFileName);
|
|
1299
|
-
const stepImportSpecifiers = new Set();
|
|
1300
|
-
if (responseBuiltins) {
|
|
1301
|
-
stepImportSpecifiers.add(responseBuiltins.importPath);
|
|
1302
|
-
}
|
|
1303
|
-
for (const stepSourceFile of stepSourceFiles) {
|
|
1304
|
-
stepImportSpecifiers.add(this.getStepRouteImportSpecifier(stepRouteFile, stepSourceFile));
|
|
1305
|
-
}
|
|
1306
|
-
const stepImports = Array.from(stepImportSpecifiers)
|
|
1307
|
-
.map((specifier) => `import '${specifier}';`)
|
|
1308
|
-
.join('\n');
|
|
1309
|
-
const serdeImports = serdeOnlyFiles
|
|
1310
|
-
.map((serdeFile) => {
|
|
1311
|
-
const normalizedSerdeFile = this.normalizeDiscoveredFilePath(serdeFile);
|
|
1312
|
-
return `import '${this.getStepRouteImportSpecifier(stepRouteFile, normalizedSerdeFile)}';`;
|
|
1313
|
-
})
|
|
1314
|
-
.join('\n');
|
|
1315
|
-
const routeContents = [
|
|
1316
|
-
'// biome-ignore-all lint: generated file',
|
|
1317
|
-
'/* eslint-disable */',
|
|
1318
|
-
stepImports,
|
|
1319
|
-
serdeImports
|
|
1320
|
-
? `// Serde files for cross-context class registration\n${serdeImports}`
|
|
1321
|
-
: '',
|
|
1322
|
-
"export { stepEntrypoint as POST } from 'workflow/runtime';",
|
|
1323
|
-
]
|
|
1324
|
-
.filter(Boolean)
|
|
1325
|
-
.join('\n');
|
|
1326
|
-
await this.writeFileIfChanged(stepRouteFile, routeContents);
|
|
1327
|
-
return {
|
|
1328
|
-
context: undefined,
|
|
1329
|
-
manifest,
|
|
1330
|
-
};
|
|
1331
|
-
}
|
|
1332
|
-
async buildWorkflowsFunction({ inputFiles, workflowGeneratedDir, tsconfigPath, routeFileName = 'route.js', discoveredEntries, }) {
|
|
1333
|
-
const workflowsRouteDir = (0, node_path_1.join)(workflowGeneratedDir, 'flow');
|
|
1334
|
-
await (0, promises_1.mkdir)(workflowsRouteDir, { recursive: true });
|
|
1335
|
-
return await this.createWorkflowsBundle({
|
|
1336
|
-
format: 'esm',
|
|
1337
|
-
outfile: (0, node_path_1.join)(workflowsRouteDir, routeFileName),
|
|
1338
|
-
bundleFinalOutput: false,
|
|
1339
|
-
// Deferred builds do not reuse the interim esbuild context. Dispose it
|
|
1340
|
-
// after each pass to avoid leaking contexts during watch-mode rebuilds.
|
|
1341
|
-
keepInterimBundleContext: false,
|
|
1342
|
-
inputFiles,
|
|
1343
|
-
tsconfigPath,
|
|
1344
|
-
discoveredEntries,
|
|
1345
|
-
});
|
|
1346
|
-
}
|
|
1347
1272
|
async buildWebhookRoute({ workflowGeneratedDir, routeFileName = 'route.js', }) {
|
|
1348
1273
|
const webhookRouteFile = (0, node_path_1.join)(workflowGeneratedDir, `webhook/[token]/${routeFileName}`);
|
|
1349
1274
|
await this.createWebhookBundle({
|