@prisma/compute-sdk 0.28.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/astro-build.d.ts +2 -0
- package/dist/astro-build.d.ts.map +1 -1
- package/dist/astro-build.js +31 -39
- package/dist/astro-build.js.map +1 -1
- package/dist/build-settings.d.ts +3 -0
- package/dist/build-settings.d.ts.map +1 -1
- package/dist/build-settings.js +13 -0
- package/dist/build-settings.js.map +1 -1
- package/dist/build-strategy.d.ts +20 -0
- package/dist/build-strategy.d.ts.map +1 -1
- package/dist/build-strategy.js +33 -1
- package/dist/build-strategy.js.map +1 -1
- package/dist/build.d.ts +2 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +16 -4
- package/dist/build.js.map +1 -1
- package/dist/bun-build.d.ts +1 -1
- package/dist/bun-build.d.ts.map +1 -1
- package/dist/bun-build.js +25 -9
- package/dist/bun-build.js.map +1 -1
- package/dist/config/frameworks.d.ts +4 -8
- package/dist/config/frameworks.d.ts.map +1 -1
- package/dist/config/frameworks.js +17 -5
- package/dist/config/frameworks.js.map +1 -1
- package/dist/config/normalize.d.ts +6 -0
- package/dist/config/normalize.d.ts.map +1 -1
- package/dist/config/normalize.js +53 -12
- package/dist/config/normalize.js.map +1 -1
- package/dist/config/types.d.ts +3 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +1 -0
- package/dist/config/types.js.map +1 -1
- package/dist/configured-artifact.d.ts +20 -0
- package/dist/configured-artifact.d.ts.map +1 -0
- package/dist/configured-artifact.js +104 -0
- package/dist/configured-artifact.js.map +1 -0
- package/dist/custom-build.d.ts +20 -0
- package/dist/custom-build.d.ts.map +1 -0
- package/dist/custom-build.js +53 -0
- package/dist/custom-build.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/nestjs-build.d.ts.map +1 -1
- package/dist/nestjs-build.js +28 -29
- package/dist/nestjs-build.js.map +1 -1
- package/dist/nextjs-build.d.ts +1 -1
- package/dist/nextjs-build.d.ts.map +1 -1
- package/dist/nextjs-build.js +25 -14
- package/dist/nextjs-build.js.map +1 -1
- package/dist/nuxt-build.d.ts +2 -0
- package/dist/nuxt-build.d.ts.map +1 -1
- package/dist/nuxt-build.js +31 -39
- package/dist/nuxt-build.js.map +1 -1
- package/dist/tanstack-start-build.d.ts +1 -1
- package/dist/tanstack-start-build.d.ts.map +1 -1
- package/dist/tanstack-start-build.js +26 -47
- package/dist/tanstack-start-build.js.map +1 -1
- package/package.json +1 -1
- package/src/astro-build.ts +39 -46
- package/src/build-settings.ts +16 -0
- package/src/build-strategy.ts +56 -1
- package/src/build.ts +16 -4
- package/src/bun-build.ts +39 -10
- package/src/config/frameworks.ts +18 -5
- package/src/config/normalize.ts +74 -13
- package/src/config/types.ts +3 -0
- package/src/configured-artifact.ts +169 -0
- package/src/custom-build.ts +73 -0
- package/src/index.ts +1 -0
- package/src/nestjs-build.ts +36 -33
- package/src/nextjs-build.ts +31 -14
- package/src/nuxt-build.ts +39 -46
- package/src/tanstack-start-build.ts +31 -53
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { cp, mkdtemp, realpath, rm, stat } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
import { normalizeArtifactSymlinks } from "./artifact-postprocess.ts";
|
|
6
|
+
import type { BuildArtifact } from "./build-strategy.ts";
|
|
7
|
+
import {
|
|
8
|
+
defaultHttpPortForBuildType,
|
|
9
|
+
type FrameworkBuildType,
|
|
10
|
+
} from "./config/frameworks.ts";
|
|
11
|
+
|
|
12
|
+
export async function stageConfiguredArtifact(options: {
|
|
13
|
+
appPath: string;
|
|
14
|
+
outputDirectory: string;
|
|
15
|
+
entrypoint: string;
|
|
16
|
+
buildType: FrameworkBuildType;
|
|
17
|
+
label: string;
|
|
18
|
+
missingEntrypointMessage?: string;
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
}): Promise<BuildArtifact> {
|
|
21
|
+
options.signal?.throwIfAborted();
|
|
22
|
+
const outputDir = resolvePathInside(
|
|
23
|
+
options.appPath,
|
|
24
|
+
options.outputDirectory,
|
|
25
|
+
`${options.label} build output directory must be a relative path inside the app directory`,
|
|
26
|
+
);
|
|
27
|
+
const outputStat = await stat(outputDir).catch(() => null);
|
|
28
|
+
if (!outputStat?.isDirectory()) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`${options.label} build output directory does not exist: ${options.outputDirectory}`,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const [realAppPath, realOutputDir] = await Promise.all([
|
|
35
|
+
realpath(path.resolve(options.appPath)),
|
|
36
|
+
realpath(outputDir),
|
|
37
|
+
]);
|
|
38
|
+
if (!isPathWithin(realAppPath, realOutputDir)) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`${options.label} build output directory must stay inside the app directory`,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const entrypoint = await resolveConfiguredArtifactEntrypoint({
|
|
45
|
+
directory: realOutputDir,
|
|
46
|
+
entrypoint: options.entrypoint,
|
|
47
|
+
label: options.label,
|
|
48
|
+
displayDirectory: options.outputDirectory,
|
|
49
|
+
missingEntrypointMessage: options.missingEntrypointMessage,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const outDir = await mkdtemp(path.join(os.tmpdir(), "compute-build-"));
|
|
53
|
+
try {
|
|
54
|
+
const artifactDir = path.join(outDir, "app");
|
|
55
|
+
await cp(realOutputDir, artifactDir, {
|
|
56
|
+
recursive: true,
|
|
57
|
+
verbatimSymlinks: true,
|
|
58
|
+
});
|
|
59
|
+
await normalizeArtifactSymlinks(
|
|
60
|
+
artifactDir,
|
|
61
|
+
options.appPath,
|
|
62
|
+
options.signal,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
directory: artifactDir,
|
|
67
|
+
entrypoint,
|
|
68
|
+
defaultPortMapping: {
|
|
69
|
+
http: defaultHttpPortForBuildType(options.buildType),
|
|
70
|
+
},
|
|
71
|
+
cleanup: () => rm(outDir, { recursive: true, force: true }),
|
|
72
|
+
};
|
|
73
|
+
} catch (error) {
|
|
74
|
+
await rm(outDir, { recursive: true, force: true });
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export async function resolveConfiguredArtifactEntrypoint(options: {
|
|
80
|
+
directory: string;
|
|
81
|
+
entrypoint: string;
|
|
82
|
+
label: string;
|
|
83
|
+
displayDirectory?: string;
|
|
84
|
+
missingEntrypointMessage?: string;
|
|
85
|
+
}): Promise<string> {
|
|
86
|
+
const entrypoint = normalizeConfiguredArtifactEntrypoint(
|
|
87
|
+
options.entrypoint,
|
|
88
|
+
options.label,
|
|
89
|
+
);
|
|
90
|
+
const entryPath = path.join(options.directory, entrypoint);
|
|
91
|
+
const entryStat = await stat(entryPath).catch(() => null);
|
|
92
|
+
if (!entryStat?.isFile()) {
|
|
93
|
+
if (options.missingEntrypointMessage) {
|
|
94
|
+
throw new Error(options.missingEntrypointMessage);
|
|
95
|
+
}
|
|
96
|
+
const directory = options.displayDirectory ?? options.directory;
|
|
97
|
+
throw new Error(
|
|
98
|
+
`${options.label} build entrypoint does not exist: ${directory}/${entrypoint}`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return entrypoint;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function normalizeConfiguredArtifactEntrypoint(
|
|
105
|
+
entrypoint: string,
|
|
106
|
+
label: string,
|
|
107
|
+
): string {
|
|
108
|
+
const normalized = path.posix.normalize(
|
|
109
|
+
entrypoint.trim().replace(/\\/g, "/"),
|
|
110
|
+
);
|
|
111
|
+
if (
|
|
112
|
+
normalized.length === 0 ||
|
|
113
|
+
normalized === "." ||
|
|
114
|
+
normalized === ".." ||
|
|
115
|
+
normalized.startsWith("../") ||
|
|
116
|
+
normalized.includes("/../") ||
|
|
117
|
+
path.win32.isAbsolute(entrypoint) ||
|
|
118
|
+
path.posix.isAbsolute(normalized) ||
|
|
119
|
+
/^[A-Za-z]:/.test(normalized)
|
|
120
|
+
) {
|
|
121
|
+
throw new Error(
|
|
122
|
+
`${label} build entrypoint must be a relative path inside the output directory`,
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return normalized;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function resolvePathInside(
|
|
130
|
+
root: string,
|
|
131
|
+
relativePath: string,
|
|
132
|
+
errorMessage: string,
|
|
133
|
+
): string {
|
|
134
|
+
const raw = relativePath.trim().replace(/\\/g, "/");
|
|
135
|
+
const normalized = path.posix.normalize(raw);
|
|
136
|
+
if (
|
|
137
|
+
raw.length === 0 ||
|
|
138
|
+
normalized === ".." ||
|
|
139
|
+
normalized.startsWith("../") ||
|
|
140
|
+
normalized.includes("/../") ||
|
|
141
|
+
path.win32.isAbsolute(relativePath) ||
|
|
142
|
+
path.posix.isAbsolute(normalized) ||
|
|
143
|
+
/^[A-Za-z]:/.test(normalized)
|
|
144
|
+
) {
|
|
145
|
+
throw new Error(errorMessage);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const resolved = path.resolve(root, normalized);
|
|
149
|
+
const relative = path.relative(root, resolved);
|
|
150
|
+
if (
|
|
151
|
+
relative === ".." ||
|
|
152
|
+
relative.startsWith(`..${path.sep}`) ||
|
|
153
|
+
path.isAbsolute(relative)
|
|
154
|
+
) {
|
|
155
|
+
throw new Error(errorMessage);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return resolved;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function isPathWithin(root: string, candidate: string): boolean {
|
|
162
|
+
const relative = path.relative(root, candidate);
|
|
163
|
+
return (
|
|
164
|
+
relative === "" ||
|
|
165
|
+
(!relative.startsWith(`..${path.sep}`) &&
|
|
166
|
+
relative !== ".." &&
|
|
167
|
+
!path.isAbsolute(relative))
|
|
168
|
+
);
|
|
169
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { type BuildSettings, resolveBuildSettings } from "./build-settings.ts";
|
|
2
|
+
import {
|
|
3
|
+
type BuildArtifact,
|
|
4
|
+
type BuildStrategy,
|
|
5
|
+
runBuildSettingsCommand,
|
|
6
|
+
} from "./build-strategy.ts";
|
|
7
|
+
import {
|
|
8
|
+
normalizeConfiguredArtifactEntrypoint,
|
|
9
|
+
stageConfiguredArtifact,
|
|
10
|
+
} from "./configured-artifact.ts";
|
|
11
|
+
import type { BuildCommandIo } from "./workspace.ts";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Generic artifact strategy for frameworks the SDK does not know about yet.
|
|
15
|
+
* Runs an optional command, stages a configured output directory as-is, and
|
|
16
|
+
* starts the configured entrypoint from inside that artifact.
|
|
17
|
+
*/
|
|
18
|
+
export class CustomBuild implements BuildStrategy {
|
|
19
|
+
readonly #appPath: string;
|
|
20
|
+
readonly #entrypoint?: string;
|
|
21
|
+
readonly #buildSettings?: BuildSettings;
|
|
22
|
+
readonly #io?: BuildCommandIo;
|
|
23
|
+
|
|
24
|
+
constructor(options: {
|
|
25
|
+
appPath: string;
|
|
26
|
+
entrypoint?: string;
|
|
27
|
+
buildSettings?: BuildSettings;
|
|
28
|
+
io?: BuildCommandIo;
|
|
29
|
+
}) {
|
|
30
|
+
this.#appPath = options.appPath;
|
|
31
|
+
this.#entrypoint = options.entrypoint;
|
|
32
|
+
this.#buildSettings = options.buildSettings;
|
|
33
|
+
this.#io = options.io;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async canBuild(_signal?: AbortSignal): Promise<boolean> {
|
|
37
|
+
return Boolean(this.#entrypoint ?? this.#buildSettings?.entrypoint);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async execute(signal?: AbortSignal): Promise<BuildArtifact> {
|
|
41
|
+
signal?.throwIfAborted();
|
|
42
|
+
const settings =
|
|
43
|
+
this.#buildSettings ??
|
|
44
|
+
(await resolveBuildSettings({
|
|
45
|
+
appPath: this.#appPath,
|
|
46
|
+
buildType: "custom",
|
|
47
|
+
signal,
|
|
48
|
+
}));
|
|
49
|
+
|
|
50
|
+
const entrypoint = this.#entrypoint ?? settings.entrypoint;
|
|
51
|
+
if (!entrypoint) {
|
|
52
|
+
throw new Error("Custom build entrypoint is required");
|
|
53
|
+
}
|
|
54
|
+
normalizeConfiguredArtifactEntrypoint(entrypoint, "Custom");
|
|
55
|
+
|
|
56
|
+
await runBuildSettingsCommand({
|
|
57
|
+
appPath: this.#appPath,
|
|
58
|
+
settings,
|
|
59
|
+
failurePrefix: "Custom",
|
|
60
|
+
io: this.#io,
|
|
61
|
+
signal,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
return stageConfiguredArtifact({
|
|
65
|
+
appPath: this.#appPath,
|
|
66
|
+
outputDirectory: settings.outputDirectory,
|
|
67
|
+
entrypoint,
|
|
68
|
+
buildType: "custom",
|
|
69
|
+
label: "Custom",
|
|
70
|
+
signal,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/index.ts
CHANGED
package/src/nestjs-build.ts
CHANGED
|
@@ -24,15 +24,11 @@ import type { BuildArtifact, BuildStrategy } from "./build-strategy.ts";
|
|
|
24
24
|
import {
|
|
25
25
|
hasPackageDependency,
|
|
26
26
|
hasRootFile,
|
|
27
|
-
|
|
27
|
+
runBuildSettingsCommand,
|
|
28
28
|
} from "./build-strategy.ts";
|
|
29
29
|
import { defaultHttpPortForBuildType } from "./config/frameworks.ts";
|
|
30
30
|
import { resolveSourceRoot } from "./config/source-root.ts";
|
|
31
|
-
import {
|
|
32
|
-
type BuildCommandIo,
|
|
33
|
-
readPackageManifest,
|
|
34
|
-
runBuildCommand,
|
|
35
|
-
} from "./workspace.ts";
|
|
31
|
+
import { type BuildCommandIo, readPackageManifest } from "./workspace.ts";
|
|
36
32
|
|
|
37
33
|
const NEST_CLI_FILENAME = "nest-cli.json";
|
|
38
34
|
|
|
@@ -81,37 +77,26 @@ export class NestjsBuild implements BuildStrategy {
|
|
|
81
77
|
signal,
|
|
82
78
|
}));
|
|
83
79
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (!usingFrameworkDefault && settings.buildCommand) {
|
|
91
|
-
await runBuildCommand({
|
|
92
|
-
appPath: this.#appPath,
|
|
93
|
-
command: settings.buildCommand,
|
|
94
|
-
failurePrefix: "NestJS",
|
|
95
|
-
env: this.#io?.env,
|
|
96
|
-
onOutput: this.#io?.onOutput,
|
|
97
|
-
signal,
|
|
98
|
-
});
|
|
99
|
-
} else {
|
|
100
|
-
await runPackageCli({
|
|
101
|
-
appPath: this.#appPath,
|
|
80
|
+
await runBuildSettingsCommand({
|
|
81
|
+
appPath: this.#appPath,
|
|
82
|
+
settings,
|
|
83
|
+
failurePrefix: "NestJS",
|
|
84
|
+
defaultCli: {
|
|
85
|
+
source: "NestJS default",
|
|
102
86
|
cliName: "nest",
|
|
103
87
|
args: ["build"],
|
|
104
|
-
failurePrefix: "NestJS",
|
|
105
88
|
missingMessage:
|
|
106
89
|
"Could not find the Nest CLI. Add a `build` script to package.json, install @nestjs/cli, or ensure npx/bunx is available.",
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
90
|
+
},
|
|
91
|
+
io: this.#io,
|
|
92
|
+
signal,
|
|
93
|
+
});
|
|
112
94
|
|
|
113
95
|
signal?.throwIfAborted();
|
|
114
|
-
const compiledEntry = await this.#resolveCompiledEntrypoint(
|
|
96
|
+
const compiledEntry = await this.#resolveCompiledEntrypoint(
|
|
97
|
+
settings,
|
|
98
|
+
signal,
|
|
99
|
+
);
|
|
115
100
|
|
|
116
101
|
const outDir = await mkdtemp(path.join(os.tmpdir(), "compute-build-"));
|
|
117
102
|
try {
|
|
@@ -140,9 +125,16 @@ export class NestjsBuild implements BuildStrategy {
|
|
|
140
125
|
* separators. Prefers `package.json` `main`, then the path computed from
|
|
141
126
|
* `nest-cli.json` and the tsconfig `outDir`, then the common defaults.
|
|
142
127
|
*/
|
|
143
|
-
async #resolveCompiledEntrypoint(
|
|
128
|
+
async #resolveCompiledEntrypoint(
|
|
129
|
+
settings: BuildSettings,
|
|
130
|
+
signal?: AbortSignal,
|
|
131
|
+
): Promise<string> {
|
|
144
132
|
const candidates: string[] = [];
|
|
145
133
|
|
|
134
|
+
if (settings.entrypoint) {
|
|
135
|
+
candidates.push(joinPosix(settings.outputDirectory, settings.entrypoint));
|
|
136
|
+
}
|
|
137
|
+
|
|
146
138
|
const fromMain = await this.#mainFieldEntrypoint(signal);
|
|
147
139
|
if (fromMain) {
|
|
148
140
|
candidates.push(fromMain);
|
|
@@ -153,7 +145,7 @@ export class NestjsBuild implements BuildStrategy {
|
|
|
153
145
|
candidates.push(fromConfig);
|
|
154
146
|
}
|
|
155
147
|
|
|
156
|
-
candidates.push(...
|
|
148
|
+
candidates.push(...compiledEntrypointDefaults(settings.outputDirectory));
|
|
157
149
|
|
|
158
150
|
for (const candidate of candidates) {
|
|
159
151
|
signal?.throwIfAborted();
|
|
@@ -195,6 +187,17 @@ export class NestjsBuild implements BuildStrategy {
|
|
|
195
187
|
}
|
|
196
188
|
}
|
|
197
189
|
|
|
190
|
+
function compiledEntrypointDefaults(outputDirectory: string): string[] {
|
|
191
|
+
if (outputDirectory === "dist") {
|
|
192
|
+
return DEFAULT_COMPILED_ENTRYPOINTS;
|
|
193
|
+
}
|
|
194
|
+
return [
|
|
195
|
+
joinPosix(outputDirectory, "src/main.js"),
|
|
196
|
+
joinPosix(outputDirectory, "main.js"),
|
|
197
|
+
...DEFAULT_COMPILED_ENTRYPOINTS,
|
|
198
|
+
];
|
|
199
|
+
}
|
|
200
|
+
|
|
198
201
|
interface NestCliConfig {
|
|
199
202
|
sourceRoot?: string;
|
|
200
203
|
entryFile?: string;
|
package/src/nextjs-build.ts
CHANGED
|
@@ -9,9 +9,14 @@ import {
|
|
|
9
9
|
resolveBuildSettings,
|
|
10
10
|
} from "./build-settings.ts";
|
|
11
11
|
import type { BuildArtifact, BuildStrategy } from "./build-strategy.ts";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
hasPackageDependency,
|
|
14
|
+
hasRootFile,
|
|
15
|
+
runBuildSettingsCommand,
|
|
16
|
+
} from "./build-strategy.ts";
|
|
13
17
|
import { defaultHttpPortForBuildType } from "./config/frameworks.ts";
|
|
14
|
-
import {
|
|
18
|
+
import { resolveConfiguredArtifactEntrypoint } from "./configured-artifact.ts";
|
|
19
|
+
import type { BuildCommandIo } from "./workspace.ts";
|
|
15
20
|
|
|
16
21
|
const NEXT_CONFIG_FILENAMES = [
|
|
17
22
|
"next.config.js",
|
|
@@ -63,20 +68,24 @@ export class NextjsBuild implements BuildStrategy {
|
|
|
63
68
|
buildType: "nextjs",
|
|
64
69
|
signal,
|
|
65
70
|
}));
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
await runBuildSettingsCommand({
|
|
72
|
+
appPath: this.#appPath,
|
|
73
|
+
settings,
|
|
74
|
+
failurePrefix: "Next.js",
|
|
75
|
+
defaultCli: {
|
|
76
|
+
source: "Next.js default",
|
|
77
|
+
cliName: "next",
|
|
78
|
+
args: ["build"],
|
|
79
|
+
missingMessage:
|
|
80
|
+
"Could not find the Next.js CLI. Install it with `npm install next` or ensure npx/bunx is available.",
|
|
81
|
+
},
|
|
82
|
+
io: this.#io,
|
|
83
|
+
signal,
|
|
84
|
+
});
|
|
76
85
|
|
|
77
86
|
const standaloneDir = path.join(this.#appPath, settings.outputDirectory);
|
|
78
87
|
if (!(await directoryExists(standaloneDir))) {
|
|
79
|
-
if (this.#requireStandalone) {
|
|
88
|
+
if (this.#requireStandalone || settings.entrypoint) {
|
|
80
89
|
throw new Error(
|
|
81
90
|
`Next.js build did not produce standalone output at ${settings.outputDirectory}. ` +
|
|
82
91
|
'Set output: "standalone" in your next.config; this deploy target requires it.',
|
|
@@ -97,7 +106,15 @@ export class NextjsBuild implements BuildStrategy {
|
|
|
97
106
|
appPath: this.#appPath,
|
|
98
107
|
signal,
|
|
99
108
|
});
|
|
100
|
-
const entrypoint =
|
|
109
|
+
const entrypoint = settings.entrypoint
|
|
110
|
+
? await resolveConfiguredArtifactEntrypoint({
|
|
111
|
+
directory: artifactDir,
|
|
112
|
+
entrypoint: settings.entrypoint,
|
|
113
|
+
label: "Next.js",
|
|
114
|
+
displayDirectory: settings.outputDirectory,
|
|
115
|
+
missingEntrypointMessage: `Next.js standalone output did not contain configured entrypoint ${settings.outputDirectory}/${settings.entrypoint}.`,
|
|
116
|
+
})
|
|
117
|
+
: await findStandaloneEntrypoint(artifactDir);
|
|
101
118
|
await copyStaticAssets({
|
|
102
119
|
appPath: this.#appPath,
|
|
103
120
|
artifactDir,
|
package/src/nuxt-build.ts
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import os from "node:os";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
|
|
5
|
-
import { normalizeArtifactSymlinks } from "./artifact-postprocess.ts";
|
|
1
|
+
import { type BuildSettings, resolveBuildSettings } from "./build-settings.ts";
|
|
6
2
|
import type { BuildArtifact, BuildStrategy } from "./build-strategy.ts";
|
|
7
3
|
import {
|
|
8
4
|
hasPackageDependency,
|
|
9
5
|
hasRootFile,
|
|
10
|
-
|
|
6
|
+
runBuildSettingsCommand,
|
|
11
7
|
} from "./build-strategy.ts";
|
|
12
|
-
import {
|
|
8
|
+
import { stageConfiguredArtifact } from "./configured-artifact.ts";
|
|
13
9
|
import type { BuildCommandIo } from "./workspace.ts";
|
|
14
10
|
|
|
15
11
|
const NUXT_CONFIG_FILENAMES = [
|
|
@@ -26,10 +22,16 @@ const NUXT_CONFIG_FILENAMES = [
|
|
|
26
22
|
*/
|
|
27
23
|
export class NuxtBuild implements BuildStrategy {
|
|
28
24
|
readonly #appPath: string;
|
|
25
|
+
readonly #buildSettings?: BuildSettings;
|
|
29
26
|
readonly #io?: BuildCommandIo;
|
|
30
27
|
|
|
31
|
-
constructor(options: {
|
|
28
|
+
constructor(options: {
|
|
29
|
+
appPath: string;
|
|
30
|
+
buildSettings?: BuildSettings;
|
|
31
|
+
io?: BuildCommandIo;
|
|
32
|
+
}) {
|
|
32
33
|
this.#appPath = options.appPath;
|
|
34
|
+
this.#buildSettings = options.buildSettings;
|
|
33
35
|
this.#io = options.io;
|
|
34
36
|
}
|
|
35
37
|
|
|
@@ -42,48 +44,39 @@ export class NuxtBuild implements BuildStrategy {
|
|
|
42
44
|
|
|
43
45
|
async execute(signal?: AbortSignal): Promise<BuildArtifact> {
|
|
44
46
|
signal?.throwIfAborted();
|
|
45
|
-
|
|
47
|
+
const settings =
|
|
48
|
+
this.#buildSettings ??
|
|
49
|
+
(await resolveBuildSettings({
|
|
50
|
+
appPath: this.#appPath,
|
|
51
|
+
buildType: "nuxt",
|
|
52
|
+
signal,
|
|
53
|
+
}));
|
|
54
|
+
|
|
55
|
+
await runBuildSettingsCommand({
|
|
46
56
|
appPath: this.#appPath,
|
|
47
|
-
|
|
48
|
-
args: ["build"],
|
|
57
|
+
settings,
|
|
49
58
|
failurePrefix: "Nuxt",
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
defaultCli: {
|
|
60
|
+
source: "Nuxt default",
|
|
61
|
+
cliName: "nuxt",
|
|
62
|
+
args: ["build"],
|
|
63
|
+
missingMessage:
|
|
64
|
+
"Could not find the Nuxt CLI. Install it with `npm install nuxt` or ensure npx/bunx is available.",
|
|
65
|
+
},
|
|
66
|
+
io: this.#io,
|
|
54
67
|
signal,
|
|
55
68
|
});
|
|
56
69
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
const artifactDir = path.join(outDir, "app");
|
|
70
|
-
await cp(outputDir, artifactDir, {
|
|
71
|
-
recursive: true,
|
|
72
|
-
verbatimSymlinks: true,
|
|
73
|
-
});
|
|
74
|
-
// Materialize any symlinks into the app/workspace node_modules so the
|
|
75
|
-
// artifact is self-contained once unpacked elsewhere.
|
|
76
|
-
await normalizeArtifactSymlinks(artifactDir, this.#appPath, signal);
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
directory: artifactDir,
|
|
80
|
-
entrypoint: "server/index.mjs",
|
|
81
|
-
defaultPortMapping: { http: defaultHttpPortForBuildType("nuxt") },
|
|
82
|
-
cleanup: () => rm(outDir, { recursive: true, force: true }),
|
|
83
|
-
};
|
|
84
|
-
} catch (error) {
|
|
85
|
-
await rm(outDir, { recursive: true, force: true });
|
|
86
|
-
throw error;
|
|
87
|
-
}
|
|
70
|
+
return stageConfiguredArtifact({
|
|
71
|
+
appPath: this.#appPath,
|
|
72
|
+
outputDirectory: settings.outputDirectory,
|
|
73
|
+
entrypoint: settings.entrypoint ?? "server/index.mjs",
|
|
74
|
+
buildType: "nuxt",
|
|
75
|
+
label: "Nuxt",
|
|
76
|
+
missingEntrypointMessage: settings.entrypoint
|
|
77
|
+
? undefined
|
|
78
|
+
: `Nuxt build did not produce a Nitro node server entrypoint at ${settings.outputDirectory}/server/index.mjs. Ensure nitro.preset is 'node-server' (the default) - set NITRO_PRESET=node-server or remove any custom preset from nuxt.config.`,
|
|
79
|
+
signal,
|
|
80
|
+
});
|
|
88
81
|
}
|
|
89
82
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import { cp, mkdtemp, rm, stat } from "node:fs/promises";
|
|
2
|
-
import os from "node:os";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
|
|
5
|
-
import { normalizeArtifactSymlinks } from "./artifact-postprocess.ts";
|
|
6
1
|
import { type BuildSettings, resolveBuildSettings } from "./build-settings.ts";
|
|
7
2
|
import type { BuildArtifact, BuildStrategy } from "./build-strategy.ts";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
import {
|
|
4
|
+
hasPackageDependency,
|
|
5
|
+
runBuildSettingsCommand,
|
|
6
|
+
} from "./build-strategy.ts";
|
|
7
|
+
import { stageConfiguredArtifact } from "./configured-artifact.ts";
|
|
8
|
+
import type { BuildCommandIo } from "./workspace.ts";
|
|
11
9
|
|
|
12
10
|
const TANSTACK_START_PACKAGES = [
|
|
13
11
|
"@tanstack/react-start",
|
|
@@ -47,51 +45,31 @@ export class TanstackStartBuild implements BuildStrategy {
|
|
|
47
45
|
buildType: "tanstack-start",
|
|
48
46
|
signal,
|
|
49
47
|
}));
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
() => null,
|
|
65
|
-
);
|
|
66
|
-
if (!entryStat?.isFile()) {
|
|
67
|
-
throw new Error(
|
|
68
|
-
`TanStack Start build did not produce a Nitro node server entrypoint at ${settings.outputDirectory}/${entrypoint}. ` +
|
|
69
|
-
"Ensure your vite.config includes the tanstackStart() and nitro() plugins with the default node preset.",
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const outDir = await mkdtemp(path.join(os.tmpdir(), "compute-build-"));
|
|
74
|
-
try {
|
|
75
|
-
const artifactDir = path.join(outDir, "app");
|
|
76
|
-
await cp(outputDir, artifactDir, {
|
|
77
|
-
recursive: true,
|
|
78
|
-
verbatimSymlinks: true,
|
|
79
|
-
});
|
|
80
|
-
// Materialize any symlinks into the app/workspace node_modules so the
|
|
81
|
-
// artifact is self-contained once unpacked elsewhere.
|
|
82
|
-
await normalizeArtifactSymlinks(artifactDir, this.#appPath, signal);
|
|
48
|
+
await runBuildSettingsCommand({
|
|
49
|
+
appPath: this.#appPath,
|
|
50
|
+
settings,
|
|
51
|
+
failurePrefix: "TanStack Start",
|
|
52
|
+
defaultCli: {
|
|
53
|
+
source: "TanStack Start default",
|
|
54
|
+
cliName: "vite",
|
|
55
|
+
args: ["build"],
|
|
56
|
+
missingMessage:
|
|
57
|
+
"Could not find the Vite CLI. Install it with `npm install vite` or ensure npx/bunx is available.",
|
|
58
|
+
},
|
|
59
|
+
io: this.#io,
|
|
60
|
+
signal,
|
|
61
|
+
});
|
|
83
62
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
63
|
+
return stageConfiguredArtifact({
|
|
64
|
+
appPath: this.#appPath,
|
|
65
|
+
outputDirectory: settings.outputDirectory,
|
|
66
|
+
entrypoint: settings.entrypoint ?? "server/index.mjs",
|
|
67
|
+
buildType: "tanstack-start",
|
|
68
|
+
label: "TanStack Start",
|
|
69
|
+
missingEntrypointMessage: settings.entrypoint
|
|
70
|
+
? undefined
|
|
71
|
+
: `TanStack Start build did not produce a Nitro node server entrypoint at ${settings.outputDirectory}/server/index.mjs. Ensure your vite.config includes the tanstackStart() and nitro() plugins with the default node preset.`,
|
|
72
|
+
signal,
|
|
73
|
+
});
|
|
96
74
|
}
|
|
97
75
|
}
|