@mintlify/previewing 4.0.1519 → 4.0.1521

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.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,101 @@
1
+ import fse from 'fs-extra';
2
+ import os from 'os';
3
+ import path from 'path';
4
+ import { rewriteCssUrls } from '../local-preview/export-assets.js';
5
+ import { applyBasePathToExport, findBasePathConflict, normalizeExportBasePath, prefixNextAssetPaths, prefixNextStaticPaths, prefixNextStaticPathsInPayload, } from '../local-preview/export-base-path.js';
6
+ import { generateExportLlmsTxt } from '../local-preview/export-llms.js';
7
+ const push = (payload) => `<script>self.__next_f.push(${JSON.stringify([1, payload])})</script>`;
8
+ const readPayload = (html) => [...html.matchAll(/self\.__next_f\.push\((\[1,".*?"\])\)<\/script>/g)]
9
+ .map((match) => {
10
+ const parsed = JSON.parse(match[1] ?? '');
11
+ return Array.isArray(parsed) && typeof parsed[1] === 'string' ? parsed[1] : '';
12
+ })
13
+ .join('');
14
+ describe('normalizeExportBasePath', () => {
15
+ it.each([
16
+ [undefined, ''],
17
+ ['', ''],
18
+ ['/', ''],
19
+ ['docs', '/docs'],
20
+ ['/docs/', '/docs'],
21
+ ['/docs/v1', '/docs/v1'],
22
+ ])('normalizes %s to %s', (input, expected) => {
23
+ expect(normalizeExportBasePath(input)).toBe(expected);
24
+ });
25
+ it.each(['/docs/../etc', '/docs//v1', '/docs?x=1', '/my docs', '/do"cs'])('rejects %s', (input) => {
26
+ expect(() => normalizeExportBasePath(input)).toThrow('invalid base path');
27
+ });
28
+ });
29
+ describe('findBasePathConflict', () => {
30
+ it('returns the first page that starts with the base path', () => {
31
+ expect(findBasePathConflict(['/', '/quickstart', '/docs/intro'], '/docs')).toBe('/docs/intro');
32
+ expect(findBasePathConflict(['/', '/docs'], '/docs')).toBe('/docs');
33
+ });
34
+ it('ignores pages that only share a prefix, and exports without a base path', () => {
35
+ expect(findBasePathConflict(['/docsearch', '/guides/docs'], '/docs')).toBeUndefined();
36
+ expect(findBasePathConflict(['/docs/intro'], '')).toBeUndefined();
37
+ });
38
+ });
39
+ describe('prefixNextAssetPaths', () => {
40
+ it('prefixes chunk base and asset literals but not runtime concatenations', () => {
41
+ const source = 'let t="/_next/",r=1;e.v("/_next/static/media/worker.js");x={path:"/_next/image"};let a=r.assetPrefix+"/_next/"+p';
42
+ expect(prefixNextAssetPaths(source, '/docs')).toBe('let t="/docs/_next/",r=1;e.v("/docs/_next/static/media/worker.js");x={path:"/docs/_next/image"};let a=r.assetPrefix+"/_next/"+p');
43
+ });
44
+ });
45
+ describe('prefixNextStaticPaths', () => {
46
+ it('prefixes static attributes and flight chunk lists but not escaped text', () => {
47
+ const html = [
48
+ '<script src="/_next/static/chunks/a.js" async=""></script>',
49
+ '<link rel="stylesheet" href="/docs/_next/static/css/b.css"/>',
50
+ push('9:I[123,["/_next/static/chunks/a.js","/_next/static/chunks/c.js"],"default"]\n'),
51
+ push('b:["$","code",null,{"children":"\\"/_next/static/chunks/escaped.js\\""}]\n'),
52
+ ].join('');
53
+ const result = prefixNextStaticPaths(html, '/docs');
54
+ expect(result).toContain('<script src="/docs/_next/static/chunks/a.js"');
55
+ expect(result).toContain('href="/docs/_next/static/css/b.css"');
56
+ const payload = readPayload(result);
57
+ expect(payload).toContain('9:I[123,["/docs/_next/static/chunks/a.js","/docs/_next/static/chunks/c.js"]');
58
+ expect(payload).toContain('\\"/_next/static/chunks/escaped.js\\"');
59
+ });
60
+ it('leaves html untouched without a base path', () => {
61
+ const html = '<script src="/_next/static/chunks/a.js"></script>' +
62
+ push('9:I[1,["/_next/static/chunks/a.js"]]\n');
63
+ expect(prefixNextStaticPaths(html, '')).toBe(html);
64
+ });
65
+ });
66
+ describe('prefixNextStaticPathsInPayload', () => {
67
+ it('prefixes chunk paths in a saved rsc payload but not escaped text', () => {
68
+ const payload = `1:I[123,["/_next/static/chunks/a.js"],"default"]\n3:["$","p",null,{"children":"\\"/_next/static/x.js\\""}]\n`;
69
+ expect(prefixNextStaticPathsInPayload(payload, '/docs')).toBe(payload.replace('["/_next/static/chunks/a.js"]', '["/docs/_next/static/chunks/a.js"]'));
70
+ expect(prefixNextStaticPathsInPayload(payload, '')).toBe(payload);
71
+ });
72
+ });
73
+ describe('applyBasePathToExport', () => {
74
+ let exportDir;
75
+ beforeEach(async () => {
76
+ exportDir = await fse.mkdtemp(path.join(os.tmpdir(), 'mint-export-base-path-test-'));
77
+ });
78
+ afterEach(async () => {
79
+ await fse.remove(exportDir);
80
+ });
81
+ it('patches html and turbopack chunks inside the export', async () => {
82
+ await fse.outputFile(path.join(exportDir, 'guides', 'index.html'), '<script src="/_next/static/chunks/a.js"></script>');
83
+ await fse.outputFile(path.join(exportDir, '_next', 'static', 'chunks', 'turbopack-1.js'), 'let t="/_next/";');
84
+ await fse.outputFile(path.join(exportDir, 'images', 'app.js'), 'let t="/_next/";');
85
+ await fse.outputFile(path.join(exportDir, 'guides', 'index.txt'), '1:I[1,["/_next/static/chunks/a.js"],"default"]\n');
86
+ await applyBasePathToExport(exportDir, '/docs');
87
+ await expect(fse.readFile(path.join(exportDir, 'guides', 'index.html'), 'utf8')).resolves.toBe('<script src="/docs/_next/static/chunks/a.js"></script>');
88
+ await expect(fse.readFile(path.join(exportDir, '_next', 'static', 'chunks', 'turbopack-1.js'), 'utf8')).resolves.toBe('let t="/docs/_next/";');
89
+ await expect(fse.readFile(path.join(exportDir, 'images', 'app.js'), 'utf8')).resolves.toBe('let t="/_next/";');
90
+ await expect(fse.readFile(path.join(exportDir, 'guides', 'index.txt'), 'utf8')).resolves.toBe('1:I[1,["/docs/_next/static/chunks/a.js"],"default"]\n');
91
+ });
92
+ });
93
+ describe('base path aware css and llms.txt', () => {
94
+ it('makes root-relative urls in local css relative to the stylesheet', () => {
95
+ const css = rewriteCssUrls('@font-face{src:url(/_next/static/media/inter.woff2)}', undefined, '/_next/static/chunks/app.css', () => undefined);
96
+ expect(css).toBe('@font-face{src:url(../media/inter.woff2)}');
97
+ });
98
+ it('prefixes llms.txt links with the base path', () => {
99
+ expect(generateExportLlmsTxt({ name: 'Conduit' }, [{ href: '/quickstart', title: 'Quickstart' }], ['/quickstart'], '/docs')).toBe('# Conduit\n\n## Docs\n\n- [Quickstart](/docs/quickstart)\n');
100
+ });
101
+ });
@@ -1,7 +1,7 @@
1
1
  import fse from 'fs-extra';
2
2
  import os from 'os';
3
3
  import path from 'path';
4
- import { generatePages, writeStaticUserInfo } from '../local-preview/export.js';
4
+ import { generatePages, withIndexRouteAliases, writeStaticUserInfo, } from '../local-preview/export.js';
5
5
  import { getGroupFilteredRoutes } from '../local-preview/getGroupFilteredRoutes.js';
6
6
  describe('getGroupFilteredRoutes', () => {
7
7
  it('prunes routes outside the selected groups', () => {
@@ -21,6 +21,20 @@ describe('getGroupFilteredRoutes', () => {
21
21
  expect(routes).toEqual(['/', '/index', '/quickstart', '/authenticated']);
22
22
  });
23
23
  });
24
+ describe('withIndexRouteAliases', () => {
25
+ it('adds the parent route for nested index pages', () => {
26
+ expect(withIndexRouteAliases(['/', '/index', '/agent/index', '/agent/slack'])).toEqual([
27
+ '/',
28
+ '/index',
29
+ '/agent/index',
30
+ '/agent',
31
+ '/agent/slack',
32
+ ]);
33
+ });
34
+ it('does not duplicate routes that are already listed', () => {
35
+ expect(withIndexRouteAliases(['/cli', '/cli/index'])).toEqual(['/cli', '/cli/index']);
36
+ });
37
+ });
24
38
  describe('generatePages', () => {
25
39
  let outputDir;
26
40
  beforeEach(async () => {
@@ -3,6 +3,7 @@ export type LocalizeAssetsResult = {
3
3
  downloaded: string[];
4
4
  failed: string[];
5
5
  };
6
+ export declare function walkFiles(dir: string): AsyncGenerator<string>;
6
7
  export declare function collectAssetPaths(exportDir: string): Promise<Set<string>>;
7
8
  export declare function rewriteCssUrls(css: string, cssUrl: string | undefined, cssAssetPath: string, onAsset: (assetPath: string) => void): string;
8
9
  export declare function localizeAssets(exportDir: string, fetchAsset?: FetchAsset): Promise<LocalizeAssetsResult>;
@@ -6,7 +6,7 @@ const ASSET_PATH_PATTERN = new RegExp(`${MINT_EXPORT_ASSETS_PREFIX.replace(/\//g
6
6
  const CSS_URL_PATTERN = /url\(\s*(['"]?)([^'")]+)\1\s*\)/g;
7
7
  const CODE_LANGUAGE_PATTERN = /\slanguage="([^"]+)"/g;
8
8
  const CONCURRENCY = 10;
9
- async function* walkFiles(dir) {
9
+ export async function* walkFiles(dir) {
10
10
  for (const entry of await fse.readdir(dir, { withFileTypes: true })) {
11
11
  const entryPath = path.join(dir, entry.name);
12
12
  if (entry.isDirectory()) {
@@ -54,6 +54,9 @@ export function rewriteCssUrls(css, cssUrl, cssAssetPath, onAsset) {
54
54
  return css.replace(CSS_URL_PATTERN, (match, quote, rawUrl) => {
55
55
  if (rawUrl.startsWith('data:') || rawUrl.startsWith('#'))
56
56
  return match;
57
+ if (!cssUrl && rawUrl.startsWith('/') && !rawUrl.startsWith('//')) {
58
+ return `url(${quote}${path.posix.relative(path.posix.dirname(cssAssetPath), rawUrl)}${quote})`;
59
+ }
57
60
  let absoluteUrl;
58
61
  try {
59
62
  absoluteUrl = new URL(rawUrl.startsWith('//') ? `https:${rawUrl}` : rawUrl, cssUrl).toString();
@@ -0,0 +1,6 @@
1
+ export declare function normalizeExportBasePath(value: string | undefined): string;
2
+ export declare const findBasePathConflict: (routes: string[], basePath: string) => string | undefined;
3
+ export declare const prefixNextAssetPaths: (source: string, basePath: string) => string;
4
+ export declare const prefixNextStaticPathsInPayload: (payload: string, basePath: string) => string;
5
+ export declare const prefixNextStaticPaths: (html: string, basePath: string) => string;
6
+ export declare function applyBasePathToExport(exportDir: string, basePath: string): Promise<void>;
@@ -0,0 +1,43 @@
1
+ import { normalizeBasePath } from '@mintlify/common';
2
+ import fse from 'fs-extra';
3
+ import path from 'path';
4
+ import { walkFiles } from './export-assets.js';
5
+ const CHUNK_BASE_PATH_PATTERN = /(?<=[=(,:]\s*)(["'])\/_next\//g;
6
+ const NEXT_STATIC_IN_PAYLOAD_PATTERN = /(?<!\\)"\/_next\/static\//g;
7
+ const NEXT_STATIC_IN_HTML_PATTERN = /(?<!\\)(\\?)"\/_next\/static\//g;
8
+ const BASE_PATH_PATTERN = /^(\/[\w-]+)+$/;
9
+ export function normalizeExportBasePath(value) {
10
+ const basePath = normalizeBasePath(value?.trim());
11
+ if (basePath && !BASE_PATH_PATTERN.test(basePath)) {
12
+ throw new Error(`invalid base path: ${value}`);
13
+ }
14
+ return basePath;
15
+ }
16
+ export const findBasePathConflict = (routes, basePath) => basePath
17
+ ? routes.find((route) => route === basePath || route.startsWith(`${basePath}/`))
18
+ : undefined;
19
+ export const prefixNextAssetPaths = (source, basePath) => source.replace(CHUNK_BASE_PATH_PATTERN, (_match, quote) => `${quote}${basePath}/_next/`);
20
+ export const prefixNextStaticPathsInPayload = (payload, basePath) => payload.replace(NEXT_STATIC_IN_PAYLOAD_PATTERN, `"${basePath}/_next/static/`);
21
+ export const prefixNextStaticPaths = (html, basePath) => html.replace(NEXT_STATIC_IN_HTML_PATTERN, `$1"${basePath}/_next/static/`);
22
+ export async function applyBasePathToExport(exportDir, basePath) {
23
+ const nextStaticDir = path.join(exportDir, '_next', 'static');
24
+ if (!basePath || !(await fse.pathExists(nextStaticDir)))
25
+ return;
26
+ for await (const file of walkFiles(exportDir)) {
27
+ if (file.endsWith('.html') || path.basename(file) === 'index.txt') {
28
+ const source = await fse.readFile(file, 'utf8');
29
+ const patched = file.endsWith('.html')
30
+ ? prefixNextStaticPaths(source, basePath)
31
+ : prefixNextStaticPathsInPayload(source, basePath);
32
+ if (patched !== source)
33
+ await fse.writeFile(file, patched, 'utf8');
34
+ continue;
35
+ }
36
+ if (!file.startsWith(nextStaticDir + path.sep) || !file.endsWith('.js'))
37
+ continue;
38
+ const source = await fse.readFile(file, 'utf8');
39
+ const patched = prefixNextAssetPaths(source, basePath);
40
+ if (patched !== source)
41
+ await fse.writeFile(file, patched, 'utf8');
42
+ }
43
+ }
@@ -1 +1 @@
1
- export declare function generateExportLlmsTxt(docsConfig: unknown, generatedNav: unknown, routes: string[]): string;
1
+ export declare function generateExportLlmsTxt(docsConfig: unknown, generatedNav: unknown, routes: string[], basePath?: string): string;
@@ -24,7 +24,7 @@ function collectPages(entry, pages) {
24
24
  }
25
25
  }
26
26
  const escapeLinkText = (text) => text.replace(/([[\]])/g, '\\$1');
27
- export function generateExportLlmsTxt(docsConfig, generatedNav, routes) {
27
+ export function generateExportLlmsTxt(docsConfig, generatedNav, routes, basePath = '') {
28
28
  const config = isRecord(docsConfig) ? docsConfig : {};
29
29
  const name = getString(config, 'name') ?? 'Documentation';
30
30
  const description = getString(config, 'description');
@@ -34,6 +34,6 @@ export function generateExportLlmsTxt(docsConfig, generatedNav, routes) {
34
34
  const exportedRoutes = new Set(routes);
35
35
  const lines = [...pages.values()]
36
36
  .filter((page) => exportedRoutes.has(page.href))
37
- .map((page) => `- [${escapeLinkText(page.title)}](${page.href})${page.description ? `: ${page.description}` : ''}\n`);
37
+ .map((page) => `- [${escapeLinkText(page.title)}](${basePath}${page.href})${page.description ? `: ${page.description}` : ''}\n`);
38
38
  return header + lines.join('');
39
39
  }
@@ -1,5 +1,6 @@
1
1
  import { ArgumentsCamelCase } from 'yargs';
2
+ export declare const withIndexRouteAliases: (routes: string[]) => string[];
2
3
  export declare function generatePages(baseUrl: string, routes: string[], outputDir: string, rootRoute?: string): Promise<number>;
3
4
  export declare function writeStaticUserInfo(tmpDir: string, groups: string[] | undefined): Promise<void>;
4
- export declare function writeLlmsTxt(tmpDir: string, routes: string[]): Promise<void>;
5
+ export declare function writeLlmsTxt(tmpDir: string, routes: string[], basePath?: string): Promise<void>;
5
6
  export declare const exportSite: (argv: ArgumentsCamelCase) => Promise<void>;
@@ -13,6 +13,7 @@ import { CLIENT_PATH, CMD_EXEC_PATH, VERSION_PATH, NEXT_PUBLIC_PATH, NEXT_PROPS_
13
13
  import { addLog, clearLogs } from '../logging-state.js';
14
14
  import { ErrorLog, SpinnerLog, SuccessLog, WarningLog } from '../logs.js';
15
15
  import { localizeAssets } from './export-assets.js';
16
+ import { applyBasePathToExport, findBasePathConflict, normalizeExportBasePath, } from './export-base-path.js';
16
17
  import { generateExportLlmsTxt } from './export-llms.js';
17
18
  import { getGroupFilteredRoutes } from './getGroupFilteredRoutes.js';
18
19
  import { setupNext } from './setupNext.js';
@@ -37,6 +38,10 @@ function prepareRoutesForExport(routes, groups) {
37
38
  rootRoute: firstAccessibleRoute,
38
39
  };
39
40
  }
41
+ const INDEX_SUFFIX = '/index';
42
+ export const withIndexRouteAliases = (routes) => [
43
+ ...new Set(routes.flatMap((route) => route.endsWith(INDEX_SUFFIX) ? [route, route.slice(0, -INDEX_SUFFIX.length) || '/'] : [route])),
44
+ ];
40
45
  async function withExportConsoleSilenced(task) {
41
46
  const originalConsole = {
42
47
  log: console.log,
@@ -122,9 +127,9 @@ export async function generatePages(baseUrl, routes, outputDir, rootRoute) {
122
127
  await Promise.all(Array.from({ length: Math.min(CONCURRENCY, routes.length) }, () => worker()));
123
128
  return failedPageCount;
124
129
  }
125
- async function startServer() {
130
+ async function startServer(basePath) {
126
131
  const app = express();
127
- const requestHandler = await setupNext();
132
+ const requestHandler = await setupNext(basePath ? { assetPrefix: basePath } : undefined);
128
133
  app.use('/', express.static(NEXT_PUBLIC_PATH));
129
134
  app.all('*', (req, res) => requestHandler(req, res));
130
135
  const server = createServer(app);
@@ -148,7 +153,7 @@ export async function writeStaticUserInfo(tmpDir, groups) {
148
153
  user: { groups },
149
154
  });
150
155
  }
151
- async function bundleStaticAssets(tmpDir, groups) {
156
+ async function bundleStaticAssets(tmpDir, groups, basePath) {
152
157
  const nextStaticSrc = path.join(CLIENT_PATH, '.next', 'static');
153
158
  if (await pathExists(nextStaticSrc)) {
154
159
  await fse.copy(nextStaticSrc, path.join(tmpDir, '_next', 'static'));
@@ -162,12 +167,13 @@ async function bundleStaticAssets(tmpDir, groups) {
162
167
  }
163
168
  }
164
169
  await writeStaticUserInfo(tmpDir, groups);
165
- await fse.copy(path.join(EXPORT_SCRIPTS_DIR, 'serve.js'), path.join(tmpDir, 'serve.js'));
170
+ const serveScript = await fse.readFile(path.join(EXPORT_SCRIPTS_DIR, 'serve.js'), 'utf8');
171
+ await fse.writeFile(path.join(tmpDir, 'serve.js'), serveScript.replace("const BASE_PATH = '';", `const BASE_PATH = ${JSON.stringify(basePath)};`));
166
172
  await fse.copy(path.join(EXPORT_SCRIPTS_DIR, 'README.md'), path.join(tmpDir, 'README.md'));
167
173
  await fse.copy(path.join(EXPORT_SCRIPTS_DIR, 'start-docs.sh'), path.join(tmpDir, 'Start Docs.command'));
168
174
  await fse.copy(path.join(EXPORT_SCRIPTS_DIR, 'start-docs.bat'), path.join(tmpDir, 'Start Docs.bat'));
169
175
  }
170
- export async function writeLlmsTxt(tmpDir, routes) {
176
+ export async function writeLlmsTxt(tmpDir, routes, basePath = '') {
171
177
  const llmsTxtPath = path.join(tmpDir, 'llms.txt');
172
178
  if (await pathExists(llmsTxtPath))
173
179
  return;
@@ -175,16 +181,17 @@ export async function writeLlmsTxt(tmpDir, routes) {
175
181
  fse.readJson(path.join(NEXT_PROPS_PATH, 'docs.json')).catch(() => undefined),
176
182
  fse.readJson(path.join(NEXT_PROPS_PATH, 'generatedDocsNav.json')).catch(() => undefined),
177
183
  ]);
178
- await fse.writeFile(llmsTxtPath, generateExportLlmsTxt(docsConfig, generatedNav, routes), 'utf8');
184
+ await fse.writeFile(llmsTxtPath, generateExportLlmsTxt(docsConfig, generatedNav, routes, basePath), 'utf8');
179
185
  }
180
186
  async function closeServer(server) {
181
187
  await new Promise((resolve) => {
182
188
  server.close(() => resolve());
183
189
  });
184
190
  }
185
- async function generateExportArchive(routes, outputPath, groups) {
186
- const { server, port } = await startServer();
187
- const { routes: routesToGenerate, rootRoute } = prepareRoutesForExport(routes, groups);
191
+ async function generateExportArchive(routes, outputPath, groups, basePath) {
192
+ const { server, port } = await startServer(basePath);
193
+ const { routes: preparedRoutes, rootRoute } = prepareRoutesForExport(routes, groups);
194
+ const routesToGenerate = withIndexRouteAliases(preparedRoutes);
188
195
  let tmpDir;
189
196
  try {
190
197
  clearLogs();
@@ -198,8 +205,9 @@ async function generateExportArchive(routes, outputPath, groups) {
198
205
  throw new Error(`failed to export: ${failedPageCount} page(s) could not be generated.`);
199
206
  }
200
207
  addLog(_jsx(SpinnerLog, { message: "collecting static assets..." }));
201
- await bundleStaticAssets(exportDir, groups);
202
- await writeLlmsTxt(exportDir, routes);
208
+ await bundleStaticAssets(exportDir, groups, basePath);
209
+ await applyBasePathToExport(exportDir, basePath);
210
+ await writeLlmsTxt(exportDir, routes, basePath);
203
211
  addLog(_jsx(SpinnerLog, { message: "bundling external assets..." }));
204
212
  const { failed } = await localizeAssets(exportDir);
205
213
  addLog(_jsx(SpinnerLog, { message: "creating zip archive..." }));
@@ -225,6 +233,13 @@ export const exportSite = async (argv) => {
225
233
  const clientVersion = argv['client-version'];
226
234
  const localClientVersion = argv['local-client-version'];
227
235
  const groups = argv.groups;
236
+ let basePath = '';
237
+ try {
238
+ basePath = normalizeExportBasePath(argv.basePath);
239
+ }
240
+ catch (err) {
241
+ await fatal(err instanceof Error ? err.message : 'invalid base path');
242
+ }
228
243
  const cliVersion = argv.cliVersion;
229
244
  const disableOpenApi = argv.disableOpenapi;
230
245
  const outputPath = path.resolve(argv.output);
@@ -268,10 +283,14 @@ export const exportSite = async (argv) => {
268
283
  catch (err) {
269
284
  await fatal(err instanceof Error && err.message ? err.message : 'failed to collect routes');
270
285
  }
286
+ const conflictingRoute = findBasePathConflict(routes, basePath);
287
+ if (conflictingRoute) {
288
+ await fatal(`--base-path ${basePath} conflicts with the page ${conflictingRoute}. Pages can't start with the base path, so pick a different one.`);
289
+ }
271
290
  addLog(_jsx(SpinnerLog, { message: "starting local server..." }));
272
- process.env.MINT_EXPORT = JSON.stringify({ groups });
291
+ process.env.MINT_EXPORT = JSON.stringify({ groups, basePath: basePath || undefined });
273
292
  try {
274
- await generateExportArchive(routes, outputPath, groups);
293
+ await generateExportArchive(routes, outputPath, groups, basePath);
275
294
  }
276
295
  catch (err) {
277
296
  await fatal(err instanceof Error && err.message ? err.message : 'export failed');
@@ -19,4 +19,6 @@
19
19
  *
20
20
  * @returns the request handler provided by next.js
21
21
  */
22
- export declare const setupNext: () => Promise<any>;
22
+ export declare const setupNext: ({ assetPrefix }?: {
23
+ assetPrefix?: string;
24
+ }) => Promise<any>;
@@ -22,7 +22,7 @@ import { CLIENT_PATH, NEXT_CONFIG_PATH, NEXT_ROUTER_SERVER_PATH, NEXT_SIDE_EFFEC
22
22
  *
23
23
  * @returns the request handler provided by next.js
24
24
  */
25
- export const setupNext = async () => {
25
+ export const setupNext = async ({ assetPrefix } = {}) => {
26
26
  const hostname = process.env.HOSTNAME || 'localhost';
27
27
  let config;
28
28
  try {
@@ -38,7 +38,7 @@ export const setupNext = async () => {
38
38
  }
39
39
  throw err;
40
40
  }
41
- process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(config);
41
+ process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(assetPrefix === undefined ? config : { ...config, assetPrefix });
42
42
  // The server.js provided by next.js's standalone build does a similar import of this file.
43
43
  // Not sure what side effects are being created, but want to change as little as possible.
44
44
  // Also, Windows requires us to use `pathToFileURL` (see #899)