@arcadialdev/arcality 4.0.0 → 4.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/package.json +1 -1
- package/scripts/generate.mjs +21 -0
- package/src/services/routeDiscovery.mjs +18 -3
package/package.json
CHANGED
package/scripts/generate.mjs
CHANGED
|
@@ -78,6 +78,19 @@ function matchesPageFilters(routeEntry, filters) {
|
|
|
78
78
|
return haystacks.some(value => value === normalized || value.includes(normalized));
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
82
|
+
|
|
83
|
+
function isLikelyUuidFilter(filter) {
|
|
84
|
+
return UUID_RE.test(String(filter || '').trim());
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function formatRouteExamples(routes, maxItems = 3) {
|
|
88
|
+
return routes
|
|
89
|
+
.slice(0, maxItems)
|
|
90
|
+
.map(entry => `${entry.route} -> ${entry.pagePath}`)
|
|
91
|
+
.join('\n- ');
|
|
92
|
+
}
|
|
93
|
+
|
|
81
94
|
|
|
82
95
|
function limitEntries(entries, count) {
|
|
83
96
|
if (!Number.isFinite(count) || count <= 0) return entries;
|
|
@@ -114,6 +127,14 @@ function printSummary(analysis, selectedRoutes, options, generationContext) {
|
|
|
114
127
|
|
|
115
128
|
if (selectedRoutes.length === 0) {
|
|
116
129
|
console.log('\nNo candidate routes matched the provided filters.');
|
|
130
|
+
const uuidFilters = (options.page || []).filter(isLikelyUuidFilter);
|
|
131
|
+
if (uuidFilters.length > 0) {
|
|
132
|
+
console.log('Tip: the current --page filter only matches route fragments or page file paths, not backend page IDs or UUIDs.');
|
|
133
|
+
}
|
|
134
|
+
if ((options.page || []).length > 0 && analysis.routes.length > 0) {
|
|
135
|
+
console.log('Try values such as a route (`/checkout`) or a page path fragment (`app/checkout/page.tsx`).');
|
|
136
|
+
console.log(`Examples:\n- ${formatRouteExamples(analysis.routes)}`);
|
|
137
|
+
}
|
|
117
138
|
return;
|
|
118
139
|
}
|
|
119
140
|
|
|
@@ -221,23 +221,38 @@ function analyzeSourceSignals(sourceFile, route) {
|
|
|
221
221
|
const fileLower = toPosix(sourceFile).toLowerCase();
|
|
222
222
|
const semanticFileLower = fileLower.replace(/\([^/\\]+\)/g, '');
|
|
223
223
|
const has = (...patterns) => patterns.some(pattern => lower.includes(pattern));
|
|
224
|
+
const count = (...patterns) => patterns.reduce((total, pattern) => total + (lower.match(new RegExp(pattern, 'g')) || []).length, 0);
|
|
224
225
|
const routeHas = (...patterns) => patterns.some(pattern => routeLower.includes(pattern) || semanticFileLower.includes(pattern));
|
|
225
226
|
const isRouterConfigFile = has('createbrowserrouter', 'useroutes', '<routes', '<route');
|
|
226
227
|
const contextualHas = (...patterns) => {
|
|
227
228
|
if (routeHas(...patterns)) return true;
|
|
228
229
|
return !isRouterConfigFile && has(...patterns);
|
|
229
230
|
};
|
|
231
|
+
const formControlCount = count(
|
|
232
|
+
'<input',
|
|
233
|
+
'<select',
|
|
234
|
+
'<textarea',
|
|
235
|
+
'textfield',
|
|
236
|
+
'inputbase',
|
|
237
|
+
'autocomplete',
|
|
238
|
+
'radiogroup',
|
|
239
|
+
'checkbox'
|
|
240
|
+
);
|
|
241
|
+
const hasStepFlow = contextualHas('siguiente', 'continuar', 'anterior', 'atras', 'paso', 'stepper', 'wizard');
|
|
242
|
+
const hasValidationCopy = contextualHas('campo obligatorio', 'requerido', 'obligatorio', 'valida', 'validacion', 'validation');
|
|
230
243
|
|
|
231
244
|
const signals = {
|
|
232
|
-
hasForm: has('<form', 'useform', 'formik', 'react-hook-form', 'zodresolver', 'onsubmit', '
|
|
245
|
+
hasForm: has('<form', 'useform', 'formik', 'react-hook-form', 'zodresolver', 'onsubmit', 'handlesubmit')
|
|
246
|
+
|| formControlCount >= 2
|
|
247
|
+
|| (formControlCount >= 1 && (hasStepFlow || hasValidationCopy)),
|
|
233
248
|
hasTable: has('<table', 'datatable', 'ag-grid', 'tanstack table', 'role="table"', 'role="grid"'),
|
|
234
249
|
hasSearch: contextualHas('search', 'buscar', 'query', 'placeholder="buscar', 'placeholder=\'buscar'),
|
|
235
250
|
hasFilter: contextualHas('filter', 'filtro', 'filtrar'),
|
|
236
251
|
hasCreateAction: contextualHas('crear', 'create', 'nuevo', 'new ', 'agregar', 'add '),
|
|
237
252
|
hasEditAction: contextualHas('editar', 'edit', 'actualizar', 'update'),
|
|
238
|
-
hasAuth: has('password', '
|
|
253
|
+
hasAuth: has('password', 'contrase\u00f1a', 'iniciar sesi\u00f3n', 'login', 'sign in') || routeHas('login', 'signin', 'auth'),
|
|
239
254
|
hasCheckout: contextualHas('payment', 'card', 'checkout', 'billing', 'stripe'),
|
|
240
|
-
hasSettings: has('settings', '
|
|
255
|
+
hasSettings: has('settings', 'configuraci\u00f3n', 'preferencias', 'preferences') || routeHas('settings', 'config', 'preferences'),
|
|
241
256
|
hasUpload: contextualHas('type="file"', "type='file'", 'dropzone', 'upload', 'subir archivo', 'subir imagen'),
|
|
242
257
|
isDynamicRoute: /\[[^\]]+\]/.test(route) || /:\w+/.test(route),
|
|
243
258
|
routeSegments: routeLower.replace(/^\/+/, '').split('/').filter(Boolean),
|