@yoamigo.com/core 0.4.8 → 1.0.1

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/router.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode, MouseEvent } from 'react';
3
- export { Route, Switch, useParams } from 'wouter';
3
+ export { Route, Switch, useLocation, useParams } from 'wouter';
4
4
 
5
5
  /**
6
6
  * Router Abstraction - Shared Types
@@ -55,4 +55,82 @@ declare function Router({ children, base }: RouterProps): react_jsx_runtime.JSX.
55
55
  */
56
56
  declare function ScrollRestoration(): null;
57
57
 
58
- export { Link, type LinkProps, type NavigateFunction, Router, type RouterProps$1 as RouterProps, ScrollRestoration, useNavigate };
58
+ /**
59
+ * Route Utilities
60
+ *
61
+ * Utilities for working with file-based routing conventions.
62
+ * Converts file paths with [param] syntax to wouter-compatible route paths.
63
+ *
64
+ * @example
65
+ * ```
66
+ * /src/pages/contact.tsx → /contact
67
+ * /src/pages/products/index.tsx → /products
68
+ * /src/pages/products/[slug].tsx → /products/:slug
69
+ * /src/pages/blog/[category]/[slug].tsx → /blog/:category/:slug
70
+ * ```
71
+ */
72
+ interface RouteDefinition {
73
+ /** The wouter-compatible route path (e.g., '/products/:slug') */
74
+ path: string;
75
+ /** The original file path */
76
+ filePath: string;
77
+ /** Parameter names extracted from the path */
78
+ params: string[];
79
+ /** Whether this is a dynamic route (has params) */
80
+ isDynamic: boolean;
81
+ }
82
+ /**
83
+ * Convert a file path to a wouter-compatible route path.
84
+ *
85
+ * Supports:
86
+ * - `/src/pages/contact.tsx` → `/contact`
87
+ * - `/src/pages/index.tsx` → `/`
88
+ * - `/src/pages/products/index.tsx` → `/products`
89
+ * - `/src/pages/products/[slug].tsx` → `/products/:slug`
90
+ * - `/src/pages/blog/[category]/[slug].tsx` → `/blog/:category/:slug`
91
+ * - `/src/pages/[...rest].tsx` → `/:rest*` (catch-all)
92
+ *
93
+ * @param filePath - The file path (e.g., '/src/pages/products/[slug].tsx')
94
+ * @param options - Options for path conversion
95
+ * @returns The wouter-compatible route path
96
+ */
97
+ declare function filePathToRoutePath(filePath: string, options?: {
98
+ /** Pages directory prefix to strip (default: '/src/pages') */
99
+ pagesDir?: string;
100
+ /** File extensions to remove (default: ['.tsx', '.ts', '.jsx', '.js']) */
101
+ extensions?: string[];
102
+ }): string;
103
+ /**
104
+ * Extract parameter names from a file path.
105
+ *
106
+ * @param filePath - The file path (e.g., '/src/pages/blog/[category]/[slug].tsx')
107
+ * @returns Array of parameter names (e.g., ['category', 'slug'])
108
+ */
109
+ declare function extractRouteParams(filePath: string): string[];
110
+ /**
111
+ * Create a RouteDefinition from a file path.
112
+ *
113
+ * @param filePath - The file path (e.g., '/src/pages/products/[slug].tsx')
114
+ * @param options - Options for path conversion
115
+ * @returns RouteDefinition object
116
+ */
117
+ declare function createRouteDefinition(filePath: string, options?: Parameters<typeof filePathToRoutePath>[1]): RouteDefinition;
118
+ /**
119
+ * Sort route definitions by specificity (most specific first).
120
+ * Static routes come before dynamic routes.
121
+ * More specific dynamic routes come before less specific ones.
122
+ *
123
+ * @param routes - Array of RouteDefinition objects
124
+ * @returns Sorted array (most specific first)
125
+ */
126
+ declare function sortRoutesBySpecificity(routes: RouteDefinition[]): RouteDefinition[];
127
+ /**
128
+ * Generate a path with parameters filled in.
129
+ *
130
+ * @param routePath - The route path with params (e.g., '/products/:slug')
131
+ * @param params - Object with parameter values (e.g., { slug: 'guitar' })
132
+ * @returns The filled path (e.g., '/products/guitar')
133
+ */
134
+ declare function generatePath(routePath: string, params: Record<string, string>): string;
135
+
136
+ export { Link, type LinkProps, type NavigateFunction, type RouteDefinition, Router, type RouterProps$1 as RouterProps, ScrollRestoration, createRouteDefinition, extractRouteParams, filePathToRoutePath, generatePath, sortRoutesBySpecificity, useNavigate };
package/dist/router.js CHANGED
@@ -137,13 +137,86 @@ function ScrollRestoration() {
137
137
  }
138
138
 
139
139
  // src/router/index.ts
140
- import { Route, Switch, useParams } from "wouter";
140
+ import { Route, Switch, useParams, useLocation as useLocation3 } from "wouter";
141
+
142
+ // src/router/route-utils.ts
143
+ function filePathToRoutePath(filePath, options = {}) {
144
+ const {
145
+ pagesDir = "/src/pages",
146
+ extensions = [".tsx", ".ts", ".jsx", ".js"]
147
+ } = options;
148
+ let path = filePath;
149
+ if (path.startsWith(pagesDir)) {
150
+ path = path.slice(pagesDir.length);
151
+ }
152
+ for (const ext of extensions) {
153
+ if (path.endsWith(ext)) {
154
+ path = path.slice(0, -ext.length);
155
+ break;
156
+ }
157
+ }
158
+ if (path.endsWith("/index")) {
159
+ path = path.slice(0, -6) || "/";
160
+ }
161
+ path = path.replace(/\[\.\.\.([^\]]+)\]/g, ":$1*");
162
+ path = path.replace(/\[([^\]]+)\]/g, ":$1");
163
+ if (!path.startsWith("/")) {
164
+ path = "/" + path;
165
+ }
166
+ if (path === "" || path === "/index") {
167
+ return "/";
168
+ }
169
+ return path;
170
+ }
171
+ function extractRouteParams(filePath) {
172
+ const matches = filePath.matchAll(/\[\.\.\.([^\]]+)\]|\[([^\]]+)\]/g);
173
+ const params = [];
174
+ for (const match of matches) {
175
+ params.push(match[1] || match[2]);
176
+ }
177
+ return params;
178
+ }
179
+ function createRouteDefinition(filePath, options) {
180
+ const path = filePathToRoutePath(filePath, options);
181
+ const params = extractRouteParams(filePath);
182
+ return {
183
+ path,
184
+ filePath,
185
+ params,
186
+ isDynamic: params.length > 0
187
+ };
188
+ }
189
+ function sortRoutesBySpecificity(routes) {
190
+ return [...routes].sort((a, b) => {
191
+ if (!a.isDynamic && b.isDynamic) return -1;
192
+ if (a.isDynamic && !b.isDynamic) return 1;
193
+ const aSegments = a.path.split("/").filter(Boolean);
194
+ const bSegments = b.path.split("/").filter(Boolean);
195
+ if (aSegments.length !== bSegments.length) {
196
+ return bSegments.length - aSegments.length;
197
+ }
198
+ return a.params.length - b.params.length;
199
+ });
200
+ }
201
+ function generatePath(routePath, params) {
202
+ let path = routePath;
203
+ for (const [key, value] of Object.entries(params)) {
204
+ path = path.replace(new RegExp(`:${key}\\*?`, "g"), encodeURIComponent(value));
205
+ }
206
+ return path;
207
+ }
141
208
  export {
142
209
  Link,
143
210
  Route,
144
211
  Router,
145
212
  ScrollRestoration,
146
213
  Switch,
214
+ createRouteDefinition,
215
+ extractRouteParams,
216
+ filePathToRoutePath,
217
+ generatePath,
218
+ sortRoutesBySpecificity,
219
+ useLocation3 as useLocation,
147
220
  useNavigate,
148
221
  useParams
149
222
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yoamigo.com/core",
3
- "version": "0.4.8",
3
+ "version": "1.0.1",
4
4
  "description": "Core components, router, and utilities for YoAmigo templates",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -1,6 +0,0 @@
1
- /**
2
- * Initialize builder selection when running in iframe
3
- */
4
- declare function initBuilderSelection(): void;
5
-
6
- export { initBuilderSelection as i };