@typicalday/firegraph 0.5.0 → 0.6.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.
@@ -1295,8 +1295,8 @@ var require_node = __commonJS({
1295
1295
  }
1296
1296
  break;
1297
1297
  case "FILE":
1298
- var fs2 = __require("fs");
1299
- stream2 = new fs2.SyncWriteStream(fd2, { autoClose: false });
1298
+ var fs3 = __require("fs");
1299
+ stream2 = new fs3.SyncWriteStream(fd2, { autoClose: false });
1300
1300
  stream2._type = "fs";
1301
1301
  break;
1302
1302
  case "PIPE":
@@ -14083,11 +14083,11 @@ var require_mime_types = __commonJS({
14083
14083
  }
14084
14084
  return exts[0];
14085
14085
  }
14086
- function lookup(path4) {
14087
- if (!path4 || typeof path4 !== "string") {
14086
+ function lookup(path5) {
14087
+ if (!path5 || typeof path5 !== "string") {
14088
14088
  return false;
14089
14089
  }
14090
- var extension2 = extname("x." + path4).toLowerCase().substr(1);
14090
+ var extension2 = extname("x." + path5).toLowerCase().substr(1);
14091
14091
  if (!extension2) {
14092
14092
  return false;
14093
14093
  }
@@ -17602,7 +17602,7 @@ var require_path_to_regexp = __commonJS({
17602
17602
  "editor/node_modules/.pnpm/path-to-regexp@0.1.12/node_modules/path-to-regexp/index.js"(exports, module) {
17603
17603
  module.exports = pathToRegexp;
17604
17604
  var MATCHING_GROUP_REGEXP = /\\.|\((?:\?<(.*?)>)?(?!\?)/g;
17605
- function pathToRegexp(path4, keys, options) {
17605
+ function pathToRegexp(path5, keys, options) {
17606
17606
  options = options || {};
17607
17607
  keys = keys || [];
17608
17608
  var strict = options.strict;
@@ -17616,8 +17616,8 @@ var require_path_to_regexp = __commonJS({
17616
17616
  var pos = 0;
17617
17617
  var backtrack = "";
17618
17618
  var m;
17619
- if (path4 instanceof RegExp) {
17620
- while (m = MATCHING_GROUP_REGEXP.exec(path4.source)) {
17619
+ if (path5 instanceof RegExp) {
17620
+ while (m = MATCHING_GROUP_REGEXP.exec(path5.source)) {
17621
17621
  if (m[0][0] === "\\") continue;
17622
17622
  keys.push({
17623
17623
  name: m[1] || name++,
@@ -17625,18 +17625,18 @@ var require_path_to_regexp = __commonJS({
17625
17625
  offset: m.index
17626
17626
  });
17627
17627
  }
17628
- return path4;
17628
+ return path5;
17629
17629
  }
17630
- if (Array.isArray(path4)) {
17631
- path4 = path4.map(function(value) {
17630
+ if (Array.isArray(path5)) {
17631
+ path5 = path5.map(function(value) {
17632
17632
  return pathToRegexp(value, keys, options).source;
17633
17633
  });
17634
- return new RegExp(path4.join("|"), flags);
17634
+ return new RegExp(path5.join("|"), flags);
17635
17635
  }
17636
- if (typeof path4 !== "string") {
17636
+ if (typeof path5 !== "string") {
17637
17637
  throw new TypeError("path must be a string, array of strings, or regular expression");
17638
17638
  }
17639
- path4 = path4.replace(
17639
+ path5 = path5.replace(
17640
17640
  /\\.|(\/)?(\.)?:(\w+)(\(.*?\))?(\*)?(\?)?|[.*]|\/\(/g,
17641
17641
  function(match, slash, format, key, capture, star, optional2, offset) {
17642
17642
  if (match[0] === "\\") {
@@ -17653,7 +17653,7 @@ var require_path_to_regexp = __commonJS({
17653
17653
  if (slash || format) {
17654
17654
  backtrack = "";
17655
17655
  } else {
17656
- backtrack += path4.slice(pos, offset);
17656
+ backtrack += path5.slice(pos, offset);
17657
17657
  }
17658
17658
  pos = offset + match.length;
17659
17659
  if (match === "*") {
@@ -17681,7 +17681,7 @@ var require_path_to_regexp = __commonJS({
17681
17681
  return result;
17682
17682
  }
17683
17683
  );
17684
- while (m = MATCHING_GROUP_REGEXP.exec(path4)) {
17684
+ while (m = MATCHING_GROUP_REGEXP.exec(path5)) {
17685
17685
  if (m[0][0] === "\\") continue;
17686
17686
  if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m.index) {
17687
17687
  keys.splice(keysOffset + i, 0, {
@@ -17693,13 +17693,13 @@ var require_path_to_regexp = __commonJS({
17693
17693
  }
17694
17694
  i++;
17695
17695
  }
17696
- path4 += strict ? "" : path4[path4.length - 1] === "/" ? "?" : "/?";
17696
+ path5 += strict ? "" : path5[path5.length - 1] === "/" ? "?" : "/?";
17697
17697
  if (end) {
17698
- path4 += "$";
17699
- } else if (path4[path4.length - 1] !== "/") {
17700
- path4 += lookahead ? "(?=/|$)" : "(?:/|$)";
17698
+ path5 += "$";
17699
+ } else if (path5[path5.length - 1] !== "/") {
17700
+ path5 += lookahead ? "(?=/|$)" : "(?:/|$)";
17701
17701
  }
17702
- return new RegExp("^" + path4, flags);
17702
+ return new RegExp("^" + path5, flags);
17703
17703
  }
17704
17704
  }
17705
17705
  });
@@ -17712,19 +17712,19 @@ var require_layer = __commonJS({
17712
17712
  var debug = require_src()("express:router:layer");
17713
17713
  var hasOwnProperty = Object.prototype.hasOwnProperty;
17714
17714
  module.exports = Layer;
17715
- function Layer(path4, options, fn) {
17715
+ function Layer(path5, options, fn) {
17716
17716
  if (!(this instanceof Layer)) {
17717
- return new Layer(path4, options, fn);
17717
+ return new Layer(path5, options, fn);
17718
17718
  }
17719
- debug("new %o", path4);
17719
+ debug("new %o", path5);
17720
17720
  var opts = options || {};
17721
17721
  this.handle = fn;
17722
17722
  this.name = fn.name || "<anonymous>";
17723
17723
  this.params = void 0;
17724
17724
  this.path = void 0;
17725
- this.regexp = pathRegexp(path4, this.keys = [], opts);
17726
- this.regexp.fast_star = path4 === "*";
17727
- this.regexp.fast_slash = path4 === "/" && opts.end === false;
17725
+ this.regexp = pathRegexp(path5, this.keys = [], opts);
17726
+ this.regexp.fast_star = path5 === "*";
17727
+ this.regexp.fast_slash = path5 === "/" && opts.end === false;
17728
17728
  }
17729
17729
  Layer.prototype.handle_error = function handle_error(error48, req, res, next) {
17730
17730
  var fn = this.handle;
@@ -17748,20 +17748,20 @@ var require_layer = __commonJS({
17748
17748
  next(err);
17749
17749
  }
17750
17750
  };
17751
- Layer.prototype.match = function match(path4) {
17751
+ Layer.prototype.match = function match(path5) {
17752
17752
  var match2;
17753
- if (path4 != null) {
17753
+ if (path5 != null) {
17754
17754
  if (this.regexp.fast_slash) {
17755
17755
  this.params = {};
17756
17756
  this.path = "";
17757
17757
  return true;
17758
17758
  }
17759
17759
  if (this.regexp.fast_star) {
17760
- this.params = { "0": decode_param(path4) };
17761
- this.path = path4;
17760
+ this.params = { "0": decode_param(path5) };
17761
+ this.path = path5;
17762
17762
  return true;
17763
17763
  }
17764
- match2 = this.regexp.exec(path4);
17764
+ match2 = this.regexp.exec(path5);
17765
17765
  }
17766
17766
  if (!match2) {
17767
17767
  this.params = void 0;
@@ -17854,10 +17854,10 @@ var require_route = __commonJS({
17854
17854
  var slice = Array.prototype.slice;
17855
17855
  var toString = Object.prototype.toString;
17856
17856
  module.exports = Route;
17857
- function Route(path4) {
17858
- this.path = path4;
17857
+ function Route(path5) {
17858
+ this.path = path5;
17859
17859
  this.stack = [];
17860
- debug("new %o", path4);
17860
+ debug("new %o", path5);
17861
17861
  this.methods = {};
17862
17862
  }
17863
17863
  Route.prototype._handles_method = function _handles_method(method) {
@@ -18069,8 +18069,8 @@ var require_router = __commonJS({
18069
18069
  if (++sync > 100) {
18070
18070
  return setImmediate(next, err);
18071
18071
  }
18072
- var path4 = getPathname(req);
18073
- if (path4 == null) {
18072
+ var path5 = getPathname(req);
18073
+ if (path5 == null) {
18074
18074
  return done(layerError);
18075
18075
  }
18076
18076
  var layer;
@@ -18078,7 +18078,7 @@ var require_router = __commonJS({
18078
18078
  var route;
18079
18079
  while (match !== true && idx < stack.length) {
18080
18080
  layer = stack[idx++];
18081
- match = matchLayer(layer, path4);
18081
+ match = matchLayer(layer, path5);
18082
18082
  route = layer.route;
18083
18083
  if (typeof match !== "boolean") {
18084
18084
  layerError = layerError || match;
@@ -18116,18 +18116,18 @@ var require_router = __commonJS({
18116
18116
  } else if (route) {
18117
18117
  layer.handle_request(req, res, next);
18118
18118
  } else {
18119
- trim_prefix(layer, layerError, layerPath, path4);
18119
+ trim_prefix(layer, layerError, layerPath, path5);
18120
18120
  }
18121
18121
  sync = 0;
18122
18122
  });
18123
18123
  }
18124
- function trim_prefix(layer, layerError, layerPath, path4) {
18124
+ function trim_prefix(layer, layerError, layerPath, path5) {
18125
18125
  if (layerPath.length !== 0) {
18126
- if (layerPath !== path4.slice(0, layerPath.length)) {
18126
+ if (layerPath !== path5.slice(0, layerPath.length)) {
18127
18127
  next(layerError);
18128
18128
  return;
18129
18129
  }
18130
- var c = path4[layerPath.length];
18130
+ var c = path5[layerPath.length];
18131
18131
  if (c && c !== "/" && c !== ".") return next(layerError);
18132
18132
  debug("trim prefix (%s) from url %s", layerPath, req.url);
18133
18133
  removed = layerPath;
@@ -18205,7 +18205,7 @@ var require_router = __commonJS({
18205
18205
  };
18206
18206
  proto.use = function use(fn) {
18207
18207
  var offset = 0;
18208
- var path4 = "/";
18208
+ var path5 = "/";
18209
18209
  if (typeof fn !== "function") {
18210
18210
  var arg = fn;
18211
18211
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -18213,7 +18213,7 @@ var require_router = __commonJS({
18213
18213
  }
18214
18214
  if (typeof arg !== "function") {
18215
18215
  offset = 1;
18216
- path4 = fn;
18216
+ path5 = fn;
18217
18217
  }
18218
18218
  }
18219
18219
  var callbacks = flatten(slice.call(arguments, offset));
@@ -18225,8 +18225,8 @@ var require_router = __commonJS({
18225
18225
  if (typeof fn !== "function") {
18226
18226
  throw new TypeError("Router.use() requires a middleware function but got a " + gettype(fn));
18227
18227
  }
18228
- debug("use %o %s", path4, fn.name || "<anonymous>");
18229
- var layer = new Layer(path4, {
18228
+ debug("use %o %s", path5, fn.name || "<anonymous>");
18229
+ var layer = new Layer(path5, {
18230
18230
  sensitive: this.caseSensitive,
18231
18231
  strict: false,
18232
18232
  end: false
@@ -18236,9 +18236,9 @@ var require_router = __commonJS({
18236
18236
  }
18237
18237
  return this;
18238
18238
  };
18239
- proto.route = function route(path4) {
18240
- var route2 = new Route(path4);
18241
- var layer = new Layer(path4, {
18239
+ proto.route = function route(path5) {
18240
+ var route2 = new Route(path5);
18241
+ var layer = new Layer(path5, {
18242
18242
  sensitive: this.caseSensitive,
18243
18243
  strict: this.strict,
18244
18244
  end: true
@@ -18248,8 +18248,8 @@ var require_router = __commonJS({
18248
18248
  return route2;
18249
18249
  };
18250
18250
  methods.concat("all").forEach(function(method) {
18251
- proto[method] = function(path4) {
18252
- var route = this.route(path4);
18251
+ proto[method] = function(path5) {
18252
+ var route = this.route(path5);
18253
18253
  route[method].apply(route, slice.call(arguments, 1));
18254
18254
  return this;
18255
18255
  };
@@ -18285,9 +18285,9 @@ var require_router = __commonJS({
18285
18285
  }
18286
18286
  return toString.call(obj).replace(objectRegExp, "$1");
18287
18287
  }
18288
- function matchLayer(layer, path4) {
18288
+ function matchLayer(layer, path5) {
18289
18289
  try {
18290
- return layer.match(path4);
18290
+ return layer.match(path5);
18291
18291
  } catch (err) {
18292
18292
  return err;
18293
18293
  }
@@ -18405,13 +18405,13 @@ var require_view = __commonJS({
18405
18405
  "editor/node_modules/.pnpm/express@4.22.1/node_modules/express/lib/view.js"(exports, module) {
18406
18406
  "use strict";
18407
18407
  var debug = require_src()("express:view");
18408
- var path4 = __require("path");
18409
- var fs2 = __require("fs");
18410
- var dirname = path4.dirname;
18411
- var basename = path4.basename;
18412
- var extname = path4.extname;
18413
- var join3 = path4.join;
18414
- var resolve2 = path4.resolve;
18408
+ var path5 = __require("path");
18409
+ var fs3 = __require("fs");
18410
+ var dirname = path5.dirname;
18411
+ var basename = path5.basename;
18412
+ var extname = path5.extname;
18413
+ var join3 = path5.join;
18414
+ var resolve2 = path5.resolve;
18415
18415
  module.exports = View;
18416
18416
  function View(name, options) {
18417
18417
  var opts = options || {};
@@ -18440,17 +18440,17 @@ var require_view = __commonJS({
18440
18440
  this.path = this.lookup(fileName);
18441
18441
  }
18442
18442
  View.prototype.lookup = function lookup(name) {
18443
- var path5;
18443
+ var path6;
18444
18444
  var roots = [].concat(this.root);
18445
18445
  debug('lookup "%s"', name);
18446
- for (var i = 0; i < roots.length && !path5; i++) {
18446
+ for (var i = 0; i < roots.length && !path6; i++) {
18447
18447
  var root = roots[i];
18448
18448
  var loc = resolve2(root, name);
18449
18449
  var dir = dirname(loc);
18450
18450
  var file2 = basename(loc);
18451
- path5 = this.resolve(dir, file2);
18451
+ path6 = this.resolve(dir, file2);
18452
18452
  }
18453
- return path5;
18453
+ return path6;
18454
18454
  };
18455
18455
  View.prototype.render = function render(options, callback) {
18456
18456
  debug('render "%s"', this.path);
@@ -18458,21 +18458,21 @@ var require_view = __commonJS({
18458
18458
  };
18459
18459
  View.prototype.resolve = function resolve3(dir, file2) {
18460
18460
  var ext = this.ext;
18461
- var path5 = join3(dir, file2);
18462
- var stat = tryStat(path5);
18461
+ var path6 = join3(dir, file2);
18462
+ var stat = tryStat(path6);
18463
18463
  if (stat && stat.isFile()) {
18464
- return path5;
18464
+ return path6;
18465
18465
  }
18466
- path5 = join3(dir, basename(file2, ext), "index" + ext);
18467
- stat = tryStat(path5);
18466
+ path6 = join3(dir, basename(file2, ext), "index" + ext);
18467
+ stat = tryStat(path6);
18468
18468
  if (stat && stat.isFile()) {
18469
- return path5;
18469
+ return path6;
18470
18470
  }
18471
18471
  };
18472
- function tryStat(path5) {
18473
- debug('stat "%s"', path5);
18472
+ function tryStat(path6) {
18473
+ debug('stat "%s"', path6);
18474
18474
  try {
18475
- return fs2.statSync(path5);
18475
+ return fs3.statSync(path6);
18476
18476
  } catch (e) {
18477
18477
  return void 0;
18478
18478
  }
@@ -18826,8 +18826,8 @@ var require_types = __commonJS({
18826
18826
  // editor/node_modules/.pnpm/mime@1.6.0/node_modules/mime/mime.js
18827
18827
  var require_mime = __commonJS({
18828
18828
  "editor/node_modules/.pnpm/mime@1.6.0/node_modules/mime/mime.js"(exports, module) {
18829
- var path4 = __require("path");
18830
- var fs2 = __require("fs");
18829
+ var path5 = __require("path");
18830
+ var fs3 = __require("fs");
18831
18831
  function Mime() {
18832
18832
  this.types = /* @__PURE__ */ Object.create(null);
18833
18833
  this.extensions = /* @__PURE__ */ Object.create(null);
@@ -18848,7 +18848,7 @@ var require_mime = __commonJS({
18848
18848
  };
18849
18849
  Mime.prototype.load = function(file2) {
18850
18850
  this._loading = file2;
18851
- var map2 = {}, content = fs2.readFileSync(file2, "ascii"), lines = content.split(/[\r\n]+/);
18851
+ var map2 = {}, content = fs3.readFileSync(file2, "ascii"), lines = content.split(/[\r\n]+/);
18852
18852
  lines.forEach(function(line) {
18853
18853
  var fields = line.replace(/\s*#.*|^\s*|\s*$/g, "").split(/\s+/);
18854
18854
  map2[fields.shift()] = fields;
@@ -18856,8 +18856,8 @@ var require_mime = __commonJS({
18856
18856
  this.define(map2);
18857
18857
  this._loading = null;
18858
18858
  };
18859
- Mime.prototype.lookup = function(path5, fallback) {
18860
- var ext = path5.replace(/^.*[\.\/\\]/, "").toLowerCase();
18859
+ Mime.prototype.lookup = function(path6, fallback) {
18860
+ var ext = path6.replace(/^.*[\.\/\\]/, "").toLowerCase();
18861
18861
  return this.types[ext] || fallback || this.default_type;
18862
18862
  };
18863
18863
  Mime.prototype.extension = function(mimeType) {
@@ -19086,33 +19086,33 @@ var require_send = __commonJS({
19086
19086
  var escapeHtml = require_escape_html();
19087
19087
  var etag = require_etag();
19088
19088
  var fresh = require_fresh();
19089
- var fs2 = __require("fs");
19089
+ var fs3 = __require("fs");
19090
19090
  var mime = require_mime();
19091
19091
  var ms = require_ms2();
19092
19092
  var onFinished = require_on_finished();
19093
19093
  var parseRange = require_range_parser();
19094
- var path4 = __require("path");
19094
+ var path5 = __require("path");
19095
19095
  var statuses = require_statuses();
19096
19096
  var Stream = __require("stream");
19097
19097
  var util = __require("util");
19098
- var extname = path4.extname;
19099
- var join3 = path4.join;
19100
- var normalize = path4.normalize;
19101
- var resolve2 = path4.resolve;
19102
- var sep = path4.sep;
19098
+ var extname = path5.extname;
19099
+ var join3 = path5.join;
19100
+ var normalize = path5.normalize;
19101
+ var resolve2 = path5.resolve;
19102
+ var sep = path5.sep;
19103
19103
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
19104
19104
  var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
19105
19105
  var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
19106
19106
  module.exports = send;
19107
19107
  module.exports.mime = mime;
19108
- function send(req, path5, options) {
19109
- return new SendStream(req, path5, options);
19108
+ function send(req, path6, options) {
19109
+ return new SendStream(req, path6, options);
19110
19110
  }
19111
- function SendStream(req, path5, options) {
19111
+ function SendStream(req, path6, options) {
19112
19112
  Stream.call(this);
19113
19113
  var opts = options || {};
19114
19114
  this.options = opts;
19115
- this.path = path5;
19115
+ this.path = path6;
19116
19116
  this.req = req;
19117
19117
  this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true;
19118
19118
  this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true;
@@ -19158,8 +19158,8 @@ var require_send = __commonJS({
19158
19158
  this._index = index2;
19159
19159
  return this;
19160
19160
  }, "send.index: pass index as option");
19161
- SendStream.prototype.root = function root(path5) {
19162
- this._root = resolve2(String(path5));
19161
+ SendStream.prototype.root = function root(path6) {
19162
+ this._root = resolve2(String(path6));
19163
19163
  debug("root %s", this._root);
19164
19164
  return this;
19165
19165
  };
@@ -19272,10 +19272,10 @@ var require_send = __commonJS({
19272
19272
  var lastModified = this.res.getHeader("Last-Modified");
19273
19273
  return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
19274
19274
  };
19275
- SendStream.prototype.redirect = function redirect(path5) {
19275
+ SendStream.prototype.redirect = function redirect(path6) {
19276
19276
  var res = this.res;
19277
19277
  if (hasListeners(this, "directory")) {
19278
- this.emit("directory", res, path5);
19278
+ this.emit("directory", res, path6);
19279
19279
  return;
19280
19280
  }
19281
19281
  if (this.hasTrailingSlash()) {
@@ -19295,42 +19295,42 @@ var require_send = __commonJS({
19295
19295
  SendStream.prototype.pipe = function pipe2(res) {
19296
19296
  var root = this._root;
19297
19297
  this.res = res;
19298
- var path5 = decode3(this.path);
19299
- if (path5 === -1) {
19298
+ var path6 = decode3(this.path);
19299
+ if (path6 === -1) {
19300
19300
  this.error(400);
19301
19301
  return res;
19302
19302
  }
19303
- if (~path5.indexOf("\0")) {
19303
+ if (~path6.indexOf("\0")) {
19304
19304
  this.error(400);
19305
19305
  return res;
19306
19306
  }
19307
19307
  var parts;
19308
19308
  if (root !== null) {
19309
- if (path5) {
19310
- path5 = normalize("." + sep + path5);
19309
+ if (path6) {
19310
+ path6 = normalize("." + sep + path6);
19311
19311
  }
19312
- if (UP_PATH_REGEXP.test(path5)) {
19313
- debug('malicious path "%s"', path5);
19312
+ if (UP_PATH_REGEXP.test(path6)) {
19313
+ debug('malicious path "%s"', path6);
19314
19314
  this.error(403);
19315
19315
  return res;
19316
19316
  }
19317
- parts = path5.split(sep);
19318
- path5 = normalize(join3(root, path5));
19317
+ parts = path6.split(sep);
19318
+ path6 = normalize(join3(root, path6));
19319
19319
  } else {
19320
- if (UP_PATH_REGEXP.test(path5)) {
19321
- debug('malicious path "%s"', path5);
19320
+ if (UP_PATH_REGEXP.test(path6)) {
19321
+ debug('malicious path "%s"', path6);
19322
19322
  this.error(403);
19323
19323
  return res;
19324
19324
  }
19325
- parts = normalize(path5).split(sep);
19326
- path5 = resolve2(path5);
19325
+ parts = normalize(path6).split(sep);
19326
+ path6 = resolve2(path6);
19327
19327
  }
19328
19328
  if (containsDotFile(parts)) {
19329
19329
  var access = this._dotfiles;
19330
19330
  if (access === void 0) {
19331
19331
  access = parts[parts.length - 1][0] === "." ? this._hidden ? "allow" : "ignore" : "allow";
19332
19332
  }
19333
- debug('%s dotfile "%s"', access, path5);
19333
+ debug('%s dotfile "%s"', access, path6);
19334
19334
  switch (access) {
19335
19335
  case "allow":
19336
19336
  break;
@@ -19344,13 +19344,13 @@ var require_send = __commonJS({
19344
19344
  }
19345
19345
  }
19346
19346
  if (this._index.length && this.hasTrailingSlash()) {
19347
- this.sendIndex(path5);
19347
+ this.sendIndex(path6);
19348
19348
  return res;
19349
19349
  }
19350
- this.sendFile(path5);
19350
+ this.sendFile(path6);
19351
19351
  return res;
19352
19352
  };
19353
- SendStream.prototype.send = function send2(path5, stat) {
19353
+ SendStream.prototype.send = function send2(path6, stat) {
19354
19354
  var len = stat.size;
19355
19355
  var options = this.options;
19356
19356
  var opts = {};
@@ -19362,9 +19362,9 @@ var require_send = __commonJS({
19362
19362
  this.headersAlreadySent();
19363
19363
  return;
19364
19364
  }
19365
- debug('pipe "%s"', path5);
19366
- this.setHeader(path5, stat);
19367
- this.type(path5);
19365
+ debug('pipe "%s"', path6);
19366
+ this.setHeader(path6, stat);
19367
+ this.type(path6);
19368
19368
  if (this.isConditionalGET()) {
19369
19369
  if (this.isPreconditionFailure()) {
19370
19370
  this.error(412);
@@ -19413,28 +19413,28 @@ var require_send = __commonJS({
19413
19413
  res.end();
19414
19414
  return;
19415
19415
  }
19416
- this.stream(path5, opts);
19416
+ this.stream(path6, opts);
19417
19417
  };
19418
- SendStream.prototype.sendFile = function sendFile(path5) {
19418
+ SendStream.prototype.sendFile = function sendFile(path6) {
19419
19419
  var i = 0;
19420
19420
  var self = this;
19421
- debug('stat "%s"', path5);
19422
- fs2.stat(path5, function onstat(err, stat) {
19423
- if (err && err.code === "ENOENT" && !extname(path5) && path5[path5.length - 1] !== sep) {
19421
+ debug('stat "%s"', path6);
19422
+ fs3.stat(path6, function onstat(err, stat) {
19423
+ if (err && err.code === "ENOENT" && !extname(path6) && path6[path6.length - 1] !== sep) {
19424
19424
  return next(err);
19425
19425
  }
19426
19426
  if (err) return self.onStatError(err);
19427
- if (stat.isDirectory()) return self.redirect(path5);
19428
- self.emit("file", path5, stat);
19429
- self.send(path5, stat);
19427
+ if (stat.isDirectory()) return self.redirect(path6);
19428
+ self.emit("file", path6, stat);
19429
+ self.send(path6, stat);
19430
19430
  });
19431
19431
  function next(err) {
19432
19432
  if (self._extensions.length <= i) {
19433
19433
  return err ? self.onStatError(err) : self.error(404);
19434
19434
  }
19435
- var p = path5 + "." + self._extensions[i++];
19435
+ var p = path6 + "." + self._extensions[i++];
19436
19436
  debug('stat "%s"', p);
19437
- fs2.stat(p, function(err2, stat) {
19437
+ fs3.stat(p, function(err2, stat) {
19438
19438
  if (err2) return next(err2);
19439
19439
  if (stat.isDirectory()) return next();
19440
19440
  self.emit("file", p, stat);
@@ -19442,7 +19442,7 @@ var require_send = __commonJS({
19442
19442
  });
19443
19443
  }
19444
19444
  };
19445
- SendStream.prototype.sendIndex = function sendIndex(path5) {
19445
+ SendStream.prototype.sendIndex = function sendIndex(path6) {
19446
19446
  var i = -1;
19447
19447
  var self = this;
19448
19448
  function next(err) {
@@ -19450,9 +19450,9 @@ var require_send = __commonJS({
19450
19450
  if (err) return self.onStatError(err);
19451
19451
  return self.error(404);
19452
19452
  }
19453
- var p = join3(path5, self._index[i]);
19453
+ var p = join3(path6, self._index[i]);
19454
19454
  debug('stat "%s"', p);
19455
- fs2.stat(p, function(err2, stat) {
19455
+ fs3.stat(p, function(err2, stat) {
19456
19456
  if (err2) return next(err2);
19457
19457
  if (stat.isDirectory()) return next();
19458
19458
  self.emit("file", p, stat);
@@ -19461,10 +19461,10 @@ var require_send = __commonJS({
19461
19461
  }
19462
19462
  next();
19463
19463
  };
19464
- SendStream.prototype.stream = function stream(path5, options) {
19464
+ SendStream.prototype.stream = function stream(path6, options) {
19465
19465
  var self = this;
19466
19466
  var res = this.res;
19467
- var stream2 = fs2.createReadStream(path5, options);
19467
+ var stream2 = fs3.createReadStream(path6, options);
19468
19468
  this.emit("stream", stream2);
19469
19469
  stream2.pipe(res);
19470
19470
  function cleanup2() {
@@ -19479,10 +19479,10 @@ var require_send = __commonJS({
19479
19479
  self.emit("end");
19480
19480
  });
19481
19481
  };
19482
- SendStream.prototype.type = function type(path5) {
19482
+ SendStream.prototype.type = function type(path6) {
19483
19483
  var res = this.res;
19484
19484
  if (res.getHeader("Content-Type")) return;
19485
- var type2 = mime.lookup(path5);
19485
+ var type2 = mime.lookup(path6);
19486
19486
  if (!type2) {
19487
19487
  debug("no content-type");
19488
19488
  return;
@@ -19491,9 +19491,9 @@ var require_send = __commonJS({
19491
19491
  debug("content-type %s", type2);
19492
19492
  res.setHeader("Content-Type", type2 + (charset ? "; charset=" + charset : ""));
19493
19493
  };
19494
- SendStream.prototype.setHeader = function setHeader(path5, stat) {
19494
+ SendStream.prototype.setHeader = function setHeader(path6, stat) {
19495
19495
  var res = this.res;
19496
- this.emit("headers", res, path5, stat);
19496
+ this.emit("headers", res, path6, stat);
19497
19497
  if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
19498
19498
  debug("accept ranges");
19499
19499
  res.setHeader("Accept-Ranges", "bytes");
@@ -19552,9 +19552,9 @@ var require_send = __commonJS({
19552
19552
  }
19553
19553
  return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err);
19554
19554
  }
19555
- function decode3(path5) {
19555
+ function decode3(path6) {
19556
19556
  try {
19557
- return decodeURIComponent(path5);
19557
+ return decodeURIComponent(path6);
19558
19558
  } catch (err) {
19559
19559
  return -1;
19560
19560
  }
@@ -20463,10 +20463,10 @@ var require_utils2 = __commonJS({
20463
20463
  var querystring = __require("querystring");
20464
20464
  exports.etag = createETagGenerator({ weak: false });
20465
20465
  exports.wetag = createETagGenerator({ weak: true });
20466
- exports.isAbsolute = function(path4) {
20467
- if ("/" === path4[0]) return true;
20468
- if (":" === path4[1] && ("\\" === path4[2] || "/" === path4[2])) return true;
20469
- if ("\\\\" === path4.substring(0, 2)) return true;
20466
+ exports.isAbsolute = function(path5) {
20467
+ if ("/" === path5[0]) return true;
20468
+ if (":" === path5[1] && ("\\" === path5[2] || "/" === path5[2])) return true;
20469
+ if ("\\\\" === path5.substring(0, 2)) return true;
20470
20470
  };
20471
20471
  exports.flatten = deprecate.function(
20472
20472
  flatten,
@@ -20677,7 +20677,7 @@ var require_application = __commonJS({
20677
20677
  };
20678
20678
  app2.use = function use(fn) {
20679
20679
  var offset = 0;
20680
- var path4 = "/";
20680
+ var path5 = "/";
20681
20681
  if (typeof fn !== "function") {
20682
20682
  var arg = fn;
20683
20683
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -20685,7 +20685,7 @@ var require_application = __commonJS({
20685
20685
  }
20686
20686
  if (typeof arg !== "function") {
20687
20687
  offset = 1;
20688
- path4 = fn;
20688
+ path5 = fn;
20689
20689
  }
20690
20690
  }
20691
20691
  var fns = flatten(slice.call(arguments, offset));
@@ -20696,12 +20696,12 @@ var require_application = __commonJS({
20696
20696
  var router = this._router;
20697
20697
  fns.forEach(function(fn2) {
20698
20698
  if (!fn2 || !fn2.handle || !fn2.set) {
20699
- return router.use(path4, fn2);
20699
+ return router.use(path5, fn2);
20700
20700
  }
20701
- debug(".use app under %s", path4);
20702
- fn2.mountpath = path4;
20701
+ debug(".use app under %s", path5);
20702
+ fn2.mountpath = path5;
20703
20703
  fn2.parent = this;
20704
- router.use(path4, function mounted_app(req, res, next) {
20704
+ router.use(path5, function mounted_app(req, res, next) {
20705
20705
  var orig = req.app;
20706
20706
  fn2.handle(req, res, function(err) {
20707
20707
  setPrototypeOf(req, orig.request);
@@ -20713,9 +20713,9 @@ var require_application = __commonJS({
20713
20713
  }, this);
20714
20714
  return this;
20715
20715
  };
20716
- app2.route = function route(path4) {
20716
+ app2.route = function route(path5) {
20717
20717
  this.lazyrouter();
20718
- return this._router.route(path4);
20718
+ return this._router.route(path5);
20719
20719
  };
20720
20720
  app2.engine = function engine(ext, fn) {
20721
20721
  if (typeof fn !== "function") {
@@ -20766,7 +20766,7 @@ var require_application = __commonJS({
20766
20766
  }
20767
20767
  return this;
20768
20768
  };
20769
- app2.path = function path4() {
20769
+ app2.path = function path5() {
20770
20770
  return this.parent ? this.parent.path() + this.mountpath : "";
20771
20771
  };
20772
20772
  app2.enabled = function enabled(setting) {
@@ -20782,19 +20782,19 @@ var require_application = __commonJS({
20782
20782
  return this.set(setting, false);
20783
20783
  };
20784
20784
  methods.forEach(function(method) {
20785
- app2[method] = function(path4) {
20785
+ app2[method] = function(path5) {
20786
20786
  if (method === "get" && arguments.length === 1) {
20787
- return this.set(path4);
20787
+ return this.set(path5);
20788
20788
  }
20789
20789
  this.lazyrouter();
20790
- var route = this._router.route(path4);
20790
+ var route = this._router.route(path5);
20791
20791
  route[method].apply(route, slice.call(arguments, 1));
20792
20792
  return this;
20793
20793
  };
20794
20794
  });
20795
- app2.all = function all(path4) {
20795
+ app2.all = function all(path5) {
20796
20796
  this.lazyrouter();
20797
- var route = this._router.route(path4);
20797
+ var route = this._router.route(path5);
20798
20798
  var args = slice.call(arguments, 1);
20799
20799
  for (var i = 0; i < methods.length; i++) {
20800
20800
  route[methods[i]].apply(route, args);
@@ -21553,7 +21553,7 @@ var require_request = __commonJS({
21553
21553
  var subdomains2 = !isIP(hostname3) ? hostname3.split(".").reverse() : [hostname3];
21554
21554
  return subdomains2.slice(offset);
21555
21555
  });
21556
- defineGetter(req, "path", function path4() {
21556
+ defineGetter(req, "path", function path5() {
21557
21557
  return parse3(this).pathname;
21558
21558
  });
21559
21559
  defineGetter(req, "hostname", function hostname3() {
@@ -21875,7 +21875,7 @@ var require_response = __commonJS({
21875
21875
  var http = __require("http");
21876
21876
  var isAbsolute = require_utils2().isAbsolute;
21877
21877
  var onFinished = require_on_finished();
21878
- var path4 = __require("path");
21878
+ var path5 = __require("path");
21879
21879
  var statuses = require_statuses();
21880
21880
  var merge2 = require_utils_merge();
21881
21881
  var sign = require_cookie_signature().sign;
@@ -21884,9 +21884,9 @@ var require_response = __commonJS({
21884
21884
  var setCharset = require_utils2().setCharset;
21885
21885
  var cookie = require_cookie();
21886
21886
  var send = require_send();
21887
- var extname = path4.extname;
21887
+ var extname = path5.extname;
21888
21888
  var mime = send.mime;
21889
- var resolve2 = path4.resolve;
21889
+ var resolve2 = path5.resolve;
21890
21890
  var vary = require_vary();
21891
21891
  var res = Object.create(http.ServerResponse.prototype);
21892
21892
  module.exports = res;
@@ -22063,26 +22063,26 @@ var require_response = __commonJS({
22063
22063
  this.type("txt");
22064
22064
  return this.send(body);
22065
22065
  };
22066
- res.sendFile = function sendFile(path5, options, callback) {
22066
+ res.sendFile = function sendFile(path6, options, callback) {
22067
22067
  var done = callback;
22068
22068
  var req = this.req;
22069
22069
  var res2 = this;
22070
22070
  var next = req.next;
22071
22071
  var opts = options || {};
22072
- if (!path5) {
22072
+ if (!path6) {
22073
22073
  throw new TypeError("path argument is required to res.sendFile");
22074
22074
  }
22075
- if (typeof path5 !== "string") {
22075
+ if (typeof path6 !== "string") {
22076
22076
  throw new TypeError("path must be a string to res.sendFile");
22077
22077
  }
22078
22078
  if (typeof options === "function") {
22079
22079
  done = options;
22080
22080
  opts = {};
22081
22081
  }
22082
- if (!opts.root && !isAbsolute(path5)) {
22082
+ if (!opts.root && !isAbsolute(path6)) {
22083
22083
  throw new TypeError("path must be absolute or specify root to res.sendFile");
22084
22084
  }
22085
- var pathname = encodeURI(path5);
22085
+ var pathname = encodeURI(path6);
22086
22086
  var file2 = send(req, pathname, opts);
22087
22087
  sendfile(res2, file2, opts, function(err) {
22088
22088
  if (done) return done(err);
@@ -22092,7 +22092,7 @@ var require_response = __commonJS({
22092
22092
  }
22093
22093
  });
22094
22094
  };
22095
- res.sendfile = function(path5, options, callback) {
22095
+ res.sendfile = function(path6, options, callback) {
22096
22096
  var done = callback;
22097
22097
  var req = this.req;
22098
22098
  var res2 = this;
@@ -22102,7 +22102,7 @@ var require_response = __commonJS({
22102
22102
  done = options;
22103
22103
  opts = {};
22104
22104
  }
22105
- var file2 = send(req, path5, opts);
22105
+ var file2 = send(req, path6, opts);
22106
22106
  sendfile(res2, file2, opts, function(err) {
22107
22107
  if (done) return done(err);
22108
22108
  if (err && err.code === "EISDIR") return next();
@@ -22115,7 +22115,7 @@ var require_response = __commonJS({
22115
22115
  res.sendfile,
22116
22116
  "res.sendfile: Use res.sendFile instead"
22117
22117
  );
22118
- res.download = function download(path5, filename, options, callback) {
22118
+ res.download = function download(path6, filename, options, callback) {
22119
22119
  var done = callback;
22120
22120
  var name = filename;
22121
22121
  var opts = options || null;
@@ -22132,7 +22132,7 @@ var require_response = __commonJS({
22132
22132
  opts = filename;
22133
22133
  }
22134
22134
  var headers = {
22135
- "Content-Disposition": contentDisposition(name || path5)
22135
+ "Content-Disposition": contentDisposition(name || path6)
22136
22136
  };
22137
22137
  if (opts && opts.headers) {
22138
22138
  var keys = Object.keys(opts.headers);
@@ -22145,7 +22145,7 @@ var require_response = __commonJS({
22145
22145
  }
22146
22146
  opts = Object.create(opts);
22147
22147
  opts.headers = headers;
22148
- var fullPath = !opts.root ? resolve2(path5) : path5;
22148
+ var fullPath = !opts.root ? resolve2(path6) : path6;
22149
22149
  return this.sendFile(fullPath, opts, done);
22150
22150
  };
22151
22151
  res.contentType = res.type = function contentType(type) {
@@ -22446,11 +22446,11 @@ var require_serve_static = __commonJS({
22446
22446
  }
22447
22447
  var forwardError = !fallthrough;
22448
22448
  var originalUrl = parseUrl.original(req);
22449
- var path4 = parseUrl(req).pathname;
22450
- if (path4 === "/" && originalUrl.pathname.substr(-1) !== "/") {
22451
- path4 = "";
22449
+ var path5 = parseUrl(req).pathname;
22450
+ if (path5 === "/" && originalUrl.pathname.substr(-1) !== "/") {
22451
+ path5 = "";
22452
22452
  }
22453
- var stream = send(req, path4, opts);
22453
+ var stream = send(req, path5, opts);
22454
22454
  stream.on("directory", onDirectory);
22455
22455
  if (setHeaders) {
22456
22456
  stream.on("headers", setHeaders);
@@ -26057,8 +26057,8 @@ var require_utils3 = __commonJS({
26057
26057
  }
26058
26058
  return ind;
26059
26059
  }
26060
- function removeDotSegments(path4) {
26061
- let input = path4;
26060
+ function removeDotSegments(path5) {
26061
+ let input = path5;
26062
26062
  const output = [];
26063
26063
  let nextSlash = -1;
26064
26064
  let len = 0;
@@ -26257,8 +26257,8 @@ var require_schemes = __commonJS({
26257
26257
  wsComponent.secure = void 0;
26258
26258
  }
26259
26259
  if (wsComponent.resourceName) {
26260
- const [path4, query] = wsComponent.resourceName.split("?");
26261
- wsComponent.path = path4 && path4 !== "/" ? path4 : void 0;
26260
+ const [path5, query] = wsComponent.resourceName.split("?");
26261
+ wsComponent.path = path5 && path5 !== "/" ? path5 : void 0;
26262
26262
  wsComponent.query = query;
26263
26263
  wsComponent.resourceName = void 0;
26264
26264
  }
@@ -29319,7 +29319,7 @@ var require_ajv = __commonJS({
29319
29319
  // editor/server/index.ts
29320
29320
  var import_express = __toESM(require_express2(), 1);
29321
29321
  var import_cors = __toESM(require_lib3(), 1);
29322
- import path3 from "path";
29322
+ import path4 from "path";
29323
29323
  import { fileURLToPath } from "url";
29324
29324
  import { Firestore } from "@google-cloud/firestore";
29325
29325
 
@@ -30325,23 +30325,23 @@ function matchScopeAny(scopePath, patterns) {
30325
30325
  if (!patterns || patterns.length === 0) return true;
30326
30326
  return patterns.some((p) => matchScope(scopePath, p));
30327
30327
  }
30328
- function matchSegments(path4, pi, pattern, qi) {
30329
- if (pi === path4.length && qi === pattern.length) return true;
30328
+ function matchSegments(path5, pi, pattern, qi) {
30329
+ if (pi === path5.length && qi === pattern.length) return true;
30330
30330
  if (qi === pattern.length) return false;
30331
30331
  const seg = pattern[qi];
30332
30332
  if (seg === "**") {
30333
30333
  if (qi === pattern.length - 1) return true;
30334
- for (let skip = 0; skip <= path4.length - pi; skip++) {
30335
- if (matchSegments(path4, pi + skip, pattern, qi + 1)) return true;
30334
+ for (let skip = 0; skip <= path5.length - pi; skip++) {
30335
+ if (matchSegments(path5, pi + skip, pattern, qi + 1)) return true;
30336
30336
  }
30337
30337
  return false;
30338
30338
  }
30339
- if (pi === path4.length) return false;
30339
+ if (pi === path5.length) return false;
30340
30340
  if (seg === "*") {
30341
- return matchSegments(path4, pi + 1, pattern, qi + 1);
30341
+ return matchSegments(path5, pi + 1, pattern, qi + 1);
30342
30342
  }
30343
- if (path4[pi] === seg) {
30344
- return matchSegments(path4, pi + 1, pattern, qi + 1);
30343
+ if (path5[pi] === seg) {
30344
+ return matchSegments(path5, pi + 1, pattern, qi + 1);
30345
30345
  }
30346
30346
  return false;
30347
30347
  }
@@ -31686,7 +31686,9 @@ function introspectRegistry(registry2, dynamicNames) {
31686
31686
  hasDataSchema: !!entry.jsonSchema,
31687
31687
  fields,
31688
31688
  isNodeEntry: isNode,
31689
- isDynamic
31689
+ isDynamic,
31690
+ targetGraph: entry.targetGraph,
31691
+ allowedIn: entry.allowedIn
31690
31692
  };
31691
31693
  if (meta3.isNodeEntry) {
31692
31694
  nodeTypes.push(meta3);
@@ -31767,6 +31769,7 @@ function resilientView(ViewClass, tagName) {
31767
31769
  export function defineViews(input) {
31768
31770
  const nodes = {};
31769
31771
  const edges = {};
31772
+ const collections = {};
31770
31773
  const registry = (typeof customElements !== 'undefined' && typeof customElements.define === 'function')
31771
31774
  ? customElements : null;
31772
31775
 
@@ -31790,7 +31793,17 @@ export function defineViews(input) {
31790
31793
  edges[axbType] = { views: viewMetas, sampleData: config.sampleData };
31791
31794
  }
31792
31795
 
31793
- return { nodes, edges };
31796
+ for (const [colName, config] of Object.entries(input.collections ?? {})) {
31797
+ const viewMetas = [];
31798
+ for (const ViewClass of config.views) {
31799
+ const tagName = 'fg-col-' + sanitizeTagPart(colName) + '-' + sanitizeTagPart(ViewClass.viewName);
31800
+ viewMetas.push({ tagName, viewName: ViewClass.viewName, description: ViewClass.description });
31801
+ if (registry && !registry.get(tagName)) registry.define(tagName, resilientView(ViewClass, tagName));
31802
+ }
31803
+ collections[colName] = { views: viewMetas, sampleData: config.sampleData };
31804
+ }
31805
+
31806
+ return { nodes, edges, collections };
31794
31807
  }
31795
31808
  `;
31796
31809
  var REACT_ADAPTER_SHIM = `
@@ -31882,9 +31895,10 @@ async function loadSveltePlugin() {
31882
31895
  return null;
31883
31896
  }
31884
31897
  }
31885
- async function bundleEntityViews(discovery) {
31898
+ async function bundleEntityViews(discovery, collectionViewPaths) {
31886
31899
  const nodeViews = [];
31887
31900
  const edgeViews = [];
31901
+ const colViews = collectionViewPaths ?? [];
31888
31902
  for (const [name, entity] of discovery.nodes) {
31889
31903
  if (entity.viewsPath) {
31890
31904
  nodeViews.push({ name, absPath: path.resolve(entity.viewsPath) });
@@ -31895,10 +31909,11 @@ async function bundleEntityViews(discovery) {
31895
31909
  edgeViews.push({ name, absPath: path.resolve(entity.viewsPath) });
31896
31910
  }
31897
31911
  }
31898
- if (nodeViews.length === 0 && edgeViews.length === 0) return null;
31912
+ if (nodeViews.length === 0 && edgeViews.length === 0 && colViews.length === 0) return null;
31899
31913
  const imports = [];
31900
31914
  const nodeEntries = [];
31901
31915
  const edgeEntries = [];
31916
+ const colEntries = [];
31902
31917
  nodeViews.forEach(({ name, absPath }, i) => {
31903
31918
  const varName = `nodeViews_${i}`;
31904
31919
  imports.push(`import ${varName} from '${absPath.replace(/\\/g, "/")}';`);
@@ -31909,6 +31924,11 @@ async function bundleEntityViews(discovery) {
31909
31924
  imports.push(`import ${varName} from '${absPath.replace(/\\/g, "/")}';`);
31910
31925
  edgeEntries.push(` '${name}': { views: Array.isArray(${varName}) ? ${varName} : ${varName}.default || [] }`);
31911
31926
  });
31927
+ colViews.forEach(({ name, absPath }, i) => {
31928
+ const varName = `colViews_${i}`;
31929
+ imports.push(`import ${varName} from '${absPath.replace(/\\/g, "/")}';`);
31930
+ colEntries.push(` '${name}': { views: Array.isArray(${varName}) ? ${varName} : ${varName}.default || [] }`);
31931
+ });
31912
31932
  const syntheticEntry = `
31913
31933
  ${imports.join("\n")}
31914
31934
  import { defineViews } from 'firegraph';
@@ -31919,6 +31939,9 @@ ${nodeEntries.join(",\n")}
31919
31939
  },
31920
31940
  edges: {
31921
31941
  ${edgeEntries.join(",\n")}
31942
+ },
31943
+ collections: {
31944
+ ${colEntries.join(",\n")}
31922
31945
  }
31923
31946
  });
31924
31947
  `;
@@ -32219,6 +32242,113 @@ function mergeViewDefaults(discovery, configDefaults) {
32219
32242
  return { nodes, edges };
32220
32243
  }
32221
32244
 
32245
+ // editor/server/collections-loader.ts
32246
+ import path3 from "path";
32247
+ import fs2 from "fs";
32248
+ function extractPathParams(pathTemplate) {
32249
+ const params = [];
32250
+ const re = /\{([^}]+)\}/g;
32251
+ let m;
32252
+ while ((m = re.exec(pathTemplate)) !== null) {
32253
+ params.push(m[1]);
32254
+ }
32255
+ return params;
32256
+ }
32257
+ function discoverCollections(entitiesDir) {
32258
+ const collectionsDir = path3.join(entitiesDir, "collections");
32259
+ if (!fs2.existsSync(collectionsDir)) return [];
32260
+ let entries;
32261
+ try {
32262
+ entries = fs2.readdirSync(collectionsDir, { withFileTypes: true });
32263
+ } catch {
32264
+ return [];
32265
+ }
32266
+ const results = [];
32267
+ for (const entry of entries) {
32268
+ if (!entry.isDirectory()) continue;
32269
+ const name = entry.name;
32270
+ const dir = path3.join(collectionsDir, name);
32271
+ const collectionJsonPath = path3.join(dir, "collection.json");
32272
+ if (!fs2.existsSync(collectionJsonPath)) continue;
32273
+ let collectionJson;
32274
+ try {
32275
+ const raw = fs2.readFileSync(collectionJsonPath, "utf-8");
32276
+ collectionJson = JSON.parse(raw);
32277
+ } catch (err) {
32278
+ console.warn(`[firegraph] Skipping collection "${name}": invalid collection.json \u2014 ${err.message}`);
32279
+ continue;
32280
+ }
32281
+ if (!collectionJson.path || typeof collectionJson.path !== "string") continue;
32282
+ let fields = [];
32283
+ let hasSchema = false;
32284
+ const schemaJsonPath = path3.join(dir, "schema.json");
32285
+ if (fs2.existsSync(schemaJsonPath)) {
32286
+ try {
32287
+ const raw = fs2.readFileSync(schemaJsonPath, "utf-8");
32288
+ const schema = JSON.parse(raw);
32289
+ fields = jsonSchemaToFieldMeta(schema);
32290
+ hasSchema = true;
32291
+ } catch {
32292
+ }
32293
+ }
32294
+ const pathParams = extractPathParams(collectionJson.path);
32295
+ const defaultOrderBy = collectionJson.orderBy ? {
32296
+ field: collectionJson.orderBy.field,
32297
+ direction: collectionJson.orderBy.direction ?? "asc"
32298
+ } : void 0;
32299
+ let viewsPath;
32300
+ for (const ext of ["ts", "js", "mts", "mjs"]) {
32301
+ const candidate = path3.join(dir, `views.${ext}`);
32302
+ if (fs2.existsSync(candidate)) {
32303
+ viewsPath = candidate;
32304
+ break;
32305
+ }
32306
+ }
32307
+ let sampleData;
32308
+ const sampleJsonPath = path3.join(dir, "sample.json");
32309
+ if (fs2.existsSync(sampleJsonPath)) {
32310
+ try {
32311
+ sampleData = JSON.parse(fs2.readFileSync(sampleJsonPath, "utf-8"));
32312
+ } catch {
32313
+ }
32314
+ }
32315
+ results.push({
32316
+ name,
32317
+ path: collectionJson.path,
32318
+ description: collectionJson.description,
32319
+ typeField: collectionJson.typeField,
32320
+ typeValue: collectionJson.typeValue,
32321
+ parentNodeType: collectionJson.parentNodeType,
32322
+ fields,
32323
+ hasSchema,
32324
+ pathParams,
32325
+ defaultOrderBy,
32326
+ viewsPath,
32327
+ sampleData
32328
+ });
32329
+ }
32330
+ return results;
32331
+ }
32332
+ async function buildCollectionViewRegistry(collections) {
32333
+ const result = {};
32334
+ for (const col of collections) {
32335
+ if (!col.viewsPath) continue;
32336
+ try {
32337
+ const viewClasses = await loadViewClasses(col.viewsPath);
32338
+ if (viewClasses.length === 0) continue;
32339
+ const views = viewClasses.map((vc) => ({
32340
+ tagName: `fg-col-${sanitizeTagPart(col.name)}-${sanitizeTagPart(vc.viewName)}`,
32341
+ viewName: vc.viewName,
32342
+ description: vc.description
32343
+ }));
32344
+ result[col.name] = { views, sampleData: col.sampleData };
32345
+ } catch (err) {
32346
+ console.warn(`[firegraph] Failed to load views for collection "${col.name}": ${err.message}`);
32347
+ }
32348
+ }
32349
+ return result;
32350
+ }
32351
+
32222
32352
  // editor/node_modules/.pnpm/@trpc+server@11.10.0_typescript@5.9.3/node_modules/@trpc/server/dist/codes-DagpWZLc.mjs
32223
32353
  function mergeWithoutOverrides(obj1, ...objs) {
32224
32354
  const newObj = Object.assign(emptyObject(), obj1);
@@ -32339,27 +32469,27 @@ var noop = () => {
32339
32469
  var freezeIfAvailable = (obj) => {
32340
32470
  if (Object.freeze) Object.freeze(obj);
32341
32471
  };
32342
- function createInnerProxy(callback, path4, memo2) {
32472
+ function createInnerProxy(callback, path5, memo2) {
32343
32473
  var _memo$cacheKey;
32344
- const cacheKey = path4.join(".");
32474
+ const cacheKey = path5.join(".");
32345
32475
  (_memo$cacheKey = memo2[cacheKey]) !== null && _memo$cacheKey !== void 0 || (memo2[cacheKey] = new Proxy(noop, {
32346
32476
  get(_obj, key) {
32347
32477
  if (typeof key !== "string" || key === "then") return void 0;
32348
- return createInnerProxy(callback, [...path4, key], memo2);
32478
+ return createInnerProxy(callback, [...path5, key], memo2);
32349
32479
  },
32350
32480
  apply(_1, _2, args) {
32351
- const lastOfPath = path4[path4.length - 1];
32481
+ const lastOfPath = path5[path5.length - 1];
32352
32482
  let opts = {
32353
32483
  args,
32354
- path: path4
32484
+ path: path5
32355
32485
  };
32356
32486
  if (lastOfPath === "call") opts = {
32357
32487
  args: args.length >= 2 ? [args[1]] : [],
32358
- path: path4.slice(0, -1)
32488
+ path: path5.slice(0, -1)
32359
32489
  };
32360
32490
  else if (lastOfPath === "apply") opts = {
32361
32491
  args: args.length >= 2 ? args[1] : [],
32362
- path: path4.slice(0, -1)
32492
+ path: path5.slice(0, -1)
32363
32493
  };
32364
32494
  freezeIfAvailable(opts.args);
32365
32495
  freezeIfAvailable(opts.path);
@@ -32487,7 +32617,7 @@ var require_objectSpread2 = __commonJS2({ "../../node_modules/.pnpm/@oxc-project
32487
32617
  } });
32488
32618
  var import_objectSpread2 = __toESM2(require_objectSpread2(), 1);
32489
32619
  function getErrorShape(opts) {
32490
- const { path: path4, error: error48, config: config2 } = opts;
32620
+ const { path: path5, error: error48, config: config2 } = opts;
32491
32621
  const { code } = opts.error;
32492
32622
  const shape = {
32493
32623
  message: error48.message,
@@ -32498,7 +32628,7 @@ function getErrorShape(opts) {
32498
32628
  }
32499
32629
  };
32500
32630
  if (config2.isDev && typeof opts.error.stack === "string") shape.data.stack = opts.error.stack;
32501
- if (typeof path4 === "string") shape.data.path = path4;
32631
+ if (typeof path5 === "string") shape.data.path = path5;
32502
32632
  return config2.errorFormatter((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { shape }));
32503
32633
  }
32504
32634
 
@@ -32624,12 +32754,12 @@ function createRouterFactory(config2) {
32624
32754
  })
32625
32755
  };
32626
32756
  }
32627
- function step(from, path4 = []) {
32757
+ function step(from, path5 = []) {
32628
32758
  const aggregate = emptyObject();
32629
32759
  for (const [key, item] of Object.entries(from !== null && from !== void 0 ? from : {})) {
32630
32760
  if (isLazy(item)) {
32631
- lazy$1[[...path4, key].join(".")] = createLazyLoader({
32632
- path: path4,
32761
+ lazy$1[[...path5, key].join(".")] = createLazyLoader({
32762
+ path: path5,
32633
32763
  ref: item,
32634
32764
  key,
32635
32765
  aggregate
@@ -32637,14 +32767,14 @@ function createRouterFactory(config2) {
32637
32767
  continue;
32638
32768
  }
32639
32769
  if (isRouter(item)) {
32640
- aggregate[key] = step(item._def.record, [...path4, key]);
32770
+ aggregate[key] = step(item._def.record, [...path5, key]);
32641
32771
  continue;
32642
32772
  }
32643
32773
  if (!isProcedure(item)) {
32644
- aggregate[key] = step(item, [...path4, key]);
32774
+ aggregate[key] = step(item, [...path5, key]);
32645
32775
  continue;
32646
32776
  }
32647
- const newPath = [...path4, key].join(".");
32777
+ const newPath = [...path5, key].join(".");
32648
32778
  if (procedures[newPath]) throw new Error(`Duplicate key: ${newPath}`);
32649
32779
  procedures[newPath] = item;
32650
32780
  aggregate[key] = item;
@@ -32669,15 +32799,15 @@ function createRouterFactory(config2) {
32669
32799
  function isProcedure(procedureOrRouter) {
32670
32800
  return typeof procedureOrRouter === "function";
32671
32801
  }
32672
- async function getProcedureAtPath(router, path4) {
32802
+ async function getProcedureAtPath(router, path5) {
32673
32803
  const { _def } = router;
32674
- let procedure = _def.procedures[path4];
32804
+ let procedure = _def.procedures[path5];
32675
32805
  while (!procedure) {
32676
- const key = Object.keys(_def.lazy).find((key$1) => path4.startsWith(key$1));
32806
+ const key = Object.keys(_def.lazy).find((key$1) => path5.startsWith(key$1));
32677
32807
  if (!key) return null;
32678
32808
  const lazyRouter = _def.lazy[key];
32679
32809
  await lazyRouter.load();
32680
- procedure = _def.procedures[path4];
32810
+ procedure = _def.procedures[path5];
32681
32811
  }
32682
32812
  return procedure;
32683
32813
  }
@@ -32686,15 +32816,15 @@ function createCallerFactory() {
32686
32816
  const { _def } = router;
32687
32817
  return function createCaller(ctxOrCallback, opts) {
32688
32818
  return createRecursiveProxy(async (innerOpts) => {
32689
- const { path: path4, args } = innerOpts;
32690
- const fullPath = path4.join(".");
32691
- if (path4.length === 1 && path4[0] === "_def") return _def;
32819
+ const { path: path5, args } = innerOpts;
32820
+ const fullPath = path5.join(".");
32821
+ if (path5.length === 1 && path5[0] === "_def") return _def;
32692
32822
  const procedure = await getProcedureAtPath(router, fullPath);
32693
32823
  let ctx = void 0;
32694
32824
  try {
32695
32825
  if (!procedure) throw new TRPCError({
32696
32826
  code: "NOT_FOUND",
32697
- message: `No procedure found on path "${path4}"`
32827
+ message: `No procedure found on path "${path5}"`
32698
32828
  });
32699
32829
  ctx = isFunction(ctxOrCallback) ? await Promise.resolve(ctxOrCallback()) : ctxOrCallback;
32700
32830
  return await procedure({
@@ -32910,11 +33040,11 @@ var jsonContentTypeHandler = {
32910
33040
  }
32911
33041
  return acc;
32912
33042
  });
32913
- const calls = await Promise.all(paths.map(async (path4, index) => {
32914
- const procedure = await getProcedureAtPath(opts.router, path4);
33043
+ const calls = await Promise.all(paths.map(async (path5, index) => {
33044
+ const procedure = await getProcedureAtPath(opts.router, path5);
32915
33045
  return {
32916
33046
  batchIndex: index,
32917
- path: path4,
33047
+ path: path5,
32918
33048
  procedure,
32919
33049
  getRawInput: async () => {
32920
33050
  const inputs = await getInputs.read();
@@ -33722,9 +33852,9 @@ function isPromise(value) {
33722
33852
  return (isObject(value) || isFunction(value)) && typeof (value === null || value === void 0 ? void 0 : value["then"]) === "function" && typeof (value === null || value === void 0 ? void 0 : value["catch"]) === "function";
33723
33853
  }
33724
33854
  var MaxDepthError = class extends Error {
33725
- constructor(path4) {
33726
- super("Max depth reached at path: " + path4.join("."));
33727
- this.path = path4;
33855
+ constructor(path5) {
33856
+ super("Max depth reached at path: " + path5.join("."));
33857
+ this.path = path5;
33728
33858
  }
33729
33859
  };
33730
33860
  function createBatchStreamProducer(_x3) {
@@ -33742,16 +33872,16 @@ function _createBatchStreamProducer() {
33742
33872
  mergedIterables.add(iterable$1);
33743
33873
  return idx;
33744
33874
  }
33745
- function encodePromise(promise2, path4) {
33875
+ function encodePromise(promise2, path5) {
33746
33876
  return registerAsync(/* @__PURE__ */ function() {
33747
33877
  var _ref = (0, import_wrapAsyncGenerator$2.default)(function* (idx) {
33748
- const error48 = checkMaxDepth(path4);
33878
+ const error48 = checkMaxDepth(path5);
33749
33879
  if (error48) {
33750
33880
  promise2.catch((cause) => {
33751
33881
  var _opts$onError;
33752
33882
  (_opts$onError = opts.onError) === null || _opts$onError === void 0 || _opts$onError.call(opts, {
33753
33883
  error: cause,
33754
- path: path4
33884
+ path: path5
33755
33885
  });
33756
33886
  });
33757
33887
  promise2 = Promise.reject(error48);
@@ -33761,20 +33891,20 @@ function _createBatchStreamProducer() {
33761
33891
  yield [
33762
33892
  idx,
33763
33893
  PROMISE_STATUS_FULFILLED,
33764
- encode3(next, path4)
33894
+ encode3(next, path5)
33765
33895
  ];
33766
33896
  } catch (cause) {
33767
33897
  var _opts$onError2, _opts$formatError;
33768
33898
  (_opts$onError2 = opts.onError) === null || _opts$onError2 === void 0 || _opts$onError2.call(opts, {
33769
33899
  error: cause,
33770
- path: path4
33900
+ path: path5
33771
33901
  });
33772
33902
  yield [
33773
33903
  idx,
33774
33904
  PROMISE_STATUS_REJECTED,
33775
33905
  (_opts$formatError = opts.formatError) === null || _opts$formatError === void 0 ? void 0 : _opts$formatError.call(opts, {
33776
33906
  error: cause,
33777
- path: path4
33907
+ path: path5
33778
33908
  })
33779
33909
  ];
33780
33910
  }
@@ -33784,12 +33914,12 @@ function _createBatchStreamProducer() {
33784
33914
  };
33785
33915
  }());
33786
33916
  }
33787
- function encodeAsyncIterable(iterable$1, path4) {
33917
+ function encodeAsyncIterable(iterable$1, path5) {
33788
33918
  return registerAsync(/* @__PURE__ */ function() {
33789
33919
  var _ref2 = (0, import_wrapAsyncGenerator$2.default)(function* (idx) {
33790
33920
  try {
33791
33921
  var _usingCtx$1 = (0, import_usingCtx$1.default)();
33792
- const error48 = checkMaxDepth(path4);
33922
+ const error48 = checkMaxDepth(path5);
33793
33923
  if (error48) throw error48;
33794
33924
  const iterator = _usingCtx$1.a(iteratorResource(iterable$1));
33795
33925
  try {
@@ -33799,28 +33929,28 @@ function _createBatchStreamProducer() {
33799
33929
  yield [
33800
33930
  idx,
33801
33931
  ASYNC_ITERABLE_STATUS_RETURN,
33802
- encode3(next.value, path4)
33932
+ encode3(next.value, path5)
33803
33933
  ];
33804
33934
  break;
33805
33935
  }
33806
33936
  yield [
33807
33937
  idx,
33808
33938
  ASYNC_ITERABLE_STATUS_YIELD,
33809
- encode3(next.value, path4)
33939
+ encode3(next.value, path5)
33810
33940
  ];
33811
33941
  }
33812
33942
  } catch (cause) {
33813
33943
  var _opts$onError3, _opts$formatError2;
33814
33944
  (_opts$onError3 = opts.onError) === null || _opts$onError3 === void 0 || _opts$onError3.call(opts, {
33815
33945
  error: cause,
33816
- path: path4
33946
+ path: path5
33817
33947
  });
33818
33948
  yield [
33819
33949
  idx,
33820
33950
  ASYNC_ITERABLE_STATUS_ERROR,
33821
33951
  (_opts$formatError2 = opts.formatError) === null || _opts$formatError2 === void 0 ? void 0 : _opts$formatError2.call(opts, {
33822
33952
  error: cause,
33823
- path: path4
33953
+ path: path5
33824
33954
  })
33825
33955
  ];
33826
33956
  }
@@ -33835,27 +33965,27 @@ function _createBatchStreamProducer() {
33835
33965
  };
33836
33966
  }());
33837
33967
  }
33838
- function checkMaxDepth(path4) {
33839
- if (opts.maxDepth && path4.length > opts.maxDepth) return new MaxDepthError(path4);
33968
+ function checkMaxDepth(path5) {
33969
+ if (opts.maxDepth && path5.length > opts.maxDepth) return new MaxDepthError(path5);
33840
33970
  return null;
33841
33971
  }
33842
- function encodeAsync3(value, path4) {
33843
- if (isPromise(value)) return [CHUNK_VALUE_TYPE_PROMISE, encodePromise(value, path4)];
33972
+ function encodeAsync3(value, path5) {
33973
+ if (isPromise(value)) return [CHUNK_VALUE_TYPE_PROMISE, encodePromise(value, path5)];
33844
33974
  if (isAsyncIterable(value)) {
33845
- if (opts.maxDepth && path4.length >= opts.maxDepth) throw new Error("Max depth reached");
33846
- return [CHUNK_VALUE_TYPE_ASYNC_ITERABLE, encodeAsyncIterable(value, path4)];
33975
+ if (opts.maxDepth && path5.length >= opts.maxDepth) throw new Error("Max depth reached");
33976
+ return [CHUNK_VALUE_TYPE_ASYNC_ITERABLE, encodeAsyncIterable(value, path5)];
33847
33977
  }
33848
33978
  return null;
33849
33979
  }
33850
- function encode3(value, path4) {
33980
+ function encode3(value, path5) {
33851
33981
  if (value === void 0) return [[]];
33852
- const reg = encodeAsync3(value, path4);
33982
+ const reg = encodeAsync3(value, path5);
33853
33983
  if (reg) return [[placeholder], [null, ...reg]];
33854
33984
  if (!isPlainObject(value)) return [[value]];
33855
33985
  const newObj = emptyObject();
33856
33986
  const asyncValues = [];
33857
33987
  for (const [key, item] of Object.entries(value)) {
33858
- const transformed = encodeAsync3(item, [...path4, key]);
33988
+ const transformed = encodeAsync3(item, [...path5, key]);
33859
33989
  if (!transformed) {
33860
33990
  newObj[key] = item;
33861
33991
  continue;
@@ -34295,11 +34425,11 @@ async function resolveResponse(opts) {
34295
34425
  var _call$procedure$_def$2, _call$procedure3, _opts$onError2;
34296
34426
  const error$1 = getTRPCErrorFromUnknown(errorOpts.error);
34297
34427
  const input = call === null || call === void 0 ? void 0 : call.result();
34298
- const path4 = call === null || call === void 0 ? void 0 : call.path;
34428
+ const path5 = call === null || call === void 0 ? void 0 : call.path;
34299
34429
  const type = (_call$procedure$_def$2 = call === null || call === void 0 || (_call$procedure3 = call.procedure) === null || _call$procedure3 === void 0 ? void 0 : _call$procedure3._def.type) !== null && _call$procedure$_def$2 !== void 0 ? _call$procedure$_def$2 : "unknown";
34300
34430
  (_opts$onError2 = opts.onError) === null || _opts$onError2 === void 0 || _opts$onError2.call(opts, {
34301
34431
  error: error$1,
34302
- path: path4,
34432
+ path: path5,
34303
34433
  input,
34304
34434
  ctx: ctxManager.valueOrUndefined(),
34305
34435
  req: opts.req,
@@ -34310,7 +34440,7 @@ async function resolveResponse(opts) {
34310
34440
  ctx: ctxManager.valueOrUndefined(),
34311
34441
  error: error$1,
34312
34442
  input,
34313
- path: path4,
34443
+ path: path5,
34314
34444
  type
34315
34445
  });
34316
34446
  return shape;
@@ -34379,14 +34509,14 @@ async function resolveResponse(opts) {
34379
34509
  const call = info === null || info === void 0 ? void 0 : info.calls[errorOpts.path[0]];
34380
34510
  const error48 = getTRPCErrorFromUnknown(errorOpts.error);
34381
34511
  const input = call === null || call === void 0 ? void 0 : call.result();
34382
- const path4 = call === null || call === void 0 ? void 0 : call.path;
34512
+ const path5 = call === null || call === void 0 ? void 0 : call.path;
34383
34513
  const type = (_call$procedure$_def$3 = call === null || call === void 0 || (_call$procedure4 = call.procedure) === null || _call$procedure4 === void 0 ? void 0 : _call$procedure4._def.type) !== null && _call$procedure$_def$3 !== void 0 ? _call$procedure$_def$3 : "unknown";
34384
34514
  const shape = getErrorShape({
34385
34515
  config: config2,
34386
34516
  ctx: ctxManager.valueOrUndefined(),
34387
34517
  error: error48,
34388
34518
  input,
34389
- path: path4,
34519
+ path: path5,
34390
34520
  type
34391
34521
  });
34392
34522
  return shape;
@@ -34965,24 +35095,24 @@ async function nodeHTTPRequestHandler(opts) {
34965
35095
  var import_objectSpread26 = __toESM2(require_objectSpread2(), 1);
34966
35096
  function createExpressMiddleware(opts) {
34967
35097
  return (req, res) => {
34968
- let path4 = "";
35098
+ let path5 = "";
34969
35099
  run(async () => {
34970
- path4 = req.path.slice(req.path.lastIndexOf("/") + 1);
35100
+ path5 = req.path.slice(req.path.lastIndexOf("/") + 1);
34971
35101
  await nodeHTTPRequestHandler((0, import_objectSpread26.default)((0, import_objectSpread26.default)({}, opts), {}, {
34972
35102
  req,
34973
35103
  res,
34974
- path: path4
35104
+ path: path5
34975
35105
  }));
34976
35106
  }).catch(internal_exceptionHandler((0, import_objectSpread26.default)({
34977
35107
  req,
34978
35108
  res,
34979
- path: path4
35109
+ path: path5
34980
35110
  }, opts)));
34981
35111
  };
34982
35112
  }
34983
35113
 
34984
35114
  // editor/server/trpc.ts
34985
- import { Timestamp as Timestamp2 } from "@google-cloud/firestore";
35115
+ import { Timestamp as Timestamp2, FieldPath } from "@google-cloud/firestore";
34986
35116
 
34987
35117
  // editor/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js
34988
35118
  var external_exports = {};
@@ -35751,10 +35881,10 @@ function mergeDefs(...defs) {
35751
35881
  function cloneDef(schema) {
35752
35882
  return mergeDefs(schema._zod.def);
35753
35883
  }
35754
- function getElementAtPath(obj, path4) {
35755
- if (!path4)
35884
+ function getElementAtPath(obj, path5) {
35885
+ if (!path5)
35756
35886
  return obj;
35757
- return path4.reduce((acc, key) => acc?.[key], obj);
35887
+ return path5.reduce((acc, key) => acc?.[key], obj);
35758
35888
  }
35759
35889
  function promiseAllObject(promisesObj) {
35760
35890
  const keys = Object.keys(promisesObj);
@@ -36137,11 +36267,11 @@ function aborted(x, startIndex = 0) {
36137
36267
  }
36138
36268
  return false;
36139
36269
  }
36140
- function prefixIssues(path4, issues) {
36270
+ function prefixIssues(path5, issues) {
36141
36271
  return issues.map((iss) => {
36142
36272
  var _a2;
36143
36273
  (_a2 = iss).path ?? (_a2.path = []);
36144
- iss.path.unshift(path4);
36274
+ iss.path.unshift(path5);
36145
36275
  return iss;
36146
36276
  });
36147
36277
  }
@@ -36324,7 +36454,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
36324
36454
  }
36325
36455
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
36326
36456
  const result = { errors: [] };
36327
- const processError = (error49, path4 = []) => {
36457
+ const processError = (error49, path5 = []) => {
36328
36458
  var _a2, _b;
36329
36459
  for (const issue2 of error49.issues) {
36330
36460
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -36334,7 +36464,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
36334
36464
  } else if (issue2.code === "invalid_element") {
36335
36465
  processError({ issues: issue2.issues }, issue2.path);
36336
36466
  } else {
36337
- const fullpath = [...path4, ...issue2.path];
36467
+ const fullpath = [...path5, ...issue2.path];
36338
36468
  if (fullpath.length === 0) {
36339
36469
  result.errors.push(mapper(issue2));
36340
36470
  continue;
@@ -36366,8 +36496,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
36366
36496
  }
36367
36497
  function toDotPath(_path) {
36368
36498
  const segs = [];
36369
- const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
36370
- for (const seg of path4) {
36499
+ const path5 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
36500
+ for (const seg of path5) {
36371
36501
  if (typeof seg === "number")
36372
36502
  segs.push(`[${seg}]`);
36373
36503
  else if (typeof seg === "symbol")
@@ -48344,13 +48474,13 @@ function resolveRef(ref, ctx) {
48344
48474
  if (!ref.startsWith("#")) {
48345
48475
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
48346
48476
  }
48347
- const path4 = ref.slice(1).split("/").filter(Boolean);
48348
- if (path4.length === 0) {
48477
+ const path5 = ref.slice(1).split("/").filter(Boolean);
48478
+ if (path5.length === 0) {
48349
48479
  return ctx.rootSchema;
48350
48480
  }
48351
48481
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
48352
- if (path4[0] === defsKey) {
48353
- const key = path4[1];
48482
+ if (path5[0] === defsKey) {
48483
+ const key = path5[1];
48354
48484
  if (!key || !ctx.defs[key]) {
48355
48485
  throw new Error(`Reference not found: ${ref}`);
48356
48486
  }
@@ -48778,16 +48908,16 @@ var writeProcedure = t.procedure.use(async ({ ctx, next }) => {
48778
48908
  return next();
48779
48909
  });
48780
48910
  var NODE_RELATION2 = "is";
48911
+ function serializeValue2(value) {
48912
+ if (value instanceof Timestamp2) return value.toDate().toISOString();
48913
+ if (Array.isArray(value)) return value.map(serializeValue2);
48914
+ if (value && typeof value === "object") return serializeRecord(value);
48915
+ return value;
48916
+ }
48781
48917
  function serializeRecord(doc) {
48782
48918
  const result = {};
48783
48919
  for (const [key, value] of Object.entries(doc)) {
48784
- if (value instanceof Timestamp2) {
48785
- result[key] = value.toDate().toISOString();
48786
- } else if (value && typeof value === "object" && !Array.isArray(value)) {
48787
- result[key] = serializeRecord(value);
48788
- } else {
48789
- result[key] = value;
48790
- }
48920
+ result[key] = serializeValue2(value);
48791
48921
  }
48792
48922
  return result;
48793
48923
  }
@@ -48800,6 +48930,55 @@ function stripTypePrefix(raw) {
48800
48930
  }
48801
48931
  return raw;
48802
48932
  }
48933
+ function resolveCollectionPath(rootCollection, scope) {
48934
+ if (!scope) return rootCollection;
48935
+ const segments = scope.split("/");
48936
+ if (segments.length % 2 !== 0) {
48937
+ throw new TRPCError({
48938
+ code: "BAD_REQUEST",
48939
+ message: `Invalid scope path: "${scope}". Must be pairs of parentUid/subgraphName.`
48940
+ });
48941
+ }
48942
+ return `${rootCollection}/${scope}`;
48943
+ }
48944
+ function getScopedClient(rootClient, scope) {
48945
+ if (!scope) return rootClient;
48946
+ const segments = scope.split("/");
48947
+ if (segments.length % 2 !== 0) {
48948
+ throw new TRPCError({
48949
+ code: "BAD_REQUEST",
48950
+ message: `Invalid scope path: "${scope}". Must be pairs of parentUid/subgraphName.`
48951
+ });
48952
+ }
48953
+ let client = rootClient;
48954
+ for (let i = 0; i < segments.length; i += 2) {
48955
+ client = client.subgraph(segments[i], segments[i + 1]);
48956
+ }
48957
+ return client;
48958
+ }
48959
+ var scopeSchema = external_exports.string().optional();
48960
+ function substitutePathTemplate(template, params = {}) {
48961
+ return template.replace(/\{([^}]+)\}/g, (_, key) => {
48962
+ if (!(key in params)) {
48963
+ throw new TRPCError({ code: "BAD_REQUEST", message: `Missing required path parameter: "${key}"` });
48964
+ }
48965
+ const val = params[key];
48966
+ if (!val) {
48967
+ throw new TRPCError({ code: "BAD_REQUEST", message: `Path parameter "${key}" must not be empty` });
48968
+ }
48969
+ if (val.includes("/")) {
48970
+ throw new TRPCError({ code: "BAD_REQUEST", message: `Path parameter "${key}" must not contain "/"` });
48971
+ }
48972
+ return val;
48973
+ });
48974
+ }
48975
+ function getCollectionDef(ctx, name) {
48976
+ const def = ctx.collectionDefs.find((c) => c.name === name);
48977
+ if (!def) {
48978
+ throw new TRPCError({ code: "NOT_FOUND", message: `Collection "${name}" not found.` });
48979
+ }
48980
+ return def;
48981
+ }
48803
48982
  var appRouter = t.router({
48804
48983
  // --- Config ---
48805
48984
  getConfig: publicProcedure.query(({ ctx }) => ({
@@ -48827,7 +49006,8 @@ var appRouter = t.router({
48827
49006
  inverseLabel: e.inverseLabel,
48828
49007
  titleField: e.titleField,
48829
49008
  subtitleField: e.subtitleField,
48830
- isDynamic: e.isDynamic
49009
+ isDynamic: e.isDynamic,
49010
+ targetGraph: e.targetGraph
48831
49011
  }));
48832
49012
  return {
48833
49013
  nodeTypes,
@@ -48835,13 +49015,26 @@ var appRouter = t.router({
48835
49015
  readonly: ctx.readonly,
48836
49016
  nodeSchemas: ctx.schemaMetadata.nodeTypes,
48837
49017
  edgeSchemas: ctx.schemaMetadata.edgeTypes,
48838
- dynamicMode: ctx.reloadFn !== null
49018
+ dynamicMode: ctx.reloadFn !== null,
49019
+ collections: ctx.collectionDefs.map((c) => ({
49020
+ name: c.name,
49021
+ path: c.path,
49022
+ description: c.description,
49023
+ typeField: c.typeField,
49024
+ typeValue: c.typeValue,
49025
+ parentNodeType: c.parentNodeType,
49026
+ fields: c.fields,
49027
+ hasSchema: c.hasSchema,
49028
+ pathParams: c.pathParams,
49029
+ defaultOrderBy: c.defaultOrderBy
49030
+ }))
48839
49031
  };
48840
49032
  }),
48841
49033
  // --- Views ---
48842
49034
  getViews: publicProcedure.query(({ ctx }) => {
48843
49035
  const nodes = ctx.viewRegistry?.nodes ? { ...ctx.viewRegistry.nodes } : {};
48844
49036
  const edges = ctx.viewRegistry?.edges ? { ...ctx.viewRegistry.edges } : {};
49037
+ const collections = { ...ctx.collectionViewRegistry };
48845
49038
  if (ctx.dynamicTypeMeta) {
48846
49039
  for (const [name, meta3] of Object.entries(ctx.dynamicTypeMeta.nodes)) {
48847
49040
  if (!meta3.viewTemplate) continue;
@@ -48866,8 +49059,8 @@ var appRouter = t.router({
48866
49059
  }
48867
49060
  }
48868
49061
  }
48869
- const hasViews = Object.keys(nodes).length > 0 || Object.keys(edges).length > 0;
48870
- return { nodes, edges, hasViews };
49062
+ const hasViews = Object.keys(nodes).length > 0 || Object.keys(edges).length > 0 || Object.keys(collections).length > 0;
49063
+ return { nodes, edges, collections, hasViews };
48871
49064
  }),
48872
49065
  // --- Reload Schema (dynamic registry) ---
48873
49066
  reloadSchema: writeProcedure.mutation(async ({ ctx }) => {
@@ -48886,6 +49079,7 @@ var appRouter = t.router({
48886
49079
  })),
48887
49080
  // --- Browse Nodes ---
48888
49081
  getNodes: publicProcedure.input(external_exports.object({
49082
+ scope: scopeSchema,
48889
49083
  type: external_exports.string().optional(),
48890
49084
  limit: external_exports.number().min(1).max(200).default(25),
48891
49085
  startAfter: external_exports.string().optional(),
@@ -48902,7 +49096,7 @@ var appRouter = t.router({
48902
49096
  value: external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()])
48903
49097
  })).optional()
48904
49098
  })).query(async ({ ctx, input }) => {
48905
- const col = ctx.db.collection(ctx.collection);
49099
+ const col = ctx.db.collection(resolveCollectionPath(ctx.collection, input.scope));
48906
49100
  const builtinSortFields = ["aUid", "createdAt", "updatedAt"];
48907
49101
  let effectiveSortBy;
48908
49102
  if (builtinSortFields.includes(input.sortBy)) {
@@ -48950,8 +49144,8 @@ var appRouter = t.router({
48950
49144
  return { nodes, hasMore, nextCursor };
48951
49145
  }),
48952
49146
  // --- Get Single Node ---
48953
- getNodeDetail: publicProcedure.input(external_exports.object({ uid: external_exports.string() })).query(async ({ ctx, input }) => {
48954
- const col = ctx.db.collection(ctx.collection);
49147
+ getNodeDetail: publicProcedure.input(external_exports.object({ scope: scopeSchema, uid: external_exports.string() })).query(async ({ ctx, input }) => {
49148
+ const col = ctx.db.collection(resolveCollectionPath(ctx.collection, input.scope));
48955
49149
  const edgeLimit = 50;
48956
49150
  const uid = stripTypePrefix(input.uid);
48957
49151
  const nodeDoc = await col.doc(uid).get();
@@ -48963,8 +49157,8 @@ var appRouter = t.router({
48963
49157
  return { node, outEdges, inEdges };
48964
49158
  }),
48965
49159
  // --- Batch Get Nodes ---
48966
- getNodesBatch: publicProcedure.input(external_exports.object({ uids: external_exports.array(external_exports.string()).min(1).max(100) })).query(async ({ ctx, input }) => {
48967
- const col = ctx.db.collection(ctx.collection);
49160
+ getNodesBatch: publicProcedure.input(external_exports.object({ scope: scopeSchema, uids: external_exports.array(external_exports.string()).min(1).max(100) })).query(async ({ ctx, input }) => {
49161
+ const col = ctx.db.collection(resolveCollectionPath(ctx.collection, input.scope));
48968
49162
  const cleanUids = input.uids.map(stripTypePrefix);
48969
49163
  const refs = cleanUids.map((uid) => col.doc(uid));
48970
49164
  const snapshots = await ctx.db.getAll(...refs);
@@ -48976,6 +49170,7 @@ var appRouter = t.router({
48976
49170
  }),
48977
49171
  // --- Query Edges ---
48978
49172
  getEdges: publicProcedure.input(external_exports.object({
49173
+ scope: scopeSchema,
48979
49174
  aType: external_exports.string().optional(),
48980
49175
  aUid: external_exports.string().optional(),
48981
49176
  axbType: external_exports.string().optional(),
@@ -48991,7 +49186,7 @@ var appRouter = t.router({
48991
49186
  value: external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()])
48992
49187
  })).optional()
48993
49188
  })).query(async ({ ctx, input }) => {
48994
- const col = ctx.db.collection(ctx.collection);
49189
+ const col = ctx.db.collection(resolveCollectionPath(ctx.collection, input.scope));
48995
49190
  let query = col;
48996
49191
  if (input.aType) query = query.where("aType", "==", input.aType);
48997
49192
  if (input.aUid) query = query.where("aUid", "==", input.aUid);
@@ -49037,6 +49232,7 @@ var appRouter = t.router({
49037
49232
  }),
49038
49233
  // --- Traversal ---
49039
49234
  traverse: publicProcedure.input(external_exports.object({
49235
+ scope: scopeSchema,
49040
49236
  startUid: external_exports.string().min(1),
49041
49237
  hops: external_exports.array(external_exports.object({
49042
49238
  axbType: external_exports.string(),
@@ -49057,7 +49253,7 @@ var appRouter = t.router({
49057
49253
  maxReads: external_exports.number().default(100),
49058
49254
  concurrency: external_exports.number().default(5)
49059
49255
  })).mutation(async ({ ctx, input }) => {
49060
- const col = ctx.db.collection(ctx.collection);
49256
+ const col = ctx.db.collection(resolveCollectionPath(ctx.collection, input.scope));
49061
49257
  let totalReads = 0;
49062
49258
  let truncated = false;
49063
49259
  let sourceUids = [input.startUid];
@@ -49144,12 +49340,13 @@ var appRouter = t.router({
49144
49340
  }),
49145
49341
  // --- Search ---
49146
49342
  search: publicProcedure.input(external_exports.object({
49343
+ scope: scopeSchema,
49147
49344
  q: external_exports.string(),
49148
49345
  limit: external_exports.number().min(1).max(50).default(20)
49149
49346
  })).query(async ({ ctx, input }) => {
49150
49347
  const q = input.q.trim();
49151
49348
  if (!q) return { results: [] };
49152
- const col = ctx.db.collection(ctx.collection);
49349
+ const col = ctx.db.collection(resolveCollectionPath(ctx.collection, input.scope));
49153
49350
  const strippedQ = stripTypePrefix(q);
49154
49351
  const nodeDoc = await col.doc(strippedQ).get();
49155
49352
  const results = [];
@@ -49173,8 +49370,8 @@ var appRouter = t.router({
49173
49370
  return { results: results.slice(0, input.limit) };
49174
49371
  }),
49175
49372
  // --- Check Node Exists ---
49176
- checkNode: publicProcedure.input(external_exports.object({ uid: external_exports.string().min(1) })).query(async ({ ctx, input }) => {
49177
- const doc = await ctx.db.collection(ctx.collection).doc(stripTypePrefix(input.uid)).get();
49373
+ checkNode: publicProcedure.input(external_exports.object({ scope: scopeSchema, uid: external_exports.string().min(1) })).query(async ({ ctx, input }) => {
49374
+ const doc = await ctx.db.collection(resolveCollectionPath(ctx.collection, input.scope)).doc(stripTypePrefix(input.uid)).get();
49178
49375
  if (!doc.exists) return { exists: false, node: null };
49179
49376
  const data = serializeRecord(doc.data());
49180
49377
  return {
@@ -49184,23 +49381,26 @@ var appRouter = t.router({
49184
49381
  }),
49185
49382
  // --- Check Edge Exists ---
49186
49383
  checkEdge: publicProcedure.input(external_exports.object({
49384
+ scope: scopeSchema,
49187
49385
  aUid: external_exports.string().min(1),
49188
49386
  axbType: external_exports.string().min(1),
49189
49387
  bUid: external_exports.string().min(1)
49190
49388
  })).query(async ({ ctx, input }) => {
49191
49389
  const docId = computeEdgeDocId(input.aUid, input.axbType, input.bUid);
49192
- const doc = await ctx.db.collection(ctx.collection).doc(docId).get();
49390
+ const doc = await ctx.db.collection(resolveCollectionPath(ctx.collection, input.scope)).doc(docId).get();
49193
49391
  return { exists: doc.exists };
49194
49392
  }),
49195
49393
  // --- Write: Create Node ---
49196
49394
  createNode: writeProcedure.input(external_exports.object({
49395
+ scope: scopeSchema,
49197
49396
  aType: external_exports.string(),
49198
49397
  uid: external_exports.string().optional(),
49199
49398
  data: external_exports.record(external_exports.string(), external_exports.unknown())
49200
49399
  })).mutation(async ({ ctx, input }) => {
49201
49400
  try {
49401
+ const client = getScopedClient(ctx.graphClient, input.scope);
49202
49402
  const nodeUid = input.uid || generateId();
49203
- await ctx.graphClient.putNode(input.aType, nodeUid, input.data);
49403
+ await client.putNode(input.aType, nodeUid, input.data);
49204
49404
  return { success: true, uid: nodeUid };
49205
49405
  } catch (err) {
49206
49406
  if (err instanceof ValidationError || err instanceof RegistryViolationError) {
@@ -49211,15 +49411,17 @@ var appRouter = t.router({
49211
49411
  }),
49212
49412
  // --- Write: Update Node ---
49213
49413
  updateNode: writeProcedure.input(external_exports.object({
49414
+ scope: scopeSchema,
49214
49415
  uid: external_exports.string(),
49215
49416
  data: external_exports.record(external_exports.string(), external_exports.unknown())
49216
49417
  })).mutation(async ({ ctx, input }) => {
49217
49418
  try {
49218
- const existing = await ctx.graphClient.getNode(input.uid);
49419
+ const client = getScopedClient(ctx.graphClient, input.scope);
49420
+ const existing = await client.getNode(input.uid);
49219
49421
  if (!existing) {
49220
49422
  throw new TRPCError({ code: "NOT_FOUND", message: "Node not found" });
49221
49423
  }
49222
- await ctx.graphClient.putNode(existing.aType, input.uid, input.data);
49424
+ await client.putNode(existing.aType, input.uid, input.data);
49223
49425
  return { success: true };
49224
49426
  } catch (err) {
49225
49427
  if (err instanceof TRPCError) throw err;
@@ -49230,13 +49432,15 @@ var appRouter = t.router({
49230
49432
  }
49231
49433
  }),
49232
49434
  // --- Write: Delete Node ---
49233
- deleteNode: writeProcedure.input(external_exports.object({ uid: external_exports.string() })).mutation(async ({ ctx, input }) => {
49234
- await ctx.graphClient.removeNode(input.uid);
49435
+ deleteNode: writeProcedure.input(external_exports.object({ scope: scopeSchema, uid: external_exports.string() })).mutation(async ({ ctx, input }) => {
49436
+ const client = getScopedClient(ctx.graphClient, input.scope);
49437
+ await client.removeNode(input.uid);
49235
49438
  return { success: true };
49236
49439
  }),
49237
49440
  // --- Write: Delete Node + Cascade (all edges) ---
49238
- deleteNodeCascade: writeProcedure.input(external_exports.object({ uid: external_exports.string() })).mutation(async ({ ctx, input }) => {
49239
- const result = await ctx.graphClient.removeNodeCascade(input.uid);
49441
+ deleteNodeCascade: writeProcedure.input(external_exports.object({ scope: scopeSchema, uid: external_exports.string() })).mutation(async ({ ctx, input }) => {
49442
+ const client = getScopedClient(ctx.graphClient, input.scope);
49443
+ const result = await client.removeNodeCascade(input.uid);
49240
49444
  return {
49241
49445
  success: result.nodeDeleted,
49242
49446
  edgesDeleted: result.edgesDeleted,
@@ -49250,6 +49454,7 @@ var appRouter = t.router({
49250
49454
  }),
49251
49455
  // --- Write: Create Edge ---
49252
49456
  createEdge: writeProcedure.input(external_exports.object({
49457
+ scope: scopeSchema,
49253
49458
  aType: external_exports.string(),
49254
49459
  aUid: external_exports.string(),
49255
49460
  axbType: external_exports.string(),
@@ -49258,7 +49463,8 @@ var appRouter = t.router({
49258
49463
  data: external_exports.record(external_exports.string(), external_exports.unknown())
49259
49464
  })).mutation(async ({ ctx, input }) => {
49260
49465
  try {
49261
- await ctx.graphClient.putEdge(
49466
+ const client = getScopedClient(ctx.graphClient, input.scope);
49467
+ await client.putEdge(
49262
49468
  input.aType,
49263
49469
  input.aUid,
49264
49470
  input.axbType,
@@ -49276,6 +49482,7 @@ var appRouter = t.router({
49276
49482
  }),
49277
49483
  // --- Write: Create Edge + Target Node atomically ---
49278
49484
  createEdgeWithNode: writeProcedure.input(external_exports.object({
49485
+ scope: scopeSchema,
49279
49486
  aType: external_exports.string(),
49280
49487
  axbType: external_exports.string(),
49281
49488
  bType: external_exports.string(),
@@ -49289,13 +49496,14 @@ var appRouter = t.router({
49289
49496
  nodeData: external_exports.record(external_exports.string(), external_exports.unknown())
49290
49497
  })).mutation(async ({ ctx, input }) => {
49291
49498
  try {
49499
+ const client = getScopedClient(ctx.graphClient, input.scope);
49292
49500
  const newUid = input.newNodeUid || generateId();
49293
49501
  const newNodeType = input.newNodeSide === "b" ? input.bType : input.aType;
49294
49502
  const aUid = input.newNodeSide === "a" ? newUid : input.existingUid;
49295
49503
  const bUid = input.newNodeSide === "b" ? newUid : input.existingUid;
49296
49504
  const [existingNode, existingEdge] = await Promise.all([
49297
- ctx.graphClient.getNode(newUid),
49298
- ctx.graphClient.getEdge(aUid, input.axbType, bUid)
49505
+ client.getNode(newUid),
49506
+ client.getEdge(aUid, input.axbType, bUid)
49299
49507
  ]);
49300
49508
  if (existingNode && existingEdge) {
49301
49509
  throw new TRPCError({
@@ -49303,7 +49511,7 @@ var appRouter = t.router({
49303
49511
  message: `Both node "${newUid}" and edge ${aUid} \u2014[${input.axbType}]\u2192 ${bUid} already exist.`
49304
49512
  });
49305
49513
  }
49306
- await ctx.graphClient.runTransaction(async (tx) => {
49514
+ await client.runTransaction(async (tx) => {
49307
49515
  if (!existingNode) {
49308
49516
  await tx.putNode(newNodeType, newUid, input.nodeData);
49309
49517
  }
@@ -49327,15 +49535,18 @@ var appRouter = t.router({
49327
49535
  }),
49328
49536
  // --- Write: Delete Edge ---
49329
49537
  deleteEdge: writeProcedure.input(external_exports.object({
49538
+ scope: scopeSchema,
49330
49539
  aUid: external_exports.string(),
49331
49540
  axbType: external_exports.string(),
49332
49541
  bUid: external_exports.string()
49333
49542
  })).mutation(async ({ ctx, input }) => {
49334
- await ctx.graphClient.removeEdge(input.aUid, input.axbType, input.bUid);
49543
+ const client = getScopedClient(ctx.graphClient, input.scope);
49544
+ await client.removeEdge(input.aUid, input.axbType, input.bUid);
49335
49545
  return { success: true };
49336
49546
  }),
49337
49547
  // --- Write: Bulk Delete Edges (by query) ---
49338
49548
  bulkDeleteEdges: writeProcedure.input(external_exports.object({
49549
+ scope: scopeSchema,
49339
49550
  aUid: external_exports.string().optional(),
49340
49551
  axbType: external_exports.string().optional(),
49341
49552
  bUid: external_exports.string().optional(),
@@ -49347,12 +49558,13 @@ var appRouter = t.router({
49347
49558
  value: external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()])
49348
49559
  })).optional()
49349
49560
  })).mutation(async ({ ctx, input }) => {
49350
- const { where: whereClauses, ...params } = input;
49561
+ const client = getScopedClient(ctx.graphClient, input.scope);
49562
+ const { where: whereClauses, scope: _scope, ...params } = input;
49351
49563
  const findParams = { ...params };
49352
49564
  if (whereClauses && whereClauses.length > 0) {
49353
49565
  findParams.where = whereClauses;
49354
49566
  }
49355
- const result = await ctx.graphClient.bulkRemoveEdges(findParams);
49567
+ const result = await client.bulkRemoveEdges(findParams);
49356
49568
  return {
49357
49569
  success: true,
49358
49570
  deleted: result.deleted,
@@ -49366,18 +49578,132 @@ var appRouter = t.router({
49366
49578
  }),
49367
49579
  // --- Write: Delete specific edges by ID ---
49368
49580
  deleteEdgesBatch: writeProcedure.input(external_exports.object({
49581
+ scope: scopeSchema,
49369
49582
  edges: external_exports.array(external_exports.object({
49370
49583
  aUid: external_exports.string(),
49371
49584
  axbType: external_exports.string(),
49372
49585
  bUid: external_exports.string()
49373
49586
  })).min(1).max(500)
49374
49587
  })).mutation(async ({ ctx, input }) => {
49375
- const batch = ctx.graphClient.batch();
49588
+ const client = getScopedClient(ctx.graphClient, input.scope);
49589
+ const batch = client.batch();
49376
49590
  for (const e of input.edges) {
49377
49591
  await batch.removeEdge(e.aUid, e.axbType, e.bUid);
49378
49592
  }
49379
49593
  await batch.commit();
49380
49594
  return { success: true, deleted: input.edges.length };
49595
+ }),
49596
+ // --- Plain Collection Procedures ---
49597
+ getCollectionDocs: publicProcedure.input(external_exports.object({
49598
+ collectionName: external_exports.string(),
49599
+ params: external_exports.record(external_exports.string(), external_exports.string()).optional(),
49600
+ cursor: external_exports.string().optional(),
49601
+ limit: external_exports.number().int().min(1).max(100).default(50)
49602
+ })).query(async ({ ctx, input }) => {
49603
+ const def = getCollectionDef(ctx, input.collectionName);
49604
+ const colPath = substitutePathTemplate(def.path, input.params ?? {});
49605
+ const col = ctx.db.collection(colPath);
49606
+ let query = col;
49607
+ if (def.typeField && def.typeValue !== void 0) {
49608
+ query = query.where(def.typeField, "==", def.typeValue);
49609
+ }
49610
+ if (def.defaultOrderBy) {
49611
+ query = query.orderBy(def.defaultOrderBy.field, def.defaultOrderBy.direction);
49612
+ } else {
49613
+ query = query.orderBy(FieldPath.documentId());
49614
+ }
49615
+ query = query.limit(input.limit + 1);
49616
+ if (input.cursor) {
49617
+ const cursorSnap = await col.doc(input.cursor).get();
49618
+ if (!cursorSnap.exists) {
49619
+ throw new TRPCError({
49620
+ code: "NOT_FOUND",
49621
+ message: `Cursor document "${input.cursor}" no longer exists. Refresh to start from the first page.`
49622
+ });
49623
+ }
49624
+ query = query.startAfter(cursorSnap);
49625
+ }
49626
+ const snapshot = await query.get();
49627
+ const docs = snapshot.docs.slice(0, input.limit);
49628
+ const hasMore = snapshot.docs.length > input.limit;
49629
+ const documents = docs.map((doc) => ({
49630
+ id: doc.id,
49631
+ data: serializeRecord(doc.data())
49632
+ }));
49633
+ const nextCursor = hasMore && docs.length > 0 ? docs[docs.length - 1].id : null;
49634
+ return {
49635
+ documents,
49636
+ hasMore,
49637
+ nextCursor
49638
+ };
49639
+ }),
49640
+ getCollectionDoc: publicProcedure.input(external_exports.object({
49641
+ collectionName: external_exports.string(),
49642
+ params: external_exports.record(external_exports.string(), external_exports.string()).optional(),
49643
+ docId: external_exports.string()
49644
+ })).query(async ({ ctx, input }) => {
49645
+ const def = getCollectionDef(ctx, input.collectionName);
49646
+ const colPath = substitutePathTemplate(def.path, input.params ?? {});
49647
+ const snap = await ctx.db.collection(colPath).doc(input.docId).get();
49648
+ if (!snap.exists) {
49649
+ throw new TRPCError({ code: "NOT_FOUND", message: `Document "${input.docId}" not found.` });
49650
+ }
49651
+ const docData = snap.data();
49652
+ if (def.typeField && def.typeValue !== void 0 && docData[def.typeField] !== def.typeValue) {
49653
+ throw new TRPCError({ code: "NOT_FOUND", message: `Document "${input.docId}" not found.` });
49654
+ }
49655
+ return { id: snap.id, data: serializeRecord(docData) };
49656
+ }),
49657
+ createCollectionDoc: writeProcedure.input(external_exports.object({
49658
+ collectionName: external_exports.string(),
49659
+ params: external_exports.record(external_exports.string(), external_exports.string()).optional(),
49660
+ data: external_exports.record(external_exports.string(), external_exports.unknown())
49661
+ })).mutation(async ({ ctx, input }) => {
49662
+ const def = getCollectionDef(ctx, input.collectionName);
49663
+ const colPath = substitutePathTemplate(def.path, input.params ?? {});
49664
+ const docData = { ...input.data };
49665
+ if (def.typeField && def.typeValue !== void 0) {
49666
+ docData[def.typeField] = def.typeValue;
49667
+ }
49668
+ const docRef = await ctx.db.collection(colPath).add(docData);
49669
+ return { success: true, id: docRef.id };
49670
+ }),
49671
+ updateCollectionDoc: writeProcedure.input(external_exports.object({
49672
+ collectionName: external_exports.string(),
49673
+ params: external_exports.record(external_exports.string(), external_exports.string()).optional(),
49674
+ docId: external_exports.string(),
49675
+ data: external_exports.record(external_exports.string(), external_exports.unknown())
49676
+ })).mutation(async ({ ctx, input }) => {
49677
+ const def = getCollectionDef(ctx, input.collectionName);
49678
+ const colPath = substitutePathTemplate(def.path, input.params ?? {});
49679
+ if (def.typeField && def.typeValue !== void 0) {
49680
+ const snap = await ctx.db.collection(colPath).doc(input.docId).get();
49681
+ if (!snap.exists || snap.data()[def.typeField] !== def.typeValue) {
49682
+ throw new TRPCError({ code: "NOT_FOUND", message: `Document "${input.docId}" not found.` });
49683
+ }
49684
+ }
49685
+ const docData = { ...input.data };
49686
+ if (def.typeField && def.typeValue !== void 0) {
49687
+ docData[def.typeField] = def.typeValue;
49688
+ }
49689
+ await ctx.db.collection(colPath).doc(input.docId).set(docData, { merge: true });
49690
+ return { success: true };
49691
+ }),
49692
+ deleteCollectionDoc: writeProcedure.input(external_exports.object({
49693
+ collectionName: external_exports.string(),
49694
+ params: external_exports.record(external_exports.string(), external_exports.string()).optional(),
49695
+ docId: external_exports.string()
49696
+ })).mutation(async ({ ctx, input }) => {
49697
+ const def = getCollectionDef(ctx, input.collectionName);
49698
+ const colPath = substitutePathTemplate(def.path, input.params ?? {});
49699
+ if (def.typeField && def.typeValue !== void 0) {
49700
+ const snap = await ctx.db.collection(colPath).doc(input.docId).get();
49701
+ if (!snap.exists || snap.data()[def.typeField] !== def.typeValue) {
49702
+ throw new TRPCError({ code: "NOT_FOUND", message: `Document "${input.docId}" not found.` });
49703
+ }
49704
+ }
49705
+ await ctx.db.collection(colPath).doc(input.docId).delete();
49706
+ return { success: true };
49381
49707
  })
49382
49708
  });
49383
49709
 
@@ -49869,7 +50195,7 @@ ${elements.join("\n")}`;
49869
50195
  }
49870
50196
 
49871
50197
  // editor/server/index.ts
49872
- var __dirname = path3.dirname(fileURLToPath(import.meta.url));
50198
+ var __dirname = path4.dirname(fileURLToPath(import.meta.url));
49873
50199
  function parseArgs() {
49874
50200
  const args = process.argv.slice(2);
49875
50201
  let configPath;
@@ -49929,6 +50255,8 @@ var resolvedChatEnabled = false;
49929
50255
  var resolvedChatModel = "sonnet";
49930
50256
  var resolvedChatMaxConcurrency = 2;
49931
50257
  var viewDefaultsData = null;
50258
+ var resolvedCollectionDefs = [];
50259
+ var collectionViewRegistry = {};
49932
50260
  var resolvedRegistryMode;
49933
50261
  var db;
49934
50262
  var state = {
@@ -49951,7 +50279,7 @@ async function init() {
49951
50279
  const fileConfig = loaded?.config ?? {};
49952
50280
  if (loaded) {
49953
50281
  resolvedConfigPath = loaded.configPath;
49954
- console.log(` Config loaded from ${path3.relative(process.cwd(), loaded.configPath)}`);
50282
+ console.log(` Config loaded from ${path4.relative(process.cwd(), loaded.configPath)}`);
49955
50283
  }
49956
50284
  resolvedProject = cliArgs.project ?? fileConfig.project;
49957
50285
  resolvedCollection = cliArgs.collection ?? fileConfig.collection ?? "graph";
@@ -50074,6 +50402,11 @@ async function reloadDynamicSchema() {
50074
50402
  async function initEntitiesMode(fileConfig) {
50075
50403
  console.log(` Discovering entities from ${resolvedEntitiesPath}...`);
50076
50404
  const { result: discovery, warnings } = discoverEntities(resolvedEntitiesPath);
50405
+ resolvedCollectionDefs = discoverCollections(resolvedEntitiesPath);
50406
+ if (resolvedCollectionDefs.length > 0) {
50407
+ console.log(` Collections loaded: ${resolvedCollectionDefs.length} collection(s)`);
50408
+ }
50409
+ collectionViewRegistry = await buildCollectionViewRegistry(resolvedCollectionDefs);
50077
50410
  if (warnings.length > 0) {
50078
50411
  for (const w of warnings) {
50079
50412
  console.log(` [warn] ${w.message}`);
@@ -50097,8 +50430,11 @@ async function initEntitiesMode(fileConfig) {
50097
50430
  const nodeViewCount = Object.values(state.viewRegistry.nodes).reduce((sum, m) => sum + m.views.length, 0);
50098
50431
  const edgeViewCount = Object.values(state.viewRegistry.edges).reduce((sum, m) => sum + m.views.length, 0);
50099
50432
  console.log(` Views loaded: ${nodeViewCount} node views, ${edgeViewCount} edge views`);
50433
+ }
50434
+ const colViewPaths = resolvedCollectionDefs.filter((c) => c.viewsPath).map((c) => ({ name: c.name, absPath: path4.resolve(c.viewsPath) }));
50435
+ if (state.viewRegistry || colViewPaths.length > 0) {
50100
50436
  console.log(` Bundling views for browser...`);
50101
- state.viewBundle = await bundleEntityViews(discovery);
50437
+ state.viewBundle = await bundleEntityViews(discovery, colViewPaths);
50102
50438
  if (state.viewBundle) {
50103
50439
  console.log(` Views bundled (${(state.viewBundle.code.length / 1024).toFixed(1)} KB)`);
50104
50440
  }
@@ -50159,7 +50495,9 @@ async function start() {
50159
50495
  projectId: resolvedProject,
50160
50496
  viewDefaults: viewDefaultsData,
50161
50497
  chatEnabled: resolvedChatEnabled,
50162
- chatModel: resolvedChatModel
50498
+ chatModel: resolvedChatModel,
50499
+ collectionDefs: resolvedCollectionDefs,
50500
+ collectionViewRegistry
50163
50501
  },
50164
50502
  state,
50165
50503
  resolvedRegistryMode ? reloadDynamicSchema : void 0
@@ -50175,17 +50513,17 @@ async function start() {
50175
50513
  }
50176
50514
  const isProduction = process.env.NODE_ENV === "production";
50177
50515
  if (isProduction) {
50178
- const clientDir = path3.join(__dirname, "..", "client");
50516
+ const clientDir = path4.join(__dirname, "..", "client");
50179
50517
  app.use(import_express.default.static(clientDir));
50180
50518
  app.get("*", (_req, res) => {
50181
- res.sendFile(path3.join(clientDir, "index.html"));
50519
+ res.sendFile(path4.join(clientDir, "index.html"));
50182
50520
  });
50183
50521
  }
50184
50522
  const server = app.listen(resolvedPort, () => {
50185
50523
  console.log("");
50186
50524
  console.log(" Firegraph Editor");
50187
50525
  if (resolvedConfigPath) {
50188
- console.log(` Config: ${path3.relative(process.cwd(), resolvedConfigPath)}`);
50526
+ console.log(` Config: ${path4.relative(process.cwd(), resolvedConfigPath)}`);
50189
50527
  }
50190
50528
  console.log(` Project: ${resolvedProject || "(auto-detected via ADC)"}`);
50191
50529
  console.log(` Collection: ${resolvedCollection}`);