@tanstack/start-plugin-core 1.120.4-alpha.14 → 1.120.4-alpha.15
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/cjs/nitro/nitro-plugin.cjs +36 -2
- package/dist/cjs/nitro/nitro-plugin.cjs.map +1 -1
- package/dist/cjs/plugin.d.cts +622 -0
- package/dist/cjs/prerender.cjs +22 -13
- package/dist/cjs/prerender.cjs.map +1 -1
- package/dist/cjs/schema.cjs +15 -1
- package/dist/cjs/schema.cjs.map +1 -1
- package/dist/cjs/schema.d.cts +2297 -520
- package/dist/esm/nitro/nitro-plugin.js +36 -2
- package/dist/esm/nitro/nitro-plugin.js.map +1 -1
- package/dist/esm/plugin.d.ts +622 -0
- package/dist/esm/prerender.js +22 -13
- package/dist/esm/prerender.js.map +1 -1
- package/dist/esm/schema.d.ts +2297 -520
- package/dist/esm/schema.js +15 -1
- package/dist/esm/schema.js.map +1 -1
- package/package.json +4 -4
- package/src/nitro/nitro-plugin.ts +40 -0
- package/src/prerender.ts +29 -17
- package/src/schema.ts +18 -0
package/dist/esm/schema.js
CHANGED
|
@@ -77,7 +77,8 @@ function createTanStackStartOptionsSchema(frameworkPlugin = {}) {
|
|
|
77
77
|
concurrency: z.number().optional(),
|
|
78
78
|
filter: z.function().args(pageSchema).returns(z.any()).optional(),
|
|
79
79
|
failOnError: z.boolean().optional()
|
|
80
|
-
}).and(pagePrerenderOptionsSchema.optional()).optional()
|
|
80
|
+
}).and(pagePrerenderOptionsSchema.optional()).optional(),
|
|
81
|
+
shell: shellSchema.optional()
|
|
81
82
|
}).optional().default({});
|
|
82
83
|
}
|
|
83
84
|
const pageSitemapOptionsSchema = z.object({
|
|
@@ -114,6 +115,7 @@ const pageBaseSchema = z.object({
|
|
|
114
115
|
});
|
|
115
116
|
const pagePrerenderOptionsSchema = z.object({
|
|
116
117
|
enabled: z.boolean().optional(),
|
|
118
|
+
outputPath: z.string().optional(),
|
|
117
119
|
autoSubfolderIndex: z.boolean().optional(),
|
|
118
120
|
crawlLinks: z.boolean().optional(),
|
|
119
121
|
retryCount: z.number().optional(),
|
|
@@ -125,6 +127,18 @@ const pagePrerenderOptionsSchema = z.object({
|
|
|
125
127
|
})
|
|
126
128
|
).returns(z.any()).optional()
|
|
127
129
|
});
|
|
130
|
+
const shellSchema = z.object({
|
|
131
|
+
enabled: z.boolean().optional().default(true),
|
|
132
|
+
maskPath: z.string().optional().default("/"),
|
|
133
|
+
autoRedirect: z.boolean().optional().default(true),
|
|
134
|
+
prerender: pagePrerenderOptionsSchema.optional().default({}).transform((opts) => ({
|
|
135
|
+
outputPath: opts.outputPath ?? "/_shell",
|
|
136
|
+
crawlLinks: false,
|
|
137
|
+
retryCount: 0,
|
|
138
|
+
...opts,
|
|
139
|
+
enabled: true
|
|
140
|
+
}))
|
|
141
|
+
});
|
|
128
142
|
const pageSchema = pageBaseSchema.extend({
|
|
129
143
|
prerender: pagePrerenderOptionsSchema.optional()
|
|
130
144
|
});
|
package/dist/esm/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sources":["../../src/schema.ts"],"sourcesContent":["import path from 'node:path'\nimport { existsSync } from 'node:fs'\nimport { z } from 'zod'\nimport { configSchema, getConfig } from '@tanstack/router-generator'\nimport type { NitroConfig } from 'nitropack'\n\nconst tsrConfig = configSchema.partial().extend({\n srcDirectory: z.string().optional().default('src'),\n})\n\nexport function createTanStackConfig<\n TFrameworkPlugin extends Record<string, unknown>,\n>(frameworkPlugin?: TFrameworkPlugin) {\n const schema = createTanStackStartOptionsSchema(frameworkPlugin)\n\n return {\n schema,\n parse: (opts?: z.input<typeof schema>) => {\n const options = schema.parse(opts)\n\n const srcDirectory = options.tsr.srcDirectory\n\n const routesDirectory =\n options.tsr.routesDirectory ?? path.join(srcDirectory, 'routes')\n\n const generatedRouteTree =\n options.tsr.generatedRouteTree ??\n path.join(srcDirectory, 'routeTree.gen.ts')\n\n const clientEntryPath = (() => {\n if (options.client.entry) {\n return path.join(srcDirectory, options.client.entry)\n }\n\n if (existsSync(path.join(srcDirectory, 'client.tsx'))) {\n return path.join(srcDirectory, 'client.tsx')\n }\n\n return '/~start/default-client-entry'\n })()\n\n const serverEntryPath = (() => {\n if (options.server.entry) {\n return path.join(srcDirectory, options.server.entry)\n }\n\n if (existsSync(path.join(srcDirectory, 'server.tsx'))) {\n return path.join(srcDirectory, 'server.tsx')\n }\n\n return '/~start/default-server-entry'\n })()\n\n return {\n ...options,\n tsr: {\n ...options.tsr,\n ...getConfig({\n ...options.tsr,\n routesDirectory,\n generatedRouteTree,\n }),\n },\n clientEntryPath,\n serverEntryPath,\n }\n },\n }\n}\n\nexport function createTanStackStartOptionsSchema(\n frameworkPlugin: Record<string, unknown> = {},\n) {\n return z\n .object({\n root: z.string().optional().default(process.cwd()),\n target: z.custom<NitroConfig['preset']>().optional(),\n ...frameworkPlugin,\n tsr: tsrConfig.optional().default({}),\n client: z\n .object({\n entry: z.string().optional(),\n base: z.string().optional().default('/_build'),\n })\n .optional()\n .default({}),\n server: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n serverFns: z\n .object({\n base: z.string().optional().default('/_server'),\n })\n .optional()\n .default({}),\n public: z\n .object({\n dir: z.string().optional().default('public'),\n base: z.string().optional().default('/'),\n })\n .optional()\n .default({}),\n pages: z\n .array(z.union([z.string(), pageSchema]))\n .optional()\n .default([]),\n sitemap: pagePrerenderOptionsSchema\n .extend({\n host: z.string().optional(),\n })\n .optional(),\n prerender: z\n .object({\n enabled: z.boolean().optional(),\n concurrency: z.number().optional(),\n filter: z.function().args(pageSchema).returns(z.any()).optional(),\n failOnError: z.boolean().optional(),\n })\n .and(pagePrerenderOptionsSchema.optional())\n .optional(),\n })\n .optional()\n .default({})\n}\n\nconst pageSitemapOptionsSchema = z.object({\n exclude: z.boolean().optional(),\n priority: z.number().min(0).max(1).optional(),\n changefreq: z\n .enum(['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'])\n .optional(),\n lastmod: z.union([z.string(), z.date()]).optional(),\n alternateRefs: z\n .array(\n z.object({\n href: z.string(),\n hreflang: z.string(),\n }),\n )\n .optional(),\n images: z\n .array(\n z.object({\n loc: z.string(),\n caption: z.string().optional(),\n title: z.string().optional(),\n }),\n )\n .optional(),\n news: z\n .object({\n publication: z.object({\n name: z.string(),\n language: z.string(),\n }),\n publicationDate: z.union([z.string(), z.date()]),\n title: z.string(),\n })\n .optional(),\n})\n\nconst pageBaseSchema = z.object({\n path: z.string(),\n sitemap: pageSitemapOptionsSchema.optional(),\n fromCrawl: z.boolean().optional(),\n})\n\nconst pagePrerenderOptionsSchema = z.object({\n enabled: z.boolean().optional(),\n autoSubfolderIndex: z.boolean().optional(),\n crawlLinks: z.boolean().optional(),\n retryCount: z.number().optional(),\n retryDelay: z.number().optional(),\n onSuccess: z\n .function()\n .args(\n z.object({\n page: pageBaseSchema,\n html: z.string(),\n }),\n )\n .returns(z.any())\n .optional(),\n})\n\nexport const pageSchema = pageBaseSchema.extend({\n prerender: pagePrerenderOptionsSchema.optional(),\n})\n\nexport type Page = z.infer<typeof pageSchema>\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"schema.js","sources":["../../src/schema.ts"],"sourcesContent":["import path from 'node:path'\nimport { existsSync } from 'node:fs'\nimport { z } from 'zod'\nimport { configSchema, getConfig } from '@tanstack/router-generator'\nimport type { NitroConfig } from 'nitropack'\n\nconst tsrConfig = configSchema.partial().extend({\n srcDirectory: z.string().optional().default('src'),\n})\n\nexport function createTanStackConfig<\n TFrameworkPlugin extends Record<string, unknown>,\n>(frameworkPlugin?: TFrameworkPlugin) {\n const schema = createTanStackStartOptionsSchema(frameworkPlugin)\n\n return {\n schema,\n parse: (opts?: z.input<typeof schema>) => {\n const options = schema.parse(opts)\n\n const srcDirectory = options.tsr.srcDirectory\n\n const routesDirectory =\n options.tsr.routesDirectory ?? path.join(srcDirectory, 'routes')\n\n const generatedRouteTree =\n options.tsr.generatedRouteTree ??\n path.join(srcDirectory, 'routeTree.gen.ts')\n\n const clientEntryPath = (() => {\n if (options.client.entry) {\n return path.join(srcDirectory, options.client.entry)\n }\n\n if (existsSync(path.join(srcDirectory, 'client.tsx'))) {\n return path.join(srcDirectory, 'client.tsx')\n }\n\n return '/~start/default-client-entry'\n })()\n\n const serverEntryPath = (() => {\n if (options.server.entry) {\n return path.join(srcDirectory, options.server.entry)\n }\n\n if (existsSync(path.join(srcDirectory, 'server.tsx'))) {\n return path.join(srcDirectory, 'server.tsx')\n }\n\n return '/~start/default-server-entry'\n })()\n\n return {\n ...options,\n tsr: {\n ...options.tsr,\n ...getConfig({\n ...options.tsr,\n routesDirectory,\n generatedRouteTree,\n }),\n },\n clientEntryPath,\n serverEntryPath,\n }\n },\n }\n}\n\nexport function createTanStackStartOptionsSchema(\n frameworkPlugin: Record<string, unknown> = {},\n) {\n return z\n .object({\n root: z.string().optional().default(process.cwd()),\n target: z.custom<NitroConfig['preset']>().optional(),\n ...frameworkPlugin,\n tsr: tsrConfig.optional().default({}),\n client: z\n .object({\n entry: z.string().optional(),\n base: z.string().optional().default('/_build'),\n })\n .optional()\n .default({}),\n server: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n serverFns: z\n .object({\n base: z.string().optional().default('/_server'),\n })\n .optional()\n .default({}),\n public: z\n .object({\n dir: z.string().optional().default('public'),\n base: z.string().optional().default('/'),\n })\n .optional()\n .default({}),\n pages: z\n .array(z.union([z.string(), pageSchema]))\n .optional()\n .default([]),\n sitemap: pagePrerenderOptionsSchema\n .extend({\n host: z.string().optional(),\n })\n .optional(),\n prerender: z\n .object({\n enabled: z.boolean().optional(),\n concurrency: z.number().optional(),\n filter: z.function().args(pageSchema).returns(z.any()).optional(),\n failOnError: z.boolean().optional(),\n })\n .and(pagePrerenderOptionsSchema.optional())\n .optional(),\n shell: shellSchema.optional(),\n })\n .optional()\n .default({})\n}\n\nconst pageSitemapOptionsSchema = z.object({\n exclude: z.boolean().optional(),\n priority: z.number().min(0).max(1).optional(),\n changefreq: z\n .enum(['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'])\n .optional(),\n lastmod: z.union([z.string(), z.date()]).optional(),\n alternateRefs: z\n .array(\n z.object({\n href: z.string(),\n hreflang: z.string(),\n }),\n )\n .optional(),\n images: z\n .array(\n z.object({\n loc: z.string(),\n caption: z.string().optional(),\n title: z.string().optional(),\n }),\n )\n .optional(),\n news: z\n .object({\n publication: z.object({\n name: z.string(),\n language: z.string(),\n }),\n publicationDate: z.union([z.string(), z.date()]),\n title: z.string(),\n })\n .optional(),\n})\n\nconst pageBaseSchema = z.object({\n path: z.string(),\n sitemap: pageSitemapOptionsSchema.optional(),\n fromCrawl: z.boolean().optional(),\n})\n\nconst pagePrerenderOptionsSchema = z.object({\n enabled: z.boolean().optional(),\n outputPath: z.string().optional(),\n autoSubfolderIndex: z.boolean().optional(),\n crawlLinks: z.boolean().optional(),\n retryCount: z.number().optional(),\n retryDelay: z.number().optional(),\n onSuccess: z\n .function()\n .args(\n z.object({\n page: pageBaseSchema,\n html: z.string(),\n }),\n )\n .returns(z.any())\n .optional(),\n})\n\nconst shellSchema = z.object({\n enabled: z.boolean().optional().default(true),\n maskPath: z.string().optional().default('/'),\n autoRedirect: z.boolean().optional().default(true),\n prerender: pagePrerenderOptionsSchema\n .optional()\n .default({})\n .transform((opts) => ({\n outputPath: opts.outputPath ?? '/_shell',\n crawlLinks: false,\n retryCount: 0,\n ...opts,\n enabled: true,\n })),\n})\n\nexport const pageSchema = pageBaseSchema.extend({\n prerender: pagePrerenderOptionsSchema.optional(),\n})\n\nexport type Page = z.infer<typeof pageSchema>\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/start-plugin-core",
|
|
3
|
-
"version": "1.120.4-alpha.
|
|
3
|
+
"version": "1.120.4-alpha.15",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -63,9 +63,9 @@
|
|
|
63
63
|
"ufo": "^1.5.4",
|
|
64
64
|
"xmlbuilder2": "^3.1.1",
|
|
65
65
|
"zod": "^3.24.2",
|
|
66
|
-
"@tanstack/router-
|
|
67
|
-
"@tanstack/router-
|
|
68
|
-
"@tanstack/router-
|
|
66
|
+
"@tanstack/router-core": "^1.120.4-alpha.15",
|
|
67
|
+
"@tanstack/router-utils": "^1.120.4-alpha.1",
|
|
68
|
+
"@tanstack/router-generator": "^1.120.4-alpha.15"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"vite": "^6.0.0"
|
|
@@ -80,12 +80,52 @@ export function nitroPlugin(
|
|
|
80
80
|
rollupConfig: {
|
|
81
81
|
plugins: [virtualBundlePlugin(getSsrBundle())],
|
|
82
82
|
},
|
|
83
|
+
routeRules: {
|
|
84
|
+
// TODO: We need to expose *some* kind of routeRules configuration
|
|
85
|
+
// and it needs to translate to this for now. But we should
|
|
86
|
+
// be cognizant of the probability that we will not use Nitro's
|
|
87
|
+
// routeRules configuration in the future.
|
|
88
|
+
...(options.shell?.enabled && options.shell.autoRedirect
|
|
89
|
+
? {
|
|
90
|
+
'/**': {
|
|
91
|
+
// @ts-expect-error We are using this as a marker
|
|
92
|
+
__TSS_SHELL: true,
|
|
93
|
+
redirect: {
|
|
94
|
+
to: `${options.shell.prerender.outputPath.replace(/[/]{1,}$/, '')}`,
|
|
95
|
+
statusCode: 200,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
: {}),
|
|
100
|
+
},
|
|
83
101
|
}
|
|
84
102
|
|
|
85
103
|
const nitro = await createNitro(nitroConfig)
|
|
86
104
|
|
|
87
105
|
await buildNitroEnvironment(nitro, () => build(nitro))
|
|
88
106
|
|
|
107
|
+
if (options.shell?.enabled) {
|
|
108
|
+
options.prerender = {
|
|
109
|
+
...options.prerender,
|
|
110
|
+
enabled: true,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const maskUrl = new URL(
|
|
114
|
+
options.shell.maskPath,
|
|
115
|
+
'http://localhost',
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
maskUrl.searchParams.set('__TSS_SHELL', 'true')
|
|
119
|
+
|
|
120
|
+
options.pages.push({
|
|
121
|
+
path: maskUrl.toString().replace('http://localhost', ''),
|
|
122
|
+
prerender: options.shell.prerender,
|
|
123
|
+
sitemap: {
|
|
124
|
+
exclude: true,
|
|
125
|
+
},
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
|
|
89
129
|
if (options.prerender?.enabled) {
|
|
90
130
|
await prerender({
|
|
91
131
|
options,
|
package/src/prerender.ts
CHANGED
|
@@ -20,7 +20,7 @@ export async function prerender({
|
|
|
20
20
|
nitro: Nitro
|
|
21
21
|
builder: ViteBuilder
|
|
22
22
|
}) {
|
|
23
|
-
|
|
23
|
+
console.info('Prendering pages...')
|
|
24
24
|
|
|
25
25
|
// If prerender is enabled but no pages are provided, default to prerendering the root page
|
|
26
26
|
if (options.prerender?.enabled && !options.pages.length) {
|
|
@@ -44,6 +44,14 @@ export async function prerender({
|
|
|
44
44
|
|
|
45
45
|
const nodeNitro = await createNitro({
|
|
46
46
|
...nitro.options._config,
|
|
47
|
+
routeRules: {
|
|
48
|
+
// Filter out our shell redirect rule if it exists
|
|
49
|
+
...Object.fromEntries(
|
|
50
|
+
Object.entries(nitro.options._config.routeRules ?? {}).filter(
|
|
51
|
+
([_, value]) => !(value as any).__TSS_SHELL,
|
|
52
|
+
),
|
|
53
|
+
),
|
|
54
|
+
},
|
|
47
55
|
preset: 'nitro-prerender',
|
|
48
56
|
logLevel: 0,
|
|
49
57
|
output: {
|
|
@@ -90,14 +98,14 @@ export async function prerender({
|
|
|
90
98
|
// Crawl all pages
|
|
91
99
|
const pages = await prerenderPages()
|
|
92
100
|
|
|
93
|
-
|
|
101
|
+
console.info(`Prerendered ${pages.length} pages:`)
|
|
94
102
|
pages.forEach((page) => {
|
|
95
|
-
|
|
103
|
+
console.info(`- ${page}`)
|
|
96
104
|
})
|
|
97
105
|
|
|
98
106
|
// TODO: Write the prerendered pages to the output directory
|
|
99
107
|
} catch (error) {
|
|
100
|
-
|
|
108
|
+
console.error(error)
|
|
101
109
|
} finally {
|
|
102
110
|
// Ensure server is always closed
|
|
103
111
|
// server.process.kill()
|
|
@@ -123,7 +131,7 @@ export async function prerender({
|
|
|
123
131
|
const seen = new Set<string>()
|
|
124
132
|
const retriesByPath = new Map<string, number>()
|
|
125
133
|
const concurrency = options.prerender?.concurrency ?? os.cpus().length
|
|
126
|
-
|
|
134
|
+
console.info(`Concurrency: ${concurrency}`)
|
|
127
135
|
const queue = new Queue({ concurrency })
|
|
128
136
|
|
|
129
137
|
options.pages.forEach((_page) => {
|
|
@@ -165,7 +173,7 @@ export async function prerender({
|
|
|
165
173
|
|
|
166
174
|
// Add the task
|
|
167
175
|
queue.add(async () => {
|
|
168
|
-
|
|
176
|
+
console.info(`Crawling: ${page.path}`)
|
|
169
177
|
const retries = retriesByPath.get(page.path) || 0
|
|
170
178
|
try {
|
|
171
179
|
// Fetch the route
|
|
@@ -179,23 +187,29 @@ export async function prerender({
|
|
|
179
187
|
)
|
|
180
188
|
|
|
181
189
|
if (!res.ok) {
|
|
182
|
-
throw new Error(`Failed to fetch ${page.path}: ${res.statusText}
|
|
190
|
+
throw new Error(`Failed to fetch ${page.path}: ${res.statusText}`, {
|
|
191
|
+
cause: res,
|
|
192
|
+
})
|
|
183
193
|
}
|
|
184
194
|
|
|
195
|
+
const cleanPagePath = (
|
|
196
|
+
prerenderOptions.outputPath || page.path
|
|
197
|
+
).split(/[?#]/)[0]!
|
|
198
|
+
|
|
185
199
|
// Guess route type and populate fileName
|
|
186
200
|
const contentType = res.headers.get('content-type') || ''
|
|
187
201
|
const isImplicitHTML =
|
|
188
|
-
!
|
|
202
|
+
!cleanPagePath.endsWith('.html') && contentType.includes('html')
|
|
189
203
|
// &&
|
|
190
204
|
// !JsonSigRx.test(dataBuff.subarray(0, 32).toString('utf8'))
|
|
191
|
-
const routeWithIndex =
|
|
192
|
-
?
|
|
193
|
-
:
|
|
205
|
+
const routeWithIndex = cleanPagePath.endsWith('/')
|
|
206
|
+
? cleanPagePath + 'index'
|
|
207
|
+
: cleanPagePath
|
|
194
208
|
|
|
195
209
|
const htmlPath =
|
|
196
|
-
|
|
197
|
-
? joinURL(
|
|
198
|
-
:
|
|
210
|
+
cleanPagePath.endsWith('/') || prerenderOptions.autoSubfolderIndex
|
|
211
|
+
? joinURL(cleanPagePath, 'index.html')
|
|
212
|
+
: cleanPagePath + '.html'
|
|
199
213
|
|
|
200
214
|
const filename = withoutBase(
|
|
201
215
|
isImplicitHTML ? htmlPath : routeWithIndex,
|
|
@@ -227,9 +241,7 @@ export async function prerender({
|
|
|
227
241
|
}
|
|
228
242
|
} catch (error) {
|
|
229
243
|
if (retries < (prerenderOptions.retryCount ?? 0)) {
|
|
230
|
-
|
|
231
|
-
`Encountered error, retrying: ${page.path} in 500ms`,
|
|
232
|
-
)
|
|
244
|
+
console.warn(`Encountered error, retrying: ${page.path} in 500ms`)
|
|
233
245
|
await new Promise((resolve) =>
|
|
234
246
|
setTimeout(resolve, prerenderOptions.retryDelay),
|
|
235
247
|
)
|
package/src/schema.ts
CHANGED
|
@@ -121,6 +121,7 @@ export function createTanStackStartOptionsSchema(
|
|
|
121
121
|
})
|
|
122
122
|
.and(pagePrerenderOptionsSchema.optional())
|
|
123
123
|
.optional(),
|
|
124
|
+
shell: shellSchema.optional(),
|
|
124
125
|
})
|
|
125
126
|
.optional()
|
|
126
127
|
.default({})
|
|
@@ -170,6 +171,7 @@ const pageBaseSchema = z.object({
|
|
|
170
171
|
|
|
171
172
|
const pagePrerenderOptionsSchema = z.object({
|
|
172
173
|
enabled: z.boolean().optional(),
|
|
174
|
+
outputPath: z.string().optional(),
|
|
173
175
|
autoSubfolderIndex: z.boolean().optional(),
|
|
174
176
|
crawlLinks: z.boolean().optional(),
|
|
175
177
|
retryCount: z.number().optional(),
|
|
@@ -186,6 +188,22 @@ const pagePrerenderOptionsSchema = z.object({
|
|
|
186
188
|
.optional(),
|
|
187
189
|
})
|
|
188
190
|
|
|
191
|
+
const shellSchema = z.object({
|
|
192
|
+
enabled: z.boolean().optional().default(true),
|
|
193
|
+
maskPath: z.string().optional().default('/'),
|
|
194
|
+
autoRedirect: z.boolean().optional().default(true),
|
|
195
|
+
prerender: pagePrerenderOptionsSchema
|
|
196
|
+
.optional()
|
|
197
|
+
.default({})
|
|
198
|
+
.transform((opts) => ({
|
|
199
|
+
outputPath: opts.outputPath ?? '/_shell',
|
|
200
|
+
crawlLinks: false,
|
|
201
|
+
retryCount: 0,
|
|
202
|
+
...opts,
|
|
203
|
+
enabled: true,
|
|
204
|
+
})),
|
|
205
|
+
})
|
|
206
|
+
|
|
189
207
|
export const pageSchema = pageBaseSchema.extend({
|
|
190
208
|
prerender: pagePrerenderOptionsSchema.optional(),
|
|
191
209
|
})
|