@prisma/compute-sdk 0.17.0 → 0.19.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/archive.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Create a tar.gz archive in memory from a build artifact directory.
3
3
  *
4
4
  * - Files are added under the `bundle/` prefix.
5
- * - Symlinks are followed (dereferenced).
5
+ * - Symlinks are preserved as symlink entries.
6
6
  * - A synthetic `compute.manifest.json` entry is injected at the tar root.
7
7
  *
8
8
  * Returns the gzipped archive as a Uint8Array.
package/dist/archive.js CHANGED
@@ -1,4 +1,4 @@
1
- import { lstat, readdir, readFile, readlink, stat } from "node:fs/promises";
1
+ import { lstat, readdir, readFile, readlink } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { createGzip } from "node:zlib";
4
4
  import { pack } from "tar-stream";
@@ -7,7 +7,7 @@ const COMPUTE_MANIFEST_VERSION = "1";
7
7
  * Create a tar.gz archive in memory from a build artifact directory.
8
8
  *
9
9
  * - Files are added under the `bundle/` prefix.
10
- * - Symlinks are followed (dereferenced).
10
+ * - Symlinks are preserved as symlink entries.
11
11
  * - A synthetic `compute.manifest.json` entry is injected at the tar root.
12
12
  *
13
13
  * Returns the gzipped archive as a Uint8Array.
@@ -35,16 +35,8 @@ async function addDirectory(packer, rootPath, fsPath, tarPrefix) {
35
35
  const fullPath = path.join(directoryPath, entry.name);
36
36
  const tarPath = `${tarPrefix}/${entry.name}`;
37
37
  if (entry.isSymbolicLink()) {
38
- // Dereference symlinks: stat the target and add accordingly
39
- const target = await readlink(fullPath);
40
- const resolvedPath = resolvePathWithinRoot(rootPath, path.resolve(directoryPath, target));
41
- const resolvedStat = await stat(resolvedPath);
42
- if (resolvedStat.isDirectory()) {
43
- await addDirectory(packer, rootPath, resolvedPath, tarPath);
44
- }
45
- else if (resolvedStat.isFile()) {
46
- await addFile(packer, rootPath, resolvedPath, tarPath, resolvedStat);
47
- }
38
+ const linkStat = await lstat(fullPath);
39
+ await addSymlink(packer, rootPath, fullPath, tarPath, linkStat);
48
40
  }
49
41
  else if (entry.isDirectory()) {
50
42
  await addDirectory(packer, rootPath, fullPath, tarPath);
@@ -65,6 +57,37 @@ async function addFile(packer, rootPath, fsPath, tarPath, fileStat) {
65
57
  mtime: fileStat.mtime,
66
58
  }, content);
67
59
  }
60
+ async function addSymlink(packer, rootPath, fsPath, tarPath, linkStat) {
61
+ const symlinkPath = resolvePathWithinRoot(rootPath, fsPath);
62
+ const target = await readlink(symlinkPath);
63
+ const linkname = await resolveArchiveSymlinkTarget(rootPath, symlinkPath, target);
64
+ packer.entry({
65
+ name: tarPath,
66
+ type: "symlink",
67
+ linkname,
68
+ mode: linkStat.mode,
69
+ mtime: linkStat.mtime,
70
+ });
71
+ }
72
+ async function resolveArchiveSymlinkTarget(rootPath, symlinkPath, target) {
73
+ const symlinkDir = path.dirname(symlinkPath);
74
+ const resolvedTarget = resolvePathWithinRoot(rootPath, path.isAbsolute(target) ? target : path.resolve(symlinkDir, target));
75
+ await lstat(resolvedTarget).catch((error) => {
76
+ if (isENOENT(error)) {
77
+ throw new Error(`Symlink target does not exist: ${symlinkPath} -> ${target} (resolved to ${resolvedTarget})`);
78
+ }
79
+ throw error;
80
+ });
81
+ if (!path.isAbsolute(target)) {
82
+ return target;
83
+ }
84
+ return path.relative(symlinkDir, resolvedTarget) || ".";
85
+ }
86
+ function isENOENT(error) {
87
+ return (error instanceof Error &&
88
+ "code" in error &&
89
+ error.code === "ENOENT");
90
+ }
68
91
  function resolvePathWithinRoot(rootPath, fsPath) {
69
92
  const normalizedRootPath = path.resolve(rootPath);
70
93
  const resolvedPath = path.resolve(fsPath);
@@ -1 +1 @@
1
- {"version":3,"file":"archive.js","sourceRoot":"","sources":["../src/archive.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"archive.js","sourceRoot":"","sources":["../src/archive.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"nextjs-build.d.ts","sourceRoot":"","sources":["../src/nextjs-build.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAcxE;;;GAGG;AACH,qBAAa,WAAY,YAAW,aAAa;;gBAGnC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE;IAIlC,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAO5B,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC;CAuDxC"}
1
+ {"version":3,"file":"nextjs-build.d.ts","sourceRoot":"","sources":["../src/nextjs-build.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAcxE;;;GAGG;AACH,qBAAa,WAAY,YAAW,aAAa;;gBAGnC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE;IAIlC,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAO5B,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC;CAuExC"}
@@ -1,4 +1,4 @@
1
- import { cp, mkdtemp, rm, stat } from "node:fs/promises";
1
+ import { cp, mkdtemp, readdir, rm, stat } from "node:fs/promises";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
4
  import { hasPackageDependency, hasRootFile, runPackageCli, } from "./build-strategy.js";
@@ -41,23 +41,35 @@ export class NextjsBuild {
41
41
  recursive: true,
42
42
  verbatimSymlinks: true,
43
43
  });
44
+ // In monorepos, Next preserves the workspace-relative path from the
45
+ // workspace root down to the app, so server.js lands at e.g.
46
+ // .next/standalone/apps/web/server.js, not at the standalone root.
47
+ // The runtime needs the correct entrypoint, and Next expects public/
48
+ // and .next/static/ to be siblings of server.js.
49
+ const serverSubpath = await findServerSubpath(artifactDir);
50
+ const serverDir = serverSubpath === undefined
51
+ ? artifactDir
52
+ : path.join(artifactDir, serverSubpath);
44
53
  const publicDir = path.join(this.#appPath, "public");
45
54
  if (await directoryExists(publicDir)) {
46
- await cp(publicDir, path.join(artifactDir, "public"), {
55
+ await cp(publicDir, path.join(serverDir, "public"), {
47
56
  recursive: true,
48
57
  verbatimSymlinks: true,
49
58
  });
50
59
  }
51
60
  const staticDir = path.join(this.#appPath, ".next", "static");
52
61
  if (await directoryExists(staticDir)) {
53
- await cp(staticDir, path.join(artifactDir, ".next", "static"), {
62
+ await cp(staticDir, path.join(serverDir, ".next", "static"), {
54
63
  recursive: true,
55
64
  verbatimSymlinks: true,
56
65
  });
57
66
  }
67
+ const entrypoint = serverSubpath === undefined
68
+ ? "server.js"
69
+ : path.posix.join(serverSubpath, "server.js");
58
70
  return {
59
71
  directory: artifactDir,
60
- entrypoint: "server.js",
72
+ entrypoint,
61
73
  defaultPortMapping: { http: 3000 },
62
74
  cleanup: () => rm(outDir, { recursive: true, force: true }),
63
75
  };
@@ -72,4 +84,40 @@ async function directoryExists(dirPath) {
72
84
  const s = await stat(dirPath).catch(() => null);
73
85
  return s?.isDirectory() ?? false;
74
86
  }
87
+ /**
88
+ * Scan the Next.js standalone output to find the directory that contains
89
+ * server.js, relative to the standalone root. Returns undefined when
90
+ * server.js is at the root (single-app repos) and a posix-joined subpath
91
+ * like "apps/web" for monorepos. node_modules is skipped because
92
+ * third-party packages may ship a file named server.js.
93
+ */
94
+ async function findServerSubpath(standaloneDir) {
95
+ const matches = [];
96
+ async function walk(currentDir, relative) {
97
+ const entries = await readdir(currentDir, { withFileTypes: true });
98
+ for (const entry of entries) {
99
+ if (entry.name === "node_modules")
100
+ continue;
101
+ const fullPath = path.join(currentDir, entry.name);
102
+ if (entry.isDirectory()) {
103
+ const nextRelative = relative === undefined
104
+ ? entry.name
105
+ : path.posix.join(relative, entry.name);
106
+ await walk(fullPath, nextRelative);
107
+ }
108
+ else if (entry.isFile() && entry.name === "server.js") {
109
+ matches.push(relative);
110
+ }
111
+ }
112
+ }
113
+ await walk(standaloneDir, undefined);
114
+ if (matches.length > 1) {
115
+ const locations = matches.map((m) => m ?? "<root>").join(", ");
116
+ throw new Error(`Next.js standalone output has multiple server.js files (${locations}). Cannot determine the application entrypoint.`);
117
+ }
118
+ if (matches.length === 0) {
119
+ throw new Error("Next.js standalone output is missing server.js. The build may not have completed successfully.");
120
+ }
121
+ return matches[0];
122
+ }
75
123
  //# sourceMappingURL=nextjs-build.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nextjs-build.js","sourceRoot":"","sources":["../src/nextjs-build.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nextjs-build.js","sourceRoot":"","sources":["../src/nextjs-build.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/compute-sdk",
3
- "version": "0.17.0",
3
+ "version": "0.19.0",
4
4
  "description": "TypeScript SDK for deploying and managing applications on Prisma Compute",
5
5
  "license": "Apache-2.0",
6
6
  "repository": "prisma/project-compute",
package/src/archive.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { lstat, readdir, readFile, readlink, stat } from "node:fs/promises";
1
+ import { lstat, readdir, readFile, readlink } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { createGzip } from "node:zlib";
4
4
  import { type Pack, pack } from "tar-stream";
@@ -9,7 +9,7 @@ const COMPUTE_MANIFEST_VERSION = "1" as const;
9
9
  * Create a tar.gz archive in memory from a build artifact directory.
10
10
  *
11
11
  * - Files are added under the `bundle/` prefix.
12
- * - Symlinks are followed (dereferenced).
12
+ * - Symlinks are preserved as symlink entries.
13
13
  * - A synthetic `compute.manifest.json` entry is injected at the tar root.
14
14
  *
15
15
  * Returns the gzipped archive as a Uint8Array.
@@ -56,19 +56,8 @@ async function addDirectory(
56
56
  const tarPath = `${tarPrefix}/${entry.name}`;
57
57
 
58
58
  if (entry.isSymbolicLink()) {
59
- // Dereference symlinks: stat the target and add accordingly
60
- const target = await readlink(fullPath);
61
- const resolvedPath = resolvePathWithinRoot(
62
- rootPath,
63
- path.resolve(directoryPath, target),
64
- );
65
- const resolvedStat = await stat(resolvedPath);
66
-
67
- if (resolvedStat.isDirectory()) {
68
- await addDirectory(packer, rootPath, resolvedPath, tarPath);
69
- } else if (resolvedStat.isFile()) {
70
- await addFile(packer, rootPath, resolvedPath, tarPath, resolvedStat);
71
- }
59
+ const linkStat = await lstat(fullPath);
60
+ await addSymlink(packer, rootPath, fullPath, tarPath, linkStat);
72
61
  } else if (entry.isDirectory()) {
73
62
  await addDirectory(packer, rootPath, fullPath, tarPath);
74
63
  } else if (entry.isFile()) {
@@ -98,6 +87,66 @@ async function addFile(
98
87
  );
99
88
  }
100
89
 
90
+ async function addSymlink(
91
+ packer: Pack,
92
+ rootPath: string,
93
+ fsPath: string,
94
+ tarPath: string,
95
+ linkStat: { mode: number; mtime: Date },
96
+ ): Promise<void> {
97
+ const symlinkPath = resolvePathWithinRoot(rootPath, fsPath);
98
+ const target = await readlink(symlinkPath);
99
+ const linkname = await resolveArchiveSymlinkTarget(
100
+ rootPath,
101
+ symlinkPath,
102
+ target,
103
+ );
104
+
105
+ packer.entry({
106
+ name: tarPath,
107
+ type: "symlink",
108
+ linkname,
109
+ mode: linkStat.mode,
110
+ mtime: linkStat.mtime,
111
+ });
112
+ }
113
+
114
+ async function resolveArchiveSymlinkTarget(
115
+ rootPath: string,
116
+ symlinkPath: string,
117
+ target: string,
118
+ ): Promise<string> {
119
+ const symlinkDir = path.dirname(symlinkPath);
120
+ const resolvedTarget = resolvePathWithinRoot(
121
+ rootPath,
122
+ path.isAbsolute(target) ? target : path.resolve(symlinkDir, target),
123
+ );
124
+
125
+ await lstat(resolvedTarget).catch((error) => {
126
+ if (isENOENT(error)) {
127
+ throw new Error(
128
+ `Symlink target does not exist: ${symlinkPath} -> ${target} (resolved to ${resolvedTarget})`,
129
+ );
130
+ }
131
+
132
+ throw error;
133
+ });
134
+
135
+ if (!path.isAbsolute(target)) {
136
+ return target;
137
+ }
138
+
139
+ return path.relative(symlinkDir, resolvedTarget) || ".";
140
+ }
141
+
142
+ function isENOENT(error: unknown): boolean {
143
+ return (
144
+ error instanceof Error &&
145
+ "code" in error &&
146
+ (error as { code?: string }).code === "ENOENT"
147
+ );
148
+ }
149
+
101
150
  function resolvePathWithinRoot(rootPath: string, fsPath: string): string {
102
151
  const normalizedRootPath = path.resolve(rootPath);
103
152
  const resolvedPath = path.resolve(fsPath);
@@ -1,4 +1,4 @@
1
- import { cp, mkdtemp, rm, stat } from "node:fs/promises";
1
+ import { cp, mkdtemp, readdir, rm, stat } from "node:fs/promises";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
4
  import type { BuildArtifact, BuildStrategy } from "./build-strategy.ts";
@@ -61,9 +61,20 @@ export class NextjsBuild implements BuildStrategy {
61
61
  verbatimSymlinks: true,
62
62
  });
63
63
 
64
+ // In monorepos, Next preserves the workspace-relative path from the
65
+ // workspace root down to the app, so server.js lands at e.g.
66
+ // .next/standalone/apps/web/server.js, not at the standalone root.
67
+ // The runtime needs the correct entrypoint, and Next expects public/
68
+ // and .next/static/ to be siblings of server.js.
69
+ const serverSubpath = await findServerSubpath(artifactDir);
70
+ const serverDir =
71
+ serverSubpath === undefined
72
+ ? artifactDir
73
+ : path.join(artifactDir, serverSubpath);
74
+
64
75
  const publicDir = path.join(this.#appPath, "public");
65
76
  if (await directoryExists(publicDir)) {
66
- await cp(publicDir, path.join(artifactDir, "public"), {
77
+ await cp(publicDir, path.join(serverDir, "public"), {
67
78
  recursive: true,
68
79
  verbatimSymlinks: true,
69
80
  });
@@ -71,15 +82,20 @@ export class NextjsBuild implements BuildStrategy {
71
82
 
72
83
  const staticDir = path.join(this.#appPath, ".next", "static");
73
84
  if (await directoryExists(staticDir)) {
74
- await cp(staticDir, path.join(artifactDir, ".next", "static"), {
85
+ await cp(staticDir, path.join(serverDir, ".next", "static"), {
75
86
  recursive: true,
76
87
  verbatimSymlinks: true,
77
88
  });
78
89
  }
79
90
 
91
+ const entrypoint =
92
+ serverSubpath === undefined
93
+ ? "server.js"
94
+ : path.posix.join(serverSubpath, "server.js");
95
+
80
96
  return {
81
97
  directory: artifactDir,
82
- entrypoint: "server.js",
98
+ entrypoint,
83
99
  defaultPortMapping: { http: 3000 },
84
100
  cleanup: () => rm(outDir, { recursive: true, force: true }),
85
101
  };
@@ -94,3 +110,51 @@ async function directoryExists(dirPath: string): Promise<boolean> {
94
110
  const s = await stat(dirPath).catch(() => null);
95
111
  return s?.isDirectory() ?? false;
96
112
  }
113
+
114
+ /**
115
+ * Scan the Next.js standalone output to find the directory that contains
116
+ * server.js, relative to the standalone root. Returns undefined when
117
+ * server.js is at the root (single-app repos) and a posix-joined subpath
118
+ * like "apps/web" for monorepos. node_modules is skipped because
119
+ * third-party packages may ship a file named server.js.
120
+ */
121
+ async function findServerSubpath(
122
+ standaloneDir: string,
123
+ ): Promise<string | undefined> {
124
+ const matches: (string | undefined)[] = [];
125
+
126
+ async function walk(
127
+ currentDir: string,
128
+ relative: string | undefined,
129
+ ): Promise<void> {
130
+ const entries = await readdir(currentDir, { withFileTypes: true });
131
+ for (const entry of entries) {
132
+ if (entry.name === "node_modules") continue;
133
+ const fullPath = path.join(currentDir, entry.name);
134
+ if (entry.isDirectory()) {
135
+ const nextRelative =
136
+ relative === undefined
137
+ ? entry.name
138
+ : path.posix.join(relative, entry.name);
139
+ await walk(fullPath, nextRelative);
140
+ } else if (entry.isFile() && entry.name === "server.js") {
141
+ matches.push(relative);
142
+ }
143
+ }
144
+ }
145
+
146
+ await walk(standaloneDir, undefined);
147
+
148
+ if (matches.length > 1) {
149
+ const locations = matches.map((m) => m ?? "<root>").join(", ");
150
+ throw new Error(
151
+ `Next.js standalone output has multiple server.js files (${locations}). Cannot determine the application entrypoint.`,
152
+ );
153
+ }
154
+ if (matches.length === 0) {
155
+ throw new Error(
156
+ "Next.js standalone output is missing server.js. The build may not have completed successfully.",
157
+ );
158
+ }
159
+ return matches[0];
160
+ }