meno-core 1.1.2 → 1.1.3

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.
@@ -126,10 +126,47 @@ export const ListPropDefinitionSchema = z
126
126
  .passthrough();
127
127
 
128
128
  /**
129
- * Prop definition schema (union of base and list)
130
- * Validates prop definitions from component interfaces
129
+ * Prop definition schema discriminates on `type` instead of a plain
130
+ * `z.union([List, Base])`.
131
+ *
132
+ * Why not a bare union: a `type: "list"` prop with a bad shape (the single most
133
+ * common authoring mistake — a bare-string `default` and/or a missing
134
+ * `itemSchema`, e.g. `{ type: "list", default: ["a", "b"] }`) matches NEITHER
135
+ * union branch (List wants `itemSchema` + an object-array `default`; Base's
136
+ * `type` enum has no `"list"`). The union then reports a noisy pile of
137
+ * cross-branch issues (`type` not in the base enum, `default[0]` expected object,
138
+ * …) — and, worse, when this prop sits inside a component file the outer
139
+ * `PageDataSchema` union surfaces the *page* branch's refine instead (see
140
+ * `JSONPageSchema` / `PageDataSchema` below), so the real error reads
141
+ * "JSONPage must have …root". The codec round-trips it and `astro build`
142
+ * renders it, so the only place it ever surfaces is here.
143
+ *
144
+ * Discriminating on `type` lets a list prop be validated by ONLY
145
+ * `ListPropDefinitionSchema` and collapses its failure into one actionable
146
+ * message that names the requirement, at the prop's own path.
131
147
  */
132
- export const PropDefinitionSchema = z.union([ListPropDefinitionSchema, BasePropDefinitionSchema]);
148
+ export const PropDefinitionSchema = z
149
+ .object({ type: z.string() })
150
+ .passthrough()
151
+ .superRefine((val, ctx) => {
152
+ const branch = val.type === 'list' ? ListPropDefinitionSchema : BasePropDefinitionSchema;
153
+ const result = branch.safeParse(val);
154
+ if (result.success) return;
155
+ if (val.type === 'list') {
156
+ // Collapse the list-prop failure into one actionable message rather than
157
+ // replaying zod's per-field noise. `itemSchema` is required and `default`
158
+ // must be an array of OBJECTS (one `{ field: value }` record per item).
159
+ ctx.addIssue({
160
+ code: z.ZodIssueCode.custom,
161
+ message:
162
+ 'list prop requires `itemSchema` and an object-array `default` ' +
163
+ '(each item is a `{ field: value }` object, not a bare string)',
164
+ });
165
+ return;
166
+ }
167
+ // Non-list props keep their precise per-field errors.
168
+ for (const issue of result.error.issues) ctx.addIssue(issue);
169
+ });
133
170
 
134
171
  /**
135
172
  * Style mapping schema
@@ -722,6 +759,14 @@ export const JSONPageSchema = z
722
759
  // Marks a page whose source is outside the meno-astro dialect (read-only in the editor).
723
760
  // Explicit (not just .passthrough()) so it survives a future tightening of this schema.
724
761
  _unsupported: z.object({ reason: z.string() }).passthrough().optional(),
762
+ // A component payload (`{ component: {...} }`) must NEVER validate as a page.
763
+ // Without this guard the page branch parses structurally (it's `.passthrough()`)
764
+ // and only trips the refine below — so when both branches of `PageDataSchema`
765
+ // fail, zod treats this branch as the "closest" (dirty) one and surfaces
766
+ // "JSONPage must have …root", masking the real component error (e.g. a malformed
767
+ // list prop). Rejecting a present `component` key makes this branch hard-fail on
768
+ // component payloads, so `PageDataSchema` reports the component branch instead.
769
+ component: z.undefined().optional(),
725
770
  })
726
771
  .passthrough()
727
772
  .refine(
@@ -752,8 +797,11 @@ export const PageDataWithComponentSchema = z
752
797
  .passthrough();
753
798
 
754
799
  /**
755
- * Page data schema - union of JSONPage and PageDataWithComponent
756
- * PageDataWithComponent checked first because it's more specific
800
+ * Page data schema - union of JSONPage and PageDataWithComponent.
801
+ * PageDataWithComponent is checked first because it's more specific; the
802
+ * `component: z.undefined()` guard on `JSONPageSchema` keeps a component payload
803
+ * from being mis-reported as a page (see that schema's comment), so a malformed
804
+ * prop surfaces its own error instead of the page-branch refine.
757
805
  */
758
806
  export const PageDataSchema = z.union([PageDataWithComponentSchema, JSONPageSchema]);
759
807
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meno-core",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "meno": "./dist/bin/cli.js"