@feeef.dev/cli 0.2.0 → 0.2.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 CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@feeef.dev/cli",
3
- "version": "0.2.0",
4
- "description": "Feeef developer CLI — themes, auth, and cloud tools",
3
+ "version": "0.2.1",
4
+ "description": "Feeef developer CLI — templates, auth, and cloud tools",
5
5
  "type": "module",
6
6
  "bin": {
7
- "feeef": "./dist/bin.js"
7
+ "feeef": "dist/bin.js"
8
8
  },
9
9
  "main": "./dist/index.js",
10
10
  "types": "./dist/index.d.ts",
@@ -38,7 +38,7 @@
38
38
  "feeef",
39
39
  "cli",
40
40
  "ecommerce",
41
- "theme",
41
+ "template",
42
42
  "storefront"
43
43
  ],
44
44
  "license": "UNLICENSED",
@@ -52,14 +52,14 @@
52
52
  "dotenv": "^16.4.7",
53
53
  "esbuild": "^0.25.0",
54
54
  "feeef": "^0.12.1",
55
- "picocolors": "^1.1.1"
55
+ "picocolors": "^1.1.1",
56
+ "react": "^19.2.7",
57
+ "react-dom": "^19.2.7"
56
58
  },
57
59
  "devDependencies": {
58
60
  "@types/node": "^20.12.10",
59
61
  "@types/react": "^19.2.17",
60
62
  "@types/react-dom": "^19.2.3",
61
- "react": "^19.2.7",
62
- "react-dom": "^19.2.7",
63
63
  "tsup": "^8.5.0",
64
64
  "tsx": "^4.19.3",
65
65
  "typescript": "^5.4.5"
@@ -1,13 +1,13 @@
1
- # AGENTS — Feeef Theme (READ BEFORE EDITING)
1
+ # AGENTS — Feeef Template (READ BEFORE EDITING)
2
2
 
3
- You are editing a **Feeef theme package** (this folder). Mistakes break the merchant
3
+ You are editing a **Feeef template package** (this folder). Mistakes break the merchant
4
4
  editor, the storefront preview, and published stores. Follow this file exactly.
5
5
 
6
6
  ## Mandatory mental model
7
7
 
8
8
  1. **One JSON contract** — `TemplateData` (built into `dist/data.json`) is what Feeef stores and renders. `dist/schema.json` is the editor schema.
9
9
  2. **Source vs dist** — edit `schema.ts`, `pages/`, `shared/`, `library/`, `locales/`, `props.json`; run `npm run build`. Do not hand-edit large `dist/*` as the source of truth.
10
- 3. **Theme schema is yours** — `schema.ts` (`satisfies FeeefThemeSchema`) controls pages/layouts/root `propsSchema`. Build merges Lithium built-ins into `dist/schema.json` for publish.
10
+ 3. **Template schema is yours** — `schema.ts` (`satisfies FeeefThemeSchema`) controls pages/layouts/root `propsSchema`. Build merges Lithium built-ins into `dist/schema.json` for publish.
11
11
  4. **`type: "custom"` is react-live** — published `code` is a **string** evaluated in a sandbox. It must expose top-level `function App() { … }`. Author with a flat file like `hero.tsx`: `export const meta` (include `propsSchema`) + `App`. Type props via `FeeefLivePropsOf<typeof propsSchema>`. Local/`npm` imports are **bundled at build time** (see `docs/16-AUTHORING-TS-IMPORTS.md`). Use a folder (`hero/component.tsx`) only when you need `slots/` / `children/` or colocated modules.
12
12
  5. **`code` / `propsSchema` / `slotsSchema` / `slots` / `slotsLayout` are TOP-LEVEL** on the component object — never nest them under `props`.
13
13
  6. **Planes stay separate** — schema (editable fields) ≠ merchant content (`props`) ≠ renderer.
@@ -23,7 +23,7 @@ editor, the storefront preview, and published stores. Follow this file exactly.
23
23
  7. Dark/light → [`docs/12-DARK-LIGHT-THEME.md`](./docs/12-DARK-LIGHT-THEME.md).
24
24
  8. Multilang → [`docs/13-TEMPLATE-I18N.md`](./docs/13-TEMPLATE-I18N.md).
25
25
  9. Product grids / filters → [`docs/14-FILTERATOR.md`](./docs/14-FILTERATOR.md).
26
- 10. After edits: `npm run build` (or `npm run check`), then hard-refresh `npm run dev`.
26
+ 10. After edits: `npm run build` (or `npm run check`), then refresh the draft preview (`npm run dev`).
27
27
 
28
28
  ## Hard rules (never violate)
29
29
 
@@ -44,10 +44,10 @@ editor, the storefront preview, and published stores. Follow this file exactly.
44
44
  | Do not invent unknown registry `type` strings | Prefer `custom` or built-ins |
45
45
  | Do not bypass order anti-abuse checks | Honeypot, dwell, in-flight lock |
46
46
 
47
- ## Theme layout
47
+ ## Template layout
48
48
 
49
49
  ```
50
- schema.ts # theme-owned schema overlay
50
+ schema.ts # template-owned schema overlay
51
51
  props.json # default root props
52
52
  pages/<page>/components/ # preferred — builds to sections.main
53
53
  <name>.tsx
@@ -65,6 +65,7 @@ Prefer a single `main` stack + component **slots** for chrome. Do not mix flat `
65
65
  ## Local commands
66
66
 
67
67
  ```bash
68
+ npm install -g @feeef.dev/cli # once
68
69
  feeef signin
69
70
  feeef use # bind a store
70
71
  npm install # once — React/TS types for the editor
@@ -78,13 +79,15 @@ feeef template remove component <pageId> <name> --yes
78
79
  npm run build # → dist/data.json
79
80
  npm run check
80
81
  npm run typecheck # optional IDE/tsc
81
- npm run dev # preview
82
+ npm run dev # remote draft preview (does NOT change live shop)
82
83
  npm run publish -- --apply
83
84
  ```
84
85
 
86
+ **Preview:** `npm run dev` pushes `metadata.templatePreview` and opens `?preview=…`. Customers keep live `templateData`. Exit via banner or `/?preview=0`. Go live only with `publish --apply`.
87
+
85
88
  **AI / agents:** use `feeef template add page|component` (and `remove`) instead of inventing folder trees by hand. New pages are flat `components/` → published `sections.main`. Do not mix flat `components/` with `sections/` on the same page.
86
89
 
87
- Editor: `tsconfig.json` + `types/feeef-live-scope.d.ts` + `types/feeef-template-schema.d.ts` explain react-live globals and `FeeefThemeSchema` to VS Code / Cursor.
90
+ Editor: `tsconfig.json` + `types/feeef-live-scope.d.ts` + `types/feeef-template-schema.d.ts` explain react-live globals and `FeeefThemeSchema` (template schema type) to VS Code / Cursor.
88
91
 
89
92
  ## Companion docs
90
93
 
@@ -95,10 +98,10 @@ Editor: `tsconfig.json` + `types/feeef-live-scope.d.ts` + `types/feeef-template-
95
98
  | [`docs/05-ANTI-PATTERNS.md`](./docs/05-ANTI-PATTERNS.md) | Common AI mistakes |
96
99
  | [`docs/07-SHARED-COMPONENTS.md`](./docs/07-SHARED-COMPONENTS.md) | `$ref` / shared |
97
100
  | [`docs/08-ORDER-FORM.md`](./docs/08-ORDER-FORM.md) | COD / checkout contract |
98
- | [`docs/09-THEME-PORTING.md`](./docs/09-THEME-PORTING.md) | Full-theme craft lessons |
99
- | [`docs/10-SCHEMA-LIBRARY.md`](./docs/10-SCHEMA-LIBRARY.md) | Theme library catalog |
101
+ | [`docs/09-THEME-PORTING.md`](./docs/09-THEME-PORTING.md) | Full-template craft lessons |
102
+ | [`docs/10-SCHEMA-LIBRARY.md`](./docs/10-SCHEMA-LIBRARY.md) | Template library catalog |
100
103
  | [`docs/11-PAGES-CHECKOUT-THANKS-PRODUCT.md`](./docs/11-PAGES-CHECKOUT-THANKS-PRODUCT.md) | Special pages |
101
- | [`docs/12-DARK-LIGHT-THEME.md`](./docs/12-DARK-LIGHT-THEME.md) | Theme mode + tokens |
104
+ | [`docs/12-DARK-LIGHT-THEME.md`](./docs/12-DARK-LIGHT-THEME.md) | Dark/light/system mode + tokens |
102
105
  | [`docs/13-TEMPLATE-I18N.md`](./docs/13-TEMPLATE-I18N.md) | `locales` + `t()` |
103
106
  | [`docs/14-FILTERATOR.md`](./docs/14-FILTERATOR.md) | Product/category lists |
104
107
  | [`docs/16-AUTHORING-TS-IMPORTS.md`](./docs/16-AUTHORING-TS-IMPORTS.md) | TSX + npm imports |
@@ -1,6 +1,10 @@
1
- # Feeef theme
1
+ # Feeef template
2
2
 
3
- This folder is a **Node.js package** (see `package.json`). Scripts wrap the global `feeef` CLI — install it once (`npm link` from the Feeef `cli/` package, or `npm install -g @feeef.dev/cli`).
3
+ This folder is a **Node.js package** (see `package.json`). Scripts wrap the global `feeef` CLI:
4
+
5
+ ```bash
6
+ npm install -g @feeef.dev/cli
7
+ ```
4
8
 
5
9
  **AI / Cursor:** read [`AGENTS.md`](./AGENTS.md) and [`docs/00-INDEX.md`](./docs/00-INDEX.md) first. Rules and skills live under [`.cursor/`](./.cursor/).
6
10
 
@@ -14,8 +18,8 @@ feeef use # or: feeef use <store-id-or-slug>
14
18
 
15
19
  npm run build # → dist/data.json
16
20
  npm run check
17
- npm run dev # http://{slug}.localhost.feeef.org:3456
21
+ npm run dev # remote draft preview (?preview=…) — live shop unchanged
18
22
  npm run publish -- --apply
19
23
  ```
20
24
 
21
- See `feeef template --help`.
25
+ See [`docs/04-WORKFLOW.md`](./docs/04-WORKFLOW.md) and `feeef template --help`.
@@ -1,4 +1,4 @@
1
- # Theme docs — index
1
+ # Template docs — index
2
2
 
3
3
  Read [`../AGENTS.md`](../AGENTS.md) first. Jump by task below.
4
4
 
@@ -11,13 +11,15 @@ Read [`../AGENTS.md`](../AGENTS.md) first. Jump by task below.
11
11
  | 07 | [SHARED-COMPONENTS](./07-SHARED-COMPONENTS.md) | `shared/` + `$ref` |
12
12
  | 08 | [ORDER-FORM](./08-ORDER-FORM.md) | COD / checkout contract |
13
13
  | 09 | [THEME-PORTING](./09-THEME-PORTING.md) | Craft / cart / search / PLP lessons |
14
- | 10 | [SCHEMA-LIBRARY](./10-SCHEMA-LIBRARY.md) | Drag-drop theme library |
14
+ | 10 | [SCHEMA-LIBRARY](./10-SCHEMA-LIBRARY.md) | Drag-drop template library |
15
15
  | 11 | [PAGES](./11-PAGES-CHECKOUT-THANKS-PRODUCT.md) | checkout / thanks / product |
16
16
  | 12 | [DARK-LIGHT](./12-DARK-LIGHT-THEME.md) | Dark / light / system |
17
17
  | 13 | [I18N](./13-TEMPLATE-I18N.md) | `locales/*.json` + `t()` |
18
18
  | 14 | [FILTERATOR](./14-FILTERATOR.md) | Product / category lists |
19
19
  | 16 | [TS-IMPORTS](./16-AUTHORING-TS-IMPORTS.md) | TypeScript + npm imports |
20
20
 
21
+ CLI install: `npm install -g @feeef.dev/cli` — see [04-WORKFLOW](./04-WORKFLOW.md) for draft preview vs live.
22
+
21
23
  ## Task cheat-sheet
22
24
 
23
25
  | Task | Read |
@@ -29,5 +31,5 @@ Read [`../AGENTS.md`](../AGENTS.md) first. Jump by task below.
29
31
  | Dark / light | **12** |
30
32
  | Translations | **13** |
31
33
  | Product grids / filters | **14** |
32
- | Port / polish a full theme | **09** |
33
- | Build / preview / publish | **04** |
34
+ | Port / polish a full template | **09** |
35
+ | Build / preview / publish | **04** (draft preview ≠ live) |
@@ -1,20 +1,26 @@
1
- # Theme workflow (this package)
1
+ # Template workflow (this package)
2
2
 
3
- This folder is a **Node.js theme package**. Scripts wrap the Feeef CLI (`feeef`).
3
+ This folder is a **Node.js template package**. Scripts wrap the Feeef CLI (`feeef`).
4
+
5
+ Install the CLI once:
6
+
7
+ ```bash
8
+ npm install -g @feeef.dev/cli
9
+ ```
4
10
 
5
11
  ## Setup (once)
6
12
 
7
13
  ```bash
8
- # Install Feeef CLI globally (or npm link from the Feeef cli package)
9
- feeef signin
14
+ feeef signin # browser OAuth no client secret
10
15
  feeef use # pick one of your stores
16
+ npm install # React/TS types for the editor
11
17
  ```
12
18
 
13
19
  ## Everyday loop
14
20
 
15
21
  1. Add pages/components with the CLI (or edit under `pages/`, `shared/`, `library/`, `locales/`).
16
- 2. `npm run build` → writes `dist/data.json` (+ locales).
17
- 3. `npm run dev` → pushes a **draft** preview to your store and opens `https://{slug}.…/?preview=…` (live theme unchanged).
22
+ 2. `npm run build` → writes `dist/data.json` (+ locales, schema).
23
+ 3. `npm run dev` → pushes a **draft** to your store and opens `https://{slug}.…/?preview=…`.
18
24
  4. Ship: `npm run publish -- --apply` (or `feeef template publish --apply`).
19
25
 
20
26
  | Script / command | Effect |
@@ -25,10 +31,15 @@ feeef use # pick one of your stores
25
31
  | `feeef template remove component <page> <name>` | Delete component file/folder |
26
32
  | `npm run build` | Compile source → `dist/` |
27
33
  | `npm run check` | Validate without relying on a dirty dist |
28
- | `npm run dev` | Watch/build + remote draft preview (never overwrites live) |
29
- | `npm run publish` | Upload template + locales (+ optional install) |
34
+ | `npm run dev` | Watch/build + **remote draft preview** (never overwrites live) |
35
+ | `npm run publish` | Upload template + locales (+ optional `--apply` install) |
36
+
37
+ ### Draft preview vs live
30
38
 
31
- Exit draft preview in the browser via the banner (**Exit preview**) or `/?preview=0`.
39
+ - **`npm run dev`** writes `metadata.templatePreview` only. Customers still see live `metadata.templateData`.
40
+ - Browse the full shop (home, products, cart, checkout) while the preview cookie is set.
41
+ - **Exit preview:** banner → **Exit**, or visit `/?preview=0`. Stopping the CLI clears the draft.
42
+ - **Go live:** only `publish --apply` (or merchant editor Save / install).
32
43
 
33
44
  ### Scaffold examples
34
45
 
@@ -39,13 +50,13 @@ feeef template remove component products grid --yes
39
50
  feeef template remove page products --yes
40
51
  ```
41
52
 
42
- Legacy themes that already use `sections/`: `add component` writes under `sections/main/components/` (or pass `--section header`).
53
+ Legacy templates that already use `sections/`: `add component` writes under `sections/main/components/` (or pass `--section header`).
43
54
 
44
55
  ## Source layout
45
56
 
46
57
  ```
47
58
  feeef.template.json
48
- schema.ts # theme-owned schema overlay (typed)
59
+ schema.ts # template-owned schema overlay (typed)
49
60
  props.json # default root props (data)
50
61
  pages/<page>/page.json
51
62
  pages/<page>/components/ # preferred (→ published sections.main)
@@ -62,16 +73,16 @@ locales/en.json
62
73
 
63
74
  Do **not** mix `pages/<page>/components/` and `pages/<page>/sections/` on the same page.
64
75
 
65
- ### Theme schema (`schema.ts`)
76
+ ### Template schema (`schema.ts`)
66
77
 
67
- Controls what the merchant editor sees for **this** theme (pages, layouts, root `propsSchema`). Build merges it with Lithium built-ins → `dist/schema.json` (publish uploads that as `StoreTemplate.schema`).
78
+ Controls what the merchant editor sees for **this** template (pages, layouts, root `propsSchema`). Build merges it with Lithium built-ins → `dist/schema.json` (publish uploads that as `StoreTemplate.schema`).
68
79
 
69
80
  ```ts
70
81
  export const schema = {
71
- name: "my-theme",
82
+ name: "my-template",
72
83
  version: "0.1.0",
73
84
  schema: "1.0",
74
- propsSchema: { theme: { type: "object", /* */ } },
85
+ propsSchema: { theme: { type: "object", /* light/dark mode props */ } },
75
86
  pages: {
76
87
  home: {
77
88
  name: "Home",
@@ -80,18 +91,11 @@ export const schema = {
80
91
  layout: { sm: [{ type: "column", children: ["main"] }] },
81
92
  },
82
93
  },
83
- } as const satisfies FeeefThemeSchema;
94
+ } as const satisfies FeeefThemeSchema; // type name is historical; this is the template schema
84
95
  ```
85
96
 
86
97
  Types: `types/feeef-template-schema.d.ts`. Fallback: `schema.json` (same shape).
87
98
 
88
- ## Custom components
89
- locales/en.json
90
- feeef.template.json
91
- ```
92
-
93
- Do **not** mix `pages/<page>/components/` and `pages/<page>/sections/` on the same page.
94
-
95
99
  ## Custom components
96
100
 
97
101
  - Prefer page-level `components/hero.tsx` — `export const meta` + `function App() { … }`
@@ -126,4 +130,5 @@ function App() {
126
130
  - Commit hand-tweaked `dist/data.json` as the only source of truth
127
131
  - Put `code` / schemas under `props`
128
132
  - Call `ff.orders.send` from custom checkout (use `POST /api/orders/create` — [08](./08-ORDER-FORM.md))
129
- - Set production env overrides meant for local preview only
133
+ - Expect `npm run dev` to update what customers see (it does not)
134
+ - Clone the Lithium storefront just to preview (remote draft is the default)
@@ -46,8 +46,10 @@ High-signal mistakes AIs and humans make in this system.
46
46
  | Hand-edit `dist/data.json` as primary workflow | Edit `pages/` / `shared/`, then `npm run build` |
47
47
  | Use Node APIs inside component source | Use `utils/get-template.ts` |
48
48
  | Arbitrary filesystem preview paths | Only `feeef template dev` / CLI override |
49
+ | Treating `npm run dev` as “go live” | Draft only — use `publish --apply` for customers |
50
+ | Cloning Lithium storefront just to preview | Default is remote draft (`?preview=`) |
49
51
  | Expect Shopify reference dumps to render | They are not Feeef themes |
50
- | Skip `npm run check` after edits | Rebuild and hard-refresh preview |
52
+ | Skip `npm run check` after edits | Rebuild and refresh draft preview |
51
53
  | Commit `dist/` as source | Source is the folder tree |
52
54
  | Duplicate the same footer/navbar JSX on every page | Promote to `shared/components/<id>/` + `$ref` |
53
55
  | Copy dawn-order-form as “complete” checkout | Follow `docs/08-ORDER-FORM.md` + native `order-form.tsx` |
@@ -1,8 +1,8 @@
1
1
  {
2
- "name": "feeef-theme",
2
+ "name": "feeef-template",
3
3
  "private": true,
4
4
  "version": "0.1.0",
5
- "description": "Feeef Lithium theme",
5
+ "description": "Feeef Lithium template",
6
6
  "type": "module",
7
7
  "engines": {
8
8
  "node": ">=18"
@@ -10,6 +10,7 @@
10
10
  "scripts": {
11
11
  "build": "feeef template build",
12
12
  "check": "feeef template check",
13
+ "test": "feeef template smoke",
13
14
  "dev": "feeef template dev",
14
15
  "publish": "feeef template publish",
15
16
  "typecheck": "tsc --noEmit"
@@ -25,6 +25,7 @@ Usage:
25
25
  feeef-template unpack <data.json> -o <outDir> [--force]
26
26
  feeef-template build <srcDir> [-o <data.json>]
27
27
  feeef-template check <srcDir>
28
+ feeef-template smoke <srcDir> # build + SSR-eval every custom App
28
29
  feeef-template watch <srcDir> [-o <data.json>]
29
30
 
30
31
  Examples (from storefront/):
@@ -148,6 +149,37 @@ async function main() {
148
149
  return;
149
150
  }
150
151
 
152
+ if (cmd === "smoke") {
153
+ const src = positional[0];
154
+ if (!src) {
155
+ console.error("Usage: smoke <srcDir>");
156
+ process.exit(1);
157
+ }
158
+ const srcDir = resolveFromCwd(src);
159
+ const { smokeTheme } = await import("../lib/smoke.mjs");
160
+ const result = await smokeTheme({ srcDir, build: true });
161
+ for (const f of result.failed) {
162
+ const label =
163
+ f.item.sourcePath || f.item.instanceId || f.item.loc || "?";
164
+ console.error(`✗ ${label}`);
165
+ console.error(` ${f.error.message}`);
166
+ if (f.error.stack) {
167
+ const lines = String(f.error.stack).split("\n").slice(1, 4);
168
+ for (const line of lines) console.error(` ${line.trim()}`);
169
+ }
170
+ }
171
+ if (result.failed.length) {
172
+ console.error(
173
+ `smoke failed — ${result.failed.length}/${result.total} components`,
174
+ );
175
+ process.exit(1);
176
+ }
177
+ console.log(
178
+ `✓ smoke ok — ${result.passed}/${result.total} custom components rendered`,
179
+ );
180
+ return;
181
+ }
182
+
151
183
  if (cmd === "watch") {
152
184
  const src = positional[0];
153
185
  if (!src) {
@@ -56,9 +56,10 @@ function readJson(filePath) {
56
56
  * Nested slots/children only apply to folder entries.
57
57
  * @param {string} root Absolute folder or flat file path
58
58
  * @param {string[]} fileStack
59
+ * @param {string} srcDir Theme root (for relative `sourcePath`)
59
60
  * @returns {Record<string, any>}
60
61
  */
61
- function readComponentRaw(root, fileStack) {
62
+ function readComponentRaw(root, fileStack, srcDir) {
62
63
  const loaded = loadComponentMeta(root);
63
64
  const track = loaded.jsonPath || loaded.entry || root;
64
65
  fileStack.push(track);
@@ -70,9 +71,24 @@ function readComponentRaw(root, fileStack) {
70
71
  delete component.order;
71
72
  delete component.$schema;
72
73
 
74
+ const toPosix = (p) => p.split(path.sep).join("/");
75
+ const absSource = loaded.entry || root;
76
+ try {
77
+ component.sourcePath = toPosix(path.relative(srcDir, absSource));
78
+ } catch {
79
+ component.sourcePath = toPosix(absSource);
80
+ }
81
+
73
82
  const compiled = compileComponentSource(root);
74
83
  if (compiled) {
75
84
  component.code = compiled.code;
85
+ if (compiled.entry) {
86
+ try {
87
+ component.sourcePath = toPosix(path.relative(srcDir, compiled.entry));
88
+ } catch {
89
+ /* keep prior sourcePath */
90
+ }
91
+ }
76
92
  }
77
93
 
78
94
  // Flat leaves cannot host children/slots folders.
@@ -85,7 +101,7 @@ function readComponentRaw(root, fileStack) {
85
101
  const childEntries = listComponentEntries(childrenDir);
86
102
  if (childEntries.length > 0) {
87
103
  component.children = childEntries.map((d) =>
88
- readComponentRaw(d, fileStack),
104
+ readComponentRaw(d, fileStack, srcDir),
89
105
  );
90
106
  }
91
107
  }
@@ -97,7 +113,7 @@ function readComponentRaw(root, fileStack) {
97
113
  for (const slotId of listDirs(slotsDir)) {
98
114
  const slotChildren = listComponentEntries(path.join(slotsDir, slotId));
99
115
  slotsFromDirs[slotId] = slotChildren.map((d) =>
100
- readComponentRaw(d, fileStack),
116
+ readComponentRaw(d, fileStack, srcDir),
101
117
  );
102
118
  }
103
119
  }
@@ -133,7 +149,7 @@ function buildSharedCatalog(srcDir) {
133
149
  const entries = listComponentEntries(sharedRoot);
134
150
  const ids = entries.map((p) => componentIdFromPath(p));
135
151
  for (let i = 0; i < entries.length; i++) {
136
- catalog.set(ids[i], readComponentRaw(entries[i], fileStack));
152
+ catalog.set(ids[i], readComponentRaw(entries[i], fileStack, srcDir));
137
153
  }
138
154
 
139
155
  // Expand nested shared refs inside library definitions.
@@ -229,7 +245,7 @@ export function buildTemplate({ srcDir, outPath, write = true }) {
229
245
  if (flatEntries.length > 0) {
230
246
  sections.main = {
231
247
  components: flatEntries.map((entryPath) => {
232
- const raw = readComponentRaw(entryPath, fileStack);
248
+ const raw = readComponentRaw(entryPath, fileStack, srcDir);
233
249
  if (sharedIdFromComponent(raw)) sharedPlacementCount += 1;
234
250
  return resolveSharedInTree(
235
251
  raw,
@@ -245,7 +261,7 @@ export function buildTemplate({ srcDir, outPath, write = true }) {
245
261
  const componentEntries = listComponentEntries(componentsDir);
246
262
  sections[sectionId] = {
247
263
  components: componentEntries.map((entryPath) => {
248
- const raw = readComponentRaw(entryPath, fileStack);
264
+ const raw = readComponentRaw(entryPath, fileStack, srcDir);
249
265
  if (sharedIdFromComponent(raw)) sharedPlacementCount += 1;
250
266
  return resolveSharedInTree(
251
267
  raw,
@@ -41,7 +41,7 @@ const CATALOG_KEYS = new Set([
41
41
  *
42
42
  * @param {object} opts
43
43
  * @param {string} opts.srcDir
44
- * @param {(dir: string, fileStack: string[]) => Record<string, any>} opts.readComponentRaw
44
+ * @param {(dir: string, fileStack: string[], srcDir: string) => Record<string, any>} opts.readComponentRaw
45
45
  * @param {(node: any, catalog: Map<string, any>, resolving: Set<string>, hint: string) => any} [opts.resolveSharedInTree]
46
46
  * @param {Map<string, any>} [opts.sharedCatalog]
47
47
  */
@@ -68,7 +68,7 @@ export function buildSchemaLibrary({
68
68
 
69
69
  for (const entryPath of listComponentEntries(libraryRoot)) {
70
70
  const folderName = componentIdFromPath(entryPath);
71
- let raw = readComponentRaw(entryPath, fileStack);
71
+ let raw = readComponentRaw(entryPath, fileStack, srcDir);
72
72
 
73
73
  if (resolveSharedInTree && catalog.size > 0) {
74
74
  raw = resolveSharedInTree(