@sntlr/registry-shell 1.1.1 → 1.1.2

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/cli/build.js CHANGED
@@ -1,12 +1,17 @@
1
1
  /**
2
2
  * `registry-shell build` — run `next build` against the user's project.
3
3
  *
4
- * Writes the Next build output to `<user-project>/.next` via `distDir` so
5
- * generic Next.js hosts (Vercel, self-hosted) find it where they expect.
6
- * Without this, the output would land inside
7
- * `node_modules/@sntlr/registry-shell/src/next-app/.next` and no external
8
- * host could discover it.
4
+ * Strategy: `next build` writes to its default `<next-project>/.next`
5
+ * location (inside our node_modules). After a successful build, MOVE that
6
+ * directory to `<user-project>/<paths.buildOutput ?? ".next">`.
7
+ *
8
+ * Why not use Next's `distDir` config? Next silently ignores absolute
9
+ * paths that point outside the Next project dir (the output ends up back
10
+ * in the default location). The env-var approach we tried first worked
11
+ * locally on Windows but failed on Vercel. A post-build move is
12
+ * platform-independent.
9
13
  */
14
+ import fs from "node:fs";
10
15
  import path from "node:path";
11
16
  import { spawn } from "node:child_process";
12
17
  import { NEXT_BIN, buildEnvVars, clearStaleNextCacheIfModeChanged, loadUserConfig, nextAppDir, writeUserSourcesCss, } from "./shared.js";
@@ -14,18 +19,40 @@ export async function run(args) {
14
19
  const loaded = loadUserConfig();
15
20
  clearStaleNextCacheIfModeChanged(loaded);
16
21
  writeUserSourcesCss(loaded);
17
- const userDistDir = loaded
18
- ? path.resolve(loaded.root, loaded.config.paths?.buildOutput ?? ".next")
19
- : undefined;
20
- const env = {
21
- ...process.env,
22
- ...buildEnvVars(loaded),
23
- ...(userDistDir ? { USER_DIST_DIR: userDistDir } : {}),
24
- };
25
- const child = spawn(process.execPath, [NEXT_BIN, "build", nextAppDir(), ...args], {
26
- stdio: "inherit",
27
- env,
22
+ const shellNextApp = nextAppDir();
23
+ const env = { ...process.env, ...buildEnvVars(loaded) };
24
+ const child = spawn(process.execPath, [NEXT_BIN, "build", shellNextApp, ...args], { stdio: "inherit", env });
25
+ child.on("exit", (code) => {
26
+ if (code !== 0) {
27
+ process.exit(code ?? 1);
28
+ }
29
+ if (loaded)
30
+ relocateBuildOutput(shellNextApp, loaded.root, loaded.config.paths?.buildOutput);
31
+ process.exit(0);
28
32
  });
29
- child.on("exit", (code) => process.exit(code ?? 0));
33
+ }
34
+ /**
35
+ * Moves `<shellNextApp>/.next` → `<userRoot>/<outputName ?? ".next">`.
36
+ * Idempotent: removes stale destination first. Noop if source is missing
37
+ * (e.g. Next's distDir *did* happen to work) or source and dest are the
38
+ * same path.
39
+ */
40
+ function relocateBuildOutput(shellNextApp, userRoot, outputName) {
41
+ const src = path.join(shellNextApp, ".next");
42
+ const dest = path.resolve(userRoot, outputName ?? ".next");
43
+ if (src === dest)
44
+ return;
45
+ if (!fs.existsSync(src))
46
+ return;
47
+ if (fs.existsSync(dest)) {
48
+ fs.rmSync(dest, {
49
+ recursive: true,
50
+ force: true,
51
+ maxRetries: 5,
52
+ retryDelay: 200,
53
+ });
54
+ }
55
+ fs.renameSync(src, dest);
56
+ console.log(`[registry-shell] Build output moved to ${dest}`);
30
57
  }
31
58
  //# sourceMappingURL=build.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,gCAAgC,EAChC,cAAc,EACd,UAAU,EACV,mBAAmB,GACpB,MAAM,aAAa,CAAA;AAEpB,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;IAC/B,gCAAgC,CAAC,MAAM,CAAC,CAAA;IACxC,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAC3B,MAAM,WAAW,GAAG,MAAM;QACxB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,IAAI,OAAO,CAAC;QACxE,CAAC,CAAC,SAAS,CAAA;IACb,MAAM,GAAG,GAAG;QACV,GAAG,OAAO,CAAC,GAAG;QACd,GAAG,YAAY,CAAC,MAAM,CAAC;QACvB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvD,CAAA;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE;QAChF,KAAK,EAAE,SAAS;QAChB,GAAG;KACJ,CAAC,CAAA;IACF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAA;AACrD,CAAC"}
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,gCAAgC,EAChC,cAAc,EACd,UAAU,EACV,mBAAmB,GACpB,MAAM,aAAa,CAAA;AAEpB,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;IAC/B,gCAAgC,CAAC,MAAM,CAAC,CAAA;IACxC,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAE3B,MAAM,YAAY,GAAG,UAAU,EAAE,CAAA;IACjC,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,EAAE,CAAA;IACvD,MAAM,KAAK,GAAG,KAAK,CACjB,OAAO,CAAC,QAAQ,EAChB,CAAC,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,EAC1C,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,CAC1B,CAAA;IAED,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACxB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAA;QACzB,CAAC;QACD,IAAI,MAAM;YAAE,mBAAmB,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;QAC5F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAC1B,YAAoB,EACpB,QAAgB,EAChB,UAA8B;IAE9B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,IAAI,OAAO,CAAC,CAAA;IAC1D,IAAI,GAAG,KAAK,IAAI;QAAE,OAAM;IACxB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAM;IAE/B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE;YACd,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,IAAI;YACX,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,GAAG;SAChB,CAAC,CAAA;IACJ,CAAC;IACD,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACxB,OAAO,CAAC,GAAG,CAAC,0CAA0C,IAAI,EAAE,CAAC,CAAA;AAC/D,CAAC"}
package/dist/cli/start.js CHANGED
@@ -1,24 +1,47 @@
1
1
  /**
2
2
  * `registry-shell start` — run `next start` for a prior `registry-shell build`.
3
3
  *
4
- * Mirrors build.ts: passes `USER_DIST_DIR` pointing at `<user-project>/.next`
5
- * so `next start` reads the build output from where build.ts wrote it.
4
+ * Build writes `.next/` to the user's project root (so Vercel / Netlify /
5
+ * generic Next hosts find it). `next start` expects it at its default
6
+ * location inside the Next project dir. Move it back before starting.
7
+ * Safe to run even if the move has already happened on a prior start.
6
8
  */
9
+ import fs from "node:fs";
7
10
  import path from "node:path";
8
11
  import { spawn } from "node:child_process";
9
12
  import { NEXT_BIN, buildEnvVars, loadUserConfig, nextAppDir } from "./shared.js";
10
13
  export async function run(args) {
11
14
  const loaded = loadUserConfig();
12
- const userDistDir = loaded
13
- ? path.resolve(loaded.root, loaded.config.paths?.buildOutput ?? ".next")
14
- : undefined;
15
- const env = {
16
- ...process.env,
17
- ...buildEnvVars(loaded),
18
- ...(userDistDir ? { USER_DIST_DIR: userDistDir } : {}),
19
- };
15
+ const env = { ...process.env, ...buildEnvVars(loaded) };
20
16
  const portArgs = loaded?.config.port ? ["-p", String(loaded.config.port)] : [];
21
- const child = spawn(process.execPath, [NEXT_BIN, "start", nextAppDir(), ...portArgs, ...args], { stdio: "inherit", env });
17
+ const shellNextApp = nextAppDir();
18
+ if (loaded) {
19
+ restoreBuildOutput(shellNextApp, loaded.root, loaded.config.paths?.buildOutput);
20
+ }
21
+ const child = spawn(process.execPath, [NEXT_BIN, "start", shellNextApp, ...portArgs, ...args], { stdio: "inherit", env });
22
22
  child.on("exit", (code) => process.exit(code ?? 0));
23
23
  }
24
+ /**
25
+ * Inverse of build.ts's relocation: moves `<userRoot>/<buildOutput>` back
26
+ * to `<shellNextApp>/.next` so `next start` can find it. Noop when the
27
+ * user-side `.next` is missing — we assume they ran `registry-shell start`
28
+ * against a shell-side build or are otherwise in a good state.
29
+ */
30
+ function restoreBuildOutput(shellNextApp, userRoot, outputName) {
31
+ const dest = path.join(shellNextApp, ".next");
32
+ const src = path.resolve(userRoot, outputName ?? ".next");
33
+ if (src === dest)
34
+ return;
35
+ if (!fs.existsSync(src))
36
+ return;
37
+ if (fs.existsSync(dest)) {
38
+ fs.rmSync(dest, {
39
+ recursive: true,
40
+ force: true,
41
+ maxRetries: 5,
42
+ retryDelay: 200,
43
+ });
44
+ }
45
+ fs.renameSync(src, dest);
46
+ }
24
47
  //# sourceMappingURL=start.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAEhF,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;IAC/B,MAAM,WAAW,GAAG,MAAM;QACxB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,IAAI,OAAO,CAAC;QACxE,CAAC,CAAC,SAAS,CAAA;IACb,MAAM,GAAG,GAAG;QACV,GAAG,OAAO,CAAC,GAAG;QACd,GAAG,YAAY,CAAC,MAAM,CAAC;QACvB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvD,CAAA;IACD,MAAM,QAAQ,GAAG,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9E,MAAM,KAAK,GAAG,KAAK,CACjB,OAAO,CAAC,QAAQ,EAChB,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC,EACvD,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,CAC1B,CAAA;IACD,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAA;AACrD,CAAC"}
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAEhF,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;IAC/B,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,EAAE,CAAA;IACvD,MAAM,QAAQ,GAAG,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9E,MAAM,YAAY,GAAG,UAAU,EAAE,CAAA;IAEjC,IAAI,MAAM,EAAE,CAAC;QACX,kBAAkB,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;IACjF,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CACjB,OAAO,CAAC,QAAQ,EAChB,CAAC,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC,EACvD,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,CAC1B,CAAA;IACD,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAA;AACrD,CAAC;AAED;;;;;GAKG;AACH,SAAS,kBAAkB,CACzB,YAAoB,EACpB,QAAgB,EAChB,UAA8B;IAE9B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;IAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,IAAI,OAAO,CAAC,CAAA;IACzD,IAAI,GAAG,KAAK,IAAI;QAAE,OAAM;IACxB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAM;IAE/B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE;YACd,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,IAAI;YACX,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,GAAG;SAChB,CAAC,CAAA;IACJ,CAAC;IACD,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;AAC1B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sntlr/registry-shell",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Generic Next.js viewer for component registries. Drop a registry-shell.config.ts into your registry and get a full docs/components/blocks site on localhost:3000.",
5
5
  "keywords": [
6
6
  "shadcn",
package/src/cli/build.ts CHANGED
@@ -1,12 +1,17 @@
1
1
  /**
2
2
  * `registry-shell build` — run `next build` against the user's project.
3
3
  *
4
- * Writes the Next build output to `<user-project>/.next` via `distDir` so
5
- * generic Next.js hosts (Vercel, self-hosted) find it where they expect.
6
- * Without this, the output would land inside
7
- * `node_modules/@sntlr/registry-shell/src/next-app/.next` and no external
8
- * host could discover it.
4
+ * Strategy: `next build` writes to its default `<next-project>/.next`
5
+ * location (inside our node_modules). After a successful build, MOVE that
6
+ * directory to `<user-project>/<paths.buildOutput ?? ".next">`.
7
+ *
8
+ * Why not use Next's `distDir` config? Next silently ignores absolute
9
+ * paths that point outside the Next project dir (the output ends up back
10
+ * in the default location). The env-var approach we tried first worked
11
+ * locally on Windows but failed on Vercel. A post-build move is
12
+ * platform-independent.
9
13
  */
14
+ import fs from "node:fs"
10
15
  import path from "node:path"
11
16
  import { spawn } from "node:child_process"
12
17
  import {
@@ -22,17 +27,48 @@ export async function run(args: string[]): Promise<void> {
22
27
  const loaded = loadUserConfig()
23
28
  clearStaleNextCacheIfModeChanged(loaded)
24
29
  writeUserSourcesCss(loaded)
25
- const userDistDir = loaded
26
- ? path.resolve(loaded.root, loaded.config.paths?.buildOutput ?? ".next")
27
- : undefined
28
- const env = {
29
- ...process.env,
30
- ...buildEnvVars(loaded),
31
- ...(userDistDir ? { USER_DIST_DIR: userDistDir } : {}),
32
- }
33
- const child = spawn(process.execPath, [NEXT_BIN, "build", nextAppDir(), ...args], {
34
- stdio: "inherit",
35
- env,
30
+
31
+ const shellNextApp = nextAppDir()
32
+ const env = { ...process.env, ...buildEnvVars(loaded) }
33
+ const child = spawn(
34
+ process.execPath,
35
+ [NEXT_BIN, "build", shellNextApp, ...args],
36
+ { stdio: "inherit", env },
37
+ )
38
+
39
+ child.on("exit", (code) => {
40
+ if (code !== 0) {
41
+ process.exit(code ?? 1)
42
+ }
43
+ if (loaded) relocateBuildOutput(shellNextApp, loaded.root, loaded.config.paths?.buildOutput)
44
+ process.exit(0)
36
45
  })
37
- child.on("exit", (code) => process.exit(code ?? 0))
46
+ }
47
+
48
+ /**
49
+ * Moves `<shellNextApp>/.next` → `<userRoot>/<outputName ?? ".next">`.
50
+ * Idempotent: removes stale destination first. Noop if source is missing
51
+ * (e.g. Next's distDir *did* happen to work) or source and dest are the
52
+ * same path.
53
+ */
54
+ function relocateBuildOutput(
55
+ shellNextApp: string,
56
+ userRoot: string,
57
+ outputName: string | undefined,
58
+ ): void {
59
+ const src = path.join(shellNextApp, ".next")
60
+ const dest = path.resolve(userRoot, outputName ?? ".next")
61
+ if (src === dest) return
62
+ if (!fs.existsSync(src)) return
63
+
64
+ if (fs.existsSync(dest)) {
65
+ fs.rmSync(dest, {
66
+ recursive: true,
67
+ force: true,
68
+ maxRetries: 5,
69
+ retryDelay: 200,
70
+ })
71
+ }
72
+ fs.renameSync(src, dest)
73
+ console.log(`[registry-shell] Build output moved to ${dest}`)
38
74
  }
package/src/cli/start.ts CHANGED
@@ -1,28 +1,57 @@
1
1
  /**
2
2
  * `registry-shell start` — run `next start` for a prior `registry-shell build`.
3
3
  *
4
- * Mirrors build.ts: passes `USER_DIST_DIR` pointing at `<user-project>/.next`
5
- * so `next start` reads the build output from where build.ts wrote it.
4
+ * Build writes `.next/` to the user's project root (so Vercel / Netlify /
5
+ * generic Next hosts find it). `next start` expects it at its default
6
+ * location inside the Next project dir. Move it back before starting.
7
+ * Safe to run even if the move has already happened on a prior start.
6
8
  */
9
+ import fs from "node:fs"
7
10
  import path from "node:path"
8
11
  import { spawn } from "node:child_process"
9
12
  import { NEXT_BIN, buildEnvVars, loadUserConfig, nextAppDir } from "./shared.js"
10
13
 
11
14
  export async function run(args: string[]): Promise<void> {
12
15
  const loaded = loadUserConfig()
13
- const userDistDir = loaded
14
- ? path.resolve(loaded.root, loaded.config.paths?.buildOutput ?? ".next")
15
- : undefined
16
- const env = {
17
- ...process.env,
18
- ...buildEnvVars(loaded),
19
- ...(userDistDir ? { USER_DIST_DIR: userDistDir } : {}),
20
- }
16
+ const env = { ...process.env, ...buildEnvVars(loaded) }
21
17
  const portArgs = loaded?.config.port ? ["-p", String(loaded.config.port)] : []
18
+ const shellNextApp = nextAppDir()
19
+
20
+ if (loaded) {
21
+ restoreBuildOutput(shellNextApp, loaded.root, loaded.config.paths?.buildOutput)
22
+ }
23
+
22
24
  const child = spawn(
23
25
  process.execPath,
24
- [NEXT_BIN, "start", nextAppDir(), ...portArgs, ...args],
26
+ [NEXT_BIN, "start", shellNextApp, ...portArgs, ...args],
25
27
  { stdio: "inherit", env },
26
28
  )
27
29
  child.on("exit", (code) => process.exit(code ?? 0))
28
30
  }
31
+
32
+ /**
33
+ * Inverse of build.ts's relocation: moves `<userRoot>/<buildOutput>` back
34
+ * to `<shellNextApp>/.next` so `next start` can find it. Noop when the
35
+ * user-side `.next` is missing — we assume they ran `registry-shell start`
36
+ * against a shell-side build or are otherwise in a good state.
37
+ */
38
+ function restoreBuildOutput(
39
+ shellNextApp: string,
40
+ userRoot: string,
41
+ outputName: string | undefined,
42
+ ): void {
43
+ const dest = path.join(shellNextApp, ".next")
44
+ const src = path.resolve(userRoot, outputName ?? ".next")
45
+ if (src === dest) return
46
+ if (!fs.existsSync(src)) return
47
+
48
+ if (fs.existsSync(dest)) {
49
+ fs.rmSync(dest, {
50
+ recursive: true,
51
+ force: true,
52
+ maxRetries: 5,
53
+ retryDelay: 200,
54
+ })
55
+ }
56
+ fs.renameSync(src, dest)
57
+ }
@@ -98,9 +98,10 @@ export interface BrandingConfig {
98
98
  }
99
99
 
100
100
  /**
101
- * The complete server-side contract the shell consumes. A registry package
102
- * implements this (typically in `adapter.ts`) and the shell imports the
103
- * default export via `ui-registry/registry.config.ts`.
101
+ * The complete server-side contract the shell consumes. The default
102
+ * (convention-based) implementation lives in `src/adapter/default.ts`;
103
+ * registries can override specific methods via a custom adapter module
104
+ * pointed at by `adapter` in their `registry-shell.config.ts`.
104
105
  *
105
106
  * All filesystem reads, registry-JSON serving, and MDX parsing live here —
106
107
  * the shell never touches the registry's files directly. This is what makes
@@ -45,15 +45,8 @@ function resolveUserModule(relativePath: string, fallback: string): string {
45
45
 
46
46
  const USER_PREVIEWS = resolveUserModule("components/previews", "fallback/previews.ts")
47
47
 
48
- // The CLI's `build` / `start` commands set USER_DIST_DIR to
49
- // `<user-project>/.next` so Next writes its output (and reads it back on
50
- // start) at the user's project root, not inside node_modules. Absolute
51
- // path — Next accepts that for `distDir`.
52
- const USER_DIST_DIR = process.env.USER_DIST_DIR
53
-
54
48
  const nextConfig: NextConfig = {
55
49
  output: process.env.BUILD_STANDALONE === "true" ? "standalone" : undefined,
56
- ...(USER_DIST_DIR ? { distDir: toPosix(USER_DIST_DIR) } : {}),
57
50
 
58
51
  // When installed as an external package (link:../registry-shell, npm, etc.),
59
52
  // the shell's TSX lives under the user's node_modules and Next won't