@nuasite/cli 0.40.0 → 0.42.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/index.js CHANGED
@@ -707,17 +707,17 @@ var require_visit = __commonJS((exports) => {
707
707
  visit.BREAK = BREAK;
708
708
  visit.SKIP = SKIP;
709
709
  visit.REMOVE = REMOVE;
710
- function visit_(key, node, visitor, path2) {
711
- const ctrl = callVisitor(key, node, visitor, path2);
710
+ function visit_(key, node, visitor, path) {
711
+ const ctrl = callVisitor(key, node, visitor, path);
712
712
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
713
- replaceNode(key, path2, ctrl);
714
- return visit_(key, ctrl, visitor, path2);
713
+ replaceNode(key, path, ctrl);
714
+ return visit_(key, ctrl, visitor, path);
715
715
  }
716
716
  if (typeof ctrl !== "symbol") {
717
717
  if (identity.isCollection(node)) {
718
- path2 = Object.freeze(path2.concat(node));
718
+ path = Object.freeze(path.concat(node));
719
719
  for (let i = 0;i < node.items.length; ++i) {
720
- const ci = visit_(i, node.items[i], visitor, path2);
720
+ const ci = visit_(i, node.items[i], visitor, path);
721
721
  if (typeof ci === "number")
722
722
  i = ci - 1;
723
723
  else if (ci === BREAK)
@@ -728,13 +728,13 @@ var require_visit = __commonJS((exports) => {
728
728
  }
729
729
  }
730
730
  } else if (identity.isPair(node)) {
731
- path2 = Object.freeze(path2.concat(node));
732
- const ck = visit_("key", node.key, visitor, path2);
731
+ path = Object.freeze(path.concat(node));
732
+ const ck = visit_("key", node.key, visitor, path);
733
733
  if (ck === BREAK)
734
734
  return BREAK;
735
735
  else if (ck === REMOVE)
736
736
  node.key = null;
737
- const cv = visit_("value", node.value, visitor, path2);
737
+ const cv = visit_("value", node.value, visitor, path);
738
738
  if (cv === BREAK)
739
739
  return BREAK;
740
740
  else if (cv === REMOVE)
@@ -755,17 +755,17 @@ var require_visit = __commonJS((exports) => {
755
755
  visitAsync.BREAK = BREAK;
756
756
  visitAsync.SKIP = SKIP;
757
757
  visitAsync.REMOVE = REMOVE;
758
- async function visitAsync_(key, node, visitor, path2) {
759
- const ctrl = await callVisitor(key, node, visitor, path2);
758
+ async function visitAsync_(key, node, visitor, path) {
759
+ const ctrl = await callVisitor(key, node, visitor, path);
760
760
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
761
- replaceNode(key, path2, ctrl);
762
- return visitAsync_(key, ctrl, visitor, path2);
761
+ replaceNode(key, path, ctrl);
762
+ return visitAsync_(key, ctrl, visitor, path);
763
763
  }
764
764
  if (typeof ctrl !== "symbol") {
765
765
  if (identity.isCollection(node)) {
766
- path2 = Object.freeze(path2.concat(node));
766
+ path = Object.freeze(path.concat(node));
767
767
  for (let i = 0;i < node.items.length; ++i) {
768
- const ci = await visitAsync_(i, node.items[i], visitor, path2);
768
+ const ci = await visitAsync_(i, node.items[i], visitor, path);
769
769
  if (typeof ci === "number")
770
770
  i = ci - 1;
771
771
  else if (ci === BREAK)
@@ -776,13 +776,13 @@ var require_visit = __commonJS((exports) => {
776
776
  }
777
777
  }
778
778
  } else if (identity.isPair(node)) {
779
- path2 = Object.freeze(path2.concat(node));
780
- const ck = await visitAsync_("key", node.key, visitor, path2);
779
+ path = Object.freeze(path.concat(node));
780
+ const ck = await visitAsync_("key", node.key, visitor, path);
781
781
  if (ck === BREAK)
782
782
  return BREAK;
783
783
  else if (ck === REMOVE)
784
784
  node.key = null;
785
- const cv = await visitAsync_("value", node.value, visitor, path2);
785
+ const cv = await visitAsync_("value", node.value, visitor, path);
786
786
  if (cv === BREAK)
787
787
  return BREAK;
788
788
  else if (cv === REMOVE)
@@ -809,23 +809,23 @@ var require_visit = __commonJS((exports) => {
809
809
  }
810
810
  return visitor;
811
811
  }
812
- function callVisitor(key, node, visitor, path2) {
812
+ function callVisitor(key, node, visitor, path) {
813
813
  if (typeof visitor === "function")
814
- return visitor(key, node, path2);
814
+ return visitor(key, node, path);
815
815
  if (identity.isMap(node))
816
- return visitor.Map?.(key, node, path2);
816
+ return visitor.Map?.(key, node, path);
817
817
  if (identity.isSeq(node))
818
- return visitor.Seq?.(key, node, path2);
818
+ return visitor.Seq?.(key, node, path);
819
819
  if (identity.isPair(node))
820
- return visitor.Pair?.(key, node, path2);
820
+ return visitor.Pair?.(key, node, path);
821
821
  if (identity.isScalar(node))
822
- return visitor.Scalar?.(key, node, path2);
822
+ return visitor.Scalar?.(key, node, path);
823
823
  if (identity.isAlias(node))
824
- return visitor.Alias?.(key, node, path2);
824
+ return visitor.Alias?.(key, node, path);
825
825
  return;
826
826
  }
827
- function replaceNode(key, path2, node) {
828
- const parent = path2[path2.length - 1];
827
+ function replaceNode(key, path, node) {
828
+ const parent = path[path.length - 1];
829
829
  if (identity.isCollection(parent)) {
830
830
  parent.items[key] = node;
831
831
  } else if (identity.isPair(parent)) {
@@ -1382,10 +1382,10 @@ var require_Collection = __commonJS((exports) => {
1382
1382
  var createNode = require_createNode();
1383
1383
  var identity = require_identity();
1384
1384
  var Node = require_Node();
1385
- function collectionFromPath(schema, path2, value) {
1385
+ function collectionFromPath(schema, path, value) {
1386
1386
  let v = value;
1387
- for (let i = path2.length - 1;i >= 0; --i) {
1388
- const k = path2[i];
1387
+ for (let i = path.length - 1;i >= 0; --i) {
1388
+ const k = path[i];
1389
1389
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
1390
1390
  const a = [];
1391
1391
  a[k] = v;
@@ -1404,7 +1404,7 @@ var require_Collection = __commonJS((exports) => {
1404
1404
  sourceObjects: new Map
1405
1405
  });
1406
1406
  }
1407
- var isEmptyPath = (path2) => path2 == null || typeof path2 === "object" && !!path2[Symbol.iterator]().next().done;
1407
+ var isEmptyPath = (path) => path == null || typeof path === "object" && !!path[Symbol.iterator]().next().done;
1408
1408
 
1409
1409
  class Collection extends Node.NodeBase {
1410
1410
  constructor(type, schema) {
@@ -1425,11 +1425,11 @@ var require_Collection = __commonJS((exports) => {
1425
1425
  copy.range = this.range.slice();
1426
1426
  return copy;
1427
1427
  }
1428
- addIn(path2, value) {
1429
- if (isEmptyPath(path2))
1428
+ addIn(path, value) {
1429
+ if (isEmptyPath(path))
1430
1430
  this.add(value);
1431
1431
  else {
1432
- const [key, ...rest] = path2;
1432
+ const [key, ...rest] = path;
1433
1433
  const node = this.get(key, true);
1434
1434
  if (identity.isCollection(node))
1435
1435
  node.addIn(rest, value);
@@ -1439,8 +1439,8 @@ var require_Collection = __commonJS((exports) => {
1439
1439
  throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
1440
1440
  }
1441
1441
  }
1442
- deleteIn(path2) {
1443
- const [key, ...rest] = path2;
1442
+ deleteIn(path) {
1443
+ const [key, ...rest] = path;
1444
1444
  if (rest.length === 0)
1445
1445
  return this.delete(key);
1446
1446
  const node = this.get(key, true);
@@ -1449,8 +1449,8 @@ var require_Collection = __commonJS((exports) => {
1449
1449
  else
1450
1450
  throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
1451
1451
  }
1452
- getIn(path2, keepScalar) {
1453
- const [key, ...rest] = path2;
1452
+ getIn(path, keepScalar) {
1453
+ const [key, ...rest] = path;
1454
1454
  const node = this.get(key, true);
1455
1455
  if (rest.length === 0)
1456
1456
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -1465,15 +1465,15 @@ var require_Collection = __commonJS((exports) => {
1465
1465
  return n == null || allowScalar && identity.isScalar(n) && n.value == null && !n.commentBefore && !n.comment && !n.tag;
1466
1466
  });
1467
1467
  }
1468
- hasIn(path2) {
1469
- const [key, ...rest] = path2;
1468
+ hasIn(path) {
1469
+ const [key, ...rest] = path;
1470
1470
  if (rest.length === 0)
1471
1471
  return this.has(key);
1472
1472
  const node = this.get(key, true);
1473
1473
  return identity.isCollection(node) ? node.hasIn(rest) : false;
1474
1474
  }
1475
- setIn(path2, value) {
1476
- const [key, ...rest] = path2;
1475
+ setIn(path, value) {
1476
+ const [key, ...rest] = path;
1477
1477
  if (rest.length === 0) {
1478
1478
  this.set(key, value);
1479
1479
  } else {
@@ -3863,9 +3863,9 @@ var require_Document = __commonJS((exports) => {
3863
3863
  if (assertCollection(this.contents))
3864
3864
  this.contents.add(value);
3865
3865
  }
3866
- addIn(path2, value) {
3866
+ addIn(path, value) {
3867
3867
  if (assertCollection(this.contents))
3868
- this.contents.addIn(path2, value);
3868
+ this.contents.addIn(path, value);
3869
3869
  }
3870
3870
  createAlias(node, name) {
3871
3871
  if (!node.anchor) {
@@ -3914,30 +3914,30 @@ var require_Document = __commonJS((exports) => {
3914
3914
  delete(key) {
3915
3915
  return assertCollection(this.contents) ? this.contents.delete(key) : false;
3916
3916
  }
3917
- deleteIn(path2) {
3918
- if (Collection.isEmptyPath(path2)) {
3917
+ deleteIn(path) {
3918
+ if (Collection.isEmptyPath(path)) {
3919
3919
  if (this.contents == null)
3920
3920
  return false;
3921
3921
  this.contents = null;
3922
3922
  return true;
3923
3923
  }
3924
- return assertCollection(this.contents) ? this.contents.deleteIn(path2) : false;
3924
+ return assertCollection(this.contents) ? this.contents.deleteIn(path) : false;
3925
3925
  }
3926
3926
  get(key, keepScalar) {
3927
3927
  return identity.isCollection(this.contents) ? this.contents.get(key, keepScalar) : undefined;
3928
3928
  }
3929
- getIn(path2, keepScalar) {
3930
- if (Collection.isEmptyPath(path2))
3929
+ getIn(path, keepScalar) {
3930
+ if (Collection.isEmptyPath(path))
3931
3931
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3932
- return identity.isCollection(this.contents) ? this.contents.getIn(path2, keepScalar) : undefined;
3932
+ return identity.isCollection(this.contents) ? this.contents.getIn(path, keepScalar) : undefined;
3933
3933
  }
3934
3934
  has(key) {
3935
3935
  return identity.isCollection(this.contents) ? this.contents.has(key) : false;
3936
3936
  }
3937
- hasIn(path2) {
3938
- if (Collection.isEmptyPath(path2))
3937
+ hasIn(path) {
3938
+ if (Collection.isEmptyPath(path))
3939
3939
  return this.contents !== undefined;
3940
- return identity.isCollection(this.contents) ? this.contents.hasIn(path2) : false;
3940
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path) : false;
3941
3941
  }
3942
3942
  set(key, value) {
3943
3943
  if (this.contents == null) {
@@ -3946,13 +3946,13 @@ var require_Document = __commonJS((exports) => {
3946
3946
  this.contents.set(key, value);
3947
3947
  }
3948
3948
  }
3949
- setIn(path2, value) {
3950
- if (Collection.isEmptyPath(path2)) {
3949
+ setIn(path, value) {
3950
+ if (Collection.isEmptyPath(path)) {
3951
3951
  this.contents = value;
3952
3952
  } else if (this.contents == null) {
3953
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path2), value);
3953
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path), value);
3954
3954
  } else if (assertCollection(this.contents)) {
3955
- this.contents.setIn(path2, value);
3955
+ this.contents.setIn(path, value);
3956
3956
  }
3957
3957
  }
3958
3958
  setSchema(version, options = {}) {
@@ -5846,9 +5846,9 @@ var require_cst_visit = __commonJS((exports) => {
5846
5846
  visit.BREAK = BREAK;
5847
5847
  visit.SKIP = SKIP;
5848
5848
  visit.REMOVE = REMOVE;
5849
- visit.itemAtPath = (cst, path2) => {
5849
+ visit.itemAtPath = (cst, path) => {
5850
5850
  let item = cst;
5851
- for (const [field, index] of path2) {
5851
+ for (const [field, index] of path) {
5852
5852
  const tok = item?.[field];
5853
5853
  if (tok && "items" in tok) {
5854
5854
  item = tok.items[index];
@@ -5857,23 +5857,23 @@ var require_cst_visit = __commonJS((exports) => {
5857
5857
  }
5858
5858
  return item;
5859
5859
  };
5860
- visit.parentCollection = (cst, path2) => {
5861
- const parent = visit.itemAtPath(cst, path2.slice(0, -1));
5862
- const field = path2[path2.length - 1][0];
5860
+ visit.parentCollection = (cst, path) => {
5861
+ const parent = visit.itemAtPath(cst, path.slice(0, -1));
5862
+ const field = path[path.length - 1][0];
5863
5863
  const coll = parent?.[field];
5864
5864
  if (coll && "items" in coll)
5865
5865
  return coll;
5866
5866
  throw new Error("Parent collection not found");
5867
5867
  };
5868
- function _visit(path2, item, visitor) {
5869
- let ctrl = visitor(item, path2);
5868
+ function _visit(path, item, visitor) {
5869
+ let ctrl = visitor(item, path);
5870
5870
  if (typeof ctrl === "symbol")
5871
5871
  return ctrl;
5872
5872
  for (const field of ["key", "value"]) {
5873
5873
  const token = item[field];
5874
5874
  if (token && "items" in token) {
5875
5875
  for (let i = 0;i < token.items.length; ++i) {
5876
- const ci = _visit(Object.freeze(path2.concat([[field, i]])), token.items[i], visitor);
5876
+ const ci = _visit(Object.freeze(path.concat([[field, i]])), token.items[i], visitor);
5877
5877
  if (typeof ci === "number")
5878
5878
  i = ci - 1;
5879
5879
  else if (ci === BREAK)
@@ -5884,10 +5884,10 @@ var require_cst_visit = __commonJS((exports) => {
5884
5884
  }
5885
5885
  }
5886
5886
  if (typeof ctrl === "function" && field === "key")
5887
- ctrl = ctrl(item, path2);
5887
+ ctrl = ctrl(item, path);
5888
5888
  }
5889
5889
  }
5890
- return typeof ctrl === "function" ? ctrl(item, path2) : ctrl;
5890
+ return typeof ctrl === "function" ? ctrl(item, path) : ctrl;
5891
5891
  }
5892
5892
  exports.visit = visit;
5893
5893
  });
@@ -7156,14 +7156,14 @@ var require_parser = __commonJS((exports) => {
7156
7156
  case "scalar":
7157
7157
  case "single-quoted-scalar":
7158
7158
  case "double-quoted-scalar": {
7159
- const fs3 = this.flowScalar(this.type);
7159
+ const fs = this.flowScalar(this.type);
7160
7160
  if (atNextItem || it.value) {
7161
- map.items.push({ start, key: fs3, sep: [] });
7161
+ map.items.push({ start, key: fs, sep: [] });
7162
7162
  this.onKeyLine = true;
7163
7163
  } else if (it.sep) {
7164
- this.stack.push(fs3);
7164
+ this.stack.push(fs);
7165
7165
  } else {
7166
- Object.assign(it, { key: fs3, sep: [] });
7166
+ Object.assign(it, { key: fs, sep: [] });
7167
7167
  this.onKeyLine = true;
7168
7168
  }
7169
7169
  return;
@@ -7291,13 +7291,13 @@ var require_parser = __commonJS((exports) => {
7291
7291
  case "scalar":
7292
7292
  case "single-quoted-scalar":
7293
7293
  case "double-quoted-scalar": {
7294
- const fs3 = this.flowScalar(this.type);
7294
+ const fs = this.flowScalar(this.type);
7295
7295
  if (!it || it.value)
7296
- fc.items.push({ start: [], key: fs3, sep: [] });
7296
+ fc.items.push({ start: [], key: fs, sep: [] });
7297
7297
  else if (it.sep)
7298
- this.stack.push(fs3);
7298
+ this.stack.push(fs);
7299
7299
  else
7300
- Object.assign(it, { key: fs3, sep: [] });
7300
+ Object.assign(it, { key: fs, sep: [] });
7301
7301
  return;
7302
7302
  }
7303
7303
  case "flow-map-end":
@@ -8524,13 +8524,13 @@ var require_lib = __commonJS((exports) => {
8524
8524
  this.preserveSpace = !!preserveSpace;
8525
8525
  }
8526
8526
  }
8527
- var types2 = {
8527
+ var types = {
8528
8528
  brace: new TokContext("{"),
8529
8529
  j_oTag: new TokContext("<tag"),
8530
8530
  j_cTag: new TokContext("</tag"),
8531
8531
  j_expr: new TokContext("<tag>...</tag>", true)
8532
8532
  };
8533
- types2.template = new TokContext("`", true);
8533
+ types.template = new TokContext("`", true);
8534
8534
  var beforeExpr = true;
8535
8535
  var startsExpr = true;
8536
8536
  var isLoop = true;
@@ -9065,17 +9065,17 @@ var require_lib = __commonJS((exports) => {
9065
9065
  context.pop();
9066
9066
  };
9067
9067
  tokenTypes[5].updateContext = tokenTypes[7].updateContext = tokenTypes[23].updateContext = (context) => {
9068
- context.push(types2.brace);
9068
+ context.push(types.brace);
9069
9069
  };
9070
9070
  tokenTypes[22].updateContext = (context) => {
9071
- if (context[context.length - 1] === types2.template) {
9071
+ if (context[context.length - 1] === types.template) {
9072
9072
  context.pop();
9073
9073
  } else {
9074
- context.push(types2.template);
9074
+ context.push(types.template);
9075
9075
  }
9076
9076
  };
9077
9077
  tokenTypes[143].updateContext = (context) => {
9078
- context.push(types2.j_expr, types2.j_oTag);
9078
+ context.push(types.j_expr, types.j_oTag);
9079
9079
  };
9080
9080
  var nonASCIIidentifierStartChars = "\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088F\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5C\u0C5D\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDC-\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C8A\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7DC\uA7F1-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC";
9081
9081
  var nonASCIIidentifierChars = "\xB7\u0300-\u036F\u0387\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u0897-\u089F\u08CA-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0966-\u096F\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09E6-\u09EF\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A66-\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AE6-\u0AEF\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B66-\u0B6F\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0BE6-\u0BEF\u0C00-\u0C04\u0C3C\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0CE6-\u0CEF\u0CF3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D66-\u0D6F\u0D81-\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0E50-\u0E59\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECE\u0ED0-\u0ED9\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1040-\u1049\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F-\u109D\u135D-\u135F\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u17E0-\u17E9\u180B-\u180D\u180F-\u1819\u18A9\u1920-\u192B\u1930-\u193B\u1946-\u194F\u19D0-\u19DA\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AB0-\u1ABD\u1ABF-\u1ADD\u1AE0-\u1AEB\u1B00-\u1B04\u1B34-\u1B44\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BB0-\u1BB9\u1BE6-\u1BF3\u1C24-\u1C37\u1C40-\u1C49\u1C50-\u1C59\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DFF\u200C\u200D\u203F\u2040\u2054\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\u30FB\uA620-\uA629\uA66F\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA82C\uA880\uA881\uA8B4-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F1\uA8FF-\uA909\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9D0-\uA9D9\uA9E5\uA9F0-\uA9F9\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA50-\uAA59\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uABF0-\uABF9\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFF10-\uFF19\uFF3F\uFF65";
@@ -9863,7 +9863,7 @@ var require_lib = __commonJS((exports) => {
9863
9863
  return this.finishNode(node, "TypeParameterDeclaration");
9864
9864
  }
9865
9865
  flowInTopLevelContext(cb) {
9866
- if (this.curContext() !== types2.brace) {
9866
+ if (this.curContext() !== types.brace) {
9867
9867
  const oldContext = this.state.context;
9868
9868
  this.state.context = [oldContext[0]];
9869
9869
  try {
@@ -9898,7 +9898,7 @@ var require_lib = __commonJS((exports) => {
9898
9898
  this.state.noAnonFunctionType = oldNoAnonFunctionType;
9899
9899
  });
9900
9900
  this.state.inType = oldInType;
9901
- if (!this.state.inType && this.curContext() === types2.brace) {
9901
+ if (!this.state.inType && this.curContext() === types.brace) {
9902
9902
  this.reScan_lt_gt();
9903
9903
  }
9904
9904
  this.expect(48);
@@ -11173,7 +11173,7 @@ var require_lib = __commonJS((exports) => {
11173
11173
  context
11174
11174
  } = this.state;
11175
11175
  const currentContext = context[context.length - 1];
11176
- if (currentContext === types2.j_oTag || currentContext === types2.j_expr) {
11176
+ if (currentContext === types.j_oTag || currentContext === types.j_expr) {
11177
11177
  context.pop();
11178
11178
  }
11179
11179
  }
@@ -12279,9 +12279,9 @@ var require_lib = __commonJS((exports) => {
12279
12279
  switch (this.state.type) {
12280
12280
  case 5:
12281
12281
  node = this.startNode();
12282
- this.setContext(types2.brace);
12282
+ this.setContext(types.brace);
12283
12283
  this.next();
12284
- node = this.jsxParseExpressionContainer(node, types2.j_oTag);
12284
+ node = this.jsxParseExpressionContainer(node, types.j_oTag);
12285
12285
  if (node.expression.type === "JSXEmptyExpression") {
12286
12286
  this.raise(JsxErrors.AttributeIsEmpty, node);
12287
12287
  }
@@ -12300,7 +12300,7 @@ var require_lib = __commonJS((exports) => {
12300
12300
  jsxParseSpreadChild(node) {
12301
12301
  this.next();
12302
12302
  node.expression = this.parseExpression();
12303
- this.setContext(types2.j_expr);
12303
+ this.setContext(types.j_expr);
12304
12304
  this.state.canStartJSXElement = true;
12305
12305
  this.expect(8);
12306
12306
  return this.finishNode(node, "JSXSpreadChild");
@@ -12320,11 +12320,11 @@ var require_lib = __commonJS((exports) => {
12320
12320
  jsxParseAttribute() {
12321
12321
  const node = this.startNode();
12322
12322
  if (this.match(5)) {
12323
- this.setContext(types2.brace);
12323
+ this.setContext(types.brace);
12324
12324
  this.next();
12325
12325
  this.expect(21);
12326
12326
  node.argument = this.parseMaybeAssignAllowIn();
12327
- this.setContext(types2.j_oTag);
12327
+ this.setContext(types.j_oTag);
12328
12328
  this.state.canStartJSXElement = true;
12329
12329
  this.expect(8);
12330
12330
  return this.finishNode(node, "JSXSpreadAttribute");
@@ -12383,12 +12383,12 @@ var require_lib = __commonJS((exports) => {
12383
12383
  break;
12384
12384
  case 5: {
12385
12385
  const node2 = this.startNode();
12386
- this.setContext(types2.brace);
12386
+ this.setContext(types.brace);
12387
12387
  this.next();
12388
12388
  if (this.match(21)) {
12389
12389
  children.push(this.jsxParseSpreadChild(node2));
12390
12390
  } else {
12391
- children.push(this.jsxParseExpressionContainer(node2, types2.j_expr));
12391
+ children.push(this.jsxParseExpressionContainer(node2, types.j_expr));
12392
12392
  }
12393
12393
  break;
12394
12394
  }
@@ -12451,11 +12451,11 @@ var require_lib = __commonJS((exports) => {
12451
12451
  }
12452
12452
  getTokenFromCode(code2) {
12453
12453
  const context = this.curContext();
12454
- if (context === types2.j_expr) {
12454
+ if (context === types.j_expr) {
12455
12455
  this.jsxReadToken();
12456
12456
  return;
12457
12457
  }
12458
- if (context === types2.j_oTag || context === types2.j_cTag) {
12458
+ if (context === types.j_oTag || context === types.j_cTag) {
12459
12459
  if (isIdentifierStart(code2)) {
12460
12460
  this.jsxReadWord();
12461
12461
  return;
@@ -12465,7 +12465,7 @@ var require_lib = __commonJS((exports) => {
12465
12465
  this.finishToken(144);
12466
12466
  return;
12467
12467
  }
12468
- if ((code2 === 34 || code2 === 39) && context === types2.j_oTag) {
12468
+ if ((code2 === 34 || code2 === 39) && context === types.j_oTag) {
12469
12469
  this.jsxReadString(code2);
12470
12470
  return;
12471
12471
  }
@@ -12483,17 +12483,17 @@ var require_lib = __commonJS((exports) => {
12483
12483
  type
12484
12484
  } = this.state;
12485
12485
  if (type === 56 && prevType === 143) {
12486
- context.splice(-2, 2, types2.j_cTag);
12486
+ context.splice(-2, 2, types.j_cTag);
12487
12487
  this.state.canStartJSXElement = false;
12488
12488
  } else if (type === 143) {
12489
- context.push(types2.j_oTag);
12489
+ context.push(types.j_oTag);
12490
12490
  } else if (type === 144) {
12491
12491
  const out = context[context.length - 1];
12492
- if (out === types2.j_oTag && prevType === 56 || out === types2.j_cTag) {
12492
+ if (out === types.j_oTag && prevType === 56 || out === types.j_cTag) {
12493
12493
  context.pop();
12494
- this.state.canStartJSXElement = context[context.length - 1] === types2.j_expr;
12494
+ this.state.canStartJSXElement = context[context.length - 1] === types.j_expr;
12495
12495
  } else {
12496
- this.setContext(types2.j_expr);
12496
+ this.setContext(types.j_expr);
12497
12497
  this.state.canStartJSXElement = true;
12498
12498
  }
12499
12499
  } else {
@@ -12901,7 +12901,7 @@ var require_lib = __commonJS((exports) => {
12901
12901
  this.end = 0;
12902
12902
  this.lastTokEndLoc = null;
12903
12903
  this.lastTokStartLoc = null;
12904
- this.context = [types2.brace];
12904
+ this.context = [types.brace];
12905
12905
  this.firstInvalidTemplateEscapePos = null;
12906
12906
  this.strictErrors = new Map;
12907
12907
  this.tokensLength = 0;
@@ -16304,14 +16304,14 @@ var require_lib = __commonJS((exports) => {
16304
16304
  tsParseUnionOrIntersectionType(kind, parseConstituentType, operator) {
16305
16305
  const node = this.startNode();
16306
16306
  const hasLeadingOperator = this.eat(operator);
16307
- const types3 = [];
16307
+ const types2 = [];
16308
16308
  do {
16309
- types3.push(parseConstituentType());
16309
+ types2.push(parseConstituentType());
16310
16310
  } while (this.eat(operator));
16311
- if (types3.length === 1 && !hasLeadingOperator) {
16312
- return types3[0];
16311
+ if (types2.length === 1 && !hasLeadingOperator) {
16312
+ return types2[0];
16313
16313
  }
16314
- node.types = types3;
16314
+ node.types = types2;
16315
16315
  return this.finishNode(node, kind);
16316
16316
  }
16317
16317
  tsParseIntersectionTypeOrHigher() {
@@ -16557,7 +16557,7 @@ var require_lib = __commonJS((exports) => {
16557
16557
  return this.finishNode(node, "TSTypeAliasDeclaration");
16558
16558
  }
16559
16559
  tsInTopLevelContext(cb) {
16560
- if (this.curContext() !== types2.brace) {
16560
+ if (this.curContext() !== types.brace) {
16561
16561
  const oldContext = this.state.context;
16562
16562
  this.state.context = [oldContext[0]];
16563
16563
  try {
@@ -16878,7 +16878,7 @@ var require_lib = __commonJS((exports) => {
16878
16878
  }));
16879
16879
  if (node.params.length === 0) {
16880
16880
  this.raise(TSErrors.EmptyTypeArguments, node);
16881
- } else if (!this.state.inType && this.curContext() === types2.brace) {
16881
+ } else if (!this.state.inType && this.curContext() === types.brace) {
16882
16882
  this.reScan_lt_gt();
16883
16883
  }
16884
16884
  this.expect(48);
@@ -17580,7 +17580,7 @@ var require_lib = __commonJS((exports) => {
17580
17580
  context
17581
17581
  } = this.state;
17582
17582
  const currentContext = context[context.length - 1];
17583
- if (currentContext === types2.j_oTag || currentContext === types2.j_expr) {
17583
+ if (currentContext === types.j_oTag || currentContext === types.j_expr) {
17584
17584
  context.pop();
17585
17585
  }
17586
17586
  }
@@ -22504,15 +22504,28 @@ var init_ast_parser = __esm(() => {
22504
22504
  });
22505
22505
 
22506
22506
  // ../cms/src/content-config-ast.ts
22507
- import fs3 from "fs/promises";
22508
- import path2 from "path";
22507
+ import fs from "fs/promises";
22508
+ import path from "path";
22509
+ function resolveExpression(node, bindings, visited = new Set) {
22510
+ let current = node;
22511
+ while (current.type === "Identifier") {
22512
+ if (visited.has(current.name))
22513
+ return current;
22514
+ visited.add(current.name);
22515
+ const next = bindings.get(current.name);
22516
+ if (!next)
22517
+ return current;
22518
+ current = next;
22519
+ }
22520
+ return current;
22521
+ }
22509
22522
  async function parseContentConfig() {
22510
22523
  const projectRoot = getProjectRoot();
22511
22524
  for (const configPath of ["src/content/config.ts", "src/content.config.ts"]) {
22512
- const fullPath = path2.join(projectRoot, configPath);
22525
+ const fullPath = path.join(projectRoot, configPath);
22513
22526
  let stat;
22514
22527
  try {
22515
- stat = await fs3.stat(fullPath);
22528
+ stat = await fs.stat(fullPath);
22516
22529
  } catch {
22517
22530
  continue;
22518
22531
  }
@@ -22522,7 +22535,7 @@ async function parseContentConfig() {
22522
22535
  return cached.parsed;
22523
22536
  continue;
22524
22537
  }
22525
- const content = await fs3.readFile(fullPath, "utf-8");
22538
+ const content = await fs.readFile(fullPath, "utf-8");
22526
22539
  const parsed = parseConfigSource(content, configPath);
22527
22540
  parseCache.set(fullPath, { mtimeMs: stat.mtimeMs, parsed });
22528
22541
  if (parsed.size > 0)
@@ -22535,8 +22548,10 @@ function parseConfigSource(source, sourcePath) {
22535
22548
  const ast = parseFrontmatter(source, sourcePath);
22536
22549
  if (!ast)
22537
22550
  return result;
22551
+ const bindings = new Map;
22538
22552
  const collectionDecls = new Map;
22539
22553
  const exportMap = new Map;
22554
+ const inlineCollections = new Map;
22540
22555
  for (const stmt of ast.program.body) {
22541
22556
  const varDecl = stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "VariableDeclaration" ? stmt.declaration : stmt.type === "VariableDeclaration" ? stmt : null;
22542
22557
  if (!varDecl)
@@ -22546,6 +22561,7 @@ function parseConfigSource(source, sourcePath) {
22546
22561
  continue;
22547
22562
  if (!decl.init)
22548
22563
  continue;
22564
+ bindings.set(decl.id.name, decl.init);
22549
22565
  if (decl.id.name === "collections" && decl.init.type === "ObjectExpression") {
22550
22566
  for (const prop of decl.init.properties) {
22551
22567
  if (prop.type !== "ObjectProperty")
@@ -22555,6 +22571,11 @@ function parseConfigSource(source, sourcePath) {
22555
22571
  continue;
22556
22572
  if (prop.value.type === "Identifier") {
22557
22573
  exportMap.set(prop.value.name, key);
22574
+ } else if (prop.value.type === "CallExpression" && isDefineCollectionCallee(prop.value.callee)) {
22575
+ const inlineArg = prop.value.arguments[0];
22576
+ if (inlineArg?.type === "ObjectExpression") {
22577
+ inlineCollections.set(key, inlineArg);
22578
+ }
22558
22579
  }
22559
22580
  }
22560
22581
  continue;
@@ -22567,19 +22588,46 @@ function parseConfigSource(source, sourcePath) {
22567
22588
  }
22568
22589
  }
22569
22590
  }
22591
+ const collectionObjects = new Map(inlineCollections);
22570
22592
  for (const [varName, collectionName] of exportMap) {
22571
22593
  const decl = collectionDecls.get(varName);
22572
- if (!decl)
22573
- continue;
22594
+ if (decl)
22595
+ collectionObjects.set(collectionName, decl);
22596
+ }
22597
+ for (const [collectionName, decl] of collectionObjects) {
22598
+ const loaderProperty = decl.properties.find((p) => p.type === "ObjectProperty" && propertyKeyName(p.key) === "loader");
22599
+ const loaderOptions = loaderProperty ? extractGlobLoaderOptions(loaderProperty.value, bindings) : {};
22600
+ const loaderPattern = loaderOptions.pattern;
22601
+ const loaderBase = loaderOptions.base;
22574
22602
  const schemaProperty = decl.properties.find((p) => p.type === "ObjectProperty" && propertyKeyName(p.key) === "schema");
22575
- if (!schemaProperty)
22603
+ if (!schemaProperty) {
22604
+ if (!loaderPattern)
22605
+ continue;
22606
+ result.set(collectionName, {
22607
+ name: collectionName,
22608
+ fields: [],
22609
+ loaderPattern,
22610
+ loaderBase
22611
+ });
22576
22612
  continue;
22577
- const schemaObject = unwrapSchemaToObject(schemaProperty.value);
22578
- if (!schemaObject)
22613
+ }
22614
+ const schemaObject = unwrapSchemaToObject(schemaProperty.value, bindings);
22615
+ if (!schemaObject) {
22616
+ if (!loaderPattern)
22617
+ continue;
22618
+ result.set(collectionName, {
22619
+ name: collectionName,
22620
+ fields: [],
22621
+ loaderPattern,
22622
+ loaderBase
22623
+ });
22579
22624
  continue;
22625
+ }
22580
22626
  result.set(collectionName, {
22581
22627
  name: collectionName,
22582
- fields: parseSchemaFields(schemaObject)
22628
+ fields: parseSchemaFields(schemaObject, bindings),
22629
+ loaderPattern,
22630
+ loaderBase
22583
22631
  });
22584
22632
  }
22585
22633
  return result;
@@ -22594,30 +22642,71 @@ function propertyKeyName(key) {
22594
22642
  return key.value;
22595
22643
  return null;
22596
22644
  }
22597
- function unwrapSchemaToObject(node) {
22598
- if (node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression") {
22599
- const body = node.body;
22645
+ function extractGlobLoaderOptions(node, bindings) {
22646
+ const resolved = resolveExpression(node, bindings);
22647
+ if (resolved.type !== "CallExpression")
22648
+ return {};
22649
+ if (!isGlobCallee(resolved.callee))
22650
+ return {};
22651
+ const arg = resolved.arguments[0];
22652
+ if (!arg)
22653
+ return {};
22654
+ const options = resolveExpression(arg, bindings);
22655
+ if (options.type !== "ObjectExpression")
22656
+ return {};
22657
+ const result = {};
22658
+ for (const prop of options.properties) {
22659
+ if (prop.type !== "ObjectProperty")
22660
+ continue;
22661
+ const key = propertyKeyName(prop.key);
22662
+ if (key !== "pattern" && key !== "base")
22663
+ continue;
22664
+ const value = extractStaticString(prop.value, bindings);
22665
+ if (value !== undefined)
22666
+ result[key] = value;
22667
+ }
22668
+ return result;
22669
+ }
22670
+ function extractStaticString(node, bindings) {
22671
+ const resolved = resolveExpression(node, bindings);
22672
+ if (resolved.type === "StringLiteral")
22673
+ return resolved.value;
22674
+ if (resolved.type === "TemplateLiteral" && resolved.expressions.length === 0) {
22675
+ return resolved.quasis[0]?.value.cooked ?? resolved.quasis[0]?.value.raw;
22676
+ }
22677
+ return;
22678
+ }
22679
+ function isGlobCallee(callee) {
22680
+ return callee.type === "Identifier" && callee.name === "glob";
22681
+ }
22682
+ function unwrapSchemaToObject(node, bindings) {
22683
+ const resolved = resolveExpression(node, bindings);
22684
+ if (resolved.type === "ArrowFunctionExpression" || resolved.type === "FunctionExpression") {
22685
+ const body = resolved.body;
22600
22686
  if (body.type === "BlockStatement") {
22601
22687
  for (const stmt of body.body) {
22602
22688
  if (stmt.type === "ReturnStatement" && stmt.argument) {
22603
- return unwrapSchemaToObject(stmt.argument);
22689
+ return unwrapSchemaToObject(stmt.argument, bindings);
22604
22690
  }
22605
22691
  }
22606
22692
  return null;
22607
22693
  }
22608
- return unwrapSchemaToObject(body);
22694
+ return unwrapSchemaToObject(body, bindings);
22609
22695
  }
22610
- if (node.type === "CallExpression") {
22611
- const callee = node.callee;
22696
+ if (resolved.type === "CallExpression") {
22697
+ const callee = resolved.callee;
22612
22698
  if (callee.type === "MemberExpression" && callee.object.type === "Identifier" && (callee.object.name === "z" || callee.object.name === "n") && callee.property.type === "Identifier" && callee.property.name === "object") {
22613
- const arg = node.arguments[0];
22614
- if (arg?.type === "ObjectExpression")
22615
- return arg;
22699
+ const arg = resolved.arguments[0];
22700
+ if (!arg)
22701
+ return null;
22702
+ const resolvedArg = resolveExpression(arg, bindings);
22703
+ if (resolvedArg.type === "ObjectExpression")
22704
+ return resolvedArg;
22616
22705
  }
22617
22706
  }
22618
22707
  return null;
22619
22708
  }
22620
- function parseSchemaFields(schemaObject) {
22709
+ function parseSchemaFields(schemaObject, bindings) {
22621
22710
  const fields = [];
22622
22711
  for (const prop of schemaObject.properties) {
22623
22712
  if (prop.type !== "ObjectProperty")
@@ -22626,18 +22715,18 @@ function parseSchemaFields(schemaObject) {
22626
22715
  if (!name)
22627
22716
  continue;
22628
22717
  const field = { name, required: true };
22629
- analyzeFieldExpression(prop.value, field);
22718
+ analyzeFieldExpression(prop.value, field, bindings);
22630
22719
  fields.push(field);
22631
22720
  }
22632
22721
  return fields;
22633
22722
  }
22634
- function analyzeFieldExpression(node, field) {
22635
- let current = node;
22723
+ function analyzeFieldExpression(node, field, bindings) {
22724
+ let current = resolveExpression(node, bindings);
22636
22725
  while (current) {
22637
22726
  if (current.type !== "CallExpression")
22638
22727
  return;
22639
22728
  if (isBaseCall(current)) {
22640
- analyzeBaseCall(current, field);
22729
+ analyzeBaseCall(current, field, bindings);
22641
22730
  return;
22642
22731
  }
22643
22732
  if (current.callee.type !== "MemberExpression")
@@ -22651,7 +22740,7 @@ function analyzeFieldExpression(node, field) {
22651
22740
  const direction = arg?.type === "StringLiteral" && arg.value === "desc" ? "desc" : "asc";
22652
22741
  field.orderBy = { direction };
22653
22742
  }
22654
- current = current.callee.object;
22743
+ current = resolveExpression(current.callee.object, bindings);
22655
22744
  }
22656
22745
  }
22657
22746
  function isBaseCall(node) {
@@ -22664,7 +22753,7 @@ function isBaseCall(node) {
22664
22753
  }
22665
22754
  return false;
22666
22755
  }
22667
- function analyzeBaseCall(node, field) {
22756
+ function analyzeBaseCall(node, field, bindings) {
22668
22757
  const callee = node.callee;
22669
22758
  if (callee.type === "Identifier") {
22670
22759
  if (callee.name === "image") {
@@ -22712,14 +22801,36 @@ function analyzeBaseCall(node, field) {
22712
22801
  }
22713
22802
  return;
22714
22803
  }
22804
+ if ((ns === "z" || ns === "n") && fn === "object") {
22805
+ const arg = node.arguments[0];
22806
+ if (!arg)
22807
+ return;
22808
+ const resolved = resolveExpression(arg, bindings);
22809
+ if (resolved.type === "ObjectExpression") {
22810
+ field.type = "object";
22811
+ field.fields = parseSchemaFields(resolved, bindings);
22812
+ }
22813
+ return;
22814
+ }
22715
22815
  if ((ns === "z" || ns === "n") && fn === "array") {
22716
- const inner = node.arguments[0];
22717
- if (inner?.type === "CallExpression" && inner.callee.type === "Identifier" && inner.callee.name === "reference") {
22816
+ const innerRaw = node.arguments[0];
22817
+ if (!innerRaw)
22818
+ return;
22819
+ const inner = resolveExpression(innerRaw, bindings);
22820
+ if (inner.type === "CallExpression" && inner.callee.type === "Identifier" && inner.callee.name === "reference") {
22718
22821
  const target = inner.arguments[0];
22719
22822
  if (target?.type === "StringLiteral") {
22720
22823
  field.reference = { target: target.value, isArray: true };
22721
22824
  }
22825
+ return;
22722
22826
  }
22827
+ const innerField = { name: "__item__", required: true };
22828
+ analyzeFieldExpression(inner, innerField, bindings);
22829
+ field.type = "array";
22830
+ if (innerField.type)
22831
+ field.itemType = innerField.type;
22832
+ if (innerField.fields)
22833
+ field.fields = innerField.fields;
22723
22834
  return;
22724
22835
  }
22725
22836
  }
@@ -22752,6 +22863,7 @@ var init_content_config_ast = __esm(() => {
22752
22863
  "text",
22753
22864
  "number",
22754
22865
  "image",
22866
+ "file",
22755
22867
  "url",
22756
22868
  "email",
22757
22869
  "tel",
@@ -22759,6 +22871,8 @@ var init_content_config_ast = __esm(() => {
22759
22871
  "date",
22760
22872
  "datetime",
22761
22873
  "time",
22874
+ "year",
22875
+ "month",
22762
22876
  "textarea"
22763
22877
  ]);
22764
22878
  VALID_HINT_KEYS = new Set([
@@ -22784,8 +22898,8 @@ function slugifyHref(text) {
22784
22898
  }
22785
22899
 
22786
22900
  // ../cms/src/collection-scanner.ts
22787
- import fs4 from "fs/promises";
22788
- import path3 from "path";
22901
+ import fs2 from "fs/promises";
22902
+ import path2 from "path";
22789
22903
  function normalizeFieldName(name) {
22790
22904
  return name.toLowerCase().replace(/[_-]/g, "");
22791
22905
  }
@@ -22886,7 +23000,9 @@ function inferFieldType(value, key) {
22886
23000
  }
22887
23001
  return "text";
22888
23002
  }
22889
- function mergeFieldObservations(observations) {
23003
+ function mergeFieldObservations(observations, depth = 0) {
23004
+ if (depth >= MAX_NESTED_FIELD_DEPTH)
23005
+ return [];
22890
23006
  const fields = [];
22891
23007
  for (const obs of observations) {
22892
23008
  const nonNullValues = obs.values.filter((v2) => v2 !== null && v2 !== undefined);
@@ -22937,11 +23053,21 @@ function mergeFieldObservations(observations) {
22937
23053
  for (const item of objectItems) {
22938
23054
  collectFieldObservations(subFieldMap, item, objectItems.length);
22939
23055
  }
22940
- field.fields = mergeFieldObservations(Array.from(subFieldMap.values()));
23056
+ field.fields = mergeFieldObservations(Array.from(subFieldMap.values()), depth + 1);
22941
23057
  }
22942
23058
  }
22943
23059
  }
22944
23060
  }
23061
+ if (fieldType === "object") {
23062
+ const objectValues = nonNullValues.filter((v2) => typeof v2 === "object" && v2 !== null && !Array.isArray(v2));
23063
+ if (objectValues.length > 0) {
23064
+ const subFieldMap = new Map;
23065
+ for (const item of objectValues) {
23066
+ collectFieldObservations(subFieldMap, item, objectValues.length);
23067
+ }
23068
+ field.fields = mergeFieldObservations(Array.from(subFieldMap.values()), depth + 1);
23069
+ }
23070
+ }
22945
23071
  fields.push(field);
22946
23072
  }
22947
23073
  return fields;
@@ -22957,7 +23083,7 @@ function collectFieldObservations(fieldMap, data, totalEntries) {
22957
23083
  obs.presentCount++;
22958
23084
  }
22959
23085
  }
22960
- function buildCollectionDefinition(collectionName, contentDir, fieldMap, entryInfos, entryCount, extra) {
23086
+ function assembleCollectionDefinition(collectionName, contentDir, fieldMap, entryInfos, entryCount, extra) {
22961
23087
  for (const obs of fieldMap.values()) {
22962
23088
  obs.totalEntries = entryCount;
22963
23089
  }
@@ -22967,7 +23093,7 @@ function buildCollectionDefinition(collectionName, contentDir, fieldMap, entryIn
22967
23093
  return {
22968
23094
  name: collectionName,
22969
23095
  label,
22970
- path: path3.join(contentDir, collectionName),
23096
+ path: path2.join(contentDir, collectionName),
22971
23097
  entryCount,
22972
23098
  fields,
22973
23099
  fileExtension: "md",
@@ -22975,9 +23101,71 @@ function buildCollectionDefinition(collectionName, contentDir, fieldMap, entryIn
22975
23101
  ...extra
22976
23102
  };
22977
23103
  }
23104
+ function getCollectionSourceBasePath(basePath, collectionName, contentDir) {
23105
+ const projectRoot = getProjectRoot();
23106
+ const defaultContentDir = path2.isAbsolute(contentDir) ? contentDir : path2.join(projectRoot, contentDir);
23107
+ const defaultCollectionPath = path2.join(defaultContentDir, collectionName);
23108
+ if (path2.resolve(basePath) === path2.resolve(defaultCollectionPath)) {
23109
+ return path2.join(contentDir, collectionName);
23110
+ }
23111
+ const relativeBase = path2.relative(projectRoot, basePath);
23112
+ if (relativeBase && !relativeBase.startsWith("..") && !path2.isAbsolute(relativeBase)) {
23113
+ return relativeBase;
23114
+ }
23115
+ return basePath;
23116
+ }
23117
+ async function buildCollectionDefinition(basePath, sources, collectionName, contentDir) {
23118
+ if (sources.length === 0)
23119
+ return null;
23120
+ const sourceBasePath = getCollectionSourceBasePath(basePath, collectionName, contentDir);
23121
+ const hasMd = sources.some((s) => s.relPath.endsWith(".md"));
23122
+ const fileExtension = hasMd ? "md" : "mdx";
23123
+ const fieldMap = new Map;
23124
+ const allDirectives = {};
23125
+ const entryInfos = [];
23126
+ let hasDraft = false;
23127
+ const fileContents = await Promise.all(sources.map((s) => fs2.readFile(path2.join(basePath, s.relPath), "utf-8")));
23128
+ for (let i = 0;i < sources.length; i++) {
23129
+ const source = sources[i];
23130
+ const content = fileContents[i];
23131
+ const frontmatter = parseFrontmatter2(content);
23132
+ const directives = parseFieldDirectives(content);
23133
+ for (const [key, value] of Object.entries(directives)) {
23134
+ if (!allDirectives[key]) {
23135
+ allDirectives[key] = value;
23136
+ }
23137
+ }
23138
+ const entryInfo = {
23139
+ slug: source.slug,
23140
+ sourcePath: path2.join(sourceBasePath, source.relPath)
23141
+ };
23142
+ if (frontmatter) {
23143
+ if (typeof frontmatter.title === "string") {
23144
+ entryInfo.title = frontmatter.title;
23145
+ }
23146
+ if (typeof frontmatter.draft === "boolean" && frontmatter.draft) {
23147
+ entryInfo.draft = true;
23148
+ }
23149
+ entryInfo.data = frontmatter;
23150
+ }
23151
+ entryInfos.push(entryInfo);
23152
+ if (!frontmatter)
23153
+ continue;
23154
+ if (frontmatter.draft === true)
23155
+ hasDraft = true;
23156
+ collectFieldObservations(fieldMap, frontmatter, sources.length);
23157
+ }
23158
+ const def = assembleCollectionDefinition(collectionName, contentDir, fieldMap, entryInfos, sources.length, {
23159
+ path: sourceBasePath,
23160
+ supportsDraft: hasDraft,
23161
+ fileExtension
23162
+ });
23163
+ assignFieldMetadata(def.fields, allDirectives);
23164
+ return def;
23165
+ }
22978
23166
  async function scanCollection(collectionPath, collectionName, contentDir) {
22979
23167
  try {
22980
- const dirEntries = await fs4.readdir(collectionPath, { withFileTypes: true });
23168
+ const dirEntries = await fs2.readdir(collectionPath, { withFileTypes: true });
22981
23169
  const sources = [];
22982
23170
  const takenSlugs = new Set;
22983
23171
  for (const entry of dirEntries) {
@@ -22994,9 +23182,9 @@ async function scanCollection(collectionPath, collectionName, contentDir) {
22994
23182
  if (takenSlugs.has(dir.name))
22995
23183
  return null;
22996
23184
  for (const ext of ["md", "mdx"]) {
22997
- const relPath = path3.join(dir.name, `index.${ext}`);
23185
+ const relPath = path2.join(dir.name, `index.${ext}`);
22998
23186
  try {
22999
- await fs4.access(path3.join(collectionPath, relPath));
23187
+ await fs2.access(path2.join(collectionPath, relPath));
23000
23188
  return { slug: dir.name, relPath };
23001
23189
  } catch {}
23002
23190
  }
@@ -23008,49 +23196,71 @@ async function scanCollection(collectionPath, collectionName, contentDir) {
23008
23196
  }
23009
23197
  if (sources.length === 0)
23010
23198
  return null;
23011
- const hasMd = sources.some((s) => s.relPath.endsWith(".md"));
23012
- const fileExtension = hasMd ? "md" : "mdx";
23013
- const fieldMap = new Map;
23014
- const allDirectives = {};
23015
- const entryInfos = [];
23016
- let hasDraft = false;
23017
- const fileContents = await Promise.all(sources.map((s) => fs4.readFile(path3.join(collectionPath, s.relPath), "utf-8")));
23018
- for (let i = 0;i < sources.length; i++) {
23019
- const source = sources[i];
23020
- const content = fileContents[i];
23021
- const frontmatter = parseFrontmatter2(content);
23022
- const directives = parseFieldDirectives(content);
23023
- for (const [key, value] of Object.entries(directives)) {
23024
- if (!allDirectives[key]) {
23025
- allDirectives[key] = value;
23026
- }
23199
+ return await buildCollectionDefinition(collectionPath, sources, collectionName, contentDir);
23200
+ } catch {
23201
+ return null;
23202
+ }
23203
+ }
23204
+ function globToRegExp(glob) {
23205
+ let re = "";
23206
+ for (let i = 0;i < glob.length; i++) {
23207
+ const c = glob[i];
23208
+ if (c === "*") {
23209
+ if (glob[i + 1] === "*") {
23210
+ re += ".*";
23211
+ i++;
23212
+ if (glob[i + 1] === "/")
23213
+ i++;
23214
+ } else {
23215
+ re += "[^/]*";
23027
23216
  }
23028
- const entryInfo = {
23029
- slug: source.slug,
23030
- sourcePath: path3.join(contentDir, collectionName, source.relPath)
23031
- };
23032
- if (frontmatter) {
23033
- if (typeof frontmatter.title === "string") {
23034
- entryInfo.title = frontmatter.title;
23035
- }
23036
- if (typeof frontmatter.draft === "boolean" && frontmatter.draft) {
23037
- entryInfo.draft = true;
23038
- }
23039
- entryInfo.data = frontmatter;
23217
+ } else if (c === "?") {
23218
+ re += "[^/]";
23219
+ } else if (c === "{") {
23220
+ const end = glob.indexOf("}", i);
23221
+ if (end === -1) {
23222
+ re += "\\{";
23223
+ } else {
23224
+ const opts = glob.slice(i + 1, end).split(",").map((s) => s.replace(/[.+^${}()|[\]\\]/g, "\\$&"));
23225
+ re += `(?:${opts.join("|")})`;
23226
+ i = end;
23040
23227
  }
23041
- entryInfos.push(entryInfo);
23042
- if (!frontmatter)
23043
- continue;
23044
- if (frontmatter.draft === true)
23045
- hasDraft = true;
23046
- collectFieldObservations(fieldMap, frontmatter, sources.length);
23228
+ } else if (".+^$()|[]\\".includes(c)) {
23229
+ re += `\\${c}`;
23230
+ } else {
23231
+ re += c;
23047
23232
  }
23048
- const def = buildCollectionDefinition(collectionName, contentDir, fieldMap, entryInfos, sources.length, {
23049
- supportsDraft: hasDraft,
23050
- fileExtension
23051
- });
23052
- assignFieldMetadata(def.fields, allDirectives);
23053
- return def;
23233
+ }
23234
+ return new RegExp(`^${re}$`);
23235
+ }
23236
+ async function walkFiles(dir, prefix = "") {
23237
+ let dirEntries;
23238
+ try {
23239
+ dirEntries = await fs2.readdir(dir, { withFileTypes: true });
23240
+ } catch {
23241
+ return [];
23242
+ }
23243
+ const out = [];
23244
+ for (const entry of dirEntries) {
23245
+ if (entry.name.startsWith("_") || entry.name.startsWith("."))
23246
+ continue;
23247
+ const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
23248
+ if (entry.isDirectory()) {
23249
+ out.push(...await walkFiles(path2.join(dir, entry.name), rel));
23250
+ } else if (entry.isFile()) {
23251
+ out.push(rel);
23252
+ }
23253
+ }
23254
+ return out;
23255
+ }
23256
+ async function scanGlobCollection(collectionName, baseRel, pattern, contentDir) {
23257
+ try {
23258
+ const absBase = path2.join(getProjectRoot(), baseRel);
23259
+ const matcher = globToRegExp(pattern);
23260
+ const sources = (await walkFiles(absBase)).filter((rel) => (rel.endsWith(".md") || rel.endsWith(".mdx")) && matcher.test(rel)).map((rel) => ({ slug: rel.replace(/\.(md|mdx)$/, ""), relPath: rel }));
23261
+ if (sources.length === 0)
23262
+ return null;
23263
+ return await buildCollectionDefinition(absBase, sources, collectionName, contentDir);
23054
23264
  } catch {
23055
23265
  return null;
23056
23266
  }
@@ -23069,19 +23279,53 @@ function applyParsedConfig(collections, parsed) {
23069
23279
  const field = fieldsByName.get(pf.name);
23070
23280
  if (!field)
23071
23281
  continue;
23072
- if (pf.type) {
23073
- field.type = pf.type;
23074
- if (pf.options)
23075
- field.options = pf.options;
23076
- }
23077
- if (pf.hints)
23078
- field.hints = pf.hints;
23079
- if (pf.astroImage)
23080
- field.astroImage = true;
23081
- field.required = pf.required;
23282
+ applyParsedFieldOverrides(field, pf);
23082
23283
  }
23083
23284
  }
23084
23285
  }
23286
+ function applyParsedFieldOverrides(field, pf) {
23287
+ if (pf.type) {
23288
+ field.type = pf.type;
23289
+ if (pf.options)
23290
+ field.options = pf.options;
23291
+ }
23292
+ if (pf.itemType)
23293
+ field.itemType = pf.itemType;
23294
+ if (pf.hints)
23295
+ field.hints = pf.hints;
23296
+ if (pf.astroImage)
23297
+ field.astroImage = true;
23298
+ field.required = pf.required;
23299
+ if (pf.fields) {
23300
+ const existingByName = new Map((field.fields ?? []).map((f) => [f.name, f]));
23301
+ field.fields = pf.fields.map((subPf) => {
23302
+ const existing = existingByName.get(subPf.name);
23303
+ if (existing) {
23304
+ applyParsedFieldOverrides(existing, subPf);
23305
+ return existing;
23306
+ }
23307
+ return parsedFieldToFieldDefinition(subPf);
23308
+ });
23309
+ }
23310
+ }
23311
+ function parsedFieldToFieldDefinition(pf) {
23312
+ const fd = {
23313
+ name: pf.name,
23314
+ type: pf.type ?? (pf.fields ? "object" : "text"),
23315
+ required: pf.required
23316
+ };
23317
+ if (pf.options)
23318
+ fd.options = pf.options;
23319
+ if (pf.itemType)
23320
+ fd.itemType = pf.itemType;
23321
+ if (pf.hints)
23322
+ fd.hints = pf.hints;
23323
+ if (pf.astroImage)
23324
+ fd.astroImage = true;
23325
+ if (pf.fields)
23326
+ fd.fields = pf.fields.map(parsedFieldToFieldDefinition);
23327
+ return fd;
23328
+ }
23085
23329
  function applyCollectionOrderBy(collections, parsed) {
23086
23330
  for (const [collectionName, parsedColl] of parsed) {
23087
23331
  const orderField = parsedColl.fields.find((f) => f.orderBy);
@@ -23275,7 +23519,7 @@ function detectDerivedHrefFields(collections) {
23275
23519
  }
23276
23520
  async function scanDataCollection(collectionPath, collectionName, contentDir) {
23277
23521
  try {
23278
- const dirEntries = await fs4.readdir(collectionPath, { withFileTypes: true });
23522
+ const dirEntries = await fs2.readdir(collectionPath, { withFileTypes: true });
23279
23523
  const sources = [];
23280
23524
  const takenSlugs = new Set;
23281
23525
  for (const entry of dirEntries) {
@@ -23292,9 +23536,9 @@ async function scanDataCollection(collectionPath, collectionName, contentDir) {
23292
23536
  if (takenSlugs.has(dir.name))
23293
23537
  return null;
23294
23538
  for (const indexExt of ["json", "yaml", "yml"]) {
23295
- const relPath = path3.join(dir.name, `index.${indexExt}`);
23539
+ const relPath = path2.join(dir.name, `index.${indexExt}`);
23296
23540
  try {
23297
- await fs4.access(path3.join(collectionPath, relPath));
23541
+ await fs2.access(path2.join(collectionPath, relPath));
23298
23542
  return { slug: dir.name, relPath };
23299
23543
  } catch {}
23300
23544
  }
@@ -23309,7 +23553,7 @@ async function scanDataCollection(collectionPath, collectionName, contentDir) {
23309
23553
  const fieldMap = new Map;
23310
23554
  const entryInfos = [];
23311
23555
  const ext = sources.some((s) => s.relPath.endsWith(".json")) ? "json" : sources.some((s) => s.relPath.endsWith(".yaml")) ? "yaml" : "yml";
23312
- const fileContents = await Promise.all(sources.map((s) => fs4.readFile(path3.join(collectionPath, s.relPath), "utf-8").catch(() => null)));
23556
+ const fileContents = await Promise.all(sources.map((s) => fs2.readFile(path2.join(collectionPath, s.relPath), "utf-8").catch(() => null)));
23313
23557
  for (let i = 0;i < sources.length; i++) {
23314
23558
  const source = sources[i];
23315
23559
  const raw = fileContents[i];
@@ -23327,12 +23571,12 @@ async function scanDataCollection(collectionPath, collectionName, contentDir) {
23327
23571
  entryInfos.push({
23328
23572
  slug: source.slug,
23329
23573
  title,
23330
- sourcePath: path3.join(contentDir, collectionName, source.relPath),
23574
+ sourcePath: path2.join(contentDir, collectionName, source.relPath),
23331
23575
  data
23332
23576
  });
23333
23577
  collectFieldObservations(fieldMap, data, sources.length);
23334
23578
  }
23335
- return buildCollectionDefinition(collectionName, contentDir, fieldMap, entryInfos, sources.length, {
23579
+ return assembleCollectionDefinition(collectionName, contentDir, fieldMap, entryInfos, sources.length, {
23336
23580
  type: "data",
23337
23581
  fileExtension: ext
23338
23582
  });
@@ -23342,12 +23586,12 @@ async function scanDataCollection(collectionPath, collectionName, contentDir) {
23342
23586
  }
23343
23587
  async function scanCollections(contentDir = "src/content") {
23344
23588
  const projectRoot = getProjectRoot();
23345
- const fullContentDir = path3.isAbsolute(contentDir) ? contentDir : path3.join(projectRoot, contentDir);
23589
+ const fullContentDir = path2.isAbsolute(contentDir) ? contentDir : path2.join(projectRoot, contentDir);
23346
23590
  const collections = {};
23347
23591
  try {
23348
- const entries = await fs4.readdir(fullContentDir, { withFileTypes: true });
23592
+ const entries = await fs2.readdir(fullContentDir, { withFileTypes: true });
23349
23593
  const scanPromises = entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("_") && !entry.name.startsWith(".")).map(async (entry) => {
23350
- const collectionPath = path3.join(fullContentDir, entry.name);
23594
+ const collectionPath = path2.join(fullContentDir, entry.name);
23351
23595
  const definition = await scanCollection(collectionPath, entry.name, contentDir) ?? await scanDataCollection(collectionPath, entry.name, contentDir);
23352
23596
  if (definition) {
23353
23597
  collections[entry.name] = definition;
@@ -23356,6 +23600,20 @@ async function scanCollections(contentDir = "src/content") {
23356
23600
  await Promise.all(scanPromises);
23357
23601
  } catch {}
23358
23602
  const parsed = await parseContentConfig();
23603
+ for (const [collectionName, parsedCollection] of parsed) {
23604
+ if (collections[collectionName])
23605
+ continue;
23606
+ if (!parsedCollection.loaderBase || !parsedCollection.loaderPattern)
23607
+ continue;
23608
+ const definition = await scanGlobCollection(collectionName, parsedCollection.loaderBase, parsedCollection.loaderPattern, contentDir);
23609
+ if (!definition)
23610
+ continue;
23611
+ const baseName = parsedCollection.loaderBase.replace(/[/\\]+$/, "").split(/[/\\]/).pop();
23612
+ if (baseName && baseName !== collectionName && collections[baseName]) {
23613
+ definition.parentCollection = baseName;
23614
+ }
23615
+ collections[collectionName] = definition;
23616
+ }
23359
23617
  applyParsedConfig(collections, parsed);
23360
23618
  detectReferenceFields(collections, parsed);
23361
23619
  detectDerivedHrefFields(collections);
@@ -23363,7 +23621,7 @@ async function scanCollections(contentDir = "src/content") {
23363
23621
  applyCollectionOrderBy(collections, parsed);
23364
23622
  return collections;
23365
23623
  }
23366
- var import_yaml, DATE_PATTERN, URL_PATTERN, IMAGE_EXTENSIONS, MAX_SELECT_OPTIONS = 10, TEXTAREA_MIN_LENGTH = 200, SIDEBAR_FIELD_NAMES, DIRECTIVE_PATTERN, FREE_TEXT_FIELD_NAMES, PUBLISH_TOGGLE_NAMES, PUBLISH_DATE_NAMES, FRONTMATTER_PATTERN, HREF_SUFFIXES;
23624
+ var import_yaml, DATE_PATTERN, URL_PATTERN, IMAGE_EXTENSIONS, MAX_SELECT_OPTIONS = 10, TEXTAREA_MIN_LENGTH = 200, SIDEBAR_FIELD_NAMES, DIRECTIVE_PATTERN, FREE_TEXT_FIELD_NAMES, PUBLISH_TOGGLE_NAMES, PUBLISH_DATE_NAMES, FRONTMATTER_PATTERN, MAX_NESTED_FIELD_DEPTH = 16, HREF_SUFFIXES;
23367
23625
  var init_collection_scanner = __esm(() => {
23368
23626
  init_config();
23369
23627
  init_content_config_ast();
@@ -23413,8 +23671,8 @@ var init_collection_scanner = __esm(() => {
23413
23671
  });
23414
23672
 
23415
23673
  // ../cms/src/component-registry.ts
23416
- import fs5 from "fs/promises";
23417
- import path4 from "path";
23674
+ import fs3 from "fs/promises";
23675
+ import path3 from "path";
23418
23676
 
23419
23677
  class ComponentRegistry {
23420
23678
  components = new Map;
@@ -23424,7 +23682,7 @@ class ComponentRegistry {
23424
23682
  }
23425
23683
  async scan() {
23426
23684
  for (const dir of this.componentDirs) {
23427
- const fullPath = path4.join(getProjectRoot(), dir);
23685
+ const fullPath = path3.join(getProjectRoot(), dir);
23428
23686
  try {
23429
23687
  await this.scanDirectory(fullPath, dir);
23430
23688
  } catch {}
@@ -23437,10 +23695,10 @@ class ComponentRegistry {
23437
23695
  return this.components.get(name);
23438
23696
  }
23439
23697
  async scanDirectory(dir, relativePath) {
23440
- const entries = await fs5.readdir(dir, { withFileTypes: true });
23698
+ const entries = await fs3.readdir(dir, { withFileTypes: true });
23441
23699
  for (const entry of entries) {
23442
- const fullPath = path4.join(dir, entry.name);
23443
- const relPath = path4.join(relativePath, entry.name);
23700
+ const fullPath = path3.join(dir, entry.name);
23701
+ const relPath = path3.join(relativePath, entry.name);
23444
23702
  if (entry.isDirectory()) {
23445
23703
  await this.scanDirectory(fullPath, relPath);
23446
23704
  } else if (entry.isFile() && entry.name.endsWith(".astro")) {
@@ -23450,8 +23708,8 @@ class ComponentRegistry {
23450
23708
  }
23451
23709
  async parseComponent(filePath, relativePath) {
23452
23710
  try {
23453
- const content = await fs5.readFile(filePath, "utf-8");
23454
- const componentName = path4.basename(filePath, ".astro");
23711
+ const content = await fs3.readFile(filePath, "utf-8");
23712
+ const componentName = path3.basename(filePath, ".astro");
23455
23713
  const props = await this.extractProps(content);
23456
23714
  const slots = this.extractSlots(content);
23457
23715
  const description = this.extractDescription(content);
@@ -23710,14 +23968,14 @@ var init_local = __esm(() => {
23710
23968
  });
23711
23969
 
23712
23970
  // ../cms/src/media/project-images.ts
23713
- import fs6 from "fs/promises";
23714
- import path5 from "path";
23971
+ import fs4 from "fs/promises";
23972
+ import path4 from "path";
23715
23973
  async function listProjectImages(options) {
23716
23974
  const root = getProjectRoot();
23717
- const excludeDir = options?.excludeDir ? path5.resolve(options.excludeDir) : null;
23975
+ const excludeDir = options?.excludeDir ? path4.resolve(options.excludeDir) : null;
23718
23976
  const scanDirs = [
23719
- { dir: path5.join(root, "public"), urlPrefix: "" },
23720
- { dir: path5.join(root, "src"), urlPrefix: null }
23977
+ { dir: path4.join(root, "public"), urlPrefix: "" },
23978
+ { dir: path4.join(root, "src"), urlPrefix: null }
23721
23979
  ];
23722
23980
  const results = await Promise.all(scanDirs.map(({ dir, urlPrefix }) => {
23723
23981
  const items2 = [];
@@ -23728,11 +23986,11 @@ async function listProjectImages(options) {
23728
23986
  return items;
23729
23987
  }
23730
23988
  async function scanDirectory(currentDir, baseDir, urlPrefix, excludeDir, items) {
23731
- if (excludeDir && path5.resolve(currentDir) === excludeDir)
23989
+ if (excludeDir && path4.resolve(currentDir) === excludeDir)
23732
23990
  return;
23733
23991
  let entries;
23734
23992
  try {
23735
- entries = await fs6.readdir(currentDir, { withFileTypes: true });
23993
+ entries = await fs4.readdir(currentDir, { withFileTypes: true });
23736
23994
  } catch {
23737
23995
  return;
23738
23996
  }
@@ -23741,15 +23999,15 @@ async function scanDirectory(currentDir, baseDir, urlPrefix, excludeDir, items)
23741
23999
  const name = String(entry.name);
23742
24000
  if (name.startsWith(".") || name === "node_modules")
23743
24001
  continue;
23744
- const fullPath = path5.join(currentDir, name);
24002
+ const fullPath = path4.join(currentDir, name);
23745
24003
  if (entry.isDirectory()) {
23746
24004
  subdirs.push(scanDirectory(fullPath, baseDir, urlPrefix, excludeDir, items));
23747
24005
  } else if (entry.isFile()) {
23748
- const ext = path5.extname(name).toLowerCase();
24006
+ const ext = path4.extname(name).toLowerCase();
23749
24007
  if (!IMAGE_EXTENSIONS2.has(ext))
23750
24008
  continue;
23751
- const relativePath = path5.relative(baseDir, fullPath).split(path5.sep).join("/");
23752
- const url = urlPrefix !== null ? `/${relativePath}` : `/${path5.relative(getProjectRoot(), fullPath).split(path5.sep).join("/")}`;
24009
+ const relativePath = path4.relative(baseDir, fullPath).split(path4.sep).join("/");
24010
+ const url = urlPrefix !== null ? `/${relativePath}` : `/${path4.relative(getProjectRoot(), fullPath).split(path4.sep).join("/")}`;
23753
24011
  items.push({
23754
24012
  id: `project:${url}`,
23755
24013
  url,
@@ -23769,7 +24027,7 @@ var init_project_images = __esm(() => {
23769
24027
 
23770
24028
  // ../cms/src/utils.ts
23771
24029
  import { createHash } from "crypto";
23772
- import path6 from "path";
24030
+ import path5 from "path";
23773
24031
  function normalizePagePath(url) {
23774
24032
  let pathname;
23775
24033
  try {
@@ -23822,21 +24080,21 @@ function escapeReplacement(str) {
23822
24080
  return str.replace(/\$/g, "$$$$");
23823
24081
  }
23824
24082
  function resolveSourcePath(sourcePath) {
23825
- return path6.isAbsolute(sourcePath) ? sourcePath : path6.join(getProjectRoot(), sourcePath);
24083
+ return path5.isAbsolute(sourcePath) ? sourcePath : path5.join(getProjectRoot(), sourcePath);
23826
24084
  }
23827
24085
  function resolveAndValidatePath(filePath) {
23828
24086
  const projectRoot = getProjectRoot();
23829
- const resolvedRoot = path6.resolve(projectRoot);
24087
+ const resolvedRoot = path5.resolve(projectRoot);
23830
24088
  const isAbsoluteFs = filePath.startsWith(resolvedRoot);
23831
24089
  const normalizedPath = !isAbsoluteFs && filePath.startsWith("/") ? filePath.slice(1) : filePath;
23832
- const fullPath = path6.isAbsolute(normalizedPath) ? path6.resolve(normalizedPath) : path6.resolve(projectRoot, normalizedPath);
23833
- if (!fullPath.startsWith(resolvedRoot + path6.sep) && fullPath !== resolvedRoot) {
24090
+ const fullPath = path5.isAbsolute(normalizedPath) ? path5.resolve(normalizedPath) : path5.resolve(projectRoot, normalizedPath);
24091
+ if (!fullPath.startsWith(resolvedRoot + path5.sep) && fullPath !== resolvedRoot) {
23834
24092
  throw new Error(`Path traversal detected: ${filePath}`);
23835
24093
  }
23836
24094
  return fullPath;
23837
24095
  }
23838
24096
  async function acquireFileLock(filePath) {
23839
- const key = path6.resolve(filePath);
24097
+ const key = path5.resolve(filePath);
23840
24098
  while (fileLocks.has(key)) {
23841
24099
  await fileLocks.get(key);
23842
24100
  }
@@ -23857,8 +24115,8 @@ function escapeHtml(text) {
23857
24115
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
23858
24116
  }
23859
24117
  function relativeImportPath(fromFile, toFile) {
23860
- const fromDir = path6.dirname(fromFile);
23861
- let rel = path6.relative(fromDir, toFile).split(path6.sep).join("/");
24118
+ const fromDir = path5.dirname(fromFile);
24119
+ let rel = path5.relative(fromDir, toFile).split(path5.sep).join("/");
23862
24120
  if (!rel.startsWith("."))
23863
24121
  rel = `./${rel}`;
23864
24122
  return rel;
@@ -23870,8 +24128,8 @@ var init_utils2 = __esm(() => {
23870
24128
  });
23871
24129
 
23872
24130
  // ../cms/src/handlers/component-ops.ts
23873
- import fs7 from "fs/promises";
23874
- import path7 from "path";
24131
+ import fs5 from "fs/promises";
24132
+ import path6 from "path";
23875
24133
  async function handleInsertComponent(request, manifestWriter) {
23876
24134
  const { position, referenceComponentId, componentName, props, meta } = request;
23877
24135
  if (!meta?.url) {
@@ -23904,7 +24162,7 @@ async function handleInsertComponent(request, manifestWriter) {
23904
24162
  try {
23905
24163
  let currentContent;
23906
24164
  try {
23907
- currentContent = await fs7.readFile(fullPath, "utf-8");
24165
+ currentContent = await fs5.readFile(fullPath, "utf-8");
23908
24166
  } catch {
23909
24167
  return { success: false, error: `Source file not found: ${filePath}` };
23910
24168
  }
@@ -23929,7 +24187,7 @@ async function handleInsertComponent(request, manifestWriter) {
23929
24187
  `);
23930
24188
  lines.splice(insertIndex, 0, indentedJsx);
23931
24189
  ensureComponentImport(lines, componentName, componentDef.file, filePath);
23932
- await fs7.writeFile(fullPath, lines.join(`
24190
+ await fs5.writeFile(fullPath, lines.join(`
23933
24191
  `), "utf-8");
23934
24192
  return {
23935
24193
  success: true,
@@ -23972,7 +24230,7 @@ async function handleRemoveComponent(request, manifestWriter) {
23972
24230
  try {
23973
24231
  let currentContent;
23974
24232
  try {
23975
- currentContent = await fs7.readFile(fullPath, "utf-8");
24233
+ currentContent = await fs5.readFile(fullPath, "utf-8");
23976
24234
  } catch {
23977
24235
  return { success: false, error: `Source file not found: ${filePath}` };
23978
24236
  }
@@ -23994,7 +24252,7 @@ async function handleRemoveComponent(request, manifestWriter) {
23994
24252
  removeCount++;
23995
24253
  }
23996
24254
  lines.splice(startLine, removeCount);
23997
- await fs7.writeFile(fullPath, lines.join(`
24255
+ await fs5.writeFile(fullPath, lines.join(`
23998
24256
  `), "utf-8");
23999
24257
  return {
24000
24258
  success: true,
@@ -24089,9 +24347,9 @@ function getComponentOccurrenceIndex(manifest, referenceComponent) {
24089
24347
  async function findComponentInvocationFile(projectRoot, pageUrl, manifest, referenceComponent) {
24090
24348
  if (referenceComponent.invocationSourcePath) {
24091
24349
  const filePath = normalizeFilePath(referenceComponent.invocationSourcePath);
24092
- const fullPath = path7.resolve(projectRoot, filePath);
24350
+ const fullPath = path6.resolve(projectRoot, filePath);
24093
24351
  try {
24094
- const content = await fs7.readFile(fullPath, "utf-8");
24352
+ const content = await fs5.readFile(fullPath, "utf-8");
24095
24353
  const lines = content.split(`
24096
24354
  `);
24097
24355
  const lineIndex = findComponentInvocationLine(lines, referenceComponent.componentName, referenceComponent.invocationIndex ?? 0);
@@ -24103,9 +24361,9 @@ async function findComponentInvocationFile(projectRoot, pageUrl, manifest, refer
24103
24361
  const candidates = getPageFileCandidates(pageUrl);
24104
24362
  const occurrenceIndex = getComponentOccurrenceIndex(manifest, referenceComponent);
24105
24363
  for (const candidate of candidates) {
24106
- const fullPath = path7.resolve(projectRoot, candidate);
24364
+ const fullPath = path6.resolve(projectRoot, candidate);
24107
24365
  try {
24108
- const content = await fs7.readFile(fullPath, "utf-8");
24366
+ const content = await fs5.readFile(fullPath, "utf-8");
24109
24367
  const lines = content.split(`
24110
24368
  `);
24111
24369
  const lineIndex = findComponentInvocationLine(lines, referenceComponent.componentName, occurrenceIndex);
@@ -24163,7 +24421,7 @@ function getIndentation(line) {
24163
24421
  function normalizeFilePath(p) {
24164
24422
  if (!p.startsWith("/"))
24165
24423
  return p;
24166
- const projectRoot = path7.resolve(getProjectRoot());
24424
+ const projectRoot = path6.resolve(getProjectRoot());
24167
24425
  if (p.startsWith(projectRoot))
24168
24426
  return p;
24169
24427
  return p.slice(1);
@@ -24195,7 +24453,7 @@ var init_component_ops = __esm(() => {
24195
24453
  });
24196
24454
 
24197
24455
  // ../cms/src/handlers/array-ops.ts
24198
- import fs8 from "fs/promises";
24456
+ import fs6 from "fs/promises";
24199
24457
  function parseInlineArrayName(componentName) {
24200
24458
  if (!componentName.startsWith("__array:"))
24201
24459
  return null;
@@ -24275,7 +24533,7 @@ async function resolveArrayContext(component, manifest, pageUrl) {
24275
24533
  const { arrayVarName, mapOccurrence } = parsed;
24276
24534
  const filePath2 = normalizeFilePath(component.invocationSourcePath ?? component.sourcePath);
24277
24535
  const fullPath2 = resolveAndValidatePath(filePath2);
24278
- const content2 = await fs8.readFile(fullPath2, "utf-8");
24536
+ const content2 = await fs6.readFile(fullPath2, "utf-8");
24279
24537
  const lines2 = content2.split(`
24280
24538
  `);
24281
24539
  const fmEnd2 = findFrontmatterEnd(lines2);
@@ -24320,7 +24578,7 @@ async function resolveArrayContext(component, manifest, pageUrl) {
24320
24578
  const invocation = await findComponentInvocationFile(projectRoot, pageUrl, manifest, component);
24321
24579
  const filePath = invocation?.filePath ?? normalizeFilePath(component.invocationSourcePath ?? component.sourcePath);
24322
24580
  const fullPath = resolveAndValidatePath(filePath);
24323
- const content = await fs8.readFile(fullPath, "utf-8");
24581
+ const content = await fs6.readFile(fullPath, "utf-8");
24324
24582
  const lines = content.split(`
24325
24583
  `);
24326
24584
  let refLineIndex;
@@ -24392,7 +24650,7 @@ async function handleRemoveArrayItem(request, manifestWriter) {
24392
24650
  const { fullPath, arrayIndex } = ctx;
24393
24651
  const release = await acquireFileLock(fullPath);
24394
24652
  try {
24395
- const freshContent = await fs8.readFile(fullPath, "utf-8");
24653
+ const freshContent = await fs6.readFile(fullPath, "utf-8");
24396
24654
  const freshLines = freshContent.split(`
24397
24655
  `);
24398
24656
  const freshFmEnd = findFrontmatterEnd(freshLines);
@@ -24421,7 +24679,7 @@ async function handleRemoveArrayItem(request, manifestWriter) {
24421
24679
  freshLines[removeStart - 1] = prevLine.replace(/,\s*$/, "");
24422
24680
  }
24423
24681
  }
24424
- await fs8.writeFile(fullPath, freshLines.join(`
24682
+ await fs6.writeFile(fullPath, freshLines.join(`
24425
24683
  `), "utf-8");
24426
24684
  return {
24427
24685
  success: true,
@@ -24463,7 +24721,7 @@ async function handleAddArrayItem(request, manifestWriter) {
24463
24721
  const { fullPath, arrayIndex } = ctx;
24464
24722
  const release = await acquireFileLock(fullPath);
24465
24723
  try {
24466
- const freshContent = await fs8.readFile(fullPath, "utf-8");
24724
+ const freshContent = await fs6.readFile(fullPath, "utf-8");
24467
24725
  const freshLines = freshContent.split(`
24468
24726
  `);
24469
24727
  const freshFmEnd = findFrontmatterEnd(freshLines);
@@ -24514,7 +24772,7 @@ async function handleAddArrayItem(request, manifestWriter) {
24514
24772
  break;
24515
24773
  }
24516
24774
  }
24517
- await fs8.writeFile(fullPath, freshLines.join(`
24775
+ await fs6.writeFile(fullPath, freshLines.join(`
24518
24776
  `), "utf-8");
24519
24777
  return {
24520
24778
  success: true,
@@ -24570,46 +24828,46 @@ var init_array_ops = __esm(() => {
24570
24828
 
24571
24829
  // ../cms/src/astro-image-paths.ts
24572
24830
  import { createHash as createHash2 } from "crypto";
24573
- import fs9 from "fs/promises";
24574
- import path8 from "path";
24831
+ import fs7 from "fs/promises";
24832
+ import path7 from "path";
24575
24833
  function isHugoStyleEntry(entryAbsPath) {
24576
- return HUGO_INDEX_RE.test(path8.basename(entryAbsPath));
24834
+ return HUGO_INDEX_RE.test(path7.basename(entryAbsPath));
24577
24835
  }
24578
24836
  function shortContentHash(buf) {
24579
24837
  return createHash2("sha256").update(buf).digest("hex").slice(0, 8);
24580
24838
  }
24581
24839
  async function pickAstroImageTarget(args) {
24582
- const entryDir = path8.dirname(args.entryAbsPath);
24840
+ const entryDir = path7.dirname(args.entryAbsPath);
24583
24841
  const isHugoStyle = isHugoStyleEntry(args.entryAbsPath);
24584
- const safeFilename = path8.basename(args.originalFilename);
24842
+ const safeFilename = path7.basename(args.originalFilename);
24585
24843
  if (!safeFilename || safeFilename === "." || safeFilename === "..") {
24586
24844
  throw new Error(`Invalid filename: ${args.originalFilename}`);
24587
24845
  }
24588
24846
  const baseName = isHugoStyle ? safeFilename : `${args.slug}-${safeFilename}`;
24589
- const baseAbs = path8.join(entryDir, baseName);
24847
+ const baseAbs = path7.join(entryDir, baseName);
24590
24848
  if (await isFreeOrMatching(baseAbs, args.compareBuffer)) {
24591
24849
  return { absPath: baseAbs, relPath: `./${baseName}` };
24592
24850
  }
24593
24851
  const candidateAbs = await pickHashedSibling(entryDir, baseName, args.compareBuffer);
24594
- return { absPath: candidateAbs, relPath: `./${path8.basename(candidateAbs)}` };
24852
+ return { absPath: candidateAbs, relPath: `./${path7.basename(candidateAbs)}` };
24595
24853
  }
24596
24854
  async function pickSiblingTarget(dir, filename, buf) {
24597
- const safe = path8.basename(filename);
24855
+ const safe = path7.basename(filename);
24598
24856
  if (!safe || safe === "." || safe === "..") {
24599
24857
  throw new Error(`Invalid filename: ${filename}`);
24600
24858
  }
24601
- const baseAbs = path8.join(dir, safe);
24859
+ const baseAbs = path7.join(dir, safe);
24602
24860
  if (await isFreeOrMatching(baseAbs, buf))
24603
24861
  return baseAbs;
24604
24862
  return pickHashedSibling(dir, safe, buf);
24605
24863
  }
24606
24864
  async function pickHashedSibling(dir, baseName, buf) {
24607
24865
  const hash = shortContentHash(buf);
24608
- const ext = path8.extname(baseName);
24609
- const stem = path8.basename(baseName, ext);
24866
+ const ext = path7.extname(baseName);
24867
+ const stem = path7.basename(baseName, ext);
24610
24868
  for (let attempt = 0;attempt < 5; attempt++) {
24611
24869
  const suffix = attempt === 0 ? hash : `${hash}-${attempt}`;
24612
- const candidateAbs = path8.join(dir, `${stem}-${suffix}${ext}`);
24870
+ const candidateAbs = path7.join(dir, `${stem}-${suffix}${ext}`);
24613
24871
  if (await isFreeOrMatching(candidateAbs, buf))
24614
24872
  return candidateAbs;
24615
24873
  }
@@ -24617,10 +24875,10 @@ async function pickHashedSibling(dir, baseName, buf) {
24617
24875
  }
24618
24876
  async function isFreeOrMatching(absPath, compareBuffer) {
24619
24877
  try {
24620
- const stat = await fs9.stat(absPath);
24878
+ const stat = await fs7.stat(absPath);
24621
24879
  if (stat.size !== compareBuffer.length)
24622
24880
  return false;
24623
- const existing = await fs9.readFile(absPath);
24881
+ const existing = await fs7.readFile(absPath);
24624
24882
  return compareBuffer.equals(existing);
24625
24883
  } catch {
24626
24884
  return true;
@@ -24632,8 +24890,8 @@ var init_astro_image_paths = __esm(() => {
24632
24890
  });
24633
24891
 
24634
24892
  // ../cms/src/handlers/astro-image-upload.ts
24635
- import fs10 from "fs/promises";
24636
- import path9 from "path";
24893
+ import fs8 from "fs/promises";
24894
+ import path8 from "path";
24637
24895
  async function tryAstroImageUpload(args) {
24638
24896
  const { collection, entry, field } = args.context;
24639
24897
  if (!collection || !entry || !field)
@@ -24655,12 +24913,12 @@ async function tryAstroImageUpload(args) {
24655
24913
  originalFilename: args.originalFilename,
24656
24914
  compareBuffer: args.fileBuffer
24657
24915
  });
24658
- await fs10.mkdir(path9.dirname(target.absPath), { recursive: true });
24659
- await fs10.writeFile(target.absPath, args.fileBuffer);
24916
+ await fs8.mkdir(path8.dirname(target.absPath), { recursive: true });
24917
+ await fs8.writeFile(target.absPath, args.fileBuffer);
24660
24918
  return {
24661
24919
  success: true,
24662
24920
  url: target.relPath,
24663
- filename: path9.basename(target.absPath)
24921
+ filename: path8.basename(target.absPath)
24664
24922
  };
24665
24923
  }
24666
24924
  var init_astro_image_upload = __esm(() => {
@@ -24669,12 +24927,12 @@ var init_astro_image_upload = __esm(() => {
24669
24927
  });
24670
24928
 
24671
24929
  // ../cms/src/handlers/markdown-ops.ts
24672
- import fs11 from "fs/promises";
24673
- import path10 from "path";
24930
+ import fs9 from "fs/promises";
24931
+ import path9 from "path";
24674
24932
  async function handleGetMarkdownContent(filePath) {
24675
24933
  try {
24676
24934
  const fullPath = resolveAndValidatePath(filePath);
24677
- const raw = await fs11.readFile(fullPath, "utf-8");
24935
+ const raw = await fs9.readFile(fullPath, "utf-8");
24678
24936
  if (isDataFile(filePath)) {
24679
24937
  const data = filePath.endsWith(".json") ? JSON.parse(raw) : import_yaml2.default.parse(raw);
24680
24938
  return {
@@ -24699,14 +24957,14 @@ async function handleUpdateMarkdown(request, componentDefinitions) {
24699
24957
  const release = await acquireFileLock(fullPath);
24700
24958
  try {
24701
24959
  if (isDataFile(request.filePath)) {
24702
- const raw = await fs11.readFile(fullPath, "utf-8");
24960
+ const raw = await fs9.readFile(fullPath, "utf-8");
24703
24961
  const existing = request.filePath.endsWith(".json") ? JSON.parse(raw) : import_yaml2.default.parse(raw);
24704
24962
  const merged = { ...existing ?? {}, ...request.frontmatter };
24705
24963
  const output = request.filePath.endsWith(".json") ? JSON.stringify(merged, null, 2) + `
24706
24964
  ` : import_yaml2.default.stringify(merged);
24707
- await fs11.writeFile(fullPath, output, "utf-8");
24965
+ await fs9.writeFile(fullPath, output, "utf-8");
24708
24966
  } else {
24709
- const raw = await fs11.readFile(fullPath, "utf-8");
24967
+ const raw = await fs9.readFile(fullPath, "utf-8");
24710
24968
  const existing = parseFrontmatter3(raw);
24711
24969
  const mergedFrontmatter = {
24712
24970
  ...existing.frontmatter,
@@ -24717,7 +24975,7 @@ async function handleUpdateMarkdown(request, componentDefinitions) {
24717
24975
  finalContent = ensureMdxImports(finalContent, request.filePath, componentDefinitions);
24718
24976
  }
24719
24977
  const markdownContent = serializeFrontmatter(mergedFrontmatter, finalContent);
24720
- await fs11.writeFile(fullPath, markdownContent, "utf-8");
24978
+ await fs9.writeFile(fullPath, markdownContent, "utf-8");
24721
24979
  }
24722
24980
  return { success: true };
24723
24981
  } finally {
@@ -24740,7 +24998,8 @@ async function handleCreateMarkdown(request) {
24740
24998
  return { success: false, error: `Invalid file extension "${ext}". Allowed: ${allowedExtensions.join(", ")}` };
24741
24999
  }
24742
25000
  const isData = ext === "json" || ext === "yaml" || ext === "yml";
24743
- const filePath = `src/content/${collection}/${normalizedSlug}.${ext}`;
25001
+ const layout = isData ? "flat" : await detectCollectionMarkdownLayout(collection);
25002
+ const filePath = layout === "index" ? `src/content/${collection}/${normalizedSlug}/index.${ext}` : `src/content/${collection}/${normalizedSlug}.${ext}`;
24744
25003
  const fullPath = resolveAndValidatePath(filePath);
24745
25004
  let fileContent;
24746
25005
  if (isData) {
@@ -24756,8 +25015,8 @@ async function handleCreateMarkdown(request) {
24756
25015
  fileContent = serializeFrontmatter(fullFrontmatter, content);
24757
25016
  }
24758
25017
  try {
24759
- await fs11.mkdir(path10.dirname(fullPath), { recursive: true });
24760
- await fs11.writeFile(fullPath, fileContent, { encoding: "utf-8", flag: "wx" });
25018
+ await fs9.mkdir(path9.dirname(fullPath), { recursive: true });
25019
+ await fs9.writeFile(fullPath, fileContent, { encoding: "utf-8", flag: "wx" });
24761
25020
  return {
24762
25021
  success: true,
24763
25022
  filePath,
@@ -24774,8 +25033,8 @@ async function handleCreateMarkdown(request) {
24774
25033
  async function handleDeleteMarkdown(request) {
24775
25034
  try {
24776
25035
  const fullPath = resolveAndValidatePath(request.filePath);
24777
- await fs11.access(fullPath);
24778
- await fs11.unlink(fullPath);
25036
+ await fs9.access(fullPath);
25037
+ await fs9.unlink(fullPath);
24779
25038
  return { success: true };
24780
25039
  } catch (error) {
24781
25040
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -24792,16 +25051,16 @@ async function handleRenameMarkdown(request) {
24792
25051
  if (!normalizedSlug) {
24793
25052
  return { success: false, error: "Invalid slug" };
24794
25053
  }
24795
- const dir = path10.dirname(fullPath);
24796
- const ext = path10.extname(fullPath);
24797
- const newFullPath = path10.join(dir, `${normalizedSlug}${ext}`);
25054
+ const dir = path9.dirname(fullPath);
25055
+ const ext = path9.extname(fullPath);
25056
+ const newFullPath = path9.join(dir, `${normalizedSlug}${ext}`);
24798
25057
  if (fullPath === newFullPath) {
24799
25058
  return { success: true, newFilePath: request.filePath, newSlug: normalizedSlug };
24800
25059
  }
24801
25060
  const release = await acquireFileLock(fullPath);
24802
25061
  try {
24803
25062
  try {
24804
- await fs11.link(fullPath, newFullPath);
25063
+ await fs9.link(fullPath, newFullPath);
24805
25064
  } catch (err) {
24806
25065
  if (isNodeError(err, "EEXIST")) {
24807
25066
  return { success: false, error: `File already exists: ${normalizedSlug}${ext}` };
@@ -24809,16 +25068,16 @@ async function handleRenameMarkdown(request) {
24809
25068
  throw err;
24810
25069
  }
24811
25070
  try {
24812
- await fs11.unlink(fullPath);
25071
+ await fs9.unlink(fullPath);
24813
25072
  } catch (err) {
24814
- await fs11.unlink(newFullPath).catch(() => {});
25073
+ await fs9.unlink(newFullPath).catch(() => {});
24815
25074
  throw err;
24816
25075
  }
24817
25076
  } finally {
24818
25077
  release();
24819
25078
  }
24820
25079
  const projectRoot = getProjectRoot();
24821
- const newFilePath = path10.relative(projectRoot, newFullPath).split(path10.sep).join("/");
25080
+ const newFilePath = path9.relative(projectRoot, newFullPath).split(path9.sep).join("/");
24822
25081
  return { success: true, newFilePath, newSlug: normalizedSlug };
24823
25082
  } catch (error) {
24824
25083
  const message = error instanceof Error ? error.message : String(error);
@@ -24828,6 +25087,68 @@ async function handleRenameMarkdown(request) {
24828
25087
  function isDataFile(filePath) {
24829
25088
  return filePath.endsWith(".json") || filePath.endsWith(".yaml") || filePath.endsWith(".yml");
24830
25089
  }
25090
+ async function detectCollectionMarkdownLayout(collection) {
25091
+ const existingLayout = await inferLayoutFromExistingEntries(collection);
25092
+ if (existingLayout)
25093
+ return existingLayout;
25094
+ const configLayout = await inferLayoutFromContentConfig(collection);
25095
+ if (configLayout)
25096
+ return configLayout;
25097
+ return "flat";
25098
+ }
25099
+ async function inferLayoutFromExistingEntries(collection) {
25100
+ const collectionPath = path9.join(getProjectRoot(), "src", "content", collection);
25101
+ let dirEntries;
25102
+ try {
25103
+ dirEntries = await fs9.readdir(collectionPath, { withFileTypes: true });
25104
+ } catch {
25105
+ return null;
25106
+ }
25107
+ let flatCount = 0;
25108
+ let indexCount = 0;
25109
+ const flatSlugs = new Set;
25110
+ for (const entry of dirEntries) {
25111
+ if (!entry.isFile())
25112
+ continue;
25113
+ const match = entry.name.match(/^(.+)\.(md|mdx)$/);
25114
+ if (!match)
25115
+ continue;
25116
+ flatCount++;
25117
+ flatSlugs.add(match[1]);
25118
+ }
25119
+ const subdirs = dirEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("_") && !entry.name.startsWith("."));
25120
+ const indexLookups = await Promise.all(subdirs.map(async (dir) => {
25121
+ if (flatSlugs.has(dir.name))
25122
+ return false;
25123
+ for (const ext of ["md", "mdx"]) {
25124
+ try {
25125
+ await fs9.access(path9.join(collectionPath, dir.name, `index.${ext}`));
25126
+ return true;
25127
+ } catch {}
25128
+ }
25129
+ return false;
25130
+ }));
25131
+ indexCount = indexLookups.filter(Boolean).length;
25132
+ if (indexCount > flatCount)
25133
+ return "index";
25134
+ if (flatCount > 0)
25135
+ return "flat";
25136
+ return null;
25137
+ }
25138
+ async function inferLayoutFromContentConfig(collection) {
25139
+ try {
25140
+ const parsed = await parseContentConfig();
25141
+ const pattern = parsed.get(collection)?.loaderPattern;
25142
+ if (!pattern)
25143
+ return null;
25144
+ return isIndexStyleGlobPattern(pattern) ? "index" : "flat";
25145
+ } catch {
25146
+ return null;
25147
+ }
25148
+ }
25149
+ function isIndexStyleGlobPattern(pattern) {
25150
+ return pattern.includes("index.{") || pattern.includes("*/index") || pattern.includes("**/index");
25151
+ }
24831
25152
  function parseFrontmatter3(raw) {
24832
25153
  const trimmed = raw.trimStart();
24833
25154
  if (!trimmed.startsWith("---")) {
@@ -24910,7 +25231,7 @@ function ensureMdxImports(content, filePath, componentDefinitions) {
24910
25231
  }
24911
25232
  }
24912
25233
  const root = getProjectRoot();
24913
- const mdxFullPath = path10.join(root, filePath);
25234
+ const mdxFullPath = path9.join(root, filePath);
24914
25235
  const missingImports = [];
24915
25236
  for (const name of usedComponents) {
24916
25237
  if (importedNames.has(name))
@@ -24918,7 +25239,7 @@ function ensureMdxImports(content, filePath, componentDefinitions) {
24918
25239
  const def = componentDefinitions[name];
24919
25240
  if (!def)
24920
25241
  continue;
24921
- const componentAbsPath = path10.join(root, def.file);
25242
+ const componentAbsPath = path9.join(root, def.file);
24922
25243
  const rel = relativeImportPath(mdxFullPath, componentAbsPath);
24923
25244
  missingImports.push(`import ${name} from '${rel}'`);
24924
25245
  }
@@ -24937,14 +25258,15 @@ function ensureMdxImports(content, filePath, componentDefinitions) {
24937
25258
  var import_yaml2, YAML_DATE_PATTERN;
24938
25259
  var init_markdown_ops = __esm(() => {
24939
25260
  init_config();
25261
+ init_content_config_ast();
24940
25262
  init_utils2();
24941
25263
  import_yaml2 = __toESM(require_dist(), 1);
24942
25264
  YAML_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}/;
24943
25265
  });
24944
25266
 
24945
25267
  // ../cms/src/handlers/page-ops.ts
24946
- import fs12 from "fs/promises";
24947
- import path11 from "path";
25268
+ import fs10 from "fs/promises";
25269
+ import path10 from "path";
24948
25270
  async function handleCreatePage(request) {
24949
25271
  const { title, slug } = request;
24950
25272
  const normalizedSlug = slugify(slug || title);
@@ -24956,8 +25278,8 @@ async function handleCreatePage(request) {
24956
25278
  const layoutImport = await resolveLayoutImport(request.layoutPath);
24957
25279
  const content = generatePageContent(title, layoutImport);
24958
25280
  try {
24959
- await fs12.mkdir(path11.dirname(fullPath), { recursive: true });
24960
- await fs12.writeFile(fullPath, content, { encoding: "utf-8", flag: "wx" });
25281
+ await fs10.mkdir(path10.dirname(fullPath), { recursive: true });
25282
+ await fs10.writeFile(fullPath, content, { encoding: "utf-8", flag: "wx" });
24961
25283
  const url = normalizedSlug === "index" ? "/" : `/${normalizedSlug}`;
24962
25284
  return { success: true, filePath, slug: normalizedSlug, url };
24963
25285
  } catch (error) {
@@ -24979,7 +25301,7 @@ async function handleDuplicatePage(request) {
24979
25301
  }
24980
25302
  let content;
24981
25303
  try {
24982
- content = await fs12.readFile(resolveAndValidatePath(sourceFile), "utf-8");
25304
+ content = await fs10.readFile(resolveAndValidatePath(sourceFile), "utf-8");
24983
25305
  } catch {
24984
25306
  return { success: false, error: `Could not read source file: ${sourceFile}` };
24985
25307
  }
@@ -24989,8 +25311,8 @@ async function handleDuplicatePage(request) {
24989
25311
  const newFilePath = `src/pages/${normalizedSlug}.astro`;
24990
25312
  const newFullPath = resolveAndValidatePath(newFilePath);
24991
25313
  try {
24992
- await fs12.mkdir(path11.dirname(newFullPath), { recursive: true });
24993
- await fs12.writeFile(newFullPath, content, { encoding: "utf-8", flag: "wx" });
25314
+ await fs10.mkdir(path10.dirname(newFullPath), { recursive: true });
25315
+ await fs10.writeFile(newFullPath, content, { encoding: "utf-8", flag: "wx" });
24994
25316
  const url = normalizedSlug === "index" ? "/" : `/${normalizedSlug}`;
24995
25317
  return { success: true, filePath: newFilePath, slug: normalizedSlug, url };
24996
25318
  } catch (error) {
@@ -25007,7 +25329,7 @@ async function handleDeletePage(request) {
25007
25329
  return { success: false, error: `Page not found: ${pagePath}` };
25008
25330
  }
25009
25331
  try {
25010
- await fs12.unlink(resolveAndValidatePath(pageFile));
25332
+ await fs10.unlink(resolveAndValidatePath(pageFile));
25011
25333
  return { success: true, filePath: pageFile, url: pagePath };
25012
25334
  } catch (error) {
25013
25335
  if (isNodeError(error, "ENOENT")) {
@@ -25024,10 +25346,10 @@ async function handleCheckSlugExists(slug) {
25024
25346
  return found ? { exists: true, filePath: found } : { exists: false };
25025
25347
  }
25026
25348
  async function handleGetLayouts() {
25027
- const layoutsDir = path11.join(getProjectRoot(), "src", "layouts");
25349
+ const layoutsDir = path10.join(getProjectRoot(), "src", "layouts");
25028
25350
  let entries;
25029
25351
  try {
25030
- entries = await fs12.readdir(layoutsDir, { withFileTypes: true });
25352
+ entries = await fs10.readdir(layoutsDir, { withFileTypes: true });
25031
25353
  } catch {
25032
25354
  return [];
25033
25355
  }
@@ -25035,7 +25357,7 @@ async function handleGetLayouts() {
25035
25357
  for (const entry of entries) {
25036
25358
  if (entry.isFile() && entry.name.endsWith(".astro")) {
25037
25359
  layouts.push({
25038
- name: path11.basename(entry.name, ".astro"),
25360
+ name: path10.basename(entry.name, ".astro"),
25039
25361
  path: `src/layouts/${entry.name}`
25040
25362
  });
25041
25363
  }
@@ -25047,7 +25369,7 @@ function errorMessage(error) {
25047
25369
  }
25048
25370
  async function fileExists(fullPath) {
25049
25371
  try {
25050
- await fs12.access(fullPath);
25372
+ await fs10.access(fullPath);
25051
25373
  return true;
25052
25374
  } catch {
25053
25375
  return false;
@@ -25069,7 +25391,7 @@ async function findPageFile(pagePath) {
25069
25391
  }
25070
25392
  async function resolveLayoutImport(layoutPath) {
25071
25393
  if (layoutPath) {
25072
- const name = path11.basename(layoutPath, ".astro");
25394
+ const name = path10.basename(layoutPath, ".astro");
25073
25395
  const importPath2 = `../${layoutPath.replace(/^src\//, "")}`;
25074
25396
  return { importPath: importPath2, componentName: pascalCase(name) };
25075
25397
  }
@@ -25132,10 +25454,10 @@ var init_page_ops = __esm(() => {
25132
25454
  });
25133
25455
 
25134
25456
  // ../cms/src/handlers/redirect-ops.ts
25135
- import fs13 from "fs/promises";
25136
- import path12 from "path";
25457
+ import fs11 from "fs/promises";
25458
+ import path11 from "path";
25137
25459
  function getRedirectsFilePath() {
25138
- return path12.join(getProjectRoot(), REDIRECTS_FILE);
25460
+ return path11.join(getProjectRoot(), REDIRECTS_FILE);
25139
25461
  }
25140
25462
  async function handleGetRedirects() {
25141
25463
  const lines = await readRedirectsFile(getRedirectsFilePath());
@@ -25212,7 +25534,7 @@ function formatRedirectLine(source, destination, statusCode) {
25212
25534
  }
25213
25535
  async function readRedirectsFile(filePath) {
25214
25536
  try {
25215
- const content = await fs13.readFile(filePath, "utf-8");
25537
+ const content = await fs11.readFile(filePath, "utf-8");
25216
25538
  return content.split(`
25217
25539
  `);
25218
25540
  } catch (error) {
@@ -25222,16 +25544,16 @@ async function readRedirectsFile(filePath) {
25222
25544
  }
25223
25545
  }
25224
25546
  async function writeRedirectsFile(filePath, lines) {
25225
- await fs13.mkdir(path12.dirname(filePath), { recursive: true });
25547
+ await fs11.mkdir(path11.dirname(filePath), { recursive: true });
25226
25548
  const trimmed = lines.slice();
25227
25549
  while (trimmed.length > 0 && trimmed[trimmed.length - 1].trim() === "") {
25228
25550
  trimmed.pop();
25229
25551
  }
25230
25552
  if (trimmed.length === 0) {
25231
- await fs13.writeFile(filePath, "", "utf-8");
25553
+ await fs11.writeFile(filePath, "", "utf-8");
25232
25554
  return;
25233
25555
  }
25234
- await fs13.writeFile(filePath, trimmed.join(`
25556
+ await fs11.writeFile(filePath, trimmed.join(`
25235
25557
  `) + `
25236
25558
  `, "utf-8");
25237
25559
  }
@@ -31019,8 +31341,8 @@ var init_snippet_utils = __esm(() => {
31019
31341
  });
31020
31342
 
31021
31343
  // ../cms/src/handlers/source-writer.ts
31022
- import fs14 from "fs/promises";
31023
- import path13 from "path";
31344
+ import fs12 from "fs/promises";
31345
+ import path12 from "path";
31024
31346
  async function handleUpdate(request, manifestWriter) {
31025
31347
  const { changes, meta } = request;
31026
31348
  const errors = [];
@@ -31050,17 +31372,17 @@ async function handleUpdate(request, manifestWriter) {
31050
31372
  const fullPath = resolveAndValidatePath(filePath);
31051
31373
  const release = await acquireFileLock(fullPath);
31052
31374
  try {
31053
- const currentContent = await fs14.readFile(fullPath, "utf-8");
31375
+ const currentContent = await fs12.readFile(fullPath, "utf-8");
31054
31376
  const { newContent, appliedCount, failedChanges, fileOps } = await applyChanges(currentContent, fileChanges, manifest, fullPath, meta.url);
31055
31377
  if (failedChanges.length > 0) {
31056
31378
  errors.push(...failedChanges);
31057
31379
  }
31058
31380
  if (appliedCount > 0 && newContent !== currentContent) {
31059
31381
  for (const op of fileOps) {
31060
- await fs14.mkdir(path13.dirname(op.target), { recursive: true });
31061
- await fs14.writeFile(op.target, op.bytes);
31382
+ await fs12.mkdir(path12.dirname(op.target), { recursive: true });
31383
+ await fs12.writeFile(op.target, op.bytes);
31062
31384
  }
31063
- await fs14.writeFile(fullPath, newContent, "utf-8");
31385
+ await fs12.writeFile(fullPath, newContent, "utf-8");
31064
31386
  updated += appliedCount;
31065
31387
  }
31066
31388
  } finally {
@@ -31323,8 +31645,8 @@ async function tryRewriteAssetImport(content, importInfo, newSrc, absFilePath, o
31323
31645
  const resolved = await resolveNewSrcBytes(newSrc, originUrl);
31324
31646
  if (!resolved)
31325
31647
  return null;
31326
- const originalAssetAbs = path13.resolve(path13.dirname(absFilePath), importInfo.source);
31327
- const targetAbs = await pickSiblingTarget(path13.dirname(originalAssetAbs), resolved.filename, resolved.bytes);
31648
+ const originalAssetAbs = path12.resolve(path12.dirname(absFilePath), importInfo.source);
31649
+ const targetAbs = await pickSiblingTarget(path12.dirname(originalAssetAbs), resolved.filename, resolved.bytes);
31328
31650
  const newRelImport = relativeImportPath(absFilePath, targetAbs);
31329
31651
  const newContent = content.slice(0, importInfo.sourceStart) + newRelImport + content.slice(importInfo.sourceEnd);
31330
31652
  return {
@@ -31334,11 +31656,11 @@ async function tryRewriteAssetImport(content, importInfo, newSrc, absFilePath, o
31334
31656
  };
31335
31657
  }
31336
31658
  async function resolveNewSrcBytes(newSrc, originUrl) {
31337
- const filenameFromPath = (p) => path13.basename(p.split("?")[0] ?? p);
31338
- const diskPath = newSrc.startsWith("/src/") ? path13.join(getProjectRoot(), newSrc.slice(1)) : newSrc.startsWith("/") && !newSrc.startsWith("//") ? path13.join(getProjectRoot(), "public", newSrc.replace(/^\/+/, "")) : null;
31659
+ const filenameFromPath = (p) => path12.basename(p.split("?")[0] ?? p);
31660
+ const diskPath = newSrc.startsWith("/src/") ? path12.join(getProjectRoot(), newSrc.slice(1)) : newSrc.startsWith("/") && !newSrc.startsWith("//") ? path12.join(getProjectRoot(), "public", newSrc.replace(/^\/+/, "")) : null;
31339
31661
  if (diskPath) {
31340
31662
  try {
31341
- return { bytes: await fs14.readFile(diskPath), filename: filenameFromPath(newSrc) };
31663
+ return { bytes: await fs12.readFile(diskPath), filename: filenameFromPath(newSrc) };
31342
31664
  } catch {}
31343
31665
  }
31344
31666
  try {
@@ -31883,7 +32205,7 @@ var init_source_writer = __esm(() => {
31883
32205
  });
31884
32206
 
31885
32207
  // ../cms/src/handlers/api-routes.ts
31886
- import path14 from "path";
32208
+ import path13 from "path";
31887
32209
  function requireMedia(ctx) {
31888
32210
  if (!ctx.mediaAdapter) {
31889
32211
  sendError(ctx.res, "Media storage not configured", 501);
@@ -31973,7 +32295,7 @@ var init_api_routes = __esm(() => {
31973
32295
  }),
31974
32296
  custom("POST", "markdown/delete", async ({ req, res, manifestWriter, contentDir }) => {
31975
32297
  const body = await parseJsonBody(req);
31976
- const fullPath = path14.resolve(getProjectRoot(), body.filePath?.replace(/^\//, "") ?? "");
32298
+ const fullPath = path13.resolve(getProjectRoot(), body.filePath?.replace(/^\//, "") ?? "");
31977
32299
  expectedDeletions.add(fullPath);
31978
32300
  const result = await handleDeleteMarkdown(body);
31979
32301
  if (result.success) {
@@ -32081,7 +32403,7 @@ var init_api_routes = __esm(() => {
32081
32403
  const body = await parseJsonBody(req);
32082
32404
  const result = await handleDeletePage(body);
32083
32405
  if (result.success && result.filePath) {
32084
- expectedDeletions.add(path14.resolve(getProjectRoot(), result.filePath));
32406
+ expectedDeletions.add(path13.resolve(getProjectRoot(), result.filePath));
32085
32407
  }
32086
32408
  if (result.success && body.createRedirect && body.redirectTo) {
32087
32409
  await handleAddRedirect({ source: body.pagePath, destination: body.redirectTo, statusCode: 307 });
@@ -32185,8 +32507,8 @@ var init_color_patterns = __esm(() => {
32185
32507
  });
32186
32508
 
32187
32509
  // ../cms/src/tailwind-colors.ts
32188
- import fs15 from "fs/promises";
32189
- import path15 from "path";
32510
+ import fs13 from "fs/promises";
32511
+ import path14 from "path";
32190
32512
  async function parseTailwindConfig(projectRoot = getProjectRoot()) {
32191
32513
  const cssFiles = [
32192
32514
  "src/styles/global.css",
@@ -32200,9 +32522,9 @@ async function parseTailwindConfig(projectRoot = getProjectRoot()) {
32200
32522
  ];
32201
32523
  let customColors = [];
32202
32524
  for (const cssFile of cssFiles) {
32203
- const fullPath = path15.join(projectRoot, cssFile);
32525
+ const fullPath = path14.join(projectRoot, cssFile);
32204
32526
  try {
32205
- const content = await fs15.readFile(fullPath, "utf-8");
32527
+ const content = await fs13.readFile(fullPath, "utf-8");
32206
32528
  customColors = extractColorsFromCss(content);
32207
32529
  if (customColors.length > 0) {
32208
32530
  break;
@@ -32273,9 +32595,9 @@ async function parseTextStyles(projectRoot = getProjectRoot()) {
32273
32595
  ];
32274
32596
  let customTextStyles = {};
32275
32597
  for (const cssFile of cssFiles) {
32276
- const fullPath = path15.join(projectRoot, cssFile);
32598
+ const fullPath = path14.join(projectRoot, cssFile);
32277
32599
  try {
32278
- const content = await fs15.readFile(fullPath, "utf-8");
32600
+ const content = await fs13.readFile(fullPath, "utf-8");
32279
32601
  customTextStyles = extractTextStylesFromCss(content);
32280
32602
  if (Object.values(customTextStyles).some((arr) => arr && arr.length > 0)) {
32281
32603
  break;
@@ -32697,6 +33019,7 @@ var init_tailwind_colors = __esm(() => {
32697
33019
 
32698
33020
  // ../cms/src/html-processor.ts
32699
33021
  var init_html_processor = __esm(() => {
33022
+ init_config();
32700
33023
  init_seo_processor();
32701
33024
  init_tailwind_colors();
32702
33025
  init_utils2();
@@ -32729,8 +33052,8 @@ var init_dev_middleware = __esm(() => {
32729
33052
  });
32730
33053
 
32731
33054
  // ../cms/src/manifest-writer.ts
32732
- import fs16 from "fs/promises";
32733
- import path16 from "path";
33055
+ import fs14 from "fs/promises";
33056
+ import path15 from "path";
32734
33057
 
32735
33058
  class ManifestWriter {
32736
33059
  globalManifest;
@@ -32801,10 +33124,10 @@ class ManifestWriter {
32801
33124
  }
32802
33125
  getPageManifestPath(pagePath) {
32803
33126
  if (pagePath === "/" || pagePath === "") {
32804
- return path16.join(this.outDir, "index.json");
33127
+ return path15.join(this.outDir, "index.json");
32805
33128
  }
32806
33129
  const cleanPath = pagePath.replace(/^\//, "");
32807
- return path16.join(this.outDir, `${cleanPath}.json`);
33130
+ return path15.join(this.outDir, `${cleanPath}.json`);
32808
33131
  }
32809
33132
  addPage(pagePath, entries, components, collection, seo) {
32810
33133
  this.pageManifests.set(pagePath, { entries, components, collection, seo });
@@ -32830,8 +33153,8 @@ class ManifestWriter {
32830
33153
  }
32831
33154
  async writePageManifest(pagePath, entries, components, collection, seo) {
32832
33155
  const manifestPath = this.getPageManifestPath(pagePath);
32833
- const manifestDir = path16.dirname(manifestPath);
32834
- await fs16.mkdir(manifestDir, { recursive: true });
33156
+ const manifestDir = path15.dirname(manifestPath);
33157
+ await fs14.mkdir(manifestDir, { recursive: true });
32835
33158
  const metadata = {
32836
33159
  version: MANIFEST_VERSION,
32837
33160
  generatedAt: new Date().toISOString(),
@@ -32852,7 +33175,7 @@ class ManifestWriter {
32852
33175
  if (seo) {
32853
33176
  pageManifest.seo = seo;
32854
33177
  }
32855
- await fs16.writeFile(manifestPath, JSON.stringify(pageManifest, null, 2), "utf-8");
33178
+ await fs14.writeFile(manifestPath, JSON.stringify(pageManifest, null, 2), "utf-8");
32856
33179
  }
32857
33180
  async finalize() {
32858
33181
  await this.writeQueue;
@@ -32881,7 +33204,7 @@ class ManifestWriter {
32881
33204
  }
32882
33205
  }
32883
33206
  if (this.outDir) {
32884
- const globalManifestPath = path16.join(this.outDir, this.manifestFile);
33207
+ const globalManifestPath = path15.join(this.outDir, this.manifestFile);
32885
33208
  const globalSettings = {
32886
33209
  componentDefinitions: this.componentDefinitions,
32887
33210
  pages
@@ -32895,7 +33218,7 @@ class ManifestWriter {
32895
33218
  if (this.availableTextStyles) {
32896
33219
  globalSettings.availableTextStyles = this.availableTextStyles;
32897
33220
  }
32898
- await fs16.writeFile(globalManifestPath, JSON.stringify(globalSettings, null, 2), "utf-8");
33221
+ await fs14.writeFile(globalManifestPath, JSON.stringify(globalSettings, null, 2), "utf-8");
32899
33222
  }
32900
33223
  return {
32901
33224
  totalEntries: Object.keys(this.globalManifest.entries).length,
@@ -32961,17 +33284,533 @@ var init_vite_plugin = __esm(() => {
32961
33284
  init_vite_plugin_array_transform();
32962
33285
  });
32963
33286
 
33287
+ // ../../node_modules/zod/v4/core/core.js
33288
+ function $constructor(name, initializer, params) {
33289
+ function init2(inst, def) {
33290
+ if (!inst._zod) {
33291
+ Object.defineProperty(inst, "_zod", {
33292
+ value: {
33293
+ def,
33294
+ constr: _2,
33295
+ traits: new Set
33296
+ },
33297
+ enumerable: false
33298
+ });
33299
+ }
33300
+ if (inst._zod.traits.has(name)) {
33301
+ return;
33302
+ }
33303
+ inst._zod.traits.add(name);
33304
+ initializer(inst, def);
33305
+ const proto = _2.prototype;
33306
+ const keys = Object.keys(proto);
33307
+ for (let i = 0;i < keys.length; i++) {
33308
+ const k = keys[i];
33309
+ if (!(k in inst)) {
33310
+ inst[k] = proto[k].bind(inst);
33311
+ }
33312
+ }
33313
+ }
33314
+ const Parent = params?.Parent ?? Object;
33315
+
33316
+ class Definition extends Parent {
33317
+ }
33318
+ Object.defineProperty(Definition, "name", { value: name });
33319
+ function _2(def) {
33320
+ var _a;
33321
+ const inst = params?.Parent ? new Definition : this;
33322
+ init2(inst, def);
33323
+ (_a = inst._zod).deferred ?? (_a.deferred = []);
33324
+ for (const fn of inst._zod.deferred) {
33325
+ fn();
33326
+ }
33327
+ return inst;
33328
+ }
33329
+ Object.defineProperty(_2, "init", { value: init2 });
33330
+ Object.defineProperty(_2, Symbol.hasInstance, {
33331
+ value: (inst) => {
33332
+ if (params?.Parent && inst instanceof params.Parent)
33333
+ return true;
33334
+ return inst?._zod?.traits?.has(name);
33335
+ }
33336
+ });
33337
+ Object.defineProperty(_2, "name", { value: name });
33338
+ return _2;
33339
+ }
33340
+ function config(newConfig) {
33341
+ if (newConfig)
33342
+ Object.assign(globalConfig, newConfig);
33343
+ return globalConfig;
33344
+ }
33345
+ var NEVER, $brand, globalConfig;
33346
+ var init_core = __esm(() => {
33347
+ NEVER = Object.freeze({
33348
+ status: "aborted"
33349
+ });
33350
+ $brand = Symbol("zod_brand");
33351
+ globalConfig = {};
33352
+ });
33353
+
33354
+ // ../../node_modules/zod/v4/core/util.js
33355
+ function joinValues(array, separator = "|") {
33356
+ return array.map((val) => stringifyPrimitive(val)).join(separator);
33357
+ }
33358
+ function jsonStringifyReplacer(_2, value) {
33359
+ if (typeof value === "bigint")
33360
+ return value.toString();
33361
+ return value;
33362
+ }
33363
+ function cached(getter) {
33364
+ const set = false;
33365
+ return {
33366
+ get value() {
33367
+ if (!set) {
33368
+ const value = getter();
33369
+ Object.defineProperty(this, "value", { value });
33370
+ return value;
33371
+ }
33372
+ throw new Error("cached value already set");
33373
+ }
33374
+ };
33375
+ }
33376
+ function stringifyPrimitive(value) {
33377
+ if (typeof value === "bigint")
33378
+ return value.toString() + "n";
33379
+ if (typeof value === "string")
33380
+ return `"${value}"`;
33381
+ return `${value}`;
33382
+ }
33383
+ function parsedType(data) {
33384
+ const t = typeof data;
33385
+ switch (t) {
33386
+ case "number": {
33387
+ return Number.isNaN(data) ? "nan" : "number";
33388
+ }
33389
+ case "object": {
33390
+ if (data === null) {
33391
+ return "null";
33392
+ }
33393
+ if (Array.isArray(data)) {
33394
+ return "array";
33395
+ }
33396
+ const obj = data;
33397
+ if (obj && Object.getPrototypeOf(obj) !== Object.prototype && "constructor" in obj && obj.constructor) {
33398
+ return obj.constructor.name;
33399
+ }
33400
+ }
33401
+ }
33402
+ return t;
33403
+ }
33404
+ var EVALUATING, captureStackTrace, allowsEval, propertyKeyTypes, primitiveTypes, NUMBER_FORMAT_RANGES;
33405
+ var init_util = __esm(() => {
33406
+ EVALUATING = Symbol("evaluating");
33407
+ captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {};
33408
+ allowsEval = cached(() => {
33409
+ if (typeof navigator !== "undefined" && navigator?.userAgent?.includes("Cloudflare")) {
33410
+ return false;
33411
+ }
33412
+ try {
33413
+ const F = Function;
33414
+ new F("");
33415
+ return true;
33416
+ } catch (_2) {
33417
+ return false;
33418
+ }
33419
+ });
33420
+ propertyKeyTypes = new Set(["string", "number", "symbol"]);
33421
+ primitiveTypes = new Set(["string", "number", "bigint", "boolean", "symbol", "undefined"]);
33422
+ NUMBER_FORMAT_RANGES = {
33423
+ safeint: [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER],
33424
+ int32: [-2147483648, 2147483647],
33425
+ uint32: [0, 4294967295],
33426
+ float32: [-340282346638528860000000000000000000000, 340282346638528860000000000000000000000],
33427
+ float64: [-Number.MAX_VALUE, Number.MAX_VALUE]
33428
+ };
33429
+ });
33430
+
33431
+ // ../../node_modules/zod/v4/core/errors.js
33432
+ function flattenError(error, mapper = (issue) => issue.message) {
33433
+ const fieldErrors = {};
33434
+ const formErrors = [];
33435
+ for (const sub of error.issues) {
33436
+ if (sub.path.length > 0) {
33437
+ fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];
33438
+ fieldErrors[sub.path[0]].push(mapper(sub));
33439
+ } else {
33440
+ formErrors.push(mapper(sub));
33441
+ }
33442
+ }
33443
+ return { formErrors, fieldErrors };
33444
+ }
33445
+ function formatError(error, mapper = (issue) => issue.message) {
33446
+ const fieldErrors = { _errors: [] };
33447
+ const processError = (error2) => {
33448
+ for (const issue of error2.issues) {
33449
+ if (issue.code === "invalid_union" && issue.errors.length) {
33450
+ issue.errors.map((issues) => processError({ issues }));
33451
+ } else if (issue.code === "invalid_key") {
33452
+ processError({ issues: issue.issues });
33453
+ } else if (issue.code === "invalid_element") {
33454
+ processError({ issues: issue.issues });
33455
+ } else if (issue.path.length === 0) {
33456
+ fieldErrors._errors.push(mapper(issue));
33457
+ } else {
33458
+ let curr = fieldErrors;
33459
+ let i = 0;
33460
+ while (i < issue.path.length) {
33461
+ const el = issue.path[i];
33462
+ const terminal = i === issue.path.length - 1;
33463
+ if (!terminal) {
33464
+ curr[el] = curr[el] || { _errors: [] };
33465
+ } else {
33466
+ curr[el] = curr[el] || { _errors: [] };
33467
+ curr[el]._errors.push(mapper(issue));
33468
+ }
33469
+ curr = curr[el];
33470
+ i++;
33471
+ }
33472
+ }
33473
+ }
33474
+ };
33475
+ processError(error);
33476
+ return fieldErrors;
33477
+ }
33478
+ var initializer = (inst, def) => {
33479
+ inst.name = "$ZodError";
33480
+ Object.defineProperty(inst, "_zod", {
33481
+ value: inst._zod,
33482
+ enumerable: false
33483
+ });
33484
+ Object.defineProperty(inst, "issues", {
33485
+ value: def,
33486
+ enumerable: false
33487
+ });
33488
+ inst.message = JSON.stringify(def, jsonStringifyReplacer, 2);
33489
+ Object.defineProperty(inst, "toString", {
33490
+ value: () => inst.message,
33491
+ enumerable: false
33492
+ });
33493
+ }, $ZodError, $ZodRealError;
33494
+ var init_errors = __esm(() => {
33495
+ init_core();
33496
+ init_util();
33497
+ $ZodError = $constructor("$ZodError", initializer);
33498
+ $ZodRealError = $constructor("$ZodError", initializer, { Parent: Error });
33499
+ });
33500
+
33501
+ // ../../node_modules/zod/v4/core/parse.js
33502
+ var init_parse = () => {};
33503
+
33504
+ // ../../node_modules/zod/v4/core/regexes.js
33505
+ var dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`, date;
33506
+ var init_regexes = __esm(() => {
33507
+ date = /* @__PURE__ */ new RegExp(`^${dateSource}$`);
33508
+ });
33509
+
33510
+ // ../../node_modules/zod/v4/core/checks.js
33511
+ var init_checks = () => {};
33512
+
33513
+ // ../../node_modules/zod/v4/core/versions.js
33514
+ var init_versions = () => {};
33515
+
33516
+ // ../../node_modules/zod/v4/core/schemas.js
33517
+ var init_schemas = () => {};
33518
+
33519
+ // ../../node_modules/zod/v4/locales/en.js
33520
+ function en_default() {
33521
+ return {
33522
+ localeError: error()
33523
+ };
33524
+ }
33525
+ var error = () => {
33526
+ const Sizable = {
33527
+ string: { unit: "characters", verb: "to have" },
33528
+ file: { unit: "bytes", verb: "to have" },
33529
+ array: { unit: "items", verb: "to have" },
33530
+ set: { unit: "items", verb: "to have" },
33531
+ map: { unit: "entries", verb: "to have" }
33532
+ };
33533
+ function getSizing(origin) {
33534
+ return Sizable[origin] ?? null;
33535
+ }
33536
+ const FormatDictionary = {
33537
+ regex: "input",
33538
+ email: "email address",
33539
+ url: "URL",
33540
+ emoji: "emoji",
33541
+ uuid: "UUID",
33542
+ uuidv4: "UUIDv4",
33543
+ uuidv6: "UUIDv6",
33544
+ nanoid: "nanoid",
33545
+ guid: "GUID",
33546
+ cuid: "cuid",
33547
+ cuid2: "cuid2",
33548
+ ulid: "ULID",
33549
+ xid: "XID",
33550
+ ksuid: "KSUID",
33551
+ datetime: "ISO datetime",
33552
+ date: "ISO date",
33553
+ time: "ISO time",
33554
+ duration: "ISO duration",
33555
+ ipv4: "IPv4 address",
33556
+ ipv6: "IPv6 address",
33557
+ mac: "MAC address",
33558
+ cidrv4: "IPv4 range",
33559
+ cidrv6: "IPv6 range",
33560
+ base64: "base64-encoded string",
33561
+ base64url: "base64url-encoded string",
33562
+ json_string: "JSON string",
33563
+ e164: "E.164 number",
33564
+ jwt: "JWT",
33565
+ template_literal: "input"
33566
+ };
33567
+ const TypeDictionary = {
33568
+ nan: "NaN"
33569
+ };
33570
+ return (issue) => {
33571
+ switch (issue.code) {
33572
+ case "invalid_type": {
33573
+ const expected = TypeDictionary[issue.expected] ?? issue.expected;
33574
+ const receivedType = parsedType(issue.input);
33575
+ const received = TypeDictionary[receivedType] ?? receivedType;
33576
+ return `Invalid input: expected ${expected}, received ${received}`;
33577
+ }
33578
+ case "invalid_value":
33579
+ if (issue.values.length === 1)
33580
+ return `Invalid input: expected ${stringifyPrimitive(issue.values[0])}`;
33581
+ return `Invalid option: expected one of ${joinValues(issue.values, "|")}`;
33582
+ case "too_big": {
33583
+ const adj = issue.inclusive ? "<=" : "<";
33584
+ const sizing = getSizing(issue.origin);
33585
+ if (sizing)
33586
+ return `Too big: expected ${issue.origin ?? "value"} to have ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elements"}`;
33587
+ return `Too big: expected ${issue.origin ?? "value"} to be ${adj}${issue.maximum.toString()}`;
33588
+ }
33589
+ case "too_small": {
33590
+ const adj = issue.inclusive ? ">=" : ">";
33591
+ const sizing = getSizing(issue.origin);
33592
+ if (sizing) {
33593
+ return `Too small: expected ${issue.origin} to have ${adj}${issue.minimum.toString()} ${sizing.unit}`;
33594
+ }
33595
+ return `Too small: expected ${issue.origin} to be ${adj}${issue.minimum.toString()}`;
33596
+ }
33597
+ case "invalid_format": {
33598
+ const _issue = issue;
33599
+ if (_issue.format === "starts_with") {
33600
+ return `Invalid string: must start with "${_issue.prefix}"`;
33601
+ }
33602
+ if (_issue.format === "ends_with")
33603
+ return `Invalid string: must end with "${_issue.suffix}"`;
33604
+ if (_issue.format === "includes")
33605
+ return `Invalid string: must include "${_issue.includes}"`;
33606
+ if (_issue.format === "regex")
33607
+ return `Invalid string: must match pattern ${_issue.pattern}`;
33608
+ return `Invalid ${FormatDictionary[_issue.format] ?? issue.format}`;
33609
+ }
33610
+ case "not_multiple_of":
33611
+ return `Invalid number: must be a multiple of ${issue.divisor}`;
33612
+ case "unrecognized_keys":
33613
+ return `Unrecognized key${issue.keys.length > 1 ? "s" : ""}: ${joinValues(issue.keys, ", ")}`;
33614
+ case "invalid_key":
33615
+ return `Invalid key in ${issue.origin}`;
33616
+ case "invalid_union":
33617
+ return "Invalid input";
33618
+ case "invalid_element":
33619
+ return `Invalid value in ${issue.origin}`;
33620
+ default:
33621
+ return `Invalid input`;
33622
+ }
33623
+ };
33624
+ };
33625
+ var init_en = __esm(() => {
33626
+ init_util();
33627
+ });
33628
+
33629
+ // ../../node_modules/zod/v4/locales/index.js
33630
+ var init_locales = () => {};
33631
+
33632
+ // ../../node_modules/zod/v4/core/registries.js
33633
+ class $ZodRegistry {
33634
+ constructor() {
33635
+ this._map = new WeakMap;
33636
+ this._idmap = new Map;
33637
+ }
33638
+ add(schema, ..._meta) {
33639
+ const meta = _meta[0];
33640
+ this._map.set(schema, meta);
33641
+ if (meta && typeof meta === "object" && "id" in meta) {
33642
+ this._idmap.set(meta.id, schema);
33643
+ }
33644
+ return this;
33645
+ }
33646
+ clear() {
33647
+ this._map = new WeakMap;
33648
+ this._idmap = new Map;
33649
+ return this;
33650
+ }
33651
+ remove(schema) {
33652
+ const meta = this._map.get(schema);
33653
+ if (meta && typeof meta === "object" && "id" in meta) {
33654
+ this._idmap.delete(meta.id);
33655
+ }
33656
+ this._map.delete(schema);
33657
+ return this;
33658
+ }
33659
+ get(schema) {
33660
+ const p = schema._zod.parent;
33661
+ if (p) {
33662
+ const pm = { ...this.get(p) ?? {} };
33663
+ delete pm.id;
33664
+ const f = { ...pm, ...this._map.get(schema) };
33665
+ return Object.keys(f).length ? f : undefined;
33666
+ }
33667
+ return this._map.get(schema);
33668
+ }
33669
+ has(schema) {
33670
+ return this._map.has(schema);
33671
+ }
33672
+ }
33673
+ function registry() {
33674
+ return new $ZodRegistry;
33675
+ }
33676
+ var _a, $output, $input, globalRegistry;
33677
+ var init_registries = __esm(() => {
33678
+ $output = Symbol("ZodOutput");
33679
+ $input = Symbol("ZodInput");
33680
+ (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
33681
+ globalRegistry = globalThis.__zod_globalRegistry;
33682
+ });
33683
+
33684
+ // ../../node_modules/zod/v4/core/api.js
33685
+ var init_api = () => {};
33686
+
33687
+ // ../../node_modules/zod/v4/core/to-json-schema.js
33688
+ var init_to_json_schema = () => {};
33689
+
33690
+ // ../../node_modules/zod/v4/core/json-schema.js
33691
+ var init_json_schema = () => {};
33692
+
33693
+ // ../../node_modules/zod/v4/core/index.js
33694
+ var init_core2 = __esm(() => {
33695
+ init_util();
33696
+ init_regexes();
33697
+ init_locales();
33698
+ init_json_schema();
33699
+ init_core();
33700
+ init_parse();
33701
+ init_errors();
33702
+ init_schemas();
33703
+ init_checks();
33704
+ init_versions();
33705
+ init_registries();
33706
+ init_api();
33707
+ init_to_json_schema();
33708
+ });
33709
+
33710
+ // ../../node_modules/zod/v4/classic/checks.js
33711
+ var init_checks2 = () => {};
33712
+
33713
+ // ../../node_modules/zod/v4/classic/iso.js
33714
+ var init_iso = () => {};
33715
+
33716
+ // ../../node_modules/zod/v4/classic/errors.js
33717
+ var initializer2 = (inst, issues) => {
33718
+ $ZodError.init(inst, issues);
33719
+ inst.name = "ZodError";
33720
+ Object.defineProperties(inst, {
33721
+ format: {
33722
+ value: (mapper) => formatError(inst, mapper)
33723
+ },
33724
+ flatten: {
33725
+ value: (mapper) => flattenError(inst, mapper)
33726
+ },
33727
+ addIssue: {
33728
+ value: (issue) => {
33729
+ inst.issues.push(issue);
33730
+ inst.message = JSON.stringify(inst.issues, jsonStringifyReplacer, 2);
33731
+ }
33732
+ },
33733
+ addIssues: {
33734
+ value: (issues2) => {
33735
+ inst.issues.push(...issues2);
33736
+ inst.message = JSON.stringify(inst.issues, jsonStringifyReplacer, 2);
33737
+ }
33738
+ },
33739
+ isEmpty: {
33740
+ get() {
33741
+ return inst.issues.length === 0;
33742
+ }
33743
+ }
33744
+ });
33745
+ }, ZodError, ZodRealError;
33746
+ var init_errors2 = __esm(() => {
33747
+ init_core2();
33748
+ init_core2();
33749
+ init_util();
33750
+ ZodError = $constructor("ZodError", initializer2);
33751
+ ZodRealError = $constructor("ZodError", initializer2, {
33752
+ Parent: Error
33753
+ });
33754
+ });
33755
+
33756
+ // ../../node_modules/zod/v4/classic/parse.js
33757
+ var init_parse2 = () => {};
33758
+
33759
+ // ../../node_modules/zod/v4/classic/schemas.js
33760
+ var init_schemas2 = () => {};
33761
+
33762
+ // ../../node_modules/zod/v4/classic/compat.js
33763
+ var ZodFirstPartyTypeKind;
33764
+ var init_compat = __esm(() => {
33765
+ (function(ZodFirstPartyTypeKind2) {})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
33766
+ });
33767
+
33768
+ // ../../node_modules/zod/v4/classic/coerce.js
33769
+ var init_coerce = () => {};
33770
+
33771
+ // ../../node_modules/zod/v4/classic/external.js
33772
+ var init_external = __esm(() => {
33773
+ init_core2();
33774
+ init_core2();
33775
+ init_en();
33776
+ init_locales();
33777
+ init_iso();
33778
+ init_coerce();
33779
+ init_schemas2();
33780
+ init_checks2();
33781
+ init_errors2();
33782
+ init_parse2();
33783
+ init_compat();
33784
+ config(en_default());
33785
+ });
33786
+
33787
+ // ../../node_modules/zod/v4/classic/index.js
33788
+ var init_classic = __esm(() => {
33789
+ init_external();
33790
+ });
33791
+
33792
+ // ../../node_modules/zod/v4/index.js
33793
+ var init_v4 = __esm(() => {
33794
+ init_classic();
33795
+ });
33796
+
33797
+ // ../../node_modules/astro/dist/zod.js
33798
+ var init_zod = __esm(() => {
33799
+ init_v4();
33800
+ });
33801
+
32964
33802
  // ../cms/src/field-types.ts
32965
- import { z } from "astro/zod";
32966
- var init_field_types = () => {};
33803
+ var init_field_types = __esm(() => {
33804
+ init_zod();
33805
+ });
32967
33806
  // ../cms/src/media/s3.ts
32968
33807
  var init_s3 = __esm(() => {
32969
33808
  init_local();
32970
33809
  });
32971
33810
 
32972
33811
  // ../cms/src/migrate-astro-image.ts
32973
- import fs17 from "fs/promises";
32974
- import path17 from "path";
33812
+ import fs15 from "fs/promises";
33813
+ import path16 from "path";
32975
33814
  async function migrateAstroImages(options = {}) {
32976
33815
  const projectRoot = options.projectRoot ?? getProjectRoot();
32977
33816
  const dryRun = options.dryRun ?? false;
@@ -32983,10 +33822,10 @@ async function migrateAstroImages(options = {}) {
32983
33822
  if (astroFields.length === 0 || !def.entries)
32984
33823
  continue;
32985
33824
  for (const entry of def.entries) {
32986
- const entryAbs = path17.isAbsolute(entry.sourcePath) ? entry.sourcePath : path17.join(projectRoot, entry.sourcePath);
33825
+ const entryAbs = path16.isAbsolute(entry.sourcePath) ? entry.sourcePath : path16.join(projectRoot, entry.sourcePath);
32987
33826
  let raw;
32988
33827
  try {
32989
- raw = await fs17.readFile(entryAbs, "utf-8");
33828
+ raw = await fs15.readFile(entryAbs, "utf-8");
32990
33829
  } catch {
32991
33830
  skipped.push({ entrySourcePath: entry.sourcePath, fieldName: "*", reason: "read failed" });
32992
33831
  continue;
@@ -32997,10 +33836,10 @@ async function migrateAstroImages(options = {}) {
32997
33836
  continue;
32998
33837
  }
32999
33838
  const [fullFm, fmStart, yamlBody, fmEnd] = fmMatch;
33000
- const doc = import_yaml6.parseDocument(yamlBody);
33839
+ const doc2 = import_yaml6.parseDocument(yamlBody);
33001
33840
  let mutated = false;
33002
33841
  for (const field of astroFields) {
33003
- const current = doc.get(field.name);
33842
+ const current = doc2.get(field.name);
33004
33843
  if (typeof current !== "string") {
33005
33844
  if (current != null)
33006
33845
  skipped.push({ entrySourcePath: entry.sourcePath, fieldName: field.name, reason: "non-string value" });
@@ -33008,10 +33847,10 @@ async function migrateAstroImages(options = {}) {
33008
33847
  }
33009
33848
  if (!current.startsWith("/") || current.startsWith("//"))
33010
33849
  continue;
33011
- const sourceAbs = path17.join(projectRoot, "public", current.replace(/^\/+/, ""));
33850
+ const sourceAbs = path16.join(projectRoot, "public", current.replace(/^\/+/, ""));
33012
33851
  let sourceBuf;
33013
33852
  try {
33014
- sourceBuf = await fs17.readFile(sourceAbs);
33853
+ sourceBuf = await fs15.readFile(sourceAbs);
33015
33854
  } catch {
33016
33855
  skipped.push({ entrySourcePath: entry.sourcePath, fieldName: field.name, reason: `source missing: ${sourceAbs}` });
33017
33856
  continue;
@@ -33019,14 +33858,14 @@ async function migrateAstroImages(options = {}) {
33019
33858
  const target = await pickAstroImageTarget({
33020
33859
  entryAbsPath: entryAbs,
33021
33860
  slug: entry.slug,
33022
- originalFilename: path17.basename(current),
33861
+ originalFilename: path16.basename(current),
33023
33862
  compareBuffer: sourceBuf
33024
33863
  });
33025
33864
  if (!dryRun) {
33026
- await fs17.mkdir(path17.dirname(target.absPath), { recursive: true });
33027
- await fs17.writeFile(target.absPath, sourceBuf);
33865
+ await fs15.mkdir(path16.dirname(target.absPath), { recursive: true });
33866
+ await fs15.writeFile(target.absPath, sourceBuf);
33028
33867
  }
33029
- doc.set(field.name, target.relPath);
33868
+ doc2.set(field.name, target.relPath);
33030
33869
  mutated = true;
33031
33870
  migrations.push({
33032
33871
  entrySourcePath: entry.sourcePath,
@@ -33038,9 +33877,9 @@ async function migrateAstroImages(options = {}) {
33038
33877
  });
33039
33878
  }
33040
33879
  if (mutated && !dryRun) {
33041
- const newYaml = doc.toString().replace(/\n$/, "");
33880
+ const newYaml = doc2.toString().replace(/\n$/, "");
33042
33881
  const newRaw = raw.replace(fullFm, `${fmStart}${newYaml}${fmEnd}`);
33043
- await fs17.writeFile(entryAbs, newRaw, "utf-8");
33882
+ await fs15.writeFile(entryAbs, newRaw, "utf-8");
33044
33883
  }
33045
33884
  }
33046
33885
  }
@@ -33082,7 +33921,7 @@ var exports_migrate = {};
33082
33921
  __export(exports_migrate, {
33083
33922
  migrate: () => migrate
33084
33923
  });
33085
- import path18 from "path";
33924
+ import path17 from "path";
33086
33925
  async function migrate(args) {
33087
33926
  if (args.target !== "astro-image") {
33088
33927
  console.error(`Unknown migrate target: ${args.target}`);
@@ -33101,7 +33940,7 @@ async function migrate(args) {
33101
33940
  for (const m of result.migrations) {
33102
33941
  console.log(` ${m.entrySourcePath}`);
33103
33942
  console.log(` ${m.fieldName}: ${m.originalValue} \u2192 ${m.newValue}`);
33104
- console.log(` copy: ${path18.relative(process.cwd(), m.copiedFrom)} \u2192 ${path18.relative(process.cwd(), m.copiedTo)}`);
33943
+ console.log(` copy: ${path17.relative(process.cwd(), m.copiedFrom)} \u2192 ${path17.relative(process.cwd(), m.copiedTo)}`);
33105
33944
  }
33106
33945
  }
33107
33946
  if (result.skipped.length > 0) {
@@ -33120,224 +33959,9 @@ var init_migrate = __esm(() => {
33120
33959
  init_src();
33121
33960
  });
33122
33961
 
33123
- // ../agent-summary/src/agent-summary-integration.ts
33124
- import fs2 from "fs/promises";
33125
- import { fileURLToPath } from "url";
33126
-
33127
- // ../agent-summary/src/utils.ts
33128
- import { promises as fs } from "fs";
33129
- import path from "path";
33130
- var AGENTS_PATH = path.resolve("AGENTS.md");
33131
- var SUMMARY_START = "<page_summary>";
33132
- var SUMMARY_END = "</page_summary>";
33133
- var decodeEntities = (value) => {
33134
- return value.replace(/&amp;/gi, "&").replace(/&lt;/gi, "<").replace(/&gt;/gi, ">").replace(/&quot;/gi, '"').replace(/&#39;/gi, "'").replace(/&nbsp;/gi, " ");
33135
- };
33136
- var sanitize = (value) => {
33137
- if (!value) {
33138
- return "";
33139
- }
33140
- const decoded = decodeEntities(value);
33141
- return decoded.replace(/\s+/g, " ").replace(/[\u2012-\u2015]/g, "-").replace(/\u2026/g, "...").trim();
33142
- };
33143
- var truncate = (value, maxLength) => {
33144
- if (value.length <= maxLength) {
33145
- return value;
33146
- }
33147
- return `${value.slice(0, maxLength - 3).trimEnd()}...`;
33148
- };
33149
- var normalizeRoute = (pathname) => {
33150
- const trimmed = pathname.replace(/^\/+/, "").replace(/\/+$/, "");
33151
- if (trimmed.length === 0) {
33152
- return "/";
33153
- }
33154
- return `/${trimmed}`;
33155
- };
33156
- var formatDestination = (value) => {
33157
- if (!value) {
33158
- return "/";
33159
- }
33160
- if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(value) || value.startsWith("#")) {
33161
- return value;
33162
- }
33163
- return normalizeRoute(value);
33164
- };
33165
- var resolveHtmlPath = async (distDir, pathname) => {
33166
- const normalizedRoute = normalizeRoute(pathname);
33167
- const routeSegment = normalizedRoute === "/" ? "" : normalizedRoute.slice(1);
33168
- const candidates = routeSegment === "" ? [path.join(distDir, "index.html")] : [
33169
- path.join(distDir, routeSegment, "index.html"),
33170
- path.join(distDir, `${routeSegment}.html`)
33171
- ];
33172
- for (const candidate of candidates) {
33173
- try {
33174
- const stats = await fs.stat(candidate);
33175
- if (stats.isFile()) {
33176
- return candidate;
33177
- }
33178
- } catch {}
33179
- }
33180
- return null;
33181
- };
33182
- var extractMetaFromHtml = (route, html) => {
33183
- const titleMatch = html.match(/<title[^>]*>([^<]*)<\/title>/i);
33184
- const metaMatch = html.match(/<meta[^>]+name=["']description["'][^>]*?>/i);
33185
- const contentMatch = metaMatch?.[0]?.match(/content=["']([^"']*)["']/i);
33186
- const headingMatches = [...html.matchAll(/<h([1-6])[^>]*>([\s\S]*?)<\/h\1>/gi)];
33187
- const headingEntries = headingMatches.map((match) => ({
33188
- level: `h${match[1]}`,
33189
- text: sanitize(match[2]?.replace(/<[^>]+>/g, ""))
33190
- })).filter((entry) => entry.text.length > 0);
33191
- const primaryHeading = headingEntries.find((entry) => entry.level === "h1" && entry.text.length >= 8) || headingEntries.find((entry) => entry.text.length >= 16) || headingEntries[0];
33192
- const primaryHeadingText = primaryHeading?.text ?? "";
33193
- const paragraphMatches = [...html.matchAll(/<p[^>]*>([\s\S]*?)<\/p>/gi)];
33194
- const paragraphCandidates = paragraphMatches.map((match) => sanitize(match[1]?.replace(/<[^>]+>/g, "")));
33195
- const fallbackParagraph = paragraphCandidates.find((text) => text.length >= 40) ?? paragraphCandidates[0] ?? "";
33196
- const title = sanitize(titleMatch?.[1] ?? (primaryHeadingText || "Untitled page"));
33197
- const descriptionSource = contentMatch?.[1];
33198
- const paragraphDescription = descriptionSource ? "" : fallbackParagraph;
33199
- const description = truncate((descriptionSource ? sanitize(descriptionSource) : paragraphDescription) || "Description unavailable", 220);
33200
- return {
33201
- route: normalizeRoute(route),
33202
- title,
33203
- description,
33204
- headlines: headingEntries
33205
- };
33206
- };
33207
- var createJsonlRecords = (pages, redirects) => {
33208
- const records = [];
33209
- for (const page of pages.sort((a, b) => a.route.localeCompare(b.route))) {
33210
- records.push(JSON.stringify({
33211
- kind: "page",
33212
- route: page.route,
33213
- title: page.title,
33214
- description: page.description,
33215
- headlines: page.headlines
33216
- }));
33217
- }
33218
- for (const redirect of redirects.sort((a, b) => a.from.localeCompare(b.from))) {
33219
- records.push(JSON.stringify({
33220
- kind: "redirect",
33221
- route: redirect.from,
33222
- to: redirect.to,
33223
- status: redirect.status
33224
- }));
33225
- }
33226
- return records;
33227
- };
33228
- var updateAgentsSummary = async (pages, redirects) => {
33229
- const jsonlRecords = createJsonlRecords(pages, redirects);
33230
- const summaryBody = jsonlRecords.join(`
33231
- `);
33232
- const summaryBlock = summaryBody ? `${SUMMARY_START}
33233
- ${summaryBody}
33234
- ${SUMMARY_END}
33235
- ` : `${SUMMARY_START}
33236
- ${SUMMARY_END}
33237
- `;
33238
- const agentsContent = await fs.readFile(AGENTS_PATH, "utf8").catch(() => "");
33239
- if (agentsContent.includes(SUMMARY_START) && agentsContent.includes(SUMMARY_END)) {
33240
- const startIndex = agentsContent.indexOf(SUMMARY_START);
33241
- const summaryEndIndex = agentsContent.indexOf(SUMMARY_END, startIndex);
33242
- if (summaryEndIndex === -1) {
33243
- const recovered = `${agentsContent.slice(0, startIndex)}${summaryBlock}`;
33244
- await fs.writeFile(AGENTS_PATH, recovered, "utf8");
33245
- return;
33246
- }
33247
- let endIndex = summaryEndIndex + SUMMARY_END.length;
33248
- while (endIndex < agentsContent.length && (agentsContent[endIndex] === `
33249
- ` || agentsContent[endIndex] === "\r")) {
33250
- endIndex += 1;
33251
- }
33252
- const updated = `${agentsContent.slice(0, startIndex)}${summaryBlock}${agentsContent.slice(endIndex)}`;
33253
- await fs.writeFile(AGENTS_PATH, updated, "utf8");
33254
- return;
33255
- }
33256
- const prefix = agentsContent.trimEnd();
33257
- const separator = prefix.length === 0 ? "" : `
33258
- `;
33259
- await fs.writeFile(AGENTS_PATH, `${prefix}${separator}${summaryBlock}`, "utf8");
33260
- };
33261
-
33262
- // ../agent-summary/src/agent-summary-integration.ts
33263
- var agentsSummary = () => {
33264
- const redirectPathnames = new Set;
33265
- const redirects = [];
33266
- return {
33267
- name: "agents-summary",
33268
- hooks: {
33269
- "astro:routes:resolved": ({ routes }) => {
33270
- redirectPathnames.clear();
33271
- redirects.length = 0;
33272
- for (const route of routes) {
33273
- if (route.type === "redirect" && route.pathname) {
33274
- const from = normalizeRoute(route.pathname);
33275
- redirectPathnames.add(from);
33276
- let destination = "";
33277
- let status = "";
33278
- const redirectConfig = route.redirect;
33279
- if (typeof redirectConfig === "string") {
33280
- destination = redirectConfig;
33281
- status = "302";
33282
- } else if (redirectConfig) {
33283
- destination = redirectConfig.destination;
33284
- status = redirectConfig.status?.toString() ?? "";
33285
- } else if (route.redirectRoute?.pathname) {
33286
- destination = route.redirectRoute.pathname;
33287
- }
33288
- let resolvedDestination = destination;
33289
- if (!resolvedDestination && route.redirectRoute?.pattern) {
33290
- resolvedDestination = route.redirectRoute.pattern.toString();
33291
- }
33292
- const to = resolvedDestination?.startsWith("^") ? resolvedDestination : formatDestination(resolvedDestination);
33293
- redirects.push({
33294
- from,
33295
- to,
33296
- status: status || "302"
33297
- });
33298
- }
33299
- }
33300
- },
33301
- "astro:build:done": async ({ dir, pages, logger }) => {
33302
- const distDir = fileURLToPath(dir);
33303
- const summaries = [];
33304
- for (const page of pages) {
33305
- const route = normalizeRoute(page.pathname);
33306
- if (redirectPathnames.has(route)) {
33307
- continue;
33308
- }
33309
- const htmlPath = await resolveHtmlPath(distDir, page.pathname);
33310
- if (!htmlPath) {
33311
- logger.warn(`Skipping ${page.pathname}; no HTML output found.`);
33312
- continue;
33313
- }
33314
- const html = await fs2.readFile(htmlPath, "utf8");
33315
- summaries.push(extractMetaFromHtml(page.pathname, html));
33316
- }
33317
- if (summaries.length === 0) {
33318
- logger.warn("No pages detected; AGENTS.md was not updated.");
33319
- return;
33320
- }
33321
- await updateAgentsSummary(summaries, redirects);
33322
- logger.info(`Updated AGENTS.md with ${summaries.length} page entries${redirects.length > 0 ? ` and ${redirects.length} redirects` : ""}.`);
33323
- }
33324
- }
33325
- };
33326
- };
33327
33962
  // src/index.ts
33328
- init_utils();
33329
- import { build as astroBuild, dev, preview } from "astro";
33330
33963
  import { spawn } from "child_process";
33331
- import { readFileSync as readFileSync3 } from "fs";
33332
33964
  var [, , command, ...args] = process.argv;
33333
- function hasNuaIntegration(configPath) {
33334
- try {
33335
- const content = readFileSync3(configPath, "utf-8");
33336
- return content.includes("@nuasite/agent-summary") || content.includes("agentsSummary");
33337
- } catch {
33338
- return false;
33339
- }
33340
- }
33341
33965
  function proxyToAstroCLI(command2, args2) {
33342
33966
  const astro = spawn("npx", ["astro", command2, ...args2], {
33343
33967
  stdio: "inherit",
@@ -33346,8 +33970,8 @@ function proxyToAstroCLI(command2, args2) {
33346
33970
  astro.on("close", (code) => {
33347
33971
  process.exit(code || 0);
33348
33972
  });
33349
- astro.on("error", (error) => {
33350
- console.error("Error running astro command:", error);
33973
+ astro.on("error", (error2) => {
33974
+ console.error("Error running astro command:", error2);
33351
33975
  process.exit(1);
33352
33976
  });
33353
33977
  }
@@ -33366,45 +33990,10 @@ Commands:`);
33366
33990
  All Astro CLI options are supported.
33367
33991
  `);
33368
33992
  }
33369
- var configPath = findAstroConfig();
33370
- var canProxyDirectly = configPath && hasNuaIntegration(configPath);
33371
- if (canProxyDirectly && command && ["build", "dev", "preview"].includes(command)) {
33993
+ if (command && ["build", "dev", "preview"].includes(command)) {
33372
33994
  proxyToAstroCLI(command, args);
33373
33995
  } else {
33374
33996
  switch (command) {
33375
- case "build":
33376
- astroBuild({
33377
- root: process.cwd(),
33378
- integrations: [agentsSummary()]
33379
- }).catch((error) => {
33380
- console.error("Error:", error);
33381
- process.exit(1);
33382
- });
33383
- break;
33384
- case "dev":
33385
- case "preview": {
33386
- const server = {};
33387
- for (let i = 0;i < args.length; i++) {
33388
- if (args[i] === "--port" && args[i + 1]) {
33389
- server.port = parseInt(args[i + 1], 10);
33390
- i++;
33391
- } else if (args[i] === "--host" && args[i + 1]) {
33392
- server.host = args[i + 1];
33393
- i++;
33394
- }
33395
- }
33396
- const options = {
33397
- root: process.cwd(),
33398
- integrations: [agentsSummary()],
33399
- server
33400
- };
33401
- const runner = command === "dev" ? dev : preview;
33402
- runner(options).catch((error) => {
33403
- console.error("Error:", error);
33404
- process.exit(1);
33405
- });
33406
- break;
33407
- }
33408
33997
  case "init": {
33409
33998
  const { init: init2 } = await Promise.resolve().then(() => (init_init(), exports_init));
33410
33999
  await init2({