@analogjs/vite-plugin-nitro 2.0.0-beta.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/lib/utils/get-content-files.d.ts +54 -0
- package/src/lib/utils/get-content-files.js +71 -5
- package/src/lib/utils/get-content-files.js.map +1 -1
- package/src/lib/utils/get-page-handlers.d.ts +52 -0
- package/src/lib/utils/get-page-handlers.js +68 -10
- package/src/lib/utils/get-page-handlers.js.map +1 -1
- package/src/lib/utils/register-dev-middleware.d.ts +40 -0
- package/src/lib/utils/register-dev-middleware.js +53 -4
- package/src/lib/utils/register-dev-middleware.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,2 +1,56 @@
|
|
|
1
1
|
import { PrerenderContentFile } from '../options';
|
|
2
|
+
/**
|
|
3
|
+
* Discovers content files with front matter and extracts metadata for prerendering.
|
|
4
|
+
*
|
|
5
|
+
* This function:
|
|
6
|
+
* 1. Discovers all content files matching the specified glob pattern
|
|
7
|
+
* 2. Reads each file and parses front matter metadata
|
|
8
|
+
* 3. Extracts file name, extension, and path information
|
|
9
|
+
* 4. Returns structured data for prerendering content pages
|
|
10
|
+
*
|
|
11
|
+
* @param workspaceRoot The workspace root directory path
|
|
12
|
+
* @param rootDir The project root directory relative to workspace
|
|
13
|
+
* @param glob The glob pattern to match content files (e.g., 'content/blog')
|
|
14
|
+
* @returns Array of PrerenderContentFile objects with metadata and front matter
|
|
15
|
+
*
|
|
16
|
+
* Example usage:
|
|
17
|
+
* const contentFiles = getMatchingContentFilesWithFrontMatter(
|
|
18
|
+
* '/workspace',
|
|
19
|
+
* 'apps/my-app',
|
|
20
|
+
* 'content/blog'
|
|
21
|
+
* );
|
|
22
|
+
*
|
|
23
|
+
* Sample discovered file paths:
|
|
24
|
+
* - /workspace/apps/my-app/content/blog/first-post.md
|
|
25
|
+
* - /workspace/apps/my-app/content/blog/2024/01/hello-world.md
|
|
26
|
+
* - /workspace/apps/my-app/content/blog/tech/angular-v17.mdx
|
|
27
|
+
* - /workspace/apps/my-app/content/blog/about/index.md
|
|
28
|
+
*
|
|
29
|
+
* Sample output structure:
|
|
30
|
+
* {
|
|
31
|
+
* name: 'first-post',
|
|
32
|
+
* extension: 'md',
|
|
33
|
+
* path: 'content/blog',
|
|
34
|
+
* attributes: { title: 'My First Post', date: '2024-01-01', tags: ['intro'] }
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* tinyglobby vs fast-glob comparison:
|
|
38
|
+
* - Both support the same glob patterns for file discovery
|
|
39
|
+
* - Both are efficient for finding content files
|
|
40
|
+
* - tinyglobby is now used instead of fast-glob
|
|
41
|
+
* - tinyglobby provides similar functionality with smaller bundle size
|
|
42
|
+
* - tinyglobby's globSync returns absolute paths when absolute: true is set
|
|
43
|
+
*
|
|
44
|
+
* Front matter parsing:
|
|
45
|
+
* - Uses front-matter library to parse YAML/TOML front matter
|
|
46
|
+
* - Extracts metadata like title, date, tags, author, etc.
|
|
47
|
+
* - Supports both YAML (---) and TOML (+++) delimiters
|
|
48
|
+
* - Returns structured attributes for prerendering
|
|
49
|
+
*
|
|
50
|
+
* File path processing:
|
|
51
|
+
* - Normalizes paths for cross-platform compatibility
|
|
52
|
+
* - Extracts file name without extension
|
|
53
|
+
* - Determines file extension for content type handling
|
|
54
|
+
* - Maintains relative path structure for routing
|
|
55
|
+
*/
|
|
2
56
|
export declare function getMatchingContentFilesWithFrontMatter(workspaceRoot: string, rootDir: string, glob: string): PrerenderContentFile[];
|
|
@@ -2,28 +2,94 @@ import { readFileSync } from 'node:fs';
|
|
|
2
2
|
import { join, relative, resolve } from 'node:path';
|
|
3
3
|
import { normalizePath } from 'vite';
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
|
+
import { globSync } from 'tinyglobby';
|
|
5
6
|
const require = createRequire(import.meta.url);
|
|
7
|
+
/**
|
|
8
|
+
* Discovers content files with front matter and extracts metadata for prerendering.
|
|
9
|
+
*
|
|
10
|
+
* This function:
|
|
11
|
+
* 1. Discovers all content files matching the specified glob pattern
|
|
12
|
+
* 2. Reads each file and parses front matter metadata
|
|
13
|
+
* 3. Extracts file name, extension, and path information
|
|
14
|
+
* 4. Returns structured data for prerendering content pages
|
|
15
|
+
*
|
|
16
|
+
* @param workspaceRoot The workspace root directory path
|
|
17
|
+
* @param rootDir The project root directory relative to workspace
|
|
18
|
+
* @param glob The glob pattern to match content files (e.g., 'content/blog')
|
|
19
|
+
* @returns Array of PrerenderContentFile objects with metadata and front matter
|
|
20
|
+
*
|
|
21
|
+
* Example usage:
|
|
22
|
+
* const contentFiles = getMatchingContentFilesWithFrontMatter(
|
|
23
|
+
* '/workspace',
|
|
24
|
+
* 'apps/my-app',
|
|
25
|
+
* 'content/blog'
|
|
26
|
+
* );
|
|
27
|
+
*
|
|
28
|
+
* Sample discovered file paths:
|
|
29
|
+
* - /workspace/apps/my-app/content/blog/first-post.md
|
|
30
|
+
* - /workspace/apps/my-app/content/blog/2024/01/hello-world.md
|
|
31
|
+
* - /workspace/apps/my-app/content/blog/tech/angular-v17.mdx
|
|
32
|
+
* - /workspace/apps/my-app/content/blog/about/index.md
|
|
33
|
+
*
|
|
34
|
+
* Sample output structure:
|
|
35
|
+
* {
|
|
36
|
+
* name: 'first-post',
|
|
37
|
+
* extension: 'md',
|
|
38
|
+
* path: 'content/blog',
|
|
39
|
+
* attributes: { title: 'My First Post', date: '2024-01-01', tags: ['intro'] }
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* tinyglobby vs fast-glob comparison:
|
|
43
|
+
* - Both support the same glob patterns for file discovery
|
|
44
|
+
* - Both are efficient for finding content files
|
|
45
|
+
* - tinyglobby is now used instead of fast-glob
|
|
46
|
+
* - tinyglobby provides similar functionality with smaller bundle size
|
|
47
|
+
* - tinyglobby's globSync returns absolute paths when absolute: true is set
|
|
48
|
+
*
|
|
49
|
+
* Front matter parsing:
|
|
50
|
+
* - Uses front-matter library to parse YAML/TOML front matter
|
|
51
|
+
* - Extracts metadata like title, date, tags, author, etc.
|
|
52
|
+
* - Supports both YAML (---) and TOML (+++) delimiters
|
|
53
|
+
* - Returns structured attributes for prerendering
|
|
54
|
+
*
|
|
55
|
+
* File path processing:
|
|
56
|
+
* - Normalizes paths for cross-platform compatibility
|
|
57
|
+
* - Extracts file name without extension
|
|
58
|
+
* - Determines file extension for content type handling
|
|
59
|
+
* - Maintains relative path structure for routing
|
|
60
|
+
*/
|
|
6
61
|
export function getMatchingContentFilesWithFrontMatter(workspaceRoot, rootDir, glob) {
|
|
7
|
-
//
|
|
8
|
-
const fg = require('fast-glob');
|
|
62
|
+
// Dynamically require front-matter library
|
|
9
63
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
10
64
|
const fm = require('front-matter');
|
|
65
|
+
// Normalize the project root path for consistent path handling
|
|
11
66
|
const root = normalizePath(resolve(workspaceRoot, rootDir));
|
|
67
|
+
// Resolve the content directory path relative to the project root
|
|
12
68
|
const resolvedDir = normalizePath(relative(root, join(root, glob)));
|
|
13
|
-
|
|
69
|
+
// Discover all content files in the specified directory
|
|
70
|
+
// Pattern: looks for any files in the resolved directory
|
|
71
|
+
const contentFiles = globSync([`${root}/${resolvedDir}/*`], {
|
|
14
72
|
dot: true,
|
|
73
|
+
absolute: true,
|
|
15
74
|
});
|
|
75
|
+
// Process each discovered content file to extract metadata and front matter
|
|
16
76
|
const mappedFilesWithFm = contentFiles.map((f) => {
|
|
77
|
+
// Read the file contents as UTF-8 text
|
|
17
78
|
const fileContents = readFileSync(f, 'utf8');
|
|
79
|
+
// Parse front matter from the file content
|
|
18
80
|
const raw = fm(fileContents);
|
|
81
|
+
// Get the relative file path by removing the root directory
|
|
19
82
|
const filepath = f.replace(root, '');
|
|
83
|
+
// Extract file name and extension using regex
|
|
84
|
+
// Matches: /filename.ext or /filename (with optional extension)
|
|
20
85
|
const match = filepath.match(/\/([^/.]+)(\.([^/.]+))?$/);
|
|
21
86
|
let name = '';
|
|
22
87
|
let extension = '';
|
|
23
88
|
if (match) {
|
|
24
|
-
name = match[1];
|
|
25
|
-
extension = match[3] || ''; //
|
|
89
|
+
name = match[1]; // File name without extension
|
|
90
|
+
extension = match[3] || ''; // File extension or empty string if no extension
|
|
26
91
|
}
|
|
92
|
+
// Return structured content file data for prerendering
|
|
27
93
|
return {
|
|
28
94
|
name,
|
|
29
95
|
extension,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-content-files.js","sourceRoot":"","sources":["../../../../../../packages/vite-plugin-nitro/src/lib/utils/get-content-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"get-content-files.js","sourceRoot":"","sources":["../../../../../../packages/vite-plugin-nitro/src/lib/utils/get-content-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAItC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAM,UAAU,sCAAsC,CACpD,aAAqB,EACrB,OAAe,EACf,IAAY;IAEZ,2CAA2C;IAC3C,8DAA8D;IAC9D,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAEnC,+DAA+D;IAC/D,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC;IAE5D,kEAAkE;IAClE,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAEpE,wDAAwD;IACxD,yDAAyD;IACzD,MAAM,YAAY,GAAa,QAAQ,CAAC,CAAC,GAAG,IAAI,IAAI,WAAW,IAAI,CAAC,EAAE;QACpE,GAAG,EAAE,IAAI;QACT,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,4EAA4E;IAC5E,MAAM,iBAAiB,GAA2B,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACvE,uCAAuC;QACvC,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAE7C,2CAA2C;QAC3C,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC;QAE7B,4DAA4D;QAC5D,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAErC,8CAA8C;QAC9C,gEAAgE;QAChE,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACzD,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,SAAS,GAAG,EAAE,CAAC;QACnB,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,8BAA8B;YAC/C,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,iDAAiD;QAC/E,CAAC;QAED,uDAAuD;QACvD,OAAO;YACL,IAAI;YACJ,SAAS;YACT,IAAI,EAAE,WAAW;YACjB,UAAU,EAAE,GAAG,CAAC,UAAiD;SAClE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,iBAAiB,CAAC;AAC3B,CAAC"}
|
|
@@ -6,5 +6,57 @@ type GetHandlersArgs = {
|
|
|
6
6
|
additionalPagesDirs?: string[];
|
|
7
7
|
hasAPIDir?: boolean;
|
|
8
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Discovers and generates Nitro event handlers for server-side page routes.
|
|
11
|
+
*
|
|
12
|
+
* This function:
|
|
13
|
+
* 1. Discovers all .server.ts files in the app/pages directory and additional pages directories
|
|
14
|
+
* 2. Converts file paths to route patterns using Angular-style route syntax
|
|
15
|
+
* 3. Generates Nitro event handlers with proper route mapping and lazy loading
|
|
16
|
+
* 4. Handles dynamic route parameters and catch-all routes
|
|
17
|
+
*
|
|
18
|
+
* @param workspaceRoot The workspace root directory path
|
|
19
|
+
* @param sourceRoot The source directory path (e.g., 'src')
|
|
20
|
+
* @param rootDir The project root directory relative to workspace
|
|
21
|
+
* @param additionalPagesDirs Optional array of additional pages directories to scan
|
|
22
|
+
* @param hasAPIDir Whether the project has an API directory (affects route prefixing)
|
|
23
|
+
* @returns Array of NitroEventHandler objects with handler paths and route patterns
|
|
24
|
+
*
|
|
25
|
+
* Example usage:
|
|
26
|
+
* const handlers = getPageHandlers({
|
|
27
|
+
* workspaceRoot: '/workspace',
|
|
28
|
+
* sourceRoot: 'src',
|
|
29
|
+
* rootDir: 'apps/my-app',
|
|
30
|
+
* additionalPagesDirs: ['/libs/shared/pages'],
|
|
31
|
+
* hasAPIDir: true
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* Sample discovered file paths:
|
|
35
|
+
* - /workspace/apps/my-app/src/app/pages/index.server.ts
|
|
36
|
+
* - /workspace/apps/my-app/src/app/pages/users/[id].server.ts
|
|
37
|
+
* - /workspace/apps/my-app/src/app/pages/products/[...slug].server.ts
|
|
38
|
+
* - /workspace/apps/my-app/src/app/pages/(auth)/login.server.ts
|
|
39
|
+
*
|
|
40
|
+
* Route transformation examples:
|
|
41
|
+
* - index.server.ts → /_analog/pages/index
|
|
42
|
+
* - users/[id].server.ts → /_analog/pages/users/:id
|
|
43
|
+
* - products/[...slug].server.ts → /_analog/pages/products/**:slug
|
|
44
|
+
* - (auth)/login.server.ts → /_analog/pages/-auth-/login
|
|
45
|
+
*
|
|
46
|
+
* tinyglobby vs fast-glob comparison:
|
|
47
|
+
* - Both support the same glob patterns for file discovery
|
|
48
|
+
* - Both are efficient for finding server-side page files
|
|
49
|
+
* - tinyglobby is now used instead of fast-glob
|
|
50
|
+
* - tinyglobby provides similar functionality with smaller bundle size
|
|
51
|
+
* - tinyglobby's globSync returns absolute paths when absolute: true is set
|
|
52
|
+
*
|
|
53
|
+
* Route transformation rules:
|
|
54
|
+
* 1. Removes .server.ts extension
|
|
55
|
+
* 2. Converts [param] to :param for dynamic routes
|
|
56
|
+
* 3. Converts [...param] to **:param for catch-all routes
|
|
57
|
+
* 4. Converts (group) to -group- for route groups
|
|
58
|
+
* 5. Converts dots to forward slashes
|
|
59
|
+
* 6. Prefixes with /_analog/pages and optionally /api
|
|
60
|
+
*/
|
|
9
61
|
export declare function getPageHandlers({ workspaceRoot, sourceRoot, rootDir, additionalPagesDirs, hasAPIDir, }: GetHandlersArgs): NitroEventHandler[];
|
|
10
62
|
export {};
|
|
@@ -1,21 +1,79 @@
|
|
|
1
1
|
import { resolve } from 'node:path';
|
|
2
|
-
import
|
|
2
|
+
import { globSync } from 'tinyglobby';
|
|
3
3
|
import { normalizePath } from 'vite';
|
|
4
|
+
/**
|
|
5
|
+
* Discovers and generates Nitro event handlers for server-side page routes.
|
|
6
|
+
*
|
|
7
|
+
* This function:
|
|
8
|
+
* 1. Discovers all .server.ts files in the app/pages directory and additional pages directories
|
|
9
|
+
* 2. Converts file paths to route patterns using Angular-style route syntax
|
|
10
|
+
* 3. Generates Nitro event handlers with proper route mapping and lazy loading
|
|
11
|
+
* 4. Handles dynamic route parameters and catch-all routes
|
|
12
|
+
*
|
|
13
|
+
* @param workspaceRoot The workspace root directory path
|
|
14
|
+
* @param sourceRoot The source directory path (e.g., 'src')
|
|
15
|
+
* @param rootDir The project root directory relative to workspace
|
|
16
|
+
* @param additionalPagesDirs Optional array of additional pages directories to scan
|
|
17
|
+
* @param hasAPIDir Whether the project has an API directory (affects route prefixing)
|
|
18
|
+
* @returns Array of NitroEventHandler objects with handler paths and route patterns
|
|
19
|
+
*
|
|
20
|
+
* Example usage:
|
|
21
|
+
* const handlers = getPageHandlers({
|
|
22
|
+
* workspaceRoot: '/workspace',
|
|
23
|
+
* sourceRoot: 'src',
|
|
24
|
+
* rootDir: 'apps/my-app',
|
|
25
|
+
* additionalPagesDirs: ['/libs/shared/pages'],
|
|
26
|
+
* hasAPIDir: true
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* Sample discovered file paths:
|
|
30
|
+
* - /workspace/apps/my-app/src/app/pages/index.server.ts
|
|
31
|
+
* - /workspace/apps/my-app/src/app/pages/users/[id].server.ts
|
|
32
|
+
* - /workspace/apps/my-app/src/app/pages/products/[...slug].server.ts
|
|
33
|
+
* - /workspace/apps/my-app/src/app/pages/(auth)/login.server.ts
|
|
34
|
+
*
|
|
35
|
+
* Route transformation examples:
|
|
36
|
+
* - index.server.ts → /_analog/pages/index
|
|
37
|
+
* - users/[id].server.ts → /_analog/pages/users/:id
|
|
38
|
+
* - products/[...slug].server.ts → /_analog/pages/products/**:slug
|
|
39
|
+
* - (auth)/login.server.ts → /_analog/pages/-auth-/login
|
|
40
|
+
*
|
|
41
|
+
* tinyglobby vs fast-glob comparison:
|
|
42
|
+
* - Both support the same glob patterns for file discovery
|
|
43
|
+
* - Both are efficient for finding server-side page files
|
|
44
|
+
* - tinyglobby is now used instead of fast-glob
|
|
45
|
+
* - tinyglobby provides similar functionality with smaller bundle size
|
|
46
|
+
* - tinyglobby's globSync returns absolute paths when absolute: true is set
|
|
47
|
+
*
|
|
48
|
+
* Route transformation rules:
|
|
49
|
+
* 1. Removes .server.ts extension
|
|
50
|
+
* 2. Converts [param] to :param for dynamic routes
|
|
51
|
+
* 3. Converts [...param] to **:param for catch-all routes
|
|
52
|
+
* 4. Converts (group) to -group- for route groups
|
|
53
|
+
* 5. Converts dots to forward slashes
|
|
54
|
+
* 6. Prefixes with /_analog/pages and optionally /api
|
|
55
|
+
*/
|
|
4
56
|
export function getPageHandlers({ workspaceRoot, sourceRoot, rootDir, additionalPagesDirs, hasAPIDir, }) {
|
|
57
|
+
// Normalize the project root path for consistent path handling
|
|
5
58
|
const root = normalizePath(resolve(workspaceRoot, rootDir));
|
|
6
|
-
|
|
59
|
+
// Discover all .server.ts files in the app/pages directory and additional pages directories
|
|
60
|
+
// Pattern: looks for any .server.ts files in app/pages/**/*.server.ts and additional directories
|
|
61
|
+
const endpointFiles = globSync([
|
|
7
62
|
`${root}/${sourceRoot}/app/pages/**/*.server.ts`,
|
|
8
63
|
...(additionalPagesDirs || []).map((dir) => `${workspaceRoot}${dir}/**/*.server.ts`),
|
|
9
|
-
], { dot: true });
|
|
64
|
+
], { dot: true, absolute: true });
|
|
65
|
+
// Transform each discovered file into a Nitro event handler
|
|
10
66
|
const handlers = endpointFiles.map((endpointFile) => {
|
|
67
|
+
// Convert file path to route pattern using Angular-style route syntax
|
|
11
68
|
const route = endpointFile
|
|
12
|
-
.replace(/^(.*?)\/pages/, '/pages')
|
|
13
|
-
.replace(/\.server\.ts$/, '')
|
|
14
|
-
.replace(/\[\.{3}(.+)\]/g, '**:$1')
|
|
15
|
-
.replace(/\[\.{3}(\w+)\]/g, '**:$1')
|
|
16
|
-
.replace(/\/\((.*?)\)$/, '/-$1-')
|
|
17
|
-
.replace(/\[(\w+)\]/g, ':$1')
|
|
18
|
-
.replace(/\./g, '/');
|
|
69
|
+
.replace(/^(.*?)\/pages/, '/pages') // Remove everything before /pages
|
|
70
|
+
.replace(/\.server\.ts$/, '') // Remove .server.ts extension
|
|
71
|
+
.replace(/\[\.{3}(.+)\]/g, '**:$1') // Convert [...param] to **:param (catch-all routes)
|
|
72
|
+
.replace(/\[\.{3}(\w+)\]/g, '**:$1') // Alternative catch-all pattern
|
|
73
|
+
.replace(/\/\((.*?)\)$/, '/-$1-') // Convert (group) to -group- (route groups)
|
|
74
|
+
.replace(/\[(\w+)\]/g, ':$1') // Convert [param] to :param (dynamic routes)
|
|
75
|
+
.replace(/\./g, '/'); // Convert dots to forward slashes
|
|
76
|
+
// Return Nitro event handler with absolute handler path and transformed route
|
|
19
77
|
return {
|
|
20
78
|
handler: endpointFile,
|
|
21
79
|
route: `${hasAPIDir ? '/api' : ''}/_analog${route}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-page-handlers.js","sourceRoot":"","sources":["../../../../../../packages/vite-plugin-nitro/src/lib/utils/get-page-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"get-page-handlers.js","sourceRoot":"","sources":["../../../../../../packages/vite-plugin-nitro/src/lib/utils/get-page-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAUrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,aAAa,EACb,UAAU,EACV,OAAO,EACP,mBAAmB,EACnB,SAAS,GACO;IAChB,+DAA+D;IAC/D,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC;IAE5D,4FAA4F;IAC5F,iGAAiG;IACjG,MAAM,aAAa,GAAa,QAAQ,CACtC;QACE,GAAG,IAAI,IAAI,UAAU,2BAA2B;QAChD,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC,GAAG,CAChC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,aAAa,GAAG,GAAG,iBAAiB,CACjD;KACF,EACD,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAC9B,CAAC;IAEF,4DAA4D;IAC5D,MAAM,QAAQ,GAAwB,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE;QACvE,sEAAsE;QACtE,MAAM,KAAK,GAAG,YAAY;aACvB,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,kCAAkC;aACrE,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,8BAA8B;aAC3D,OAAO,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,oDAAoD;aACvF,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,gCAAgC;aACpE,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,4CAA4C;aAC7E,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,6CAA6C;aAC1E,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,kCAAkC;QAE1D,8EAA8E;QAC9E,OAAO;YACL,OAAO,EAAE,YAAY;YACrB,KAAK,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,EAAE;YACnD,IAAI,EAAE,IAAI;SACX,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -1,2 +1,42 @@
|
|
|
1
1
|
import { ViteDevServer } from 'vite';
|
|
2
|
+
/**
|
|
3
|
+
* Registers development server middleware by discovering and loading middleware files.
|
|
4
|
+
*
|
|
5
|
+
* This function:
|
|
6
|
+
* 1. Discovers all TypeScript middleware files in the server/middleware directory
|
|
7
|
+
* 2. Dynamically loads each middleware module using Vite's SSR module loader
|
|
8
|
+
* 3. Registers each middleware handler with the Vite development server
|
|
9
|
+
* 4. Handles middleware execution flow and error handling
|
|
10
|
+
*
|
|
11
|
+
* @param root The project root directory path
|
|
12
|
+
* @param sourceRoot The source directory path (e.g., 'src')
|
|
13
|
+
* @param viteServer The Vite development server instance
|
|
14
|
+
*
|
|
15
|
+
* Example usage:
|
|
16
|
+
* await registerDevServerMiddleware('/workspace/my-app', 'src', viteServer);
|
|
17
|
+
*
|
|
18
|
+
* Sample middleware file paths that would be discovered:
|
|
19
|
+
* - /workspace/my-app/src/server/middleware/auth.ts
|
|
20
|
+
* - /workspace/my-app/src/server/middleware/cors.ts
|
|
21
|
+
* - /workspace/my-app/src/server/middleware/logging.ts
|
|
22
|
+
* - /workspace/my-app/src/server/middleware/validation.ts
|
|
23
|
+
*
|
|
24
|
+
* tinyglobby vs fast-glob comparison:
|
|
25
|
+
* - Both support the same glob patterns for file discovery
|
|
26
|
+
* - Both are efficient for finding middleware files
|
|
27
|
+
* - tinyglobby is now used instead of fast-glob
|
|
28
|
+
* - tinyglobby provides similar functionality with smaller bundle size
|
|
29
|
+
* - tinyglobby's globSync returns absolute paths when absolute: true is set
|
|
30
|
+
*
|
|
31
|
+
* globSync options explained:
|
|
32
|
+
* - dot: true - Includes files/directories that start with a dot (e.g., .env.middleware)
|
|
33
|
+
* - absolute: true - Returns absolute file paths instead of relative paths
|
|
34
|
+
*
|
|
35
|
+
* Middleware execution flow:
|
|
36
|
+
* 1. Request comes to Vite dev server
|
|
37
|
+
* 2. Each registered middleware is executed in order
|
|
38
|
+
* 3. If middleware returns a result, request processing stops
|
|
39
|
+
* 4. If middleware returns no result, next middleware is called
|
|
40
|
+
* 5. If no middleware handles the request, it continues to normal Vite processing
|
|
41
|
+
*/
|
|
2
42
|
export declare function registerDevServerMiddleware(root: string, sourceRoot: string, viteServer: ViteDevServer): Promise<void>;
|
|
@@ -1,15 +1,64 @@
|
|
|
1
1
|
import { createEvent } from 'h3';
|
|
2
|
-
import
|
|
2
|
+
import { globSync } from 'tinyglobby';
|
|
3
|
+
/**
|
|
4
|
+
* Registers development server middleware by discovering and loading middleware files.
|
|
5
|
+
*
|
|
6
|
+
* This function:
|
|
7
|
+
* 1. Discovers all TypeScript middleware files in the server/middleware directory
|
|
8
|
+
* 2. Dynamically loads each middleware module using Vite's SSR module loader
|
|
9
|
+
* 3. Registers each middleware handler with the Vite development server
|
|
10
|
+
* 4. Handles middleware execution flow and error handling
|
|
11
|
+
*
|
|
12
|
+
* @param root The project root directory path
|
|
13
|
+
* @param sourceRoot The source directory path (e.g., 'src')
|
|
14
|
+
* @param viteServer The Vite development server instance
|
|
15
|
+
*
|
|
16
|
+
* Example usage:
|
|
17
|
+
* await registerDevServerMiddleware('/workspace/my-app', 'src', viteServer);
|
|
18
|
+
*
|
|
19
|
+
* Sample middleware file paths that would be discovered:
|
|
20
|
+
* - /workspace/my-app/src/server/middleware/auth.ts
|
|
21
|
+
* - /workspace/my-app/src/server/middleware/cors.ts
|
|
22
|
+
* - /workspace/my-app/src/server/middleware/logging.ts
|
|
23
|
+
* - /workspace/my-app/src/server/middleware/validation.ts
|
|
24
|
+
*
|
|
25
|
+
* tinyglobby vs fast-glob comparison:
|
|
26
|
+
* - Both support the same glob patterns for file discovery
|
|
27
|
+
* - Both are efficient for finding middleware files
|
|
28
|
+
* - tinyglobby is now used instead of fast-glob
|
|
29
|
+
* - tinyglobby provides similar functionality with smaller bundle size
|
|
30
|
+
* - tinyglobby's globSync returns absolute paths when absolute: true is set
|
|
31
|
+
*
|
|
32
|
+
* globSync options explained:
|
|
33
|
+
* - dot: true - Includes files/directories that start with a dot (e.g., .env.middleware)
|
|
34
|
+
* - absolute: true - Returns absolute file paths instead of relative paths
|
|
35
|
+
*
|
|
36
|
+
* Middleware execution flow:
|
|
37
|
+
* 1. Request comes to Vite dev server
|
|
38
|
+
* 2. Each registered middleware is executed in order
|
|
39
|
+
* 3. If middleware returns a result, request processing stops
|
|
40
|
+
* 4. If middleware returns no result, next middleware is called
|
|
41
|
+
* 5. If no middleware handles the request, it continues to normal Vite processing
|
|
42
|
+
*/
|
|
3
43
|
export async function registerDevServerMiddleware(root, sourceRoot, viteServer) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
]
|
|
44
|
+
// Discover all TypeScript middleware files in the server/middleware directory
|
|
45
|
+
// Pattern: looks for any .ts files in server/middleware/**/*.ts
|
|
46
|
+
const middlewareFiles = globSync([`${root}/${sourceRoot}/server/middleware/**/*.ts`], {
|
|
47
|
+
dot: true,
|
|
48
|
+
absolute: true,
|
|
49
|
+
});
|
|
50
|
+
// Register each discovered middleware file with the Vite dev server
|
|
7
51
|
middlewareFiles.forEach((file) => {
|
|
8
52
|
viteServer.middlewares.use(async (req, res, next) => {
|
|
53
|
+
// Dynamically load the middleware module using Vite's SSR module loader
|
|
54
|
+
// This allows for hot module replacement during development
|
|
9
55
|
const middlewareHandler = await viteServer
|
|
10
56
|
.ssrLoadModule(file)
|
|
11
57
|
.then((m) => m.default);
|
|
58
|
+
// Execute the middleware handler with the request/response event
|
|
12
59
|
const result = await middlewareHandler(createEvent(req, res));
|
|
60
|
+
// If middleware doesn't return a result, continue to next middleware
|
|
61
|
+
// If middleware returns a result, stop processing (middleware handled the request)
|
|
13
62
|
if (!result) {
|
|
14
63
|
next();
|
|
15
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-dev-middleware.js","sourceRoot":"","sources":["../../../../../../packages/vite-plugin-nitro/src/lib/utils/register-dev-middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,WAAW,EAAE,MAAM,IAAI,CAAC;AAC/C,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"register-dev-middleware.js","sourceRoot":"","sources":["../../../../../../packages/vite-plugin-nitro/src/lib/utils/register-dev-middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,WAAW,EAAE,MAAM,IAAI,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,IAAY,EACZ,UAAkB,EAClB,UAAyB;IAEzB,8EAA8E;IAC9E,gEAAgE;IAChE,MAAM,eAAe,GAAG,QAAQ,CAC9B,CAAC,GAAG,IAAI,IAAI,UAAU,4BAA4B,CAAC,EACnD;QACE,GAAG,EAAE,IAAI;QACT,QAAQ,EAAE,IAAI;KACf,CACF,CAAC;IAEF,oEAAoE;IACpE,eAAe,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/B,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAClD,wEAAwE;YACxE,4DAA4D;YAC5D,MAAM,iBAAiB,GAAiB,MAAM,UAAU;iBACrD,aAAa,CAAC,IAAI,CAAC;iBACnB,IAAI,CAAC,CAAC,CAAU,EAAE,EAAE,CAAE,CAA+B,CAAC,OAAO,CAAC,CAAC;YAElE,iEAAiE;YACjE,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YAE9D,qEAAqE;YACrE,mFAAmF;YACnF,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,IAAI,EAAE,CAAC;YACT,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|