@fjall/deploy-core 0.89.5 → 0.89.6
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/LICENSE +50 -21
- package/README.md +25 -0
- package/dist/.minified +1 -0
- package/dist/src/__test-utils__/awsMockHelpers.d.ts +20 -0
- package/dist/src/__test-utils__/awsMockHelpers.js +1 -0
- package/dist/src/__test-utils__/index.d.ts +1 -0
- package/dist/src/__test-utils__/index.js +1 -0
- package/dist/src/aws/AwsProvider.js +0 -1
- package/dist/src/aws/SimpleAwsProvider.js +1 -70
- package/dist/src/aws/index.d.ts +4 -2
- package/dist/src/aws/index.js +1 -3
- package/dist/src/aws/organisations/accounts.js +10 -10
- package/dist/src/aws/organisations/backup.js +4 -2
- package/dist/src/aws/organisations/costAllocation.js +4 -2
- package/dist/src/aws/organisations/delegatedAdmin.d.ts +9 -0
- package/dist/src/aws/organisations/delegatedAdmin.js +43 -0
- package/dist/src/aws/organisations/identityCentre.d.ts +1 -1
- package/dist/src/aws/organisations/identityCentre.js +6 -2
- package/dist/src/aws/organisations/index.d.ts +4 -3
- package/dist/src/aws/organisations/index.js +1 -12
- package/dist/src/aws/organisations/ipam.js +4 -2
- package/dist/src/aws/organisations/organisation.js +27 -18
- package/dist/src/aws/organisations/organisationalUnits.d.ts +26 -6
- package/dist/src/aws/organisations/organisationalUnits.js +149 -35
- package/dist/src/aws/organisations/policies.js +4 -3
- package/dist/src/aws/organisations/ram.js +6 -2
- package/dist/src/aws/organisations/serviceAccess.js +12 -6
- package/dist/src/aws/organisations/trustedAccess.js +6 -2
- package/dist/src/aws/organisations/types.d.ts +23 -1
- package/dist/src/aws/organisations/types.js +1 -16
- package/dist/src/aws/utils/__tests__/cloudformationTestHelpers.d.ts +6 -0
- package/dist/src/aws/utils/__tests__/cloudformationTestHelpers.js +1 -0
- package/dist/src/aws/utils/cloudformationEventHelpers.d.ts +48 -0
- package/dist/src/aws/utils/cloudformationEventHelpers.js +1 -0
- package/dist/src/aws/utils/cloudformationEventTypes.d.ts +45 -0
- package/dist/src/aws/utils/cloudformationEventTypes.js +1 -0
- package/dist/src/aws/utils/cloudformationEvents.d.ts +8 -54
- package/dist/src/aws/utils/cloudformationEvents.js +1 -596
- package/dist/src/aws/utils/index.d.ts +5 -0
- package/dist/src/aws/utils/index.js +1 -0
- package/dist/src/aws/utils/stackStatus.js +1 -90
- package/dist/src/events/index.d.ts +13 -0
- package/dist/src/events/index.js +1 -0
- package/dist/src/index.d.ts +34 -17
- package/dist/src/index.js +41 -21
- package/dist/src/orchestration/__tests__/cascadeTestHelpers.d.ts +12 -0
- package/dist/src/orchestration/__tests__/cascadeTestHelpers.js +78 -0
- package/dist/src/orchestration/activeDeploymentGuard.d.ts +10 -0
- package/dist/src/orchestration/activeDeploymentGuard.js +39 -0
- package/dist/src/orchestration/applicationDeploy.js +46 -229
- package/dist/src/orchestration/applicationDeployHelpers.d.ts +39 -0
- package/dist/src/orchestration/applicationDeployHelpers.js +223 -0
- package/dist/src/orchestration/applicationDestroy.d.ts +14 -0
- package/dist/src/orchestration/applicationDestroy.js +131 -0
- package/dist/src/orchestration/builders/dockerBuilder.d.ts +17 -0
- package/dist/src/orchestration/builders/dockerBuilder.js +98 -0
- package/dist/src/orchestration/builders/frameworkRegistry.d.ts +23 -0
- package/dist/src/orchestration/builders/frameworkRegistry.js +1 -0
- package/dist/src/orchestration/builders/index.d.ts +4 -0
- package/dist/src/orchestration/builders/index.js +1 -0
- package/dist/src/orchestration/builders/openNextBuilder.d.ts +21 -0
- package/dist/src/orchestration/builders/openNextBuilder.js +144 -0
- package/dist/src/orchestration/cascadeDestroyHelpers.d.ts +30 -0
- package/dist/src/orchestration/cascadeDestroyHelpers.js +1 -0
- package/dist/src/orchestration/cascadeHelpers.d.ts +46 -0
- package/dist/src/orchestration/cascadeHelpers.js +160 -0
- package/dist/src/orchestration/contextHelpers.d.ts +46 -2
- package/dist/src/orchestration/contextHelpers.js +93 -1
- package/dist/src/orchestration/destroy.d.ts +13 -0
- package/dist/src/orchestration/destroy.js +67 -0
- package/dist/src/orchestration/detectionPipeline.d.ts +2 -11
- package/dist/src/orchestration/detectionPipeline.js +29 -10
- package/dist/src/orchestration/dockerBuildHelper.d.ts +10 -0
- package/dist/src/orchestration/dockerBuildHelper.js +49 -0
- package/dist/src/orchestration/dockerInterface.d.ts +4 -2
- package/dist/src/orchestration/index.d.ts +8 -1
- package/dist/src/orchestration/index.js +1 -3
- package/dist/src/orchestration/manifestSecretParser.d.ts +11 -0
- package/dist/src/orchestration/manifestSecretParser.js +1 -0
- package/dist/src/orchestration/openNextBuild.d.ts +28 -0
- package/dist/src/orchestration/openNextBuild.js +243 -0
- package/dist/src/orchestration/organisationDeploy.js +110 -233
- package/dist/src/orchestration/organisationDestroy.d.ts +24 -0
- package/dist/src/orchestration/organisationDestroy.js +189 -0
- package/dist/src/orchestration/organisationSetup.d.ts +6 -4
- package/dist/src/orchestration/organisationSetup.js +28 -8
- package/dist/src/orchestration/resolveOperation.js +68 -6
- package/dist/src/orchestration/serviceFactory.d.ts +4 -0
- package/dist/src/orchestration/serviceFactory.js +1 -16
- package/dist/src/orchestration/spawnHelpers.d.ts +47 -0
- package/dist/src/orchestration/spawnHelpers.js +1 -0
- package/dist/src/orchestration/stackCleanup.d.ts +39 -0
- package/dist/src/orchestration/stackCleanup.js +1 -0
- package/dist/src/orchestration/welcomeImageHelper.d.ts +15 -0
- package/dist/src/orchestration/welcomeImageHelper.js +64 -0
- package/dist/src/services/application/ApplicationStackService.d.ts +21 -30
- package/dist/src/services/application/ApplicationStackService.js +16 -234
- package/dist/src/services/application/applicationStackHelpers.d.ts +46 -0
- package/dist/src/services/application/applicationStackHelpers.js +248 -0
- package/dist/src/services/application/index.d.ts +1 -0
- package/dist/src/services/application/index.js +1 -1
- package/dist/src/services/index.d.ts +6 -0
- package/dist/src/services/index.js +1 -0
- package/dist/src/services/infrastructure/CdkArgumentBuilder.js +1 -67
- package/dist/src/services/infrastructure/CdkCommandRunner.d.ts +10 -2
- package/dist/src/services/infrastructure/CdkCommandRunner.js +18 -15
- package/dist/src/services/infrastructure/CdkErrorFormatter.js +16 -194
- package/dist/src/services/infrastructure/CdkEventMonitoring.js +1 -41
- package/dist/src/services/infrastructure/CdkOutputAnalyser.js +1 -1
- package/dist/src/services/infrastructure/CdkOutputParser.js +2 -33
- package/dist/src/services/infrastructure/CdkProcessManager.d.ts +5 -0
- package/dist/src/services/infrastructure/CdkProcessManager.js +81 -47
- package/dist/src/services/infrastructure/CdkService.d.ts +7 -53
- package/dist/src/services/infrastructure/CdkService.js +41 -83
- package/dist/src/services/infrastructure/CdkServiceTypes.d.ts +50 -0
- package/dist/src/services/infrastructure/CdkServiceTypes.js +0 -0
- package/dist/src/services/infrastructure/CloudFormationService.js +9 -10
- package/dist/src/services/infrastructure/ICdkProcessManager.d.ts +27 -0
- package/dist/src/services/infrastructure/ICdkProcessManager.js +1 -0
- package/dist/src/services/infrastructure/__tests__/cloudFormationTestHelpers.d.ts +9 -0
- package/dist/src/services/infrastructure/__tests__/cloudFormationTestHelpers.js +1 -0
- package/dist/src/services/infrastructure/cdkServiceHelpers.d.ts +9 -0
- package/dist/src/services/infrastructure/cdkServiceHelpers.js +1 -0
- package/dist/src/services/infrastructure/constructMapEnrichment.d.ts +7 -0
- package/dist/src/services/infrastructure/constructMapEnrichment.js +1 -0
- package/dist/src/services/infrastructure/index.d.ts +3 -1
- package/dist/src/services/infrastructure/index.js +1 -7
- package/dist/src/services/supporting/TemplateHashService.js +1 -1
- package/dist/src/services/supporting/helpers.js +1 -81
- package/dist/src/services/supporting/index.js +1 -3
- package/dist/src/steps/index.d.ts +1 -0
- package/dist/src/steps/index.js +1 -0
- package/dist/src/steps/stepRegistry.d.ts +71 -0
- package/dist/src/steps/stepRegistry.js +505 -0
- package/dist/src/types/FjallState.js +1 -118
- package/dist/src/types/ProgressEvent.js +1 -48
- package/dist/src/types/application/ApplicationServiceTypes.js +1 -30
- package/dist/src/types/application/index.js +1 -1
- package/dist/src/types/callbacks.d.ts +76 -4
- package/dist/src/types/callbacks.js +0 -1
- package/dist/src/types/constants.d.ts +2 -0
- package/dist/src/types/constants.js +1 -6
- package/dist/src/types/credentials.js +0 -1
- package/dist/src/types/deployment/DeploymentServiceTypes.d.ts +5 -2
- package/dist/src/types/deployment/DeploymentServiceTypes.js +1 -1
- package/dist/src/types/deployment/DeploymentTypes.js +0 -1
- package/dist/src/types/deployment/cloudformation.js +0 -1
- package/dist/src/types/deployment/index.d.ts +3 -1
- package/dist/src/types/deployment/index.js +1 -1
- package/dist/src/types/deployment/parallel.js +1 -10
- package/dist/src/types/deploymentEventSchema.d.ts +158 -0
- package/dist/src/types/deploymentEventSchema.js +1 -0
- package/dist/src/types/detection.d.ts +22 -0
- package/dist/src/types/detection.js +1 -0
- package/dist/src/types/entitlements.d.ts +31 -0
- package/dist/src/types/entitlements.js +0 -0
- package/dist/src/types/errors/CdkError.js +1 -20
- package/dist/src/types/errors/ServiceError.d.ts +2 -1
- package/dist/src/types/errors/ServiceError.js +1 -119
- package/dist/src/types/errors/index.d.ts +2 -0
- package/dist/src/types/errors/index.js +1 -0
- package/dist/src/types/events.d.ts +3 -9
- package/dist/src/types/events.js +0 -5
- package/dist/src/types/frameworkBuilder.d.ts +96 -0
- package/dist/src/types/frameworkBuilder.js +8 -0
- package/dist/src/types/index.d.ts +19 -4
- package/dist/src/types/index.js +1 -9
- package/dist/src/types/operations.d.ts +3 -2
- package/dist/src/types/operations.js +1 -285
- package/dist/src/types/orgConfig.d.ts +2 -10
- package/dist/src/types/orgConfig.js +0 -11
- package/dist/src/types/params.d.ts +60 -1
- package/dist/src/types/patternDetection.d.ts +14 -16
- package/dist/src/types/patternDetection.js +14 -18
- package/dist/src/types/patternTypes.d.ts +19 -0
- package/dist/src/types/patternTypes.js +1 -0
- package/dist/src/types/stepDefinitions.d.ts +163 -0
- package/dist/src/types/stepDefinitions.js +98 -0
- package/dist/src/types/validation.js +0 -1
- package/dist/src/util/dockerfileDetection.d.ts +5 -0
- package/dist/src/util/dockerfileDetection.js +1 -0
- package/dist/src/util/index.d.ts +4 -3
- package/dist/src/util/index.js +1 -3
- package/dist/src/util/sequencedCallbacks.d.ts +44 -0
- package/dist/src/util/sequencedCallbacks.js +1 -0
- package/package.json +49 -8
- package/dist/src/aws/utils/CloudFormationFailureAnalyser.d.ts +0 -32
- package/dist/src/aws/utils/CloudFormationFailureAnalyser.js +0 -228
- package/dist/src/aws/utils/errors.d.ts +0 -26
- package/dist/src/aws/utils/errors.js +0 -59
- package/dist/src/util/fsHelpers.d.ts +0 -4
- package/dist/src/util/fsHelpers.js +0 -16
- package/dist/src/util/securityHelpers.d.ts +0 -31
- package/dist/src/util/securityHelpers.js +0 -124
- package/dist/src/util/singleton.d.ts +0 -2
- package/dist/src/util/singleton.js +0 -9
- package/dist/src/util/sleep.d.ts +0 -4
- package/dist/src/util/sleep.js +0 -4
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenNext build orchestration for Next.js and Payload applications.
|
|
3
|
+
*
|
|
4
|
+
* Resolves `@opennextjs/aws` from the app's own node_modules (not from
|
|
5
|
+
* deploy-core's dependencies) and runs the build with timeout handling,
|
|
6
|
+
* stream cleanup, and credential masking.
|
|
7
|
+
*
|
|
8
|
+
* For Payload apps, generates the import map before building.
|
|
9
|
+
*/
|
|
10
|
+
import { type Result } from "@fjall/generator";
|
|
11
|
+
import type { DeployCallbacks } from "../types/callbacks.js";
|
|
12
|
+
import type { DeployOptions } from "../types/params.js";
|
|
13
|
+
import type { ApplicationOperation } from "../types/operations.js";
|
|
14
|
+
/** Default build timeout: 10 minutes */
|
|
15
|
+
export declare const BUILD_TIMEOUT_MS = 600000;
|
|
16
|
+
/** Timeout for Payload import map generation: 30 seconds */
|
|
17
|
+
export declare const IMPORT_MAP_TIMEOUT_MS = 30000;
|
|
18
|
+
/**
|
|
19
|
+
* Run the OpenNext build for a Next.js or Payload application.
|
|
20
|
+
*
|
|
21
|
+
* Checks pattern and options internally — returns `success(undefined)`
|
|
22
|
+
* when build is not needed (wrong pattern, skipBuild, infraOnly).
|
|
23
|
+
*
|
|
24
|
+
* Must be called BEFORE the detection pipeline and BEFORE the
|
|
25
|
+
* `deployOnly` early-return check, so built artefacts are available
|
|
26
|
+
* for CDK synth.
|
|
27
|
+
*/
|
|
28
|
+
export declare function runOpenNextBuild(operation: ApplicationOperation, pattern: string | null | undefined, callbacks: DeployCallbacks, options?: DeployOptions): Promise<Result<void>>;
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenNext build orchestration for Next.js and Payload applications.
|
|
3
|
+
*
|
|
4
|
+
* Resolves `@opennextjs/aws` from the app's own node_modules (not from
|
|
5
|
+
* deploy-core's dependencies) and runs the build with timeout handling,
|
|
6
|
+
* stream cleanup, and credential masking.
|
|
7
|
+
*
|
|
8
|
+
* For Payload apps, generates the import map before building.
|
|
9
|
+
*/
|
|
10
|
+
import { createRequire } from "module";
|
|
11
|
+
import { existsSync, statSync, rmSync } from "fs";
|
|
12
|
+
import { join } from "path";
|
|
13
|
+
import { success, failure } from "@fjall/generator";
|
|
14
|
+
import { filterDangerousEnvVars, maskSensitiveOutput, parseShellArgs } from "@fjall/util";
|
|
15
|
+
import { logger } from "@fjall/util/logger";
|
|
16
|
+
import { isOpenNextPattern } from "../types/patternDetection.js";
|
|
17
|
+
import { spawnWithTimeout } from "./spawnHelpers.js";
|
|
18
|
+
const OPENNEXT_PACKAGE = "@opennextjs/aws";
|
|
19
|
+
/** Default build timeout: 10 minutes */
|
|
20
|
+
export const BUILD_TIMEOUT_MS = 600_000;
|
|
21
|
+
/** Timeout for Payload import map generation: 30 seconds */
|
|
22
|
+
export const IMPORT_MAP_TIMEOUT_MS = 30_000;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the `open-next` binary from the app's own node_modules.
|
|
25
|
+
*
|
|
26
|
+
* Uses `createRequire` anchored to the app path so that the binary
|
|
27
|
+
* comes from the project's dependencies, not deploy-core's.
|
|
28
|
+
*/
|
|
29
|
+
function resolveOpenNextBinary(appPath) {
|
|
30
|
+
const require = createRequire(join(appPath, "package.json"));
|
|
31
|
+
let searchPaths;
|
|
32
|
+
try {
|
|
33
|
+
searchPaths = require.resolve.paths(OPENNEXT_PACKAGE);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
return failure(new Error(`Cannot determine module search paths for ${OPENNEXT_PACKAGE}. ` +
|
|
37
|
+
`Ensure it is installed in your project. (${err instanceof Error ? err.message : String(err)})`));
|
|
38
|
+
}
|
|
39
|
+
if (!searchPaths || searchPaths.length === 0) {
|
|
40
|
+
return failure(new Error(`Cannot determine module search paths for ${OPENNEXT_PACKAGE}. ` +
|
|
41
|
+
"Ensure it is installed in your project."));
|
|
42
|
+
}
|
|
43
|
+
for (const nodeModulesPath of searchPaths) {
|
|
44
|
+
const packageDir = join(nodeModulesPath, "@opennextjs", "aws");
|
|
45
|
+
try {
|
|
46
|
+
const stat = statSync(packageDir);
|
|
47
|
+
if (stat.isDirectory()) {
|
|
48
|
+
const binPath = join(nodeModulesPath, ".bin", "open-next");
|
|
49
|
+
if (!existsSync(binPath)) {
|
|
50
|
+
logger.debug("openNextBuild", "Package found but binary missing", {
|
|
51
|
+
nodeModulesPath,
|
|
52
|
+
binPath
|
|
53
|
+
});
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
logger.debug("openNextBuild", "Resolved OpenNext binary", {
|
|
57
|
+
binPath
|
|
58
|
+
});
|
|
59
|
+
return success(binPath);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
logger.debug("openNextBuild", "Package not at location", {
|
|
64
|
+
nodeModulesPath,
|
|
65
|
+
error: String(err)
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return failure(new Error(`Cannot find ${OPENNEXT_PACKAGE} package. ` +
|
|
70
|
+
`Ensure it is installed in your project: npm install ${OPENNEXT_PACKAGE}`));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Clean up the `.open-next/` directory on build failure to prevent
|
|
74
|
+
* stale artefacts from being used by a subsequent CDK synth.
|
|
75
|
+
*/
|
|
76
|
+
function cleanupOpenNextOutput(appPath) {
|
|
77
|
+
const openNextDir = join(appPath, ".open-next");
|
|
78
|
+
if (existsSync(openNextDir)) {
|
|
79
|
+
try {
|
|
80
|
+
rmSync(openNextDir, { recursive: true, force: true });
|
|
81
|
+
logger.debug("openNextBuild", "Cleaned up stale .open-next directory", {
|
|
82
|
+
path: openNextDir
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
logger.debug("openNextBuild", "Failed to clean up .open-next", {
|
|
87
|
+
error: String(err)
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Handle the common error cases (timeout, enoent, spawn_error) from spawnWithTimeout.
|
|
94
|
+
* Returns a failure Result for error cases, or undefined if the result is "success".
|
|
95
|
+
*/
|
|
96
|
+
function handleSpawnError(result, labels, onCleanup, onError) {
|
|
97
|
+
switch (result.type) {
|
|
98
|
+
case "timeout": {
|
|
99
|
+
onCleanup?.();
|
|
100
|
+
onError?.(labels.timeoutMsg);
|
|
101
|
+
return failure(new Error(labels.timeoutMsg));
|
|
102
|
+
}
|
|
103
|
+
case "enoent": {
|
|
104
|
+
onCleanup?.();
|
|
105
|
+
onError?.(labels.enoentMsg);
|
|
106
|
+
return failure(new Error(labels.enoentMsg));
|
|
107
|
+
}
|
|
108
|
+
case "spawn_error": {
|
|
109
|
+
const msg = `${labels.spawnErrorPrefix}: ${result.error.message}`;
|
|
110
|
+
onCleanup?.();
|
|
111
|
+
onError?.(msg);
|
|
112
|
+
return failure(new Error(msg));
|
|
113
|
+
}
|
|
114
|
+
default:
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Generate the Payload CMS import map before running the OpenNext build.
|
|
120
|
+
*/
|
|
121
|
+
async function generatePayloadImportMap(appPath, callbacks) {
|
|
122
|
+
callbacks.onOpenNextProgress?.(maskSensitiveOutput("Generating Payload import map..."));
|
|
123
|
+
const [cmd, ...args] = parseShellArgs("npx payload generate:importmap");
|
|
124
|
+
const safeEnv = filterDangerousEnvVars(globalThis.process.env);
|
|
125
|
+
const result = await spawnWithTimeout({
|
|
126
|
+
command: cmd,
|
|
127
|
+
args,
|
|
128
|
+
cwd: appPath,
|
|
129
|
+
env: { ...safeEnv, FORCE_COLOR: "0" },
|
|
130
|
+
timeout: IMPORT_MAP_TIMEOUT_MS,
|
|
131
|
+
onStdoutData: (output) => {
|
|
132
|
+
callbacks.onOpenNextProgress?.(maskSensitiveOutput(output.trim()));
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
const spawnError = handleSpawnError(result, {
|
|
136
|
+
timeoutMsg: `Payload import map generation timed out after ${IMPORT_MAP_TIMEOUT_MS / 1000} seconds`,
|
|
137
|
+
enoentMsg: "Payload CLI not found. Ensure payload is installed: npm install payload",
|
|
138
|
+
spawnErrorPrefix: "Failed to generate Payload import map"
|
|
139
|
+
});
|
|
140
|
+
if (spawnError)
|
|
141
|
+
return spawnError;
|
|
142
|
+
if (result.type !== "success")
|
|
143
|
+
return failure(new Error("Unexpected spawn result"));
|
|
144
|
+
if (result.code !== 0) {
|
|
145
|
+
const maskedOutput = maskSensitiveOutput(result.stderr || result.stdout);
|
|
146
|
+
return failure(new Error(`Payload import map generation failed (exit code ${result.code}):\n${maskedOutput}`));
|
|
147
|
+
}
|
|
148
|
+
logger.debug("openNextBuild", "Payload import map generated", { appPath });
|
|
149
|
+
callbacks.onOpenNextProgress?.(maskSensitiveOutput("Payload import map generated"));
|
|
150
|
+
return success(undefined);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Run the OpenNext build for a Next.js or Payload application.
|
|
154
|
+
*
|
|
155
|
+
* Checks pattern and options internally — returns `success(undefined)`
|
|
156
|
+
* when build is not needed (wrong pattern, skipBuild, infraOnly).
|
|
157
|
+
*
|
|
158
|
+
* Must be called BEFORE the detection pipeline and BEFORE the
|
|
159
|
+
* `deployOnly` early-return check, so built artefacts are available
|
|
160
|
+
* for CDK synth.
|
|
161
|
+
*/
|
|
162
|
+
export async function runOpenNextBuild(operation, pattern, callbacks, options) {
|
|
163
|
+
// Guard: skip if not an OpenNext pattern
|
|
164
|
+
if (!isOpenNextPattern(pattern)) {
|
|
165
|
+
return success(undefined);
|
|
166
|
+
}
|
|
167
|
+
// Guard: skip if build explicitly disabled
|
|
168
|
+
if (options?.skipBuild || options?.infraOnly) {
|
|
169
|
+
logger.debug("openNextBuild", "Build skipped", {
|
|
170
|
+
skipBuild: options?.skipBuild,
|
|
171
|
+
infraOnly: options?.infraOnly
|
|
172
|
+
});
|
|
173
|
+
callbacks.onLog?.(options?.infraOnly
|
|
174
|
+
? "Infrastructure-only mode — skipping OpenNext build"
|
|
175
|
+
: "Build skipped (--skip-build)", "info");
|
|
176
|
+
return success(undefined);
|
|
177
|
+
}
|
|
178
|
+
const appPath = operation.path;
|
|
179
|
+
// For Payload apps, generate import map first
|
|
180
|
+
if (pattern === "payload") {
|
|
181
|
+
const importMapResult = await generatePayloadImportMap(appPath, callbacks);
|
|
182
|
+
if (!importMapResult.success) {
|
|
183
|
+
callbacks.onOpenNextBuildError?.(importMapResult.error.message);
|
|
184
|
+
cleanupOpenNextOutput(appPath);
|
|
185
|
+
return failure(importMapResult.error);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Resolve OpenNext binary from the app's node_modules
|
|
189
|
+
const binaryResult = resolveOpenNextBinary(appPath);
|
|
190
|
+
if (!binaryResult.success) {
|
|
191
|
+
callbacks.onOpenNextBuildError?.(binaryResult.error.message);
|
|
192
|
+
return failure(binaryResult.error);
|
|
193
|
+
}
|
|
194
|
+
const openNextBinary = binaryResult.data;
|
|
195
|
+
// Start build
|
|
196
|
+
callbacks.onOpenNextBuildStart?.();
|
|
197
|
+
callbacks.onOpenNextProgress?.(maskSensitiveOutput("Starting OpenNext build..."));
|
|
198
|
+
const safeEnv = filterDangerousEnvVars(globalThis.process.env);
|
|
199
|
+
const projectNodeModules = join(appPath, "node_modules");
|
|
200
|
+
const result = await spawnWithTimeout({
|
|
201
|
+
command: openNextBinary,
|
|
202
|
+
args: ["build"],
|
|
203
|
+
cwd: appPath,
|
|
204
|
+
env: {
|
|
205
|
+
...safeEnv,
|
|
206
|
+
FORCE_COLOR: "0",
|
|
207
|
+
NODE_PATH: projectNodeModules,
|
|
208
|
+
npm_config_loglevel: "error",
|
|
209
|
+
PNPM_HOME: safeEnv.PNPM_HOME || ""
|
|
210
|
+
},
|
|
211
|
+
timeout: BUILD_TIMEOUT_MS,
|
|
212
|
+
onStdoutData: (output) => {
|
|
213
|
+
callbacks.onOpenNextProgress?.(maskSensitiveOutput(output.trim()));
|
|
214
|
+
},
|
|
215
|
+
onStderrData: (output) => {
|
|
216
|
+
callbacks.onOpenNextProgress?.(maskSensitiveOutput(output.trim()));
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
const spawnError = handleSpawnError(result, {
|
|
220
|
+
timeoutMsg: `OpenNext build timed out after ${BUILD_TIMEOUT_MS / 1000} seconds`,
|
|
221
|
+
enoentMsg: "OpenNext binary not found. Ensure Node.js is installed and in PATH.",
|
|
222
|
+
spawnErrorPrefix: "Failed to spawn OpenNext build"
|
|
223
|
+
}, () => cleanupOpenNextOutput(appPath), (msg) => callbacks.onOpenNextBuildError?.(msg));
|
|
224
|
+
if (spawnError)
|
|
225
|
+
return spawnError;
|
|
226
|
+
if (result.type !== "success")
|
|
227
|
+
return failure(new Error("Unexpected spawn result"));
|
|
228
|
+
if (result.code !== 0) {
|
|
229
|
+
cleanupOpenNextOutput(appPath);
|
|
230
|
+
const maskedOutput = maskSensitiveOutput(result.stderr || result.stdout);
|
|
231
|
+
callbacks.onOpenNextBuildError?.(`OpenNext build failed (exit code ${result.code})`);
|
|
232
|
+
return failure(new Error(`OpenNext build failed (exit code ${result.code}):\n${maskedOutput}`));
|
|
233
|
+
}
|
|
234
|
+
// Verify .open-next directory was created
|
|
235
|
+
const openNextDir = join(appPath, ".open-next");
|
|
236
|
+
if (!existsSync(openNextDir)) {
|
|
237
|
+
callbacks.onOpenNextBuildError?.("OpenNext build completed but .open-next directory not found");
|
|
238
|
+
return failure(new Error("OpenNext build completed but .open-next directory not found"));
|
|
239
|
+
}
|
|
240
|
+
callbacks.onOpenNextBuildComplete?.();
|
|
241
|
+
callbacks.onOpenNextProgress?.(maskSensitiveOutput("OpenNext build completed successfully"));
|
|
242
|
+
return success(undefined);
|
|
243
|
+
}
|