uidex 0.8.0 → 0.9.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/dist/cli/cli.cjs CHANGED
@@ -407,7 +407,13 @@ function validateConfig(raw) {
407
407
  fail(`conventions.features must be a string or false`);
408
408
  }
409
409
  if (c.pages !== void 0 && c.pages !== false && c.pages !== "auto") {
410
- fail(`conventions.pages must be "auto" or false`);
410
+ const p2 = c.pages;
411
+ const routesDir = typeof p2 === "object" && p2 !== null && !Array.isArray(p2) ? p2.routesDir : void 0;
412
+ if (typeof p2 !== "object" || p2 === null || Array.isArray(p2) || Object.keys(p2).some((k) => k !== "routesDir") || typeof routesDir !== "string" || routesDir.length === 0) {
413
+ fail(
414
+ `conventions.pages must be "auto", false, or { routesDir: string }`
415
+ );
416
+ }
411
417
  }
412
418
  if (c.flows !== void 0 && c.flows !== false) {
413
419
  assertStringArray(c.flows, "conventions.flows");
@@ -3266,13 +3272,26 @@ var path8 = __toESM(require("path"), 1);
3266
3272
  var PAGE_BASENAME = /^page\.(tsx|ts|jsx|js|mjs|cjs)$/;
3267
3273
  var PAGES_ROUTER_BASENAME = /\.(tsx|ts|jsx|js|mjs|cjs)$/;
3268
3274
  var ROUTE_BASENAME = /^route\.(tsx|ts|jsx|js|mjs|cjs)$/;
3269
- function detectRoutes(files) {
3275
+ function detectRoutes(files, options = {}) {
3270
3276
  const out2 = [];
3271
3277
  const seen = /* @__PURE__ */ new Set();
3278
+ const routesDir = options.routesDir ? options.routesDir.replace(/^\.?\/+/, "").replace(/\/+$/, "") : null;
3279
+ const routesDirParts = routesDir ? routesDir.split("/") : null;
3272
3280
  for (const f of files) {
3273
3281
  const rel = f.displayPath;
3274
3282
  const parts = rel.split("/");
3275
3283
  const base = parts[parts.length - 1];
3284
+ if (routesDirParts) {
3285
+ const end = dirEndIndex(parts, routesDirParts);
3286
+ if (end === -1 || end > parts.length - 1) continue;
3287
+ if (!PAGES_ROUTER_BASENAME.test(base)) continue;
3288
+ const routePath = routesStylePath(
3289
+ parts.slice(end, parts.length - 1),
3290
+ base
3291
+ );
3292
+ if (routePath !== null) push(out2, seen, routePath, f.displayPath);
3293
+ continue;
3294
+ }
3276
3295
  const appIdx = parts.indexOf("app");
3277
3296
  if (appIdx !== -1 && PAGE_BASENAME.test(base)) {
3278
3297
  const routeSegments = parts.slice(appIdx + 1, parts.length - 1);
@@ -3299,15 +3318,11 @@ function detectRoutes(files) {
3299
3318
  }
3300
3319
  const routesIdx = parts.indexOf("routes");
3301
3320
  if (routesIdx !== -1 && PAGES_ROUTER_BASENAME.test(base)) {
3302
- const segs = parts.slice(routesIdx + 1);
3303
- const last = segs[segs.length - 1];
3304
- if (last.startsWith("_")) continue;
3305
- const normalized = [
3306
- ...segs.slice(0, -1),
3307
- base.replace(/\.[^.]+$/, "")
3308
- ].filter((s) => s !== "index" && s !== "__root");
3309
- const routePath = formatNextAppPath(normalized);
3310
- push(out2, seen, routePath, f.displayPath);
3321
+ const routePath = routesStylePath(
3322
+ parts.slice(routesIdx + 1, parts.length - 1),
3323
+ base
3324
+ );
3325
+ if (routePath !== null) push(out2, seen, routePath, f.displayPath);
3311
3326
  continue;
3312
3327
  }
3313
3328
  }
@@ -3323,6 +3338,63 @@ function formatNextAppPath(segments) {
3323
3338
  if (kept.length === 0) return "/";
3324
3339
  return "/" + kept.join("/");
3325
3340
  }
3341
+ function dirEndIndex(parts, dirParts) {
3342
+ if (dirParts.length === 0) return 0;
3343
+ for (let i = 0; i + dirParts.length <= parts.length; i++) {
3344
+ let match = true;
3345
+ for (let j = 0; j < dirParts.length; j++) {
3346
+ if (parts[i + j] !== dirParts[j]) {
3347
+ match = false;
3348
+ break;
3349
+ }
3350
+ }
3351
+ if (match) return i + dirParts.length;
3352
+ }
3353
+ return -1;
3354
+ }
3355
+ function routesStylePath(dirSegs, base) {
3356
+ const fileSegs = splitFlatSegments(base.replace(/\.[^.]+$/, ""));
3357
+ const leaf = fileSegs[fileSegs.length - 1];
3358
+ if (leaf.startsWith("_")) return null;
3359
+ const rawSegs = [...dirSegs, ...fileSegs];
3360
+ if (rawSegs.some((s) => s.startsWith("-"))) return null;
3361
+ if (rawSegs[0] === "api") return null;
3362
+ return formatTanStackPath(rawSegs);
3363
+ }
3364
+ function splitFlatSegments(name) {
3365
+ const segs = [];
3366
+ let cur = "";
3367
+ let depth = 0;
3368
+ for (const ch of name) {
3369
+ if (ch === "[") depth++;
3370
+ else if (ch === "]") depth = Math.max(0, depth - 1);
3371
+ if (ch === "." && depth === 0) {
3372
+ segs.push(cur);
3373
+ cur = "";
3374
+ continue;
3375
+ }
3376
+ cur += ch;
3377
+ }
3378
+ segs.push(cur);
3379
+ return segs;
3380
+ }
3381
+ function formatTanStackPath(segments) {
3382
+ const kept = [];
3383
+ for (const seg of segments) {
3384
+ if (!seg) continue;
3385
+ if (seg === "index" || seg === "route" || seg === "__root") continue;
3386
+ if (seg.startsWith("_")) continue;
3387
+ if (seg.startsWith("(") && seg.endsWith(")")) continue;
3388
+ kept.push(normalizeTanStackSegment(seg.replace(/_$/, "")));
3389
+ }
3390
+ if (kept.length === 0) return "/";
3391
+ return "/" + kept.join("/");
3392
+ }
3393
+ function normalizeTanStackSegment(seg) {
3394
+ if (seg === "$") return "[...splat]";
3395
+ if (seg.startsWith("$")) return `[${seg.slice(1)}]`;
3396
+ return seg.replace(/\[([^\]]*)\]/g, "$1");
3397
+ }
3326
3398
  function pathToId(routePath) {
3327
3399
  if (routePath === "/") return "root";
3328
3400
  return routePath.replace(/^\/+/, "").replace(/\[\.{3}([^\]]+)\]/g, "$1").replace(/\[([^\]]+)\]/g, "$1").replace(/\//g, "-").replace(/[^a-zA-Z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
@@ -3548,9 +3620,12 @@ function resolve3(ctx) {
3548
3620
  function metaWithComposes(kind, id, base) {
3549
3621
  const composes = directChildren.get(`${kind}:${id}`);
3550
3622
  if (!composes || composes.length === 0) return base;
3551
- return { ...base ?? {}, composes };
3623
+ return { ...base, composes };
3552
3624
  }
3553
- const routes = conventions.pages === "auto" ? detectRoutes(ctx.extracted.map((e) => e.file)) : [];
3625
+ const routes = conventions.pages === false ? [] : detectRoutes(
3626
+ ctx.extracted.map((e) => e.file),
3627
+ conventions.pages === "auto" ? {} : { routesDir: conventions.pages.routesDir }
3628
+ );
3554
3629
  const handledPageFiles = /* @__PURE__ */ new Set();
3555
3630
  for (const route of routes) {
3556
3631
  const routeDir = path8.posix.dirname(route.file);