@lerret/cli 0.1.9 → 0.1.10

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "studioVersion": "0.1.0",
3
- "builtAt": "2026-05-21T21:46:23.082Z",
3
+ "builtAt": "2026-05-21T22:09:03.487Z",
4
4
  "files": [
5
5
  "apple-touch-icon.png",
6
6
  "assets/asset-runtime-B5cPbIor.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lerret/cli",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "The `lerret` design canvas CLI — a folder of plain React component files renders as a visual canvas. Includes the Vite dev server, headless export, and the bundled studio.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/export.js CHANGED
@@ -663,8 +663,15 @@ export function buildBaseFilename(artboard, extension) {
663
663
  /**
664
664
  * Compute the on-disk output path for one artboard.
665
665
  *
666
- * Structured (default): `<outDir>/<locationSegments>/<filename>`
667
- * Flat: `<outDir>/[<segments-joined-by---if-collision>]<filename>`
666
+ * Structured (default): `<outDir>/<page>[/<group>[/…]]/<filename>` per the PRD —
667
+ * the page name (derived from `artboard.pagePath`) is always present, so that
668
+ * a project with `landing/heroes/Card1.jsx` and `social/Banner.jsx` writes to
669
+ * `out/landing/heroes/Card1.png` and `out/social/Banner.png` (and assets named
670
+ * the same in different pages cannot collide).
671
+ *
672
+ * Flat: `<outDir>/[<segments-joined-by---if-collision>]<filename>` — flat mode
673
+ * never used the page prefix; we leave it as-is so existing `--flat` users see
674
+ * no path change.
668
675
  *
669
676
  * For flat layout, collision disambiguation needs to know whether OTHER items
670
677
  * in the same run would produce the same base filename. The caller supplies
@@ -676,7 +683,14 @@ export function buildBaseFilename(artboard, extension) {
676
683
  * Output root, absolute and using forward slashes.
677
684
  * @param {object} args.artboard
678
685
  * @param {string[]} args.artboard.locationSegments
679
- * Page/group chain — `[]` for an asset directly in a page.
686
+ * Group chain — `[]` for an asset directly in a page. The page level is
687
+ * derived separately from `artboard.pagePath`, not carried here (the studio's
688
+ * ZIP exporter shares this field and intentionally omits the page prefix —
689
+ * see packages/studio/src/export/zip.js).
690
+ * @param {string} [args.artboard.pagePath]
691
+ * Full LerretPath of the containing page. The basename becomes the top-level
692
+ * folder in structured mode. When absent (older callers / hand-crafted
693
+ * artboards in tests), the page level is omitted gracefully.
680
694
  * @param {string} args.filename
681
695
  * The base filename, already extension-suffixed.
682
696
  * @param {boolean} args.flat
@@ -699,14 +713,34 @@ export function buildOutputPath({ outDir, artboard, filename, flat, nameCount =
699
713
  return joinForward(outDir, filename);
700
714
  }
701
715
 
702
- if (segments.length === 0) {
716
+ const pageName = pageNameFromPagePath(artboard.pagePath);
717
+ const structuredSegs = pageName ? [pageName, ...segments] : segments;
718
+
719
+ if (structuredSegs.length === 0) {
703
720
  return joinForward(outDir, filename);
704
721
  }
705
722
 
706
- const safeSegs = segments.map(safeName);
723
+ const safeSegs = structuredSegs.map(safeName);
707
724
  return joinForward(outDir, ...safeSegs, filename);
708
725
  }
709
726
 
727
+ /**
728
+ * Extract the page-folder name from an Artboard's `pagePath`. The path is a
729
+ * forward-slash LerretPath like `/proj/.lerret/landing`; the basename is the
730
+ * page-folder name (`landing`). Returns `null` when the input is missing or
731
+ * unusable so callers can fall back gracefully.
732
+ *
733
+ * @param {unknown} pagePath
734
+ * @returns {string | null}
735
+ */
736
+ function pageNameFromPagePath(pagePath) {
737
+ if (typeof pagePath !== 'string' || pagePath.length === 0) return null;
738
+ const trimmed = pagePath.replace(/\/+$/, '');
739
+ const lastSlash = trimmed.lastIndexOf('/');
740
+ const name = lastSlash === -1 ? trimmed : trimmed.slice(lastSlash + 1);
741
+ return name.length > 0 ? name : null;
742
+ }
743
+
710
744
  /**
711
745
  * Join path segments using forward slashes, regardless of platform. The CLI
712
746
  * normalizes every path to the contract's forward-slash form at its boundary