meno-astro 0.1.5 → 0.1.7

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.
@@ -136,6 +136,25 @@ function templateToExpr(s) {
136
136
  out += escapeBacktick(s.slice(last));
137
137
  return "`" + out + "`";
138
138
  }
139
+ function rewriteItemRefs(str, itemVar) {
140
+ return str.replace(TEMPLATE_RE, (_m, expr) => {
141
+ const rewritten = String(expr).replace(/\bitemIndex\b/g, `${itemVar}Index`).replace(/\bitemFirst\b/g, `${itemVar}First`).replace(/\bitemLast\b/g, `${itemVar}Last`).replace(/\bitem\b/g, itemVar);
142
+ return `{{${rewritten}}}`;
143
+ });
144
+ }
145
+ function rewriteItemRefsInTree(node, itemVar) {
146
+ if (typeof node === "string") return rewriteItemRefs(node, itemVar);
147
+ if (Array.isArray(node)) return node.map((n) => rewriteItemRefsInTree(n, itemVar));
148
+ if (node && typeof node === "object") {
149
+ const obj = node;
150
+ const out = {};
151
+ for (const [k, v] of Object.entries(obj)) {
152
+ out[k] = k === "children" && obj.type === "list" ? v : rewriteItemRefsInTree(v, itemVar);
153
+ }
154
+ return out;
155
+ }
156
+ return node;
157
+ }
139
158
  var NON_BINDING_ROOTS = /* @__PURE__ */ new Set([
140
159
  "Astro",
141
160
  "Math",
@@ -199,8 +218,31 @@ function emitAttr(name, value, ctx) {
199
218
  return `${name}={${value}}`;
200
219
  }
201
220
  if (value === null || value === void 0) return `${name}={null}`;
221
+ if (deepHasTemplate(value)) return `${name}={${serializeExprLiteral(value)}}`;
202
222
  return `${name}={${serializeLiteral(value, { indent: INDENT, width: ctx.width })}}`;
203
223
  }
224
+ function deepHasTemplate(value) {
225
+ if (typeof value === "string") return hasTemplate(value);
226
+ if (Array.isArray(value)) return value.some(deepHasTemplate);
227
+ if (value && typeof value === "object") return Object.values(value).some(deepHasTemplate);
228
+ return false;
229
+ }
230
+ function isBareIdent(key) {
231
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key);
232
+ }
233
+ function serializeExprLiteral(value) {
234
+ if (typeof value === "string") return hasTemplate(value) ? templateToExpr(value) : JSON.stringify(value);
235
+ if (value === null || value === void 0) return "null";
236
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
237
+ if (Array.isArray(value)) return `[${value.map(serializeExprLiteral).join(", ")}]`;
238
+ if (typeof value === "object") {
239
+ const entries = Object.entries(value).map(
240
+ ([k, v]) => `${isBareIdent(k) ? k : JSON.stringify(k)}: ${serializeExprLiteral(v)}`
241
+ );
242
+ return entries.length ? `{ ${entries.join(", ")} }` : "{}";
243
+ }
244
+ return "null";
245
+ }
204
246
  function emitClassAttr(node, ctx, extraMeta) {
205
247
  const meta = { ...extraMeta };
206
248
  if (node.interactiveStyles !== void 0) meta.interactive = node.interactiveStyles;
@@ -342,6 +384,7 @@ function renderComponentInstance(node, ctx) {
342
384
  if (Object.keys(explicitProps).length === 0) {
343
385
  for (const v of ctx.loopVars) attrs.push(`${v}={${v}}`);
344
386
  }
387
+ if (ctx.cmsInScope && !("cms" in explicitProps)) attrs.push("cms={cms}");
345
388
  const cls = emitClassAttr(node, ctx, hasStyleContent(node.style) ? { instance: true } : void 0);
346
389
  if (cls) attrs.push(cls);
347
390
  const inlineStyle = emitInlineStyleAttr(node);
@@ -436,8 +479,9 @@ function renderList(node, ctx) {
436
479
  const sourceType = node.sourceType ?? "prop";
437
480
  const itemVar = node.itemAs ?? (sourceType === "collection" ? singularize(node.source) : "item");
438
481
  const indexVar = `${itemVar}Index`;
482
+ const itemChildren = itemVar === "item" ? node.children : rewriteItemRefsInTree(node.children, itemVar);
439
483
  ctx.loopVars.push(itemVar);
440
- const childBlocks = emitChildrenList(node.children, ctx);
484
+ const childBlocks = emitChildrenList(itemChildren, ctx);
441
485
  ctx.loopVars.pop();
442
486
  const childRenderedAt2 = childBlocks.map((c) => shift(c, INDENT)).join("\n");
443
487
  if (sourceType === "collection") {
@@ -603,9 +647,10 @@ function buildGetStaticPaths(cms) {
603
647
  // lib/dialect/emit/emitPage.ts
604
648
  function emitPage(page, opts) {
605
649
  const ctx = createEmitContext();
650
+ const isCms = isCmsTemplatePage(page);
651
+ if (isCms) ctx.cmsInScope = true;
606
652
  const body = page.root ? emitNode(page.root, ctx, 2) : "";
607
653
  needRuntimeComponent(ctx, "BaseLayout");
608
- const isCms = isCmsTemplatePage(page);
609
654
  const routeDir = isCms ? cmsRouteDirFromUrlPattern(page.meta.cms.urlPattern) : "";
610
655
  const depth = routeDir ? routeDir.split("/").length : 0;
611
656
  const componentPrefix = `${"../".repeat(depth + 1)}components/`;
@@ -627,7 +672,7 @@ function emitPage(page, opts) {
627
672
  fm.push(buildGetStaticPaths(page.meta.cms));
628
673
  fm.push("");
629
674
  }
630
- fm.push(`export const meta = ${serializeLiteral(page.meta ?? {}, { indent: 0 })};`);
675
+ fm.push(`const meta = ${serializeLiteral(page.meta ?? {}, { indent: 0 })};`);
631
676
  if (ctx.frontmatterConsts.length) {
632
677
  fm.push("");
633
678
  fm.push(...ctx.frontmatterConsts);
@@ -677,6 +722,8 @@ function pickComponentMeta(def) {
677
722
  function emitComponent(def, opts) {
678
723
  const ctx = createEmitContext();
679
724
  ctx.propsVar = "__props";
725
+ const itemBindings = collectItemBindings(def.structure, Object.keys(def.interface ?? {}));
726
+ if (itemBindings.includes("cms")) ctx.cmsInScope = true;
680
727
  const body = def.structure ? emitNode(def.structure, ctx, 0) : "<slot />";
681
728
  const componentMeta = pickComponentMeta(def);
682
729
  const hasMeta = Object.keys(componentMeta).length > 0;
@@ -686,7 +733,6 @@ function emitComponent(def, opts) {
686
733
  const componentImportPath = opts?.componentPaths ? (name) => `${relativeComponentImport(selfDir, opts.componentPaths[name] ?? name)}.astro` : void 0;
687
734
  const importLines = buildImportLines(ctx, { typeImports, componentPrefix: "./", componentImportPath });
688
735
  const propsBlock = buildPropsBlock(def.interface);
689
- const itemBindings = collectItemBindings(def.structure, Object.keys(def.interface ?? {}));
690
736
  const fm = [];
691
737
  if (ctx.needsContentApi) fm.push(`import { getCollection } from 'astro:content';`);
692
738
  fm.push(...importLines);
@@ -716,6 +762,120 @@ ${body}
716
762
  ${styleBlock}${scriptBlock}`.replace(/\n+$/, "\n");
717
763
  }
718
764
 
765
+ // lib/dialect/parse/scan.ts
766
+ var CLOSERS = { "{": "}", "(": ")", "[": "]" };
767
+ function scanString(src, i) {
768
+ const q = src[i];
769
+ let j = i + 1;
770
+ while (j < src.length) {
771
+ if (src[j] === "\\") {
772
+ j += 2;
773
+ continue;
774
+ }
775
+ if (src[j] === q) return j + 1;
776
+ j++;
777
+ }
778
+ throw new Error(`scanString: unterminated string from ${i}`);
779
+ }
780
+ function scanTemplate(src, i) {
781
+ let j = i + 1;
782
+ while (j < src.length) {
783
+ if (src[j] === "\\") {
784
+ j += 2;
785
+ continue;
786
+ }
787
+ if (src[j] === "`") return j + 1;
788
+ if (src[j] === "$" && src[j + 1] === "{") {
789
+ j = scanBalanced(src, j + 1);
790
+ continue;
791
+ }
792
+ j++;
793
+ }
794
+ throw new Error(`scanTemplate: unterminated template from ${i}`);
795
+ }
796
+ function scanBalanced(src, i) {
797
+ if (!CLOSERS[src[i]]) throw new Error(`scanBalanced: no open delimiter at ${i} ("${src[i]}")`);
798
+ let depth = 0;
799
+ let j = i;
800
+ while (j < src.length) {
801
+ const c = src[j];
802
+ if (c === '"' || c === "'") {
803
+ j = scanString(src, j);
804
+ continue;
805
+ }
806
+ if (c === "`") {
807
+ j = scanTemplate(src, j);
808
+ continue;
809
+ }
810
+ if (c === "{" || c === "(" || c === "[") {
811
+ depth++;
812
+ j++;
813
+ continue;
814
+ }
815
+ if (c === "}" || c === ")" || c === "]") {
816
+ depth--;
817
+ j++;
818
+ if (depth === 0) return j;
819
+ continue;
820
+ }
821
+ j++;
822
+ }
823
+ throw new Error(`scanBalanced: unbalanced from ${i}`);
824
+ }
825
+ function findTrailingGroup(expr, openChar = "(") {
826
+ let j = 0;
827
+ while (j < expr.length) {
828
+ const c = expr[j];
829
+ if (c === '"' || c === "'") {
830
+ j = scanString(expr, j);
831
+ continue;
832
+ }
833
+ if (c === "`") {
834
+ j = scanTemplate(expr, j);
835
+ continue;
836
+ }
837
+ if (c === "{" || c === "(" || c === "[") {
838
+ const end = scanBalanced(expr, j);
839
+ if (c === openChar && end === expr.length) {
840
+ return { open: j, inner: expr.slice(j + 1, end - 1) };
841
+ }
842
+ j = end;
843
+ continue;
844
+ }
845
+ j++;
846
+ }
847
+ return null;
848
+ }
849
+ function splitTopLevel(src, sep) {
850
+ const parts = [];
851
+ let start = 0;
852
+ let j = 0;
853
+ while (j < src.length) {
854
+ const c = src[j];
855
+ if (c === '"' || c === "'") {
856
+ j = scanString(src, j);
857
+ continue;
858
+ }
859
+ if (c === "`") {
860
+ j = scanTemplate(src, j);
861
+ continue;
862
+ }
863
+ if (c === "{" || c === "(" || c === "[") {
864
+ j = scanBalanced(src, j);
865
+ continue;
866
+ }
867
+ if (c === sep) {
868
+ parts.push(src.slice(start, j));
869
+ start = j + 1;
870
+ j++;
871
+ continue;
872
+ }
873
+ j++;
874
+ }
875
+ parts.push(src.slice(start));
876
+ return parts.map((s) => s.trim());
877
+ }
878
+
719
879
  // lib/dialect/parse/parseLiteral.ts
720
880
  var WS = /* @__PURE__ */ new Set([" ", " ", "\r", "\n"]);
721
881
  var IDENT_START = /[A-Za-z_$]/;
@@ -798,137 +958,98 @@ function parseArray(src, i) {
798
958
  fail(src, j, 'expected "," or "]"');
799
959
  }
800
960
  }
801
- function parseValueAt(src, i) {
802
- i = skipWs(src, i);
803
- const c = src[i];
804
- if (c === "{") return parseObject(src, i);
805
- if (c === "[") return parseArray(src, i);
806
- if (c === '"') return parseString(src, i);
807
- if (src.startsWith("true", i)) return { value: true, end: i + 4 };
808
- if (src.startsWith("false", i)) return { value: false, end: i + 5 };
809
- if (src.startsWith("null", i)) return { value: null, end: i + 4 };
810
- if (c === "-" || c === "+" || c >= "0" && c <= "9") return parseNumber(src, i);
811
- return fail(src, i, `unexpected character "${c ?? "<eof>"}"`);
812
- }
813
- function parseLiteral(src) {
814
- const { value, end } = parseValueAt(src, 0);
815
- const rest = skipWs(src, end);
816
- if (rest !== src.length) fail(src, rest, "trailing content after literal");
817
- return value;
818
- }
819
-
820
- // lib/dialect/parse/scan.ts
821
- var CLOSERS = { "{": "}", "(": ")", "[": "]" };
822
- function scanString(src, i) {
823
- const q = src[i];
824
- let j = i + 1;
825
- while (j < src.length) {
826
- if (src[j] === "\\") {
827
- j += 2;
961
+ function reverseBacktickBody(content) {
962
+ let out = "";
963
+ let i = 0;
964
+ while (i < content.length) {
965
+ const c = content[i];
966
+ if (c === "\\") {
967
+ const n = content[i + 1];
968
+ out += n === "\\" ? "\\" : n === "`" ? "`" : n === "$" ? "$" : n;
969
+ i += 2;
828
970
  continue;
829
971
  }
830
- if (src[j] === q) return j + 1;
831
- j++;
972
+ if (c === "$" && content[i + 1] === "{") {
973
+ const end = scanBalanced(content, i + 1);
974
+ out += "{{" + content.slice(i + 2, end - 1).trim() + "}}";
975
+ i = end;
976
+ continue;
977
+ }
978
+ out += c;
979
+ i++;
832
980
  }
833
- throw new Error(`scanString: unterminated string from ${i}`);
981
+ return out;
834
982
  }
835
- function scanTemplate(src, i) {
983
+ function parseBacktick(src, i) {
836
984
  let j = i + 1;
837
985
  while (j < src.length) {
838
- if (src[j] === "\\") {
986
+ const c = src[j];
987
+ if (c === "\\") {
839
988
  j += 2;
840
989
  continue;
841
990
  }
842
- if (src[j] === "`") return j + 1;
843
- if (src[j] === "$" && src[j + 1] === "{") {
991
+ if (c === "`") {
992
+ j++;
993
+ break;
994
+ }
995
+ if (c === "$" && src[j + 1] === "{") {
844
996
  j = scanBalanced(src, j + 1);
845
997
  continue;
846
998
  }
847
999
  j++;
848
1000
  }
849
- throw new Error(`scanTemplate: unterminated template from ${i}`);
1001
+ return { value: reverseBacktickBody(src.slice(i + 1, j - 1)), end: j };
850
1002
  }
851
- function scanBalanced(src, i) {
852
- if (!CLOSERS[src[i]]) throw new Error(`scanBalanced: no open delimiter at ${i} ("${src[i]}")`);
853
- let depth = 0;
1003
+ function parseExprToken(src, i) {
854
1004
  let j = i;
1005
+ let depth = 0;
855
1006
  while (j < src.length) {
856
1007
  const c = src[j];
857
- if (c === '"' || c === "'") {
858
- j = scanString(src, j);
859
- continue;
860
- }
861
- if (c === "`") {
862
- j = scanTemplate(src, j);
1008
+ if (c === '"' || c === "'" || c === "`") {
1009
+ const q = c;
1010
+ j++;
1011
+ while (j < src.length && src[j] !== q) {
1012
+ if (src[j] === "\\") j++;
1013
+ j++;
1014
+ }
1015
+ j++;
863
1016
  continue;
864
1017
  }
865
- if (c === "{" || c === "(" || c === "[") {
1018
+ if (c === "(" || c === "[" || c === "{") {
866
1019
  depth++;
867
1020
  j++;
868
1021
  continue;
869
1022
  }
870
- if (c === "}" || c === ")" || c === "]") {
1023
+ if (c === ")" || c === "]" || c === "}") {
1024
+ if (depth === 0) break;
871
1025
  depth--;
872
1026
  j++;
873
- if (depth === 0) return j;
874
1027
  continue;
875
1028
  }
1029
+ if (depth === 0 && c === ",") break;
876
1030
  j++;
877
1031
  }
878
- throw new Error(`scanBalanced: unbalanced from ${i}`);
1032
+ return { value: `{{${src.slice(i, j).trim()}}}`, end: j };
879
1033
  }
880
- function findTrailingGroup(expr, openChar = "(") {
881
- let j = 0;
882
- while (j < expr.length) {
883
- const c = expr[j];
884
- if (c === '"' || c === "'") {
885
- j = scanString(expr, j);
886
- continue;
887
- }
888
- if (c === "`") {
889
- j = scanTemplate(expr, j);
890
- continue;
891
- }
892
- if (c === "{" || c === "(" || c === "[") {
893
- const end = scanBalanced(expr, j);
894
- if (c === openChar && end === expr.length) {
895
- return { open: j, inner: expr.slice(j + 1, end - 1) };
896
- }
897
- j = end;
898
- continue;
899
- }
900
- j++;
901
- }
902
- return null;
1034
+ function parseValueAt(src, i) {
1035
+ i = skipWs(src, i);
1036
+ const c = src[i];
1037
+ if (c === "{") return parseObject(src, i);
1038
+ if (c === "[") return parseArray(src, i);
1039
+ if (c === '"') return parseString(src, i);
1040
+ if (c === "`") return parseBacktick(src, i);
1041
+ if (src.startsWith("true", i) && !IDENT_CHAR.test(src[i + 4] ?? "")) return { value: true, end: i + 4 };
1042
+ if (src.startsWith("false", i) && !IDENT_CHAR.test(src[i + 5] ?? "")) return { value: false, end: i + 5 };
1043
+ if (src.startsWith("null", i) && !IDENT_CHAR.test(src[i + 4] ?? "")) return { value: null, end: i + 4 };
1044
+ if (c === "-" || c === "+" || c >= "0" && c <= "9") return parseNumber(src, i);
1045
+ if (c !== void 0 && IDENT_START.test(c)) return parseExprToken(src, i);
1046
+ return fail(src, i, `unexpected character "${c ?? "<eof>"}"`);
903
1047
  }
904
- function splitTopLevel(src, sep) {
905
- const parts = [];
906
- let start = 0;
907
- let j = 0;
908
- while (j < src.length) {
909
- const c = src[j];
910
- if (c === '"' || c === "'") {
911
- j = scanString(src, j);
912
- continue;
913
- }
914
- if (c === "`") {
915
- j = scanTemplate(src, j);
916
- continue;
917
- }
918
- if (c === "{" || c === "(" || c === "[") {
919
- j = scanBalanced(src, j);
920
- continue;
921
- }
922
- if (c === sep) {
923
- parts.push(src.slice(start, j));
924
- start = j + 1;
925
- j++;
926
- continue;
927
- }
928
- j++;
929
- }
930
- parts.push(src.slice(start));
931
- return parts.map((s) => s.trim());
1048
+ function parseLiteral(src) {
1049
+ const { value, end } = parseValueAt(src, 0);
1050
+ const rest = skipWs(src, end);
1051
+ if (rest !== src.length) fail(src, rest, "trailing content after literal");
1052
+ return value;
932
1053
  }
933
1054
 
934
1055
  // lib/dialect/parse/callArgs.ts
@@ -1041,7 +1162,7 @@ function parseFrontmatter(code) {
1041
1162
  }
1042
1163
  const propsInterface = literalAfter(code, "resolveProps(Astro, ");
1043
1164
  const componentMeta = literalAfter(code, "const __meno = ") ?? {};
1044
- const meta = literalAfter(code, "export const meta = ");
1165
+ const meta = literalAfter(code, "const meta = ");
1045
1166
  const kind = code.includes("resolveProps(") ? "component" : "page";
1046
1167
  return { kind, ctx, meta, propsInterface, componentMeta };
1047
1168
  }
@@ -1239,6 +1360,7 @@ function otherAttrs(attrs, ctx, skip) {
1239
1360
  const out = {};
1240
1361
  for (const a of attrs) {
1241
1362
  if (skip.has(a.name)) continue;
1363
+ if (a.name === "cms" && a.isExpr && a.raw.trim() === "cms") continue;
1242
1364
  out[a.name] = attrValue(a, ctx);
1243
1365
  }
1244
1366
  return out;
@@ -1562,4 +1684,4 @@ export {
1562
1684
  emit,
1563
1685
  parse
1564
1686
  };
1565
- //# sourceMappingURL=chunk-3C3MQ4QX.js.map
1687
+ //# sourceMappingURL=chunk-Q5V5WUXZ.js.map