@analogjs/vite-plugin-nitro 3.0.0-alpha.5 → 3.0.0-alpha.51
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/package.json +26 -11
- package/src/index.d.ts +11 -9
- package/src/index.js +7 -2
- package/src/index.js.map +1 -1
- package/src/lib/build-server.d.ts +2 -2
- package/src/lib/build-server.js +45 -149
- package/src/lib/build-server.js.map +1 -1
- package/src/lib/build-sitemap.d.ts +23 -9
- package/src/lib/build-sitemap.js +132 -63
- package/src/lib/build-sitemap.js.map +1 -1
- package/src/lib/build-ssr.d.ts +3 -2
- package/src/lib/build-ssr.js +26 -18
- package/src/lib/build-ssr.js.map +1 -1
- package/src/lib/hooks/post-rendering-hook.d.ts +1 -1
- package/src/lib/hooks/post-rendering-hook.js +10 -6
- package/src/lib/hooks/post-rendering-hook.js.map +1 -1
- package/src/lib/options.d.ts +153 -106
- package/src/lib/plugins/dev-server-plugin.d.ts +3 -3
- package/src/lib/plugins/dev-server-plugin.js +98 -101
- package/src/lib/plugins/dev-server-plugin.js.map +1 -1
- package/src/lib/plugins/page-endpoints.d.ts +5 -5
- package/src/lib/plugins/page-endpoints.js +26 -46
- package/src/lib/plugins/page-endpoints.js.map +1 -1
- package/src/lib/utils/debug.d.ts +5 -0
- package/src/lib/utils/debug.js +15 -0
- package/src/lib/utils/debug.js.map +1 -0
- package/src/lib/utils/get-content-files.d.ts +55 -55
- package/src/lib/utils/get-content-files.js +95 -97
- package/src/lib/utils/get-content-files.js.map +1 -1
- package/src/lib/utils/get-page-handlers.d.ts +58 -58
- package/src/lib/utils/get-page-handlers.js +70 -84
- package/src/lib/utils/get-page-handlers.js.map +1 -1
- package/src/lib/utils/i18n-prerender.d.ts +36 -0
- package/src/lib/utils/i18n-prerender.js +23 -0
- package/src/lib/utils/i18n-prerender.js.map +1 -0
- package/src/lib/utils/load-esm.d.ts +18 -18
- package/src/lib/utils/node-web-bridge.d.ts +1 -1
- package/src/lib/utils/node-web-bridge.js +50 -45
- package/src/lib/utils/node-web-bridge.js.map +1 -1
- package/src/lib/utils/register-dev-middleware.d.ts +12 -12
- package/src/lib/utils/register-dev-middleware.js +41 -47
- package/src/lib/utils/register-dev-middleware.js.map +1 -1
- package/src/lib/utils/register-i18n-watcher.d.ts +15 -0
- package/src/lib/utils/renderers.d.ts +47 -47
- package/src/lib/utils/renderers.js +57 -56
- package/src/lib/utils/renderers.js.map +1 -1
- package/src/lib/utils/rolldown.d.ts +2 -0
- package/src/lib/utils/rolldown.js +12 -0
- package/src/lib/utils/rolldown.js.map +1 -0
- package/src/lib/vite-plugin-nitro.d.ts +3 -3
- package/src/lib/vite-plugin-nitro.js +790 -677
- package/src/lib/vite-plugin-nitro.js.map +1 -1
- package/README.md +0 -125
- package/src/lib/options.js +0 -2
- package/src/lib/options.js.map +0 -1
- package/src/lib/utils/load-esm.js +0 -23
- package/src/lib/utils/load-esm.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@analogjs/vite-plugin-nitro",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.51",
|
|
4
4
|
"description": "A Vite plugin for adding a nitro API server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Brandon Roberts <robertsbt@gmail.com>",
|
|
7
7
|
"exports": {
|
|
8
|
-
".":
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./src/index.d.ts",
|
|
10
|
+
"import": "./src/index.js",
|
|
11
|
+
"default": "./src/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./internal": {
|
|
14
|
+
"types": "./src/lib/utils/debug.d.ts",
|
|
15
|
+
"import": "./src/lib/utils/debug.js",
|
|
16
|
+
"default": "./src/lib/utils/debug.js"
|
|
17
|
+
},
|
|
9
18
|
"./package.json": "./package.json"
|
|
10
19
|
},
|
|
11
20
|
"keywords": [
|
|
@@ -29,13 +38,22 @@
|
|
|
29
38
|
"type": "github",
|
|
30
39
|
"url": "https://github.com/sponsors/brandonroberts"
|
|
31
40
|
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"sharp": ">=0.32.0"
|
|
43
|
+
},
|
|
44
|
+
"peerDependenciesMeta": {
|
|
45
|
+
"sharp": {
|
|
46
|
+
"optional": true
|
|
47
|
+
}
|
|
48
|
+
},
|
|
32
49
|
"dependencies": {
|
|
33
|
-
"
|
|
50
|
+
"defu": "^6.1.4",
|
|
51
|
+
"nitro": "3.0.260415-beta",
|
|
52
|
+
"obug": "^2.1.1",
|
|
34
53
|
"ofetch": "2.0.0-alpha.3",
|
|
35
|
-
"
|
|
36
|
-
"oxc-parser": "^0.119.0",
|
|
54
|
+
"oxc-parser": "^0.124.0",
|
|
37
55
|
"radix3": "^1.1.2",
|
|
38
|
-
"
|
|
56
|
+
"xmlbuilder2": "^4.0.3"
|
|
39
57
|
},
|
|
40
58
|
"ng-update": {
|
|
41
59
|
"packageGroup": [
|
|
@@ -56,8 +74,5 @@
|
|
|
56
74
|
"publishConfig": {
|
|
57
75
|
"access": "public",
|
|
58
76
|
"provenance": true
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
"module": "./src/index.js",
|
|
62
|
-
"main": "./src/index.js"
|
|
63
|
-
}
|
|
77
|
+
}
|
|
78
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { nitro } from
|
|
2
|
-
export {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { nitro } from "./lib/vite-plugin-nitro.js";
|
|
2
|
+
export { debugInstances } from "./lib/utils/debug.js";
|
|
3
|
+
export { nitro } from "./lib/vite-plugin-nitro.js";
|
|
4
|
+
export type { Options, SitemapConfig, SitemapEntry, SitemapExcludeRule, SitemapPriority, SitemapRouteDefinition, SitemapRouteInput, SitemapRouteSource, SitemapTransform, PrerenderSitemapConfig, PrerenderRouteConfig, PrerenderContentDir, PrerenderContentFile, I18nPrerenderOptions } from "./lib/options.js";
|
|
5
|
+
declare module "nitro/types" {
|
|
6
|
+
interface NitroRouteConfig {
|
|
7
|
+
ssr?: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface NitroRouteRules {
|
|
10
|
+
ssr?: boolean;
|
|
11
|
+
}
|
|
10
12
|
}
|
|
11
13
|
export default nitro;
|
package/src/index.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { debugInstances } from "./lib/utils/debug.js";
|
|
2
|
+
import { nitro } from "./lib/vite-plugin-nitro.js";
|
|
3
|
+
//#region packages/vite-plugin-nitro/src/index.ts
|
|
4
|
+
var src_default = nitro;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { debugInstances, src_default as default, nitro };
|
|
7
|
+
|
|
3
8
|
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import { nitro } from './lib/vite-plugin-nitro.js';\nexport { debugInstances } from './lib/utils/debug.js';\nexport { nitro } from './lib/vite-plugin-nitro.js';\nexport type {\n Options,\n SitemapConfig,\n SitemapEntry,\n SitemapExcludeRule,\n SitemapPriority,\n SitemapRouteDefinition,\n SitemapRouteInput,\n SitemapRouteSource,\n SitemapTransform,\n PrerenderSitemapConfig,\n PrerenderRouteConfig,\n PrerenderContentDir,\n PrerenderContentFile,\n I18nPrerenderOptions,\n} from './lib/options.js';\n\ndeclare module 'nitro/types' {\n interface NitroRouteConfig {\n ssr?: boolean;\n }\n\n interface NitroRouteRules {\n ssr?: boolean;\n }\n}\n\nexport default nitro;\n"],"mappings":";;;AA8BA,IAAA,cAAe"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { NitroConfig } from
|
|
2
|
-
import { Options } from
|
|
1
|
+
import type { NitroConfig } from "nitro/types";
|
|
2
|
+
import { Options } from "./options.js";
|
|
3
3
|
export declare function isVercelPreset(preset: string | undefined): boolean;
|
|
4
4
|
export declare function buildServer(options?: Options, nitroConfig?: NitroConfig, routeSourceFiles?: Record<string, string>): Promise<void>;
|
package/src/lib/build-server.js
CHANGED
|
@@ -1,152 +1,48 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { dirname, join } from
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* Nitro v3's `nitro:oxc` Rollup plugin uses OXC's resolver for every
|
|
9
|
-
* file it transforms. OXC walks up the directory tree looking for a
|
|
10
|
-
* `tsconfig.json` to load path aliases. The SSR output directory
|
|
11
|
-
* (`dist/<app>/ssr/`) is outside the source tree, so no tsconfig
|
|
12
|
-
* exists there. On Windows, OXC's upward directory walk also fails to
|
|
13
|
-
* reach the project root's tsconfig due to path normalisation issues,
|
|
14
|
-
* causing:
|
|
15
|
-
*
|
|
16
|
-
* [TSCONFIG_ERROR] Failed to load tsconfig for
|
|
17
|
-
* '../../dist/apps/blog-app/ssr/main.server.js': Tsconfig not found
|
|
18
|
-
*
|
|
19
|
-
* Writing a minimal tsconfig satisfies the resolver without adding any
|
|
20
|
-
* path aliases that would interfere with Nitro's own module resolution.
|
|
21
|
-
*/
|
|
22
|
-
function ensureSsrTsconfig(nitroConfig) {
|
|
23
|
-
const ssrEntry = nitroConfig?.alias?.['#analog/ssr'];
|
|
24
|
-
if (!ssrEntry) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
// The alias value is a normalized absolute path (forward slashes on
|
|
28
|
-
// all platforms). Convert to a native path for dirname().
|
|
29
|
-
const ssrDir = dirname(ssrEntry.replace(/\//g, join('a', 'b')[1]));
|
|
30
|
-
const tsconfigPath = join(ssrDir, 'tsconfig.json');
|
|
31
|
-
if (existsSync(tsconfigPath)) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
writeFileSync(tsconfigPath, JSON.stringify({ compilerOptions: { module: 'ESNext', moduleResolution: 'bundler' } }, null, 2), 'utf8');
|
|
1
|
+
import { addPostRenderingHooks } from "./hooks/post-rendering-hook.js";
|
|
2
|
+
import { build, copyPublicAssets, createNitro, prepare, prerender } from "nitro/builder";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
+
//#region packages/vite-plugin-nitro/src/lib/build-server.ts
|
|
6
|
+
function isVercelPreset(preset) {
|
|
7
|
+
return !!preset?.toLowerCase().includes("vercel");
|
|
35
8
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
mkdirSync(serverDir, { recursive: true });
|
|
73
|
-
writeFileSync(functionConfigPath, JSON.stringify({
|
|
74
|
-
handler: 'index.mjs',
|
|
75
|
-
launcherType: 'Nodejs',
|
|
76
|
-
shouldAddHelpers: false,
|
|
77
|
-
supportsResponseStreaming: true,
|
|
78
|
-
...nitro.options.vercel?.functions,
|
|
79
|
-
}, null, 2), 'utf8');
|
|
80
|
-
}
|
|
81
|
-
export async function buildServer(options, nitroConfig, routeSourceFiles) {
|
|
82
|
-
// ── Ensure the SSR output has a tsconfig for OXC ─────────────────
|
|
83
|
-
//
|
|
84
|
-
// Must run before createNitro() so the tsconfig is on disk when the
|
|
85
|
-
// nitro:oxc plugin initialises its resolver.
|
|
86
|
-
ensureSsrTsconfig(nitroConfig);
|
|
87
|
-
// ── Force Rollup as the server bundler ────────────────────────────
|
|
88
|
-
//
|
|
89
|
-
// Nitro v3 defaults to Rolldown when available. Rolldown is faster,
|
|
90
|
-
// but its module resolver cannot resolve relative chunk imports
|
|
91
|
-
// (e.g. `./assets/core-DTazUigR.js`) from a rebundled SSR entry on
|
|
92
|
-
// Windows. The prerender build fails with:
|
|
93
|
-
//
|
|
94
|
-
// [RESOLVE_ERROR] Could not resolve './assets/core-DTazUigR.js'
|
|
95
|
-
// in ../../dist/apps/blog-app/ssr/main.server.js
|
|
96
|
-
//
|
|
97
|
-
// This is a known Rolldown limitation with cross-directory relative
|
|
98
|
-
// paths on Windows (backslash vs forward-slash normalisation).
|
|
99
|
-
// Rollup handles these paths correctly on all platforms.
|
|
100
|
-
//
|
|
101
|
-
// The dev server already uses `builder: 'rollup'` for the same
|
|
102
|
-
// reason. Default to Rollup here too until Rolldown's resolver
|
|
103
|
-
// matures. The caller can still opt in to Rolldown explicitly via
|
|
104
|
-
// nitroConfig.builder if their platform supports it.
|
|
105
|
-
const nitro = await createNitro({
|
|
106
|
-
dev: false,
|
|
107
|
-
preset: process.env['BUILD_PRESET'],
|
|
108
|
-
...nitroConfig,
|
|
109
|
-
builder: nitroConfig?.builder ?? 'rollup',
|
|
110
|
-
});
|
|
111
|
-
if (options?.prerender?.postRenderingHooks) {
|
|
112
|
-
addPostRenderingHooks(nitro, options.prerender.postRenderingHooks);
|
|
113
|
-
}
|
|
114
|
-
await prepare(nitro);
|
|
115
|
-
await copyPublicAssets(nitro);
|
|
116
|
-
if (options?.ssr &&
|
|
117
|
-
nitroConfig?.prerender?.routes &&
|
|
118
|
-
(nitroConfig?.prerender?.routes.find((route) => route === '/') ||
|
|
119
|
-
nitroConfig?.prerender?.routes?.length === 0)) {
|
|
120
|
-
const indexFileExts = ['', '.br', '.gz'];
|
|
121
|
-
indexFileExts.forEach((fileExt) => {
|
|
122
|
-
// Remove the root index.html(.br|.gz) files
|
|
123
|
-
const indexFilePath = join(nitroConfig?.output?.publicDir ?? '', `index.html${fileExt}`);
|
|
124
|
-
rmSync(indexFilePath, { force: true });
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
if (nitroConfig?.prerender?.routes &&
|
|
128
|
-
nitroConfig?.prerender?.routes?.length > 0) {
|
|
129
|
-
console.log(`Prerendering static pages...`);
|
|
130
|
-
await prerender(nitro);
|
|
131
|
-
}
|
|
132
|
-
if (routeSourceFiles && Object.keys(routeSourceFiles).length > 0) {
|
|
133
|
-
const publicDir = nitroConfig?.output?.publicDir;
|
|
134
|
-
if (!publicDir) {
|
|
135
|
-
throw new Error('Nitro public output directory is required to write route source files.');
|
|
136
|
-
}
|
|
137
|
-
for (const [route, content] of Object.entries(routeSourceFiles)) {
|
|
138
|
-
const outputPath = join(publicDir, `${route}.md`);
|
|
139
|
-
const outputDir = dirname(outputPath);
|
|
140
|
-
mkdirSync(outputDir, { recursive: true });
|
|
141
|
-
writeFileSync(outputPath, content, 'utf8');
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
if (!options?.static) {
|
|
145
|
-
console.log('Building Server...');
|
|
146
|
-
await build(nitro);
|
|
147
|
-
ensureVercelFunctionConfig(nitro);
|
|
148
|
-
}
|
|
149
|
-
await nitro.close();
|
|
150
|
-
assertValidVercelBuildConfig(nitro);
|
|
9
|
+
async function buildServer(options, nitroConfig, routeSourceFiles) {
|
|
10
|
+
const nitro = await createNitro({
|
|
11
|
+
dev: false,
|
|
12
|
+
preset: process.env["BUILD_PRESET"],
|
|
13
|
+
...nitroConfig,
|
|
14
|
+
builder: nitroConfig?.builder ?? "rollup"
|
|
15
|
+
});
|
|
16
|
+
if (options?.prerender?.postRenderingHooks) addPostRenderingHooks(nitro, options.prerender.postRenderingHooks);
|
|
17
|
+
await prepare(nitro);
|
|
18
|
+
await copyPublicAssets(nitro);
|
|
19
|
+
if (options?.ssr && nitroConfig?.prerender?.routes && (nitroConfig?.prerender?.routes.find((route) => route === "/") || nitroConfig?.prerender?.routes?.length === 0)) [
|
|
20
|
+
"",
|
|
21
|
+
".br",
|
|
22
|
+
".gz"
|
|
23
|
+
].forEach((fileExt) => {
|
|
24
|
+
rmSync(join(nitroConfig?.output?.publicDir ?? "", `index.html${fileExt}`), { force: true });
|
|
25
|
+
});
|
|
26
|
+
if (nitroConfig?.prerender?.routes && nitroConfig?.prerender?.routes?.length > 0) {
|
|
27
|
+
console.log(`Prerendering static pages...`);
|
|
28
|
+
await prerender(nitro);
|
|
29
|
+
}
|
|
30
|
+
if (routeSourceFiles && Object.keys(routeSourceFiles).length > 0) {
|
|
31
|
+
const publicDir = nitroConfig?.output?.publicDir;
|
|
32
|
+
if (!publicDir) throw new Error("Nitro public output directory is required to write route source files.");
|
|
33
|
+
for (const [route, content] of Object.entries(routeSourceFiles)) {
|
|
34
|
+
const outputPath = join(publicDir, `${route}.md`);
|
|
35
|
+
mkdirSync(dirname(outputPath), { recursive: true });
|
|
36
|
+
writeFileSync(outputPath, content, "utf8");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (!options?.static) {
|
|
40
|
+
console.log("Building Server...");
|
|
41
|
+
await build(nitro);
|
|
42
|
+
}
|
|
43
|
+
await nitro.close();
|
|
151
44
|
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { buildServer, isVercelPreset };
|
|
47
|
+
|
|
152
48
|
//# sourceMappingURL=build-server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-server.js","
|
|
1
|
+
{"version":3,"file":"build-server.js","names":[],"sources":["../../../src/lib/build-server.ts"],"sourcesContent":["import type { NitroConfig } from 'nitro/types';\nimport {\n build,\n copyPublicAssets,\n createNitro,\n prepare,\n prerender,\n} from 'nitro/builder';\nimport { mkdirSync, rmSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { Options } from './options.js';\nimport { addPostRenderingHooks } from './hooks/post-rendering-hook.js';\n\nexport function isVercelPreset(preset: string | undefined): boolean {\n return !!preset?.toLowerCase().includes('vercel');\n}\n\nexport async function buildServer(\n options?: Options,\n nitroConfig?: NitroConfig,\n routeSourceFiles?: Record<string, string>,\n): Promise<void> {\n // ── Force Rollup as the server bundler ────────────────────────────\n //\n // Nitro v3 defaults to Rolldown when available. Rolldown is faster,\n // but its module resolver cannot resolve relative chunk imports\n // (e.g. `./assets/core-DTazUigR.js`) from a rebundled SSR entry on\n // Windows. The prerender build fails with:\n //\n // [RESOLVE_ERROR] Could not resolve './assets/core-DTazUigR.js'\n // in ../../dist/apps/blog-app/ssr/main.server.js\n //\n // This is a known Rolldown limitation with cross-directory relative\n // paths on Windows (backslash vs forward-slash normalisation).\n // Rollup handles these paths correctly on all platforms.\n //\n // The dev server already uses `builder: 'rollup'` for the same\n // reason. Default to Rollup here too until Rolldown's resolver\n // matures. The caller can still opt in to Rolldown explicitly via\n // nitroConfig.builder if their platform supports it.\n const nitro = await createNitro({\n dev: false,\n preset: process.env['BUILD_PRESET'],\n ...nitroConfig,\n builder: nitroConfig?.builder ?? 'rollup',\n });\n\n if (options?.prerender?.postRenderingHooks) {\n addPostRenderingHooks(nitro, options.prerender.postRenderingHooks);\n }\n\n await prepare(nitro);\n await copyPublicAssets(nitro);\n\n if (\n options?.ssr &&\n nitroConfig?.prerender?.routes &&\n (nitroConfig?.prerender?.routes.find((route) => route === '/') ||\n nitroConfig?.prerender?.routes?.length === 0)\n ) {\n const indexFileExts = ['', '.br', '.gz'];\n\n indexFileExts.forEach((fileExt) => {\n // Remove the root index.html(.br|.gz) files\n const indexFilePath = join(\n nitroConfig?.output?.publicDir ?? '',\n `index.html${fileExt}`,\n );\n\n rmSync(indexFilePath, { force: true });\n });\n }\n\n if (\n nitroConfig?.prerender?.routes &&\n nitroConfig?.prerender?.routes?.length > 0\n ) {\n console.log(`Prerendering static pages...`);\n await prerender(nitro);\n }\n\n if (routeSourceFiles && Object.keys(routeSourceFiles).length > 0) {\n const publicDir = nitroConfig?.output?.publicDir;\n if (!publicDir) {\n throw new Error(\n 'Nitro public output directory is required to write route source files.',\n );\n }\n\n for (const [route, content] of Object.entries(routeSourceFiles)) {\n const outputPath = join(publicDir, `${route}.md`);\n const outputDir = dirname(outputPath);\n mkdirSync(outputDir, { recursive: true });\n\n writeFileSync(outputPath, content, 'utf8');\n }\n }\n\n if (!options?.static) {\n console.log('Building Server...');\n await build(nitro);\n }\n\n await nitro.close();\n}\n"],"mappings":";;;;;AAcA,SAAgB,eAAe,QAAqC;AAClE,QAAO,CAAC,CAAC,QAAQ,aAAa,CAAC,SAAS,SAAS;;AAGnD,eAAsB,YACpB,SACA,aACA,kBACe;CAmBf,MAAM,QAAQ,MAAM,YAAY;EAC9B,KAAK;EACL,QAAQ,QAAQ,IAAI;EACpB,GAAG;EACH,SAAS,aAAa,WAAW;EAClC,CAAC;AAEF,KAAI,SAAS,WAAW,mBACtB,uBAAsB,OAAO,QAAQ,UAAU,mBAAmB;AAGpE,OAAM,QAAQ,MAAM;AACpB,OAAM,iBAAiB,MAAM;AAE7B,KACE,SAAS,OACT,aAAa,WAAW,WACvB,aAAa,WAAW,OAAO,MAAM,UAAU,UAAU,IAAI,IAC5D,aAAa,WAAW,QAAQ,WAAW,GAEvB;EAAC;EAAI;EAAO;EAAM,CAE1B,SAAS,YAAY;AAOjC,SALsB,KACpB,aAAa,QAAQ,aAAa,IAClC,aAAa,UACd,EAEqB,EAAE,OAAO,MAAM,CAAC;GACtC;AAGJ,KACE,aAAa,WAAW,UACxB,aAAa,WAAW,QAAQ,SAAS,GACzC;AACA,UAAQ,IAAI,+BAA+B;AAC3C,QAAM,UAAU,MAAM;;AAGxB,KAAI,oBAAoB,OAAO,KAAK,iBAAiB,CAAC,SAAS,GAAG;EAChE,MAAM,YAAY,aAAa,QAAQ;AACvC,MAAI,CAAC,UACH,OAAM,IAAI,MACR,yEACD;AAGH,OAAK,MAAM,CAAC,OAAO,YAAY,OAAO,QAAQ,iBAAiB,EAAE;GAC/D,MAAM,aAAa,KAAK,WAAW,GAAG,MAAM,KAAK;AAEjD,aADkB,QAAQ,WAAW,EAChB,EAAE,WAAW,MAAM,CAAC;AAEzC,iBAAc,YAAY,SAAS,OAAO;;;AAI9C,KAAI,CAAC,SAAS,QAAQ;AACpB,UAAQ,IAAI,qBAAqB;AACjC,QAAM,MAAM,MAAM;;AAGpB,OAAM,MAAM,OAAO"}
|
|
@@ -1,9 +1,23 @@
|
|
|
1
|
-
import { UserConfig } from
|
|
2
|
-
import { PrerenderSitemapConfig, SitemapConfig } from
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { UserConfig } from "vite";
|
|
2
|
+
import { PrerenderSitemapConfig, SitemapConfig, SitemapEntry } from "./options";
|
|
3
|
+
type RouteSitemapConfig = PrerenderSitemapConfig | (() => PrerenderSitemapConfig) | undefined;
|
|
4
|
+
export type PagesJson = SitemapEntry;
|
|
5
|
+
export interface BuildSitemapOptions {
|
|
6
|
+
apiPrefix?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function buildSitemap(_config: UserConfig, sitemapConfig: SitemapConfig, routes: (string | undefined)[] | (() => Promise<(string | undefined)[]>), outputDir: string, routeSitemaps: Record<string, RouteSitemapConfig>, buildOptions?: BuildSitemapOptions): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Generates hreflang alternate URLs for a given page URL.
|
|
11
|
+
* For a URL like `https://example.com/fr/about`, it produces alternates
|
|
12
|
+
* for all configured locales.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getHreflangAlternates(pageUrl: string, host: string, i18n: I18nPrerenderOptions): {
|
|
15
|
+
locale: string;
|
|
16
|
+
href: string;
|
|
17
|
+
}[];
|
|
18
|
+
/**
|
|
19
|
+
* Strips a locale prefix from a URL path.
|
|
20
|
+
* E.g., '/fr/about' -> '/about', '/en' -> '/'
|
|
21
|
+
*/
|
|
22
|
+
export declare function stripLocalePrefix(path: string, locales: string[]): string;
|
|
23
|
+
export {};
|
package/src/lib/build-sitemap.js
CHANGED
|
@@ -1,68 +1,137 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (item.priority) {
|
|
28
|
-
page.ele('priority').txt(item.priority);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
const mapPath = `${resolve(outputDir)}/sitemap.xml`;
|
|
32
|
-
try {
|
|
33
|
-
console.log(`Writing sitemap at ${mapPath}`);
|
|
34
|
-
writeFileSync(mapPath, sitemap.end({ prettyPrint: true }));
|
|
35
|
-
}
|
|
36
|
-
catch (e) {
|
|
37
|
-
console.error(`Unable to write file at ${mapPath}`, e);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { create } from "xmlbuilder2";
|
|
4
|
+
//#region packages/vite-plugin-nitro/src/lib/build-sitemap.ts
|
|
5
|
+
async function buildSitemap(_config, sitemapConfig, routes, outputDir, routeSitemaps, buildOptions = {}) {
|
|
6
|
+
const host = normalizeSitemapHost(sitemapConfig.host);
|
|
7
|
+
const sitemapData = await resolveSitemapEntries(await collectSitemapRoutes(routes, sitemapConfig.include), host, routeSitemaps, sitemapConfig, buildOptions);
|
|
8
|
+
if (!sitemapData.length) return;
|
|
9
|
+
const sitemap = createXml("urlset");
|
|
10
|
+
for (const item of sitemapData) {
|
|
11
|
+
const page = sitemap.ele("url");
|
|
12
|
+
page.ele("loc").txt(item.loc);
|
|
13
|
+
if (item.lastmod) page.ele("lastmod").txt(item.lastmod);
|
|
14
|
+
if (item.changefreq) page.ele("changefreq").txt(item.changefreq);
|
|
15
|
+
if (item.priority !== void 0) page.ele("priority").txt(String(item.priority));
|
|
16
|
+
}
|
|
17
|
+
const resolvedOutputDir = resolve(outputDir);
|
|
18
|
+
const mapPath = resolve(resolvedOutputDir, "sitemap.xml");
|
|
19
|
+
try {
|
|
20
|
+
if (!resolvedOutputDir || resolvedOutputDir === resolve()) throw new Error("Refusing to write the sitemap to the current working directory. Expected the Nitro public output directory instead.");
|
|
21
|
+
if (!existsSync(resolvedOutputDir)) mkdirSync(resolvedOutputDir, { recursive: true });
|
|
22
|
+
console.log(`Writing sitemap at ${mapPath}`);
|
|
23
|
+
writeFileSync(mapPath, sitemap.end({ prettyPrint: true }));
|
|
24
|
+
} catch (e) {
|
|
25
|
+
console.error(`Unable to write file at ${mapPath}`, e);
|
|
26
|
+
}
|
|
40
27
|
}
|
|
41
|
-
function
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
28
|
+
async function resolveSitemapEntries(routes, host, routeSitemaps, sitemapConfig, buildOptions) {
|
|
29
|
+
const defaults = sitemapConfig.defaults ?? {};
|
|
30
|
+
const seen = /* @__PURE__ */ new Set();
|
|
31
|
+
const entries = [];
|
|
32
|
+
for (const route of routes) {
|
|
33
|
+
const entry = await toSitemapEntry(route, host, routeSitemaps, defaults, sitemapConfig.transform);
|
|
34
|
+
if (!entry) continue;
|
|
35
|
+
if (isInternalSitemapRoute(entry.route, buildOptions.apiPrefix) || await isExcludedSitemapRoute(entry, sitemapConfig.exclude)) continue;
|
|
36
|
+
if (seen.has(entry.loc)) continue;
|
|
37
|
+
seen.add(entry.loc);
|
|
38
|
+
entries.push(entry);
|
|
39
|
+
}
|
|
40
|
+
return entries;
|
|
47
41
|
}
|
|
48
|
-
function
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
async function toSitemapEntry(route, host, routeSitemaps, defaults, transform) {
|
|
43
|
+
const normalizedRoute = normalizeSitemapRoute(typeof route === "string" ? route : route?.route);
|
|
44
|
+
if (!normalizedRoute) return;
|
|
45
|
+
const baseEntry = createSitemapEntry({
|
|
46
|
+
...defaults,
|
|
47
|
+
...resolveRouteSitemapConfig(routeSitemaps[normalizedRoute]),
|
|
48
|
+
...typeof route === "object" ? route : {},
|
|
49
|
+
route: normalizedRoute
|
|
50
|
+
}, host);
|
|
51
|
+
if (!transform) return baseEntry;
|
|
52
|
+
const transformed = await transform(baseEntry);
|
|
53
|
+
if (!transformed) return;
|
|
54
|
+
return createSitemapEntry({
|
|
55
|
+
...baseEntry,
|
|
56
|
+
...transformed
|
|
57
|
+
}, host);
|
|
51
58
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
// default it to an empty of array
|
|
64
|
-
routeList = [];
|
|
65
|
-
}
|
|
66
|
-
return routeList.filter(Boolean);
|
|
59
|
+
function createSitemapEntry(routeDefinition, host) {
|
|
60
|
+
const route = normalizeSitemapRoute(routeDefinition.route) ?? "/";
|
|
61
|
+
return {
|
|
62
|
+
route,
|
|
63
|
+
loc: new URL(route, ensureTrailingSlash(host)).toString(),
|
|
64
|
+
lastmod: routeDefinition.lastmod,
|
|
65
|
+
changefreq: routeDefinition.changefreq,
|
|
66
|
+
priority: routeDefinition.priority
|
|
67
|
+
};
|
|
67
68
|
}
|
|
69
|
+
function resolveRouteSitemapConfig(config) {
|
|
70
|
+
if (!config) return {};
|
|
71
|
+
return typeof config === "function" ? config() : config;
|
|
72
|
+
}
|
|
73
|
+
function normalizeSitemapHost(host) {
|
|
74
|
+
const resolvedHost = new URL(host);
|
|
75
|
+
resolvedHost.hash = "";
|
|
76
|
+
return resolvedHost.toString();
|
|
77
|
+
}
|
|
78
|
+
function ensureTrailingSlash(host) {
|
|
79
|
+
return host.endsWith("/") ? host : `${host}/`;
|
|
80
|
+
}
|
|
81
|
+
function normalizeSitemapRoute(route) {
|
|
82
|
+
if (!route) return;
|
|
83
|
+
const trimmedRoute = route.trim();
|
|
84
|
+
if (!trimmedRoute) return;
|
|
85
|
+
const [pathname, search] = (trimmedRoute.split("#", 1)[0] ?? "").split("?", 2);
|
|
86
|
+
const normalizedPathname = pathname ? `/${pathname.replace(/^\/+/, "").replace(/\/{2,}/g, "/")}` : "/";
|
|
87
|
+
return search ? `${normalizedPathname}?${search}` : normalizedPathname;
|
|
88
|
+
}
|
|
89
|
+
function isInternalSitemapRoute(route, apiPrefix = "api") {
|
|
90
|
+
const normalizedApiPrefix = normalizeSitemapRoute(`/${apiPrefix}`) ?? "/api";
|
|
91
|
+
return route === `${normalizedApiPrefix}/_analog/pages` || route.startsWith(`${normalizedApiPrefix}/_analog/pages/`);
|
|
92
|
+
}
|
|
93
|
+
async function isExcludedSitemapRoute(entry, excludeRules) {
|
|
94
|
+
if (!excludeRules?.length) return false;
|
|
95
|
+
for (const rule of excludeRules) {
|
|
96
|
+
if (typeof rule === "function") {
|
|
97
|
+
if (await rule(entry)) return true;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (rule instanceof RegExp) {
|
|
101
|
+
if (rule.test(entry.route)) return true;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (toGlobRegExp(rule).test(entry.route)) return true;
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
function toGlobRegExp(pattern) {
|
|
109
|
+
const doubleStarToken = "__ANALOG_DOUBLE_STAR__";
|
|
110
|
+
const singleStarToken = "__ANALOG_SINGLE_STAR__";
|
|
111
|
+
const regexPattern = pattern.replace(/\*\*/g, doubleStarToken).replace(/\*/g, singleStarToken).replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(new RegExp(doubleStarToken, "g"), ".*").replace(new RegExp(singleStarToken, "g"), "[^/]*");
|
|
112
|
+
return new RegExp(`^${regexPattern}$`);
|
|
113
|
+
}
|
|
114
|
+
async function collectSitemapRoutes(routes, include) {
|
|
115
|
+
const routeList = await resolveRouteInputs(routes);
|
|
116
|
+
const includedRoutes = include ? await resolveRouteInputs(include) : [];
|
|
117
|
+
return [...routeList, ...includedRoutes];
|
|
118
|
+
}
|
|
119
|
+
async function resolveRouteInputs(routes) {
|
|
120
|
+
let routeList;
|
|
121
|
+
if (typeof routes === "function") routeList = await routes();
|
|
122
|
+
else if (Array.isArray(routes)) routeList = routes;
|
|
123
|
+
else routeList = [];
|
|
124
|
+
return routeList.filter(Boolean);
|
|
125
|
+
}
|
|
126
|
+
function createXml(elementName, includeXhtml = false) {
|
|
127
|
+
const attrs = { xmlns: "https://www.sitemaps.org/schemas/sitemap/0.9" };
|
|
128
|
+
if (includeXhtml) attrs["xmlns:xhtml"] = "https://www.w3.org/1999/xhtml";
|
|
129
|
+
return create({
|
|
130
|
+
version: "1.0",
|
|
131
|
+
encoding: "UTF-8"
|
|
132
|
+
}).ele(elementName, attrs).com(`This file was automatically generated by Analog.`);
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
135
|
+
export { buildSitemap };
|
|
136
|
+
|
|
68
137
|
//# sourceMappingURL=build-sitemap.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-sitemap.js","sourceRoot":"","sources":["../../../../../packages/vite-plugin-nitro/src/lib/build-sitemap.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"build-sitemap.js","names":[],"sources":["../../../src/lib/build-sitemap.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { create } from 'xmlbuilder2';\nimport { XMLBuilder } from 'xmlbuilder2/lib/interfaces';\nimport { UserConfig } from 'vite';\nimport {\n PrerenderSitemapConfig,\n SitemapConfig,\n SitemapEntry,\n SitemapExcludeRule,\n SitemapRouteDefinition,\n SitemapRouteInput,\n SitemapRouteSource,\n} from './options';\n\ntype RouteSitemapConfig =\n | PrerenderSitemapConfig\n | (() => PrerenderSitemapConfig)\n | undefined;\n\nexport type PagesJson = SitemapEntry;\n\nexport interface BuildSitemapOptions {\n apiPrefix?: string;\n}\n\nexport async function buildSitemap(\n _config: UserConfig,\n sitemapConfig: SitemapConfig,\n routes: (string | undefined)[] | (() => Promise<(string | undefined)[]>),\n outputDir: string,\n routeSitemaps: Record<string, RouteSitemapConfig>,\n buildOptions: BuildSitemapOptions = {},\n): Promise<void> {\n const host = normalizeSitemapHost(sitemapConfig.host);\n const routeList = await collectSitemapRoutes(routes, sitemapConfig.include);\n const sitemapData = await resolveSitemapEntries(\n routeList,\n host,\n routeSitemaps,\n sitemapConfig,\n buildOptions,\n );\n\n if (!sitemapData.length) {\n return;\n }\n\n const sitemap = createXml('urlset');\n\n for (const item of sitemapData) {\n const page = sitemap.ele('url');\n page.ele('loc').txt(item.loc);\n\n if (item.lastmod) {\n page.ele('lastmod').txt(item.lastmod);\n }\n\n if (item.changefreq) {\n page.ele('changefreq').txt(item.changefreq);\n }\n\n if (item.priority !== undefined) {\n page.ele('priority').txt(String(item.priority));\n }\n }\n\n const resolvedOutputDir = resolve(outputDir);\n const mapPath = resolve(resolvedOutputDir, 'sitemap.xml');\n try {\n if (!resolvedOutputDir || resolvedOutputDir === resolve()) {\n throw new Error(\n 'Refusing to write the sitemap to the current working directory. Expected the Nitro public output directory instead.',\n );\n }\n\n if (!existsSync(resolvedOutputDir)) {\n mkdirSync(resolvedOutputDir, { recursive: true });\n }\n console.log(`Writing sitemap at ${mapPath}`);\n writeFileSync(mapPath, sitemap.end({ prettyPrint: true }));\n } catch (e) {\n console.error(`Unable to write file at ${mapPath}`, e);\n }\n}\n\nasync function resolveSitemapEntries(\n routes: SitemapRouteInput[],\n host: string,\n routeSitemaps: Record<string, RouteSitemapConfig>,\n sitemapConfig: SitemapConfig,\n buildOptions: BuildSitemapOptions,\n): Promise<SitemapEntry[]> {\n const defaults = sitemapConfig.defaults ?? {};\n const seen = new Set<string>();\n const entries: SitemapEntry[] = [];\n\n for (const route of routes) {\n const entry = await toSitemapEntry(\n route,\n host,\n routeSitemaps,\n defaults,\n sitemapConfig.transform,\n );\n\n if (!entry) {\n continue;\n }\n\n if (\n isInternalSitemapRoute(entry.route, buildOptions.apiPrefix) ||\n (await isExcludedSitemapRoute(entry, sitemapConfig.exclude))\n ) {\n continue;\n }\n\n if (seen.has(entry.loc)) {\n continue;\n }\n\n seen.add(entry.loc);\n entries.push(entry);\n }\n\n return entries;\n}\n\nasync function toSitemapEntry(\n route: SitemapRouteInput,\n host: string,\n routeSitemaps: Record<string, RouteSitemapConfig>,\n defaults: PrerenderSitemapConfig,\n transform: SitemapConfig['transform'],\n): Promise<SitemapEntry | undefined> {\n const normalizedRoute = normalizeSitemapRoute(\n typeof route === 'string' ? route : route?.route,\n );\n if (!normalizedRoute) {\n return undefined;\n }\n\n const baseEntry = createSitemapEntry(\n {\n ...defaults,\n ...resolveRouteSitemapConfig(routeSitemaps[normalizedRoute]),\n ...(typeof route === 'object' ? route : {}),\n route: normalizedRoute,\n },\n host,\n );\n\n if (!transform) {\n return baseEntry;\n }\n\n const transformed = await transform(baseEntry);\n if (!transformed) {\n return undefined;\n }\n\n return createSitemapEntry(\n {\n ...baseEntry,\n ...transformed,\n },\n host,\n );\n}\n\nfunction createSitemapEntry(\n routeDefinition: SitemapRouteDefinition,\n host: string,\n): SitemapEntry {\n const route = normalizeSitemapRoute(routeDefinition.route) ?? '/';\n\n return {\n route,\n loc: new URL(route, ensureTrailingSlash(host)).toString(),\n lastmod: routeDefinition.lastmod,\n changefreq: routeDefinition.changefreq,\n priority: routeDefinition.priority,\n };\n}\n\nfunction resolveRouteSitemapConfig(\n config: RouteSitemapConfig,\n): PrerenderSitemapConfig {\n if (!config) {\n return {};\n }\n\n return typeof config === 'function' ? config() : config;\n}\n\nfunction normalizeSitemapHost(host: string): string {\n const resolvedHost = new URL(host);\n resolvedHost.hash = '';\n return resolvedHost.toString();\n}\n\nfunction ensureTrailingSlash(host: string): string {\n return host.endsWith('/') ? host : `${host}/`;\n}\n\nfunction normalizeSitemapRoute(route: string | undefined): string | undefined {\n if (!route) {\n return undefined;\n }\n\n const trimmedRoute = route.trim();\n if (!trimmedRoute) {\n return undefined;\n }\n\n const pathWithQuery = trimmedRoute.split('#', 1)[0] ?? '';\n const [pathname, search] = pathWithQuery.split('?', 2);\n const normalizedPathname = pathname\n ? `/${pathname.replace(/^\\/+/, '').replace(/\\/{2,}/g, '/')}`\n : '/';\n\n return search ? `${normalizedPathname}?${search}` : normalizedPathname;\n}\n\nfunction isInternalSitemapRoute(route: string, apiPrefix = 'api'): boolean {\n const normalizedApiPrefix = normalizeSitemapRoute(`/${apiPrefix}`) ?? '/api';\n return (\n route === `${normalizedApiPrefix}/_analog/pages` ||\n route.startsWith(`${normalizedApiPrefix}/_analog/pages/`)\n );\n}\n\nasync function isExcludedSitemapRoute(\n entry: SitemapEntry,\n excludeRules: SitemapExcludeRule[] | undefined,\n): Promise<boolean> {\n if (!excludeRules?.length) {\n return false;\n }\n\n for (const rule of excludeRules) {\n if (typeof rule === 'function') {\n if (await rule(entry)) {\n return true;\n }\n continue;\n }\n\n if (rule instanceof RegExp) {\n if (rule.test(entry.route)) {\n return true;\n }\n continue;\n }\n\n if (toGlobRegExp(rule).test(entry.route)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction toGlobRegExp(pattern: string): RegExp {\n const doubleStarToken = '__ANALOG_DOUBLE_STAR__';\n const singleStarToken = '__ANALOG_SINGLE_STAR__';\n const escapedPattern = pattern\n .replace(/\\*\\*/g, doubleStarToken)\n .replace(/\\*/g, singleStarToken)\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&');\n const regexPattern = escapedPattern\n .replace(new RegExp(doubleStarToken, 'g'), '.*')\n .replace(new RegExp(singleStarToken, 'g'), '[^/]*');\n return new RegExp(`^${regexPattern}$`);\n}\n\nasync function collectSitemapRoutes(\n routes: (string | undefined)[] | (() => Promise<(string | undefined)[]>),\n include?: SitemapRouteSource,\n): Promise<SitemapRouteInput[]> {\n const routeList = await resolveRouteInputs(routes);\n const includedRoutes = include ? await resolveRouteInputs(include) : [];\n return [...routeList, ...includedRoutes];\n}\n\nasync function resolveRouteInputs(\n routes:\n | SitemapRouteSource\n | (string | undefined)[]\n | (() => Promise<(string | undefined)[]>),\n): Promise<SitemapRouteInput[]> {\n let routeList: SitemapRouteInput[];\n\n if (typeof routes === 'function') {\n routeList = await routes();\n } else if (Array.isArray(routes)) {\n routeList = routes;\n } else {\n routeList = [];\n }\n\n return routeList.filter(Boolean);\n}\n\n/**\n * Generates hreflang alternate URLs for a given page URL.\n * For a URL like `https://example.com/fr/about`, it produces alternates\n * for all configured locales.\n */\nexport function getHreflangAlternates(\n pageUrl: string,\n host: string,\n i18n: I18nPrerenderOptions,\n): { locale: string; href: string }[] {\n const alternates: { locale: string; href: string }[] = [];\n const normalizedHost = host.replace(/\\/+$/, '');\n\n // Extract the path portion after the host\n const path = pageUrl.replace(normalizedHost, '');\n\n // Strip locale prefix to get the base path\n const basePath = stripLocalePrefix(path, i18n.locales);\n\n for (const locale of i18n.locales) {\n const localizedPath =\n basePath === '/' || basePath === ''\n ? `/${locale}`\n : `/${locale}${basePath}`;\n alternates.push({\n locale,\n href: `${normalizedHost}${localizedPath}`,\n });\n }\n\n // Add x-default pointing to the default locale variant\n const defaultPath =\n basePath === '/' || basePath === ''\n ? `/${i18n.defaultLocale}`\n : `/${i18n.defaultLocale}${basePath}`;\n alternates.push({\n locale: 'x-default',\n href: `${normalizedHost}${defaultPath}`,\n });\n\n return alternates;\n}\n\n/**\n * Strips a locale prefix from a URL path.\n * E.g., '/fr/about' -> '/about', '/en' -> '/'\n */\nexport function stripLocalePrefix(path: string, locales: string[]): string {\n const segments = path.split('/').filter(Boolean);\n if (segments.length > 0 && locales.includes(segments[0])) {\n const rest = segments.slice(1).join('/');\n return rest ? `/${rest}` : '/';\n }\n return path || '/';\n}\n\nfunction createXml(\n elementName: 'urlset' | 'sitemapindex',\n includeXhtml = false,\n): XMLBuilder {\n const attrs: Record<string, string> = {\n xmlns: 'https://www.sitemaps.org/schemas/sitemap/0.9',\n };\n if (includeXhtml) {\n attrs['xmlns:xhtml'] = 'https://www.w3.org/1999/xhtml';\n }\n\n return create({ version: '1.0', encoding: 'UTF-8' })\n .ele(elementName, attrs)\n .com(`This file was automatically generated by Analog.`);\n}\n"],"mappings":";;;;AA0BA,eAAsB,aACpB,SACA,eACA,QACA,WACA,eACA,eAAoC,EAAE,EACvB;CACf,MAAM,OAAO,qBAAqB,cAAc,KAAK;CAErD,MAAM,cAAc,MAAM,sBADR,MAAM,qBAAqB,QAAQ,cAAc,QAAQ,EAGzE,MACA,eACA,eACA,aACD;AAED,KAAI,CAAC,YAAY,OACf;CAGF,MAAM,UAAU,UAAU,SAAS;AAEnC,MAAK,MAAM,QAAQ,aAAa;EAC9B,MAAM,OAAO,QAAQ,IAAI,MAAM;AAC/B,OAAK,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;AAE7B,MAAI,KAAK,QACP,MAAK,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ;AAGvC,MAAI,KAAK,WACP,MAAK,IAAI,aAAa,CAAC,IAAI,KAAK,WAAW;AAG7C,MAAI,KAAK,aAAa,KAAA,EACpB,MAAK,IAAI,WAAW,CAAC,IAAI,OAAO,KAAK,SAAS,CAAC;;CAInD,MAAM,oBAAoB,QAAQ,UAAU;CAC5C,MAAM,UAAU,QAAQ,mBAAmB,cAAc;AACzD,KAAI;AACF,MAAI,CAAC,qBAAqB,sBAAsB,SAAS,CACvD,OAAM,IAAI,MACR,sHACD;AAGH,MAAI,CAAC,WAAW,kBAAkB,CAChC,WAAU,mBAAmB,EAAE,WAAW,MAAM,CAAC;AAEnD,UAAQ,IAAI,sBAAsB,UAAU;AAC5C,gBAAc,SAAS,QAAQ,IAAI,EAAE,aAAa,MAAM,CAAC,CAAC;UACnD,GAAG;AACV,UAAQ,MAAM,2BAA2B,WAAW,EAAE;;;AAI1D,eAAe,sBACb,QACA,MACA,eACA,eACA,cACyB;CACzB,MAAM,WAAW,cAAc,YAAY,EAAE;CAC7C,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,UAA0B,EAAE;AAElC,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,QAAQ,MAAM,eAClB,OACA,MACA,eACA,UACA,cAAc,UACf;AAED,MAAI,CAAC,MACH;AAGF,MACE,uBAAuB,MAAM,OAAO,aAAa,UAAU,IAC1D,MAAM,uBAAuB,OAAO,cAAc,QAAQ,CAE3D;AAGF,MAAI,KAAK,IAAI,MAAM,IAAI,CACrB;AAGF,OAAK,IAAI,MAAM,IAAI;AACnB,UAAQ,KAAK,MAAM;;AAGrB,QAAO;;AAGT,eAAe,eACb,OACA,MACA,eACA,UACA,WACmC;CACnC,MAAM,kBAAkB,sBACtB,OAAO,UAAU,WAAW,QAAQ,OAAO,MAC5C;AACD,KAAI,CAAC,gBACH;CAGF,MAAM,YAAY,mBAChB;EACE,GAAG;EACH,GAAG,0BAA0B,cAAc,iBAAiB;EAC5D,GAAI,OAAO,UAAU,WAAW,QAAQ,EAAE;EAC1C,OAAO;EACR,EACD,KACD;AAED,KAAI,CAAC,UACH,QAAO;CAGT,MAAM,cAAc,MAAM,UAAU,UAAU;AAC9C,KAAI,CAAC,YACH;AAGF,QAAO,mBACL;EACE,GAAG;EACH,GAAG;EACJ,EACD,KACD;;AAGH,SAAS,mBACP,iBACA,MACc;CACd,MAAM,QAAQ,sBAAsB,gBAAgB,MAAM,IAAI;AAE9D,QAAO;EACL;EACA,KAAK,IAAI,IAAI,OAAO,oBAAoB,KAAK,CAAC,CAAC,UAAU;EACzD,SAAS,gBAAgB;EACzB,YAAY,gBAAgB;EAC5B,UAAU,gBAAgB;EAC3B;;AAGH,SAAS,0BACP,QACwB;AACxB,KAAI,CAAC,OACH,QAAO,EAAE;AAGX,QAAO,OAAO,WAAW,aAAa,QAAQ,GAAG;;AAGnD,SAAS,qBAAqB,MAAsB;CAClD,MAAM,eAAe,IAAI,IAAI,KAAK;AAClC,cAAa,OAAO;AACpB,QAAO,aAAa,UAAU;;AAGhC,SAAS,oBAAoB,MAAsB;AACjD,QAAO,KAAK,SAAS,IAAI,GAAG,OAAO,GAAG,KAAK;;AAG7C,SAAS,sBAAsB,OAA+C;AAC5E,KAAI,CAAC,MACH;CAGF,MAAM,eAAe,MAAM,MAAM;AACjC,KAAI,CAAC,aACH;CAIF,MAAM,CAAC,UAAU,WADK,aAAa,MAAM,KAAK,EAAE,CAAC,MAAM,IACd,MAAM,KAAK,EAAE;CACtD,MAAM,qBAAqB,WACvB,IAAI,SAAS,QAAQ,QAAQ,GAAG,CAAC,QAAQ,WAAW,IAAI,KACxD;AAEJ,QAAO,SAAS,GAAG,mBAAmB,GAAG,WAAW;;AAGtD,SAAS,uBAAuB,OAAe,YAAY,OAAgB;CACzE,MAAM,sBAAsB,sBAAsB,IAAI,YAAY,IAAI;AACtE,QACE,UAAU,GAAG,oBAAoB,mBACjC,MAAM,WAAW,GAAG,oBAAoB,iBAAiB;;AAI7D,eAAe,uBACb,OACA,cACkB;AAClB,KAAI,CAAC,cAAc,OACjB,QAAO;AAGT,MAAK,MAAM,QAAQ,cAAc;AAC/B,MAAI,OAAO,SAAS,YAAY;AAC9B,OAAI,MAAM,KAAK,MAAM,CACnB,QAAO;AAET;;AAGF,MAAI,gBAAgB,QAAQ;AAC1B,OAAI,KAAK,KAAK,MAAM,MAAM,CACxB,QAAO;AAET;;AAGF,MAAI,aAAa,KAAK,CAAC,KAAK,MAAM,MAAM,CACtC,QAAO;;AAIX,QAAO;;AAGT,SAAS,aAAa,SAAyB;CAC7C,MAAM,kBAAkB;CACxB,MAAM,kBAAkB;CAKxB,MAAM,eAJiB,QACpB,QAAQ,SAAS,gBAAgB,CACjC,QAAQ,OAAO,gBAAgB,CAC/B,QAAQ,qBAAqB,OAAO,CAEpC,QAAQ,IAAI,OAAO,iBAAiB,IAAI,EAAE,KAAK,CAC/C,QAAQ,IAAI,OAAO,iBAAiB,IAAI,EAAE,QAAQ;AACrD,QAAO,IAAI,OAAO,IAAI,aAAa,GAAG;;AAGxC,eAAe,qBACb,QACA,SAC8B;CAC9B,MAAM,YAAY,MAAM,mBAAmB,OAAO;CAClD,MAAM,iBAAiB,UAAU,MAAM,mBAAmB,QAAQ,GAAG,EAAE;AACvE,QAAO,CAAC,GAAG,WAAW,GAAG,eAAe;;AAG1C,eAAe,mBACb,QAI8B;CAC9B,IAAI;AAEJ,KAAI,OAAO,WAAW,WACpB,aAAY,MAAM,QAAQ;UACjB,MAAM,QAAQ,OAAO,CAC9B,aAAY;KAEZ,aAAY,EAAE;AAGhB,QAAO,UAAU,OAAO,QAAQ;;AA2DlC,SAAS,UACP,aACA,eAAe,OACH;CACZ,MAAM,QAAgC,EACpC,OAAO,gDACR;AACD,KAAI,aACF,OAAM,iBAAiB;AAGzB,QAAO,OAAO;EAAE,SAAS;EAAO,UAAU;EAAS,CAAC,CACjD,IAAI,aAAa,MAAM,CACvB,IAAI,mDAAmD"}
|
package/src/lib/build-ssr.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import { UserConfig } from
|
|
2
|
-
import { Options } from
|
|
1
|
+
import { UserConfig } from "vite";
|
|
2
|
+
import { Options } from "./options.js";
|
|
3
|
+
export declare function buildClientApp(config: UserConfig, options?: Options): Promise<void>;
|
|
3
4
|
export declare function buildSSRApp(config: UserConfig, options?: Options): Promise<void>;
|