sigpro 1.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.
@@ -0,0 +1,139 @@
1
+ # SigPro Router Plugin for Vite
2
+
3
+ A Vite plugin that automatically generates routes from your file structure in `src/pages/`, similar to Next.js file-based routing but for any JavaScript project.
4
+
5
+ ## Features
6
+
7
+ - šŸ“ **File-based routing**: Automatically creates routes from your `src/pages` directory
8
+ - šŸ”— **Dynamic routes**: Supports parameterized routes using `[param]` syntax
9
+ - 🧭 **Path-to-regexp conversion**: Dynamic routes are converted to RegExp with named capture groups
10
+ - šŸ“Š **Route map generation**: Console output shows all detected routes at build time
11
+ - šŸŽÆ **Virtual module**: Access your routes via `virtual:sigpro-routes`
12
+
13
+ ## Installation
14
+
15
+ 1. Save the plugin code in your project, for example as `plugins/sigpro-router.js`
16
+
17
+ 2. Add it to your Vite configuration:
18
+
19
+ ```javascript
20
+ // vite.config.js
21
+ import { defineConfig } from 'vite';
22
+ import sigproRouter from './plugins/sigpro-router';
23
+
24
+ export default defineConfig({
25
+ plugins: [sigproRouter()]
26
+ });
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ ### 1. Create Pages
32
+
33
+ Create `.js` files in your `src/pages` directory. Each file becomes a route:
34
+
35
+ ```
36
+ src/pages/
37
+ ā”œā”€ā”€ index.js -> /
38
+ ā”œā”€ā”€ about.js -> /about
39
+ ā”œā”€ā”€ blog/
40
+ │ ā”œā”€ā”€ index.js -> /blog
41
+ │ └── [id].js -> /blog/:id (dynamic)
42
+ └── users/
43
+ └── [userId].js -> /users/:userId (dynamic)
44
+ ```
45
+
46
+ ### 2. Access Routes in Your Application
47
+
48
+ The plugin exposes a virtual module `virtual:sigpro-routes` that exports a `routes` array:
49
+
50
+ ```javascript
51
+ // In your router or main application file
52
+ import { routes } from 'virtual:sigpro-routes';
53
+
54
+ // The routes array structure:
55
+ // [
56
+ // { path: '/', component: PageComponent, isDynamic: false, paramName: null },
57
+ // { path: /^\/blog\/(?<id>[^/]+)$/, component: PageComponent, isDynamic: true, paramName: 'id' },
58
+ // { path: /^\/users\/(?<userId>[^/]+)$/, component: PageComponent, isDynamic: true, paramName: 'userId' },
59
+ // ]
60
+
61
+ // Example usage with a simple router
62
+ function renderRoute(path) {
63
+ for (const route of routes) {
64
+ if (!route.isDynamic && route.path === path) {
65
+ return route.component();
66
+ } else if (route.isDynamic) {
67
+ const match = path.match(route.path);
68
+ if (match) {
69
+ // Access params via match.groups
70
+ const params = match.groups;
71
+ return route.component(params);
72
+ }
73
+ }
74
+ }
75
+ return '<h1>404 Not Found</h1>';
76
+ }
77
+ ```
78
+
79
+ ### 3. Build Time Output
80
+
81
+ When you run your Vite dev server or build, you'll see a route map in the console:
82
+
83
+ ```
84
+ šŸš€ [SigPro Router] Mapa de rutas generado:
85
+ šŸ“„ / -> index.js
86
+ šŸ“„ /about -> about.js
87
+ šŸ“„ /blog -> blog/index.js
88
+ šŸ”— /blog/[id] -> blog/[id].js
89
+ šŸ”— /users/[userId] -> users/[userId].js
90
+ ```
91
+
92
+ ## Route Priority
93
+
94
+ Routes are automatically prioritized:
95
+
96
+ 1. Static routes (non-dynamic) are matched before dynamic routes
97
+ 2. Routes are sorted by path length (shorter paths first)
98
+
99
+ ## Route Object Properties
100
+
101
+ Each route in the `routes` array contains:
102
+
103
+ | Property | Type | Description |
104
+ |----------|------|-------------|
105
+ | `path` | `string \| RegExp` | Static path string or RegExp for dynamic routes |
106
+ | `component` | `Function` | The imported page component/module |
107
+ | `isDynamic` | `boolean` | Whether the route has parameters |
108
+ | `paramName` | `string \| null` | The parameter name for dynamic routes |
109
+
110
+ ## Dynamic Route Parameters
111
+
112
+ For dynamic routes like `blog/[id].js`:
113
+
114
+ - The route path becomes: `new RegExp("^\\/blog\\/(?<id>[^/]+)$")`
115
+ - Parameters can be accessed via `match.groups` when matching the route
116
+
117
+ Example:
118
+ ```javascript
119
+ const match = '/blog/123'.match(/^\/blog\/(?<id>[^/]+)$/);
120
+ console.log(match.groups.id); // '123'
121
+ ```
122
+
123
+ ## Limitations
124
+
125
+ - Only scans `.js` files (no JSX/TS support by default - modify the plugin if needed)
126
+ - Requires a `src/pages` directory in your project root
127
+ - Dynamic parameters are matched as single path segments (no catch-all routes)
128
+
129
+ ## Customization
130
+
131
+ You can modify the plugin to:
132
+ - Support other file extensions (.jsx, .ts, .tsx)
133
+ - Change the pages directory location
134
+ - Add custom route sorting logic
135
+ - Implement nested dynamic routes
136
+
137
+ ---
138
+
139
+ Built for SigPro applications with Vite.
@@ -0,0 +1,141 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ /**
5
+ * SigPro Router Plugin for Vite
6
+ *
7
+ * This plugin generates routes automatically based on the file structure in src/pages/
8
+ * It creates a virtual module 'virtual:sigpro-routes' that exports a routes array
9
+ * with all the detected pages and their corresponding components.
10
+ *
11
+ * @returns {import('vite').Plugin} Vite plugin object
12
+ */
13
+ export default function sigproRouter() {
14
+ // Virtual module identifiers
15
+ const VIRTUAL_MODULE_ID = 'virtual:sigpro-routes';
16
+ const RESOLVED_VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID;
17
+
18
+ /**
19
+ * Recursively retrieves all JavaScript files from a directory
20
+ *
21
+ * @param {string} directoryPath - The path to scan for files
22
+ * @returns {string[]} Array of absolute paths to all .js files found
23
+ */
24
+ function getAllJavaScriptFiles(directoryPath) {
25
+ let filesFound = [];
26
+
27
+ // Return empty array if directory doesn't exist
28
+ if (!fs.existsSync(directoryPath)) return filesFound;
29
+
30
+ const directoryContents = fs.readdirSync(directoryPath);
31
+
32
+ directoryContents.forEach(item => {
33
+ const fullItemPath = path.resolve(directoryPath, item);
34
+ const itemStats = fs.statSync(fullItemPath);
35
+
36
+ if (itemStats && itemStats.isDirectory()) {
37
+ // Recursively scan subdirectories
38
+ filesFound = filesFound.concat(getAllJavaScriptFiles(fullItemPath));
39
+ } else if (item.endsWith('.js')) {
40
+ // Add JavaScript files to results
41
+ filesFound.push(fullItemPath);
42
+ }
43
+ });
44
+
45
+ return filesFound;
46
+ }
47
+
48
+ return {
49
+ name: 'sigpro-router',
50
+
51
+ /**
52
+ * Resolves the virtual module ID to our internal ID
53
+ *
54
+ * @param {string} importeeId - The module ID being imported
55
+ * @returns {string|null} The resolved virtual module ID or null
56
+ */
57
+ resolveId(importeeId) {
58
+ if (importeeId === VIRTUAL_MODULE_ID) return RESOLVED_VIRTUAL_MODULE_ID;
59
+ },
60
+
61
+ /**
62
+ * Generates the virtual module content with route definitions
63
+ *
64
+ * @param {string} moduleId - The resolved module ID being loaded
65
+ * @returns {string|null} Generated module code or null
66
+ */
67
+ load(moduleId) {
68
+ if (moduleId === RESOLVED_VIRTUAL_MODULE_ID) {
69
+ const PAGES_DIRECTORY = path.resolve(process.cwd(), 'src/pages');
70
+ let pageFiles = getAllJavaScriptFiles(PAGES_DIRECTORY);
71
+
72
+ /**
73
+ * Sort files to prioritize routes:
74
+ * 1. Static routes come before dynamic routes
75
+ * 2. Shorter paths come first (more specific routes)
76
+ */
77
+ pageFiles = pageFiles.sort((fileA, fileB) => {
78
+ const fileAHasDynamicParam = fileA.includes('[');
79
+ const fileBHasDynamicParam = fileB.includes('[');
80
+
81
+ if (fileAHasDynamicParam !== fileBHasDynamicParam) {
82
+ return fileAHasDynamicParam ? 1 : -1;
83
+ }
84
+ return fileA.length - fileB.length;
85
+ });
86
+
87
+ let importStatements = '';
88
+ let routeDefinitions = 'export const routes = [\n';
89
+
90
+ console.log('\nšŸš€ [SigPro Router] Generated route map:');
91
+
92
+ pageFiles.forEach((fullFilePath, index) => {
93
+ // Calculate relative path from pages directory
94
+ const relativeFilePath = path.relative(PAGES_DIRECTORY, fullFilePath).replace(/\\/g, '/');
95
+ const fileNameWithoutExtension = relativeFilePath.replace('.js', '');
96
+ const componentVariableName = `Page_${index}`;
97
+
98
+ // Convert file path to URL path
99
+ let urlPath = '/' + fileNameWithoutExtension.toLowerCase();
100
+ if (urlPath.endsWith('/index')) urlPath = urlPath.replace('/index', '') || '/';
101
+
102
+ // Detect if this is a dynamic route (contains [param])
103
+ const isDynamicRoute = urlPath.includes('[') && urlPath.includes(']');
104
+ let finalPathValue = `'${urlPath}'`;
105
+ let parameterName = null;
106
+
107
+ if (isDynamicRoute) {
108
+ // Extract parameter name from brackets (e.g., from [id] extract 'id')
109
+ const parameterMatch = urlPath.match(/\[([^\]]+)\]/);
110
+ parameterName = parameterMatch ? parameterMatch[1] : 'id';
111
+
112
+ /**
113
+ * Convert dynamic route to RegExp with named capture groups
114
+ * Example: /blog/[id] becomes new RegExp("^\\/blog\\/(?<id>[^/]+)$")
115
+ * This allows accessing parameters via match.groups.parameterName
116
+ */
117
+ const regexPattern = urlPath
118
+ .replace(/\//g, '\\/')
119
+ .replace(/\[([^\]]+)\]/, '(?<$1>[^/]+)'); // Replace [id] with (?<id>[^/]+)
120
+
121
+ finalPathValue = `new RegExp("^${regexPattern}$")`;
122
+ }
123
+
124
+ // Log route information to console
125
+ console.log(` ${isDynamicRoute ? 'šŸ”—' : 'šŸ“„'} ${urlPath.padEnd(20)} -> ${relativeFilePath}`);
126
+
127
+ // Generate import statement for this page component
128
+ importStatements += `import ${componentVariableName} from './src/pages/${relativeFilePath}';\n`;
129
+
130
+ // Generate route definition object
131
+ routeDefinitions += ` { path: ${finalPathValue}, component: ${componentVariableName}, isDynamic: ${isDynamicRoute}, paramName: ${parameterName ? `'${parameterName}'` : 'null'} },\n`;
132
+ });
133
+
134
+ routeDefinitions += '];';
135
+
136
+ // Return complete module code
137
+ return `${importStatements}\n${routeDefinitions}`;
138
+ }
139
+ }
140
+ };
141
+ }
package/index.js ADDED
@@ -0,0 +1,8 @@
1
+ // This is the main entry point of the package
2
+ // Directly exports your plugin from sigpro.js
3
+
4
+ // If your sigpro.js already exports the plugin as default, you can do:
5
+ export { default } from './sigpro.js';
6
+
7
+ // Or if you prefer CommonJS:
8
+ // module.exports = require('./sigpro.js');
package/package.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "sigpro",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "scripts": {
6
+ "del": "rm node_modules/.vite/deps -r",
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ }
11
+ }
Binary file