@prisma/cli 3.0.0-alpha.8 → 3.0.0-alpha.9
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolveBunEntrypoint } from "./bun-project.js";
|
|
2
|
-
import { cp, readdir, readlink, rm, stat } from "node:fs/promises";
|
|
2
|
+
import { chmod, copyFile, cp, lstat, mkdir, readFile, readdir, readlink, rm, stat } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { AstroBuild, BunBuild, NextjsBuild, NuxtBuild, TanstackStartBuild } from "@prisma/compute-sdk";
|
|
5
5
|
//#region src/lib/app/preview-build.ts
|
|
@@ -46,6 +46,7 @@ async function executePreviewBuild(options) {
|
|
|
46
46
|
});
|
|
47
47
|
const artifact = await strategy.execute();
|
|
48
48
|
try {
|
|
49
|
+
if (buildType === "nextjs") await restageNextjsArtifact(artifact.directory, options.appPath);
|
|
49
50
|
await normalizeArtifactSymlinks(artifact.directory, options.appPath);
|
|
50
51
|
return {
|
|
51
52
|
artifact,
|
|
@@ -104,6 +105,38 @@ async function createPreviewBuildStrategy(options) {
|
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
}
|
|
108
|
+
async function stageNextjsStandaloneArtifact(options) {
|
|
109
|
+
const standaloneRoot = path.resolve(options.standaloneDir);
|
|
110
|
+
const artifactRoot = path.resolve(options.artifactDir);
|
|
111
|
+
const appRoot = path.resolve(options.appPath);
|
|
112
|
+
await copyPathMaterializingSymlinks(standaloneRoot, artifactRoot, {
|
|
113
|
+
standaloneRoot,
|
|
114
|
+
appRoot,
|
|
115
|
+
sourceRoot: await resolveSourceRoot(appRoot)
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
async function restageNextjsArtifact(artifactDir, appPath) {
|
|
119
|
+
const standaloneDir = path.join(appPath, ".next", "standalone");
|
|
120
|
+
await rm(artifactDir, {
|
|
121
|
+
recursive: true,
|
|
122
|
+
force: true
|
|
123
|
+
});
|
|
124
|
+
await stageNextjsStandaloneArtifact({
|
|
125
|
+
standaloneDir,
|
|
126
|
+
artifactDir,
|
|
127
|
+
appPath
|
|
128
|
+
});
|
|
129
|
+
const publicDir = path.join(appPath, "public");
|
|
130
|
+
if (await directoryExists(publicDir)) await cp(publicDir, path.join(artifactDir, "public"), {
|
|
131
|
+
recursive: true,
|
|
132
|
+
verbatimSymlinks: true
|
|
133
|
+
});
|
|
134
|
+
const staticDir = path.join(appPath, ".next", "static");
|
|
135
|
+
if (await directoryExists(staticDir)) await cp(staticDir, path.join(artifactDir, ".next", "static"), {
|
|
136
|
+
recursive: true,
|
|
137
|
+
verbatimSymlinks: true
|
|
138
|
+
});
|
|
139
|
+
}
|
|
107
140
|
async function normalizeArtifactSymlinks(artifactDir, appPath) {
|
|
108
141
|
const normalizedArtifactDir = path.resolve(artifactDir);
|
|
109
142
|
const normalizedAppPath = path.resolve(appPath);
|
|
@@ -138,5 +171,69 @@ function isPathWithin(rootPath, candidatePath) {
|
|
|
138
171
|
const relativePath = path.relative(rootPath, candidatePath);
|
|
139
172
|
return relativePath === "" || !relativePath.startsWith(`..${path.sep}`) && relativePath !== ".." && !path.isAbsolute(relativePath);
|
|
140
173
|
}
|
|
174
|
+
async function copyPathMaterializingSymlinks(sourcePath, destinationPath, options) {
|
|
175
|
+
const sourceStat = await lstat(sourcePath);
|
|
176
|
+
if (sourceStat.isSymbolicLink()) {
|
|
177
|
+
await copyPathMaterializingSymlinks(await resolveSymlinkTarget(sourcePath, options), destinationPath, options);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (sourceStat.isDirectory()) {
|
|
181
|
+
await mkdir(destinationPath, { recursive: true });
|
|
182
|
+
const entries = await readdir(sourcePath, { withFileTypes: true });
|
|
183
|
+
for (const entry of entries) await copyPathMaterializingSymlinks(path.join(sourcePath, entry.name), path.join(destinationPath, entry.name), options);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (sourceStat.isFile()) {
|
|
187
|
+
await mkdir(path.dirname(destinationPath), { recursive: true });
|
|
188
|
+
await copyFile(sourcePath, destinationPath);
|
|
189
|
+
await chmod(destinationPath, sourceStat.mode);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
async function resolveSymlinkTarget(symlinkPath, options) {
|
|
193
|
+
const linkTarget = await readlink(symlinkPath);
|
|
194
|
+
const resolvedTarget = path.resolve(path.dirname(symlinkPath), linkTarget);
|
|
195
|
+
if (await pathExists(resolvedTarget)) {
|
|
196
|
+
if (!isPathWithin(options.appRoot, resolvedTarget) && !isPathWithin(options.sourceRoot, resolvedTarget)) throw new Error(`Build artifact symlink escapes the app directory: ${resolvedTarget}`);
|
|
197
|
+
return resolvedTarget;
|
|
198
|
+
}
|
|
199
|
+
if (isPathWithin(options.standaloneRoot, resolvedTarget)) {
|
|
200
|
+
const fallbackTarget = path.join(options.appRoot, path.relative(options.standaloneRoot, resolvedTarget));
|
|
201
|
+
if (await pathExists(fallbackTarget)) return fallbackTarget;
|
|
202
|
+
}
|
|
203
|
+
throw new Error(`Next.js standalone symlink target is missing: ${symlinkPath} -> ${linkTarget} (resolved to ${resolvedTarget})`);
|
|
204
|
+
}
|
|
205
|
+
async function pathExists(targetPath) {
|
|
206
|
+
try {
|
|
207
|
+
await stat(targetPath);
|
|
208
|
+
return true;
|
|
209
|
+
} catch {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
async function directoryExists(targetPath) {
|
|
214
|
+
try {
|
|
215
|
+
return (await stat(targetPath)).isDirectory();
|
|
216
|
+
} catch {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async function resolveSourceRoot(appRoot) {
|
|
221
|
+
let current = path.resolve(appRoot);
|
|
222
|
+
while (true) {
|
|
223
|
+
if (await pathExists(path.join(current, ".git")) || await pathExists(path.join(current, "pnpm-workspace.yaml")) || await pathExists(path.join(current, "bun.lock")) || await pathExists(path.join(current, "bun.lockb")) || await packageJsonDeclaresWorkspaces(current)) return current;
|
|
224
|
+
const parent = path.dirname(current);
|
|
225
|
+
if (parent === current) return path.resolve(appRoot);
|
|
226
|
+
current = parent;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
async function packageJsonDeclaresWorkspaces(directory) {
|
|
230
|
+
try {
|
|
231
|
+
const content = await readFile(path.join(directory, "package.json"), "utf8");
|
|
232
|
+
const parsed = JSON.parse(content);
|
|
233
|
+
return Boolean(parsed.workspaces);
|
|
234
|
+
} catch {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
141
238
|
//#endregion
|
|
142
239
|
export { PREVIEW_BUILD_TYPES, PreviewBuildStrategy, RESOLVED_PREVIEW_BUILD_TYPES, executePreviewBuild };
|