@arronqzy/blueprint-dsl 1.0.14 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -160,18 +160,668 @@ function registerDefaultBehaviors(registry) {
160
160
  });
161
161
  }
162
162
 
163
+ // vendor/dayjs/esm/constant.js
164
+ var SECONDS_A_MINUTE = 60;
165
+ var SECONDS_A_HOUR = SECONDS_A_MINUTE * 60;
166
+ var SECONDS_A_DAY = SECONDS_A_HOUR * 24;
167
+ var SECONDS_A_WEEK = SECONDS_A_DAY * 7;
168
+ var MILLISECONDS_A_SECOND = 1e3;
169
+ var MILLISECONDS_A_MINUTE = SECONDS_A_MINUTE * MILLISECONDS_A_SECOND;
170
+ var MILLISECONDS_A_HOUR = SECONDS_A_HOUR * MILLISECONDS_A_SECOND;
171
+ var MILLISECONDS_A_DAY = SECONDS_A_DAY * MILLISECONDS_A_SECOND;
172
+ var MILLISECONDS_A_WEEK = SECONDS_A_WEEK * MILLISECONDS_A_SECOND;
173
+ var MS = "millisecond";
174
+ var S = "second";
175
+ var MIN = "minute";
176
+ var H = "hour";
177
+ var D = "day";
178
+ var W = "week";
179
+ var M = "month";
180
+ var Q = "quarter";
181
+ var Y = "year";
182
+ var DATE = "date";
183
+ var FORMAT_DEFAULT = "YYYY-MM-DDTHH:mm:ssZ";
184
+ var INVALID_DATE_STRING = "Invalid Date";
185
+ var REGEX_PARSE = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/;
186
+ var REGEX_FORMAT = /\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g;
187
+
188
+ // vendor/dayjs/esm/locale/en.js
189
+ var en_default = {
190
+ name: "en",
191
+ weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
192
+ months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
193
+ ordinal: function ordinal(n) {
194
+ var s = ["th", "st", "nd", "rd"];
195
+ var v = n % 100;
196
+ return "[" + n + (s[(v - 20) % 10] || s[v] || s[0]) + "]";
197
+ }
198
+ };
199
+
200
+ // vendor/dayjs/esm/utils.js
201
+ var padStart = function padStart2(string, length, pad) {
202
+ var s = String(string);
203
+ if (!s || s.length >= length) return string;
204
+ return "" + Array(length + 1 - s.length).join(pad) + string;
205
+ };
206
+ var padZoneStr = function padZoneStr2(instance) {
207
+ var negMinutes = -instance.utcOffset();
208
+ var minutes = Math.abs(negMinutes);
209
+ var hourOffset = Math.floor(minutes / 60);
210
+ var minuteOffset = minutes % 60;
211
+ return (negMinutes <= 0 ? "+" : "-") + padStart(hourOffset, 2, "0") + ":" + padStart(minuteOffset, 2, "0");
212
+ };
213
+ var monthDiff = function monthDiff2(a, b) {
214
+ if (a.date() < b.date()) return -monthDiff2(b, a);
215
+ var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month());
216
+ var anchor = a.clone().add(wholeMonthDiff, M);
217
+ var c = b - anchor < 0;
218
+ var anchor2 = a.clone().add(wholeMonthDiff + (c ? -1 : 1), M);
219
+ return +(-(wholeMonthDiff + (b - anchor) / (c ? anchor - anchor2 : anchor2 - anchor)) || 0);
220
+ };
221
+ var absFloor = function absFloor2(n) {
222
+ return n < 0 ? Math.ceil(n) || 0 : Math.floor(n);
223
+ };
224
+ var prettyUnit = function prettyUnit2(u) {
225
+ var special = {
226
+ M,
227
+ y: Y,
228
+ w: W,
229
+ d: D,
230
+ D: DATE,
231
+ h: H,
232
+ m: MIN,
233
+ s: S,
234
+ ms: MS,
235
+ Q
236
+ };
237
+ return special[u] || String(u || "").toLowerCase().replace(/s$/, "");
238
+ };
239
+ var isUndefined = function isUndefined2(s) {
240
+ return s === void 0;
241
+ };
242
+ var utils_default = {
243
+ s: padStart,
244
+ z: padZoneStr,
245
+ m: monthDiff,
246
+ a: absFloor,
247
+ p: prettyUnit,
248
+ u: isUndefined
249
+ };
250
+
251
+ // vendor/dayjs/esm/index.js
252
+ var L = "en";
253
+ var Ls = {};
254
+ Ls[L] = en_default;
255
+ var IS_DAYJS = "$isDayjsObject";
256
+ var isDayjs = function isDayjs2(d) {
257
+ return d instanceof Dayjs || !!(d && d[IS_DAYJS]);
258
+ };
259
+ var parseLocale = function parseLocale2(preset, object, isLocal) {
260
+ var l;
261
+ if (!preset) return L;
262
+ if (typeof preset === "string") {
263
+ var presetLower = preset.toLowerCase();
264
+ if (Ls[presetLower]) {
265
+ l = presetLower;
266
+ }
267
+ if (object) {
268
+ Ls[presetLower] = object;
269
+ l = presetLower;
270
+ }
271
+ var presetSplit = preset.split("-");
272
+ if (!l && presetSplit.length > 1) {
273
+ return parseLocale2(presetSplit[0]);
274
+ }
275
+ } else {
276
+ var name = preset.name;
277
+ Ls[name] = preset;
278
+ l = name;
279
+ }
280
+ if (!isLocal && l) L = l;
281
+ return l || !isLocal && L;
282
+ };
283
+ var dayjs = function dayjs2(date, c) {
284
+ if (isDayjs(date)) {
285
+ return date.clone();
286
+ }
287
+ var cfg = typeof c === "object" ? c : {};
288
+ cfg.date = date;
289
+ cfg.args = arguments;
290
+ return new Dayjs(cfg);
291
+ };
292
+ var wrapper = function wrapper2(date, instance) {
293
+ return dayjs(date, {
294
+ locale: instance.$L,
295
+ utc: instance.$u,
296
+ x: instance.$x,
297
+ $offset: instance.$offset
298
+ // todo: refactor; do not use this.$offset in you code
299
+ });
300
+ };
301
+ var Utils = utils_default;
302
+ Utils.l = parseLocale;
303
+ Utils.i = isDayjs;
304
+ Utils.w = wrapper;
305
+ var parseDate = function parseDate2(cfg) {
306
+ var date = cfg.date, utc = cfg.utc;
307
+ if (date === null) return /* @__PURE__ */ new Date(NaN);
308
+ if (Utils.u(date)) return /* @__PURE__ */ new Date();
309
+ if (date instanceof Date) return new Date(date);
310
+ if (typeof date === "string" && !/Z$/i.test(date)) {
311
+ var d = date.match(REGEX_PARSE);
312
+ if (d) {
313
+ var m = d[2] - 1 || 0;
314
+ var ms = (d[7] || "0").substring(0, 3);
315
+ if (utc) {
316
+ return new Date(Date.UTC(d[1], m, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms));
317
+ }
318
+ return new Date(d[1], m, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms);
319
+ }
320
+ }
321
+ return new Date(date);
322
+ };
323
+ var Dayjs = /* @__PURE__ */ (function() {
324
+ function Dayjs2(cfg) {
325
+ this.$L = parseLocale(cfg.locale, null, true);
326
+ this.parse(cfg);
327
+ this.$x = this.$x || cfg.x || {};
328
+ this[IS_DAYJS] = true;
329
+ }
330
+ var _proto = Dayjs2.prototype;
331
+ _proto.parse = function parse(cfg) {
332
+ this.$d = parseDate(cfg);
333
+ this.init();
334
+ };
335
+ _proto.init = function init() {
336
+ var $d = this.$d;
337
+ this.$y = $d.getFullYear();
338
+ this.$M = $d.getMonth();
339
+ this.$D = $d.getDate();
340
+ this.$W = $d.getDay();
341
+ this.$H = $d.getHours();
342
+ this.$m = $d.getMinutes();
343
+ this.$s = $d.getSeconds();
344
+ this.$ms = $d.getMilliseconds();
345
+ };
346
+ _proto.$utils = function $utils() {
347
+ return Utils;
348
+ };
349
+ _proto.isValid = function isValid() {
350
+ return !(this.$d.toString() === INVALID_DATE_STRING);
351
+ };
352
+ _proto.isSame = function isSame(that, units) {
353
+ var other = dayjs(that);
354
+ return this.startOf(units) <= other && other <= this.endOf(units);
355
+ };
356
+ _proto.isAfter = function isAfter(that, units) {
357
+ return dayjs(that) < this.startOf(units);
358
+ };
359
+ _proto.isBefore = function isBefore(that, units) {
360
+ return this.endOf(units) < dayjs(that);
361
+ };
362
+ _proto.$g = function $g(input, get, set) {
363
+ if (Utils.u(input)) return this[get];
364
+ return this.set(set, input);
365
+ };
366
+ _proto.unix = function unix() {
367
+ return Math.floor(this.valueOf() / 1e3);
368
+ };
369
+ _proto.valueOf = function valueOf() {
370
+ return this.$d.getTime();
371
+ };
372
+ _proto.startOf = function startOf(units, _startOf) {
373
+ var _this = this;
374
+ var isStartOf = !Utils.u(_startOf) ? _startOf : true;
375
+ var unit = Utils.p(units);
376
+ var instanceFactory = function instanceFactory2(d, m) {
377
+ var ins = Utils.w(_this.$u ? Date.UTC(_this.$y, m, d) : new Date(_this.$y, m, d), _this);
378
+ return isStartOf ? ins : ins.endOf(D);
379
+ };
380
+ var instanceFactorySet = function instanceFactorySet2(method, slice) {
381
+ var argumentStart = [0, 0, 0, 0];
382
+ var argumentEnd = [23, 59, 59, 999];
383
+ return Utils.w(_this.toDate()[method].apply(
384
+ // eslint-disable-line prefer-spread
385
+ _this.toDate("s"),
386
+ (isStartOf ? argumentStart : argumentEnd).slice(slice)
387
+ ), _this);
388
+ };
389
+ var $W = this.$W, $M = this.$M, $D = this.$D;
390
+ var utcPad = "set" + (this.$u ? "UTC" : "");
391
+ switch (unit) {
392
+ case Y:
393
+ return isStartOf ? instanceFactory(1, 0) : instanceFactory(31, 11);
394
+ case M:
395
+ return isStartOf ? instanceFactory(1, $M) : instanceFactory(0, $M + 1);
396
+ case W: {
397
+ var weekStart = this.$locale().weekStart || 0;
398
+ var gap = ($W < weekStart ? $W + 7 : $W) - weekStart;
399
+ return instanceFactory(isStartOf ? $D - gap : $D + (6 - gap), $M);
400
+ }
401
+ case D:
402
+ case DATE:
403
+ return instanceFactorySet(utcPad + "Hours", 0);
404
+ case H:
405
+ return instanceFactorySet(utcPad + "Minutes", 1);
406
+ case MIN:
407
+ return instanceFactorySet(utcPad + "Seconds", 2);
408
+ case S:
409
+ return instanceFactorySet(utcPad + "Milliseconds", 3);
410
+ default:
411
+ return this.clone();
412
+ }
413
+ };
414
+ _proto.endOf = function endOf(arg) {
415
+ return this.startOf(arg, false);
416
+ };
417
+ _proto.$set = function $set(units, _int) {
418
+ var _C$D$C$DATE$C$M$C$Y$C;
419
+ var unit = Utils.p(units);
420
+ var utcPad = "set" + (this.$u ? "UTC" : "");
421
+ var name = (_C$D$C$DATE$C$M$C$Y$C = {}, _C$D$C$DATE$C$M$C$Y$C[D] = utcPad + "Date", _C$D$C$DATE$C$M$C$Y$C[DATE] = utcPad + "Date", _C$D$C$DATE$C$M$C$Y$C[M] = utcPad + "Month", _C$D$C$DATE$C$M$C$Y$C[Y] = utcPad + "FullYear", _C$D$C$DATE$C$M$C$Y$C[H] = utcPad + "Hours", _C$D$C$DATE$C$M$C$Y$C[MIN] = utcPad + "Minutes", _C$D$C$DATE$C$M$C$Y$C[S] = utcPad + "Seconds", _C$D$C$DATE$C$M$C$Y$C[MS] = utcPad + "Milliseconds", _C$D$C$DATE$C$M$C$Y$C)[unit];
422
+ var arg = unit === D ? this.$D + (_int - this.$W) : _int;
423
+ if (unit === M || unit === Y) {
424
+ var date = this.clone().set(DATE, 1);
425
+ date.$d[name](arg);
426
+ date.init();
427
+ this.$d = date.set(DATE, Math.min(this.$D, date.daysInMonth())).$d;
428
+ } else if (name) this.$d[name](arg);
429
+ this.init();
430
+ return this;
431
+ };
432
+ _proto.set = function set(string, _int2) {
433
+ return this.clone().$set(string, _int2);
434
+ };
435
+ _proto.get = function get(unit) {
436
+ return this[Utils.p(unit)]();
437
+ };
438
+ _proto.add = function add(number, units) {
439
+ var _this2 = this, _C$MIN$C$H$C$S$unit;
440
+ number = Number(number);
441
+ var unit = Utils.p(units);
442
+ var instanceFactorySet = function instanceFactorySet2(n) {
443
+ var d = dayjs(_this2);
444
+ return Utils.w(d.date(d.date() + Math.round(n * number)), _this2);
445
+ };
446
+ if (unit === M) {
447
+ return this.set(M, this.$M + number);
448
+ }
449
+ if (unit === Y) {
450
+ return this.set(Y, this.$y + number);
451
+ }
452
+ if (unit === D) {
453
+ return instanceFactorySet(1);
454
+ }
455
+ if (unit === W) {
456
+ return instanceFactorySet(7);
457
+ }
458
+ var step = (_C$MIN$C$H$C$S$unit = {}, _C$MIN$C$H$C$S$unit[MIN] = MILLISECONDS_A_MINUTE, _C$MIN$C$H$C$S$unit[H] = MILLISECONDS_A_HOUR, _C$MIN$C$H$C$S$unit[S] = MILLISECONDS_A_SECOND, _C$MIN$C$H$C$S$unit)[unit] || 1;
459
+ var nextTimeStamp = this.$d.getTime() + number * step;
460
+ return Utils.w(nextTimeStamp, this);
461
+ };
462
+ _proto.subtract = function subtract(number, string) {
463
+ return this.add(number * -1, string);
464
+ };
465
+ _proto.format = function format(formatStr) {
466
+ var _this3 = this;
467
+ var locale = this.$locale();
468
+ if (!this.isValid()) return locale.invalidDate || INVALID_DATE_STRING;
469
+ var str = formatStr || FORMAT_DEFAULT;
470
+ var zoneStr = Utils.z(this);
471
+ var $H = this.$H, $m = this.$m, $M = this.$M;
472
+ var weekdays = locale.weekdays, months = locale.months, meridiem = locale.meridiem;
473
+ var getShort = function getShort2(arr, index, full, length) {
474
+ return arr && (arr[index] || arr(_this3, str)) || full[index].slice(0, length);
475
+ };
476
+ var get$H = function get$H2(num) {
477
+ return Utils.s($H % 12 || 12, num, "0");
478
+ };
479
+ var meridiemFunc = meridiem || function(hour, minute, isLowercase) {
480
+ var m = hour < 12 ? "AM" : "PM";
481
+ return isLowercase ? m.toLowerCase() : m;
482
+ };
483
+ var matches = function matches2(match) {
484
+ switch (match) {
485
+ case "YY":
486
+ return String(_this3.$y).slice(-2);
487
+ case "YYYY":
488
+ return Utils.s(_this3.$y, 4, "0");
489
+ case "M":
490
+ return $M + 1;
491
+ case "MM":
492
+ return Utils.s($M + 1, 2, "0");
493
+ case "MMM":
494
+ return getShort(locale.monthsShort, $M, months, 3);
495
+ case "MMMM":
496
+ return getShort(months, $M);
497
+ case "D":
498
+ return _this3.$D;
499
+ case "DD":
500
+ return Utils.s(_this3.$D, 2, "0");
501
+ case "d":
502
+ return String(_this3.$W);
503
+ case "dd":
504
+ return getShort(locale.weekdaysMin, _this3.$W, weekdays, 2);
505
+ case "ddd":
506
+ return getShort(locale.weekdaysShort, _this3.$W, weekdays, 3);
507
+ case "dddd":
508
+ return weekdays[_this3.$W];
509
+ case "H":
510
+ return String($H);
511
+ case "HH":
512
+ return Utils.s($H, 2, "0");
513
+ case "h":
514
+ return get$H(1);
515
+ case "hh":
516
+ return get$H(2);
517
+ case "a":
518
+ return meridiemFunc($H, $m, true);
519
+ case "A":
520
+ return meridiemFunc($H, $m, false);
521
+ case "m":
522
+ return String($m);
523
+ case "mm":
524
+ return Utils.s($m, 2, "0");
525
+ case "s":
526
+ return String(_this3.$s);
527
+ case "ss":
528
+ return Utils.s(_this3.$s, 2, "0");
529
+ case "SSS":
530
+ return Utils.s(_this3.$ms, 3, "0");
531
+ case "Z":
532
+ return zoneStr;
533
+ }
534
+ return null;
535
+ };
536
+ return str.replace(REGEX_FORMAT, function(match, $1) {
537
+ return $1 || matches(match) || zoneStr.replace(":", "");
538
+ });
539
+ };
540
+ _proto.utcOffset = function utcOffset() {
541
+ return -Math.round(this.$d.getTimezoneOffset() / 15) * 15;
542
+ };
543
+ _proto.diff = function diff(input, units, _float) {
544
+ var _this4 = this;
545
+ var unit = Utils.p(units);
546
+ var that = dayjs(input);
547
+ var zoneDelta = (that.utcOffset() - this.utcOffset()) * MILLISECONDS_A_MINUTE;
548
+ var diff2 = this - that;
549
+ var getMonth = function getMonth2() {
550
+ return Utils.m(_this4, that);
551
+ };
552
+ var result;
553
+ switch (unit) {
554
+ case Y:
555
+ result = getMonth() / 12;
556
+ break;
557
+ case M:
558
+ result = getMonth();
559
+ break;
560
+ case Q:
561
+ result = getMonth() / 3;
562
+ break;
563
+ case W:
564
+ result = (diff2 - zoneDelta) / MILLISECONDS_A_WEEK;
565
+ break;
566
+ case D:
567
+ result = (diff2 - zoneDelta) / MILLISECONDS_A_DAY;
568
+ break;
569
+ case H:
570
+ result = diff2 / MILLISECONDS_A_HOUR;
571
+ break;
572
+ case MIN:
573
+ result = diff2 / MILLISECONDS_A_MINUTE;
574
+ break;
575
+ case S:
576
+ result = diff2 / MILLISECONDS_A_SECOND;
577
+ break;
578
+ default:
579
+ result = diff2;
580
+ break;
581
+ }
582
+ return _float ? result : Utils.a(result);
583
+ };
584
+ _proto.daysInMonth = function daysInMonth() {
585
+ return this.endOf(M).$D;
586
+ };
587
+ _proto.$locale = function $locale() {
588
+ return Ls[this.$L];
589
+ };
590
+ _proto.locale = function locale(preset, object) {
591
+ if (!preset) return this.$L;
592
+ var that = this.clone();
593
+ var nextLocaleName = parseLocale(preset, object, true);
594
+ if (nextLocaleName) that.$L = nextLocaleName;
595
+ return that;
596
+ };
597
+ _proto.clone = function clone() {
598
+ return Utils.w(this.$d, this);
599
+ };
600
+ _proto.toDate = function toDate() {
601
+ return new Date(this.valueOf());
602
+ };
603
+ _proto.toJSON = function toJSON() {
604
+ return this.isValid() ? this.toISOString() : null;
605
+ };
606
+ _proto.toISOString = function toISOString() {
607
+ return this.$d.toISOString();
608
+ };
609
+ _proto.toString = function toString() {
610
+ return this.$d.toUTCString();
611
+ };
612
+ return Dayjs2;
613
+ })();
614
+ var proto = Dayjs.prototype;
615
+ dayjs.prototype = proto;
616
+ [["$ms", MS], ["$s", S], ["$m", MIN], ["$H", H], ["$W", D], ["$M", M], ["$y", Y], ["$D", DATE]].forEach(function(g) {
617
+ proto[g[1]] = function(input) {
618
+ return this.$g(input, g[0], g[1]);
619
+ };
620
+ });
621
+ dayjs.extend = function(plugin, option) {
622
+ if (!plugin.$i) {
623
+ plugin(option, Dayjs, dayjs);
624
+ plugin.$i = true;
625
+ }
626
+ return dayjs;
627
+ };
628
+ dayjs.locale = parseLocale;
629
+ dayjs.isDayjs = isDayjs;
630
+ dayjs.unix = function(timestamp) {
631
+ return dayjs(timestamp * 1e3);
632
+ };
633
+ dayjs.en = Ls[L];
634
+ dayjs.Ls = Ls;
635
+ dayjs.p = {};
636
+ var esm_default = dayjs;
637
+
638
+ // src/system-root.ts
639
+ var TEMPLATE_ROOT_NAMES = ["scope", "system"];
640
+ var SYSTEM_TIME_METHOD_NAMES = [
641
+ "add",
642
+ "subtract",
643
+ "set",
644
+ "get",
645
+ "millisecond",
646
+ "second",
647
+ "minute",
648
+ "hour",
649
+ "date",
650
+ "day",
651
+ "weekday",
652
+ "isoWeekday",
653
+ "dayOfYear",
654
+ "week",
655
+ "isoWeek",
656
+ "month",
657
+ "quarter",
658
+ "year",
659
+ "weekYear",
660
+ "isoWeekYear",
661
+ "startOf",
662
+ "endOf",
663
+ "format",
664
+ "fromNow",
665
+ "toNow",
666
+ "from",
667
+ "to",
668
+ "calendar",
669
+ "diff",
670
+ "valueOf",
671
+ "unix",
672
+ "daysInMonth",
673
+ "toDate",
674
+ "toArray",
675
+ "toJSON",
676
+ "toISOString",
677
+ "toObject",
678
+ "toString",
679
+ "isBefore",
680
+ "isSame",
681
+ "isAfter",
682
+ "isSameOrBefore",
683
+ "isSameOrAfter",
684
+ "isBetween",
685
+ "isLeapYear",
686
+ "isValid",
687
+ "clone",
688
+ "locale",
689
+ "utcOffset",
690
+ "local",
691
+ "utc",
692
+ "isUTC"
693
+ ];
694
+ var SYSTEM_MATH_KEYS = [
695
+ "E",
696
+ "LN10",
697
+ "LN2",
698
+ "LOG10E",
699
+ "LOG2E",
700
+ "PI",
701
+ "SQRT1_2",
702
+ "SQRT2",
703
+ "abs",
704
+ "acos",
705
+ "acosh",
706
+ "asin",
707
+ "asinh",
708
+ "atan",
709
+ "atan2",
710
+ "atanh",
711
+ "cbrt",
712
+ "ceil",
713
+ "clz32",
714
+ "cos",
715
+ "cosh",
716
+ "exp",
717
+ "expm1",
718
+ "floor",
719
+ "fround",
720
+ "hypot",
721
+ "imul",
722
+ "log",
723
+ "log10",
724
+ "log1p",
725
+ "log2",
726
+ "max",
727
+ "min",
728
+ "pow",
729
+ "random",
730
+ "round",
731
+ "sign",
732
+ "sin",
733
+ "sinh",
734
+ "sqrt",
735
+ "tan",
736
+ "tanh",
737
+ "trunc"
738
+ ];
739
+ var SYSTEM_LOCATION_KEYS = [
740
+ "href",
741
+ "protocol",
742
+ "host",
743
+ "hostname",
744
+ "port",
745
+ "pathname",
746
+ "search",
747
+ "hash",
748
+ "origin",
749
+ "ancestorOrigins",
750
+ "assign",
751
+ "reload",
752
+ "replace",
753
+ "toString"
754
+ ];
755
+ function createLocationStub() {
756
+ return {
757
+ href: "",
758
+ protocol: "",
759
+ host: "",
760
+ hostname: "",
761
+ port: "",
762
+ pathname: "",
763
+ search: "",
764
+ hash: "",
765
+ origin: "",
766
+ assign() {
767
+ },
768
+ reload() {
769
+ },
770
+ replace() {
771
+ },
772
+ toString() {
773
+ return "";
774
+ }
775
+ };
776
+ }
777
+ function createSystemRoot() {
778
+ const locationValue = typeof globalThis !== "undefined" && "location" in globalThis && globalThis.location ? globalThis.location : createLocationStub();
779
+ return {
780
+ time: esm_default(),
781
+ math: Math,
782
+ location: locationValue
783
+ };
784
+ }
785
+ function getSystemAutocompleteTree() {
786
+ const timeMethods = {};
787
+ for (const name of SYSTEM_TIME_METHOD_NAMES) {
788
+ timeMethods[name] = /* @__PURE__ */ Object.create(null);
789
+ }
790
+ const mathKeys = {};
791
+ for (const name of SYSTEM_MATH_KEYS) {
792
+ mathKeys[name] = /* @__PURE__ */ Object.create(null);
793
+ }
794
+ const locationKeys = {};
795
+ for (const name of SYSTEM_LOCATION_KEYS) {
796
+ locationKeys[name] = /* @__PURE__ */ Object.create(null);
797
+ }
798
+ return {
799
+ time: timeMethods,
800
+ math: mathKeys,
801
+ location: locationKeys
802
+ };
803
+ }
804
+ function isDayjsValue(value) {
805
+ return esm_default.isDayjs(value);
806
+ }
807
+
163
808
  // src/scope-template.ts
164
- var SCOPE_TOKEN_RE = /\{(scope[^}]*)\}/g;
809
+ var TEMPLATE_TOKEN_RE = /\{((?:scope|system)[^}]*)\}/g;
165
810
  function hasScopeTemplate(value) {
166
- SCOPE_TOKEN_RE.lastIndex = 0;
167
- return SCOPE_TOKEN_RE.test(value);
811
+ TEMPLATE_TOKEN_RE.lastIndex = 0;
812
+ return TEMPLATE_TOKEN_RE.test(value);
168
813
  }
169
- function evaluateScopeExpression(expression, scope) {
814
+ var hasTemplateExpression = hasScopeTemplate;
815
+ function evaluateScopeExpression(expression, scope, system = createSystemRoot()) {
170
816
  const trimmed = expression.trim();
171
817
  if (!trimmed) return void 0;
172
818
  try {
173
- const fn = new Function("scope", `"use strict"; return (${trimmed});`);
174
- return fn(scope);
819
+ const fn = new Function(
820
+ "scope",
821
+ "system",
822
+ `"use strict"; return (${trimmed});`
823
+ );
824
+ return fn(scope, system);
175
825
  } catch {
176
826
  return void 0;
177
827
  }
@@ -182,6 +832,9 @@ function stringifyScopeValue(value) {
182
832
  if (typeof value === "number" || typeof value === "boolean") {
183
833
  return String(value);
184
834
  }
835
+ if (isDayjsValue(value)) {
836
+ return value.toISOString();
837
+ }
185
838
  try {
186
839
  return JSON.stringify(value);
187
840
  } catch {
@@ -208,24 +861,30 @@ function isInsideJsonString(before) {
208
861
  }
209
862
  return inString;
210
863
  }
211
- function replaceScopeTokens(template, scope, replacer) {
212
- SCOPE_TOKEN_RE.lastIndex = 0;
864
+ function replaceTemplateTokens(template, scope, system, replacer) {
865
+ TEMPLATE_TOKEN_RE.lastIndex = 0;
213
866
  return template.replace(
214
- SCOPE_TOKEN_RE,
215
- (_match, rawExpr, offset) => replacer(evaluateScopeExpression(rawExpr, scope), offset)
867
+ TEMPLATE_TOKEN_RE,
868
+ (_match, rawExpr, offset) => replacer(evaluateScopeExpression(rawExpr, scope, system), offset)
216
869
  );
217
870
  }
218
- function evaluateScopeTemplate(template, scope) {
871
+ function evaluateScopeTemplate(template, scope, system = createSystemRoot()) {
219
872
  if (!hasScopeTemplate(template)) return template;
220
- return replaceScopeTokens(template, scope, (value) => stringifyScopeValue(value));
873
+ return replaceTemplateTokens(
874
+ template,
875
+ scope,
876
+ system,
877
+ (value) => stringifyScopeValue(value)
878
+ );
221
879
  }
222
- function evaluateScopeTemplateInJson(template, scope) {
880
+ function evaluateScopeTemplateInJson(template, scope, system = createSystemRoot()) {
223
881
  if (!hasScopeTemplate(template)) return template;
224
- return replaceScopeTokens(template, scope, (value, offset) => {
882
+ return replaceTemplateTokens(template, scope, system, (value, offset) => {
225
883
  if (isInsideJsonString(template.slice(0, offset))) {
226
884
  return JSON.stringify(stringifyScopeValue(value)).slice(1, -1);
227
885
  }
228
886
  if (value === void 0) return "null";
887
+ if (isDayjsValue(value)) return JSON.stringify(value.toISOString());
229
888
  return JSON.stringify(value);
230
889
  });
231
890
  }
@@ -233,6 +892,9 @@ function looksLikeJsonText(text) {
233
892
  const trimmed = text.trim();
234
893
  return trimmed.startsWith("{") || trimmed.startsWith("[");
235
894
  }
895
+ function preserveTemplateTokensInEncode(value) {
896
+ return hasScopeTemplate(value);
897
+ }
236
898
 
237
899
  // src/fetch-config.ts
238
900
  var FETCH_HTTP_METHODS = [
@@ -277,7 +939,8 @@ function normalizeFetchRequestConfig(config) {
277
939
  ...config?.headers
278
940
  },
279
941
  headersJson: config?.headersJson,
280
- swaggerEndpoints: config?.swaggerEndpoints
942
+ swaggerEndpoints: config?.swaggerEndpoints,
943
+ apiCollectionSyncNotice: config?.apiCollectionSyncNotice
281
944
  };
282
945
  }
283
946
  function joinFetchUrl(base, path) {
@@ -425,8 +1088,8 @@ async function executeFetch(config, options) {
425
1088
  }
426
1089
 
427
1090
  // src/scope-autocomplete.ts
428
- function getValueAtPath(scope, path) {
429
- let current = scope;
1091
+ function getValueAtPath(root, path) {
1092
+ let current = root;
430
1093
  for (const part of path) {
431
1094
  if (current === null || typeof current !== "object") return void 0;
432
1095
  current = current[part];
@@ -439,63 +1102,193 @@ function listObjectKeys(value) {
439
1102
  }
440
1103
  return Object.keys(value);
441
1104
  }
1105
+ function matchRootPrefix(inner) {
1106
+ if (!inner) return "partial";
1107
+ for (const name of TEMPLATE_ROOT_NAMES) {
1108
+ if (inner === name) return name;
1109
+ if (name.startsWith(inner) && !inner.includes("?") && !inner.includes(".")) {
1110
+ return "partial";
1111
+ }
1112
+ }
1113
+ return null;
1114
+ }
1115
+ function splitPathBody(body) {
1116
+ let depth = 0;
1117
+ let current = "";
1118
+ const segments = [];
1119
+ let i = 0;
1120
+ while (i < body.length) {
1121
+ const ch = body[i];
1122
+ if (ch === "(" || ch === "[" || ch === "{") {
1123
+ depth += 1;
1124
+ current += ch;
1125
+ i += 1;
1126
+ continue;
1127
+ }
1128
+ if (ch === ")" || ch === "]" || ch === "}") {
1129
+ depth = Math.max(0, depth - 1);
1130
+ current += ch;
1131
+ i += 1;
1132
+ continue;
1133
+ }
1134
+ if (depth > 0) {
1135
+ current += ch;
1136
+ i += 1;
1137
+ continue;
1138
+ }
1139
+ if (body.startsWith("?.", i)) {
1140
+ segments.push(current);
1141
+ current = "";
1142
+ i += 2;
1143
+ continue;
1144
+ }
1145
+ if (ch === ".") {
1146
+ segments.push(current);
1147
+ current = "";
1148
+ i += 1;
1149
+ continue;
1150
+ }
1151
+ current += ch;
1152
+ i += 1;
1153
+ }
1154
+ if (depth > 0) return null;
1155
+ const endsWithSeparator = body.endsWith("?.") || body.endsWith(".") && !body.endsWith("?.") && !body.endsWith("..");
1156
+ if (endsWithSeparator) {
1157
+ const path = segments.map((s) => stripCallSuffix(s)).filter((s) => s.length > 0);
1158
+ return { segments: path, endsWithSeparator: true, partialOrComplete: "" };
1159
+ }
1160
+ const cleaned = segments.map((s) => stripCallSuffix(s)).filter((s) => s.length > 0);
1161
+ const lastRaw = current;
1162
+ const lastClean = stripCallSuffix(lastRaw);
1163
+ if (lastRaw.includes("(") && lastRaw.endsWith(")")) {
1164
+ return {
1165
+ segments: [...cleaned, lastClean].filter(Boolean),
1166
+ endsWithSeparator: false,
1167
+ partialOrComplete: lastClean
1168
+ };
1169
+ }
1170
+ return {
1171
+ segments: cleaned,
1172
+ endsWithSeparator: false,
1173
+ partialOrComplete: lastClean
1174
+ };
1175
+ }
1176
+ function stripCallSuffix(segment) {
1177
+ const idx = segment.indexOf("(");
1178
+ if (idx < 0) return segment.trim();
1179
+ return segment.slice(0, idx).trim();
1180
+ }
442
1181
  function parseScopeAutocomplete(text, cursor, scope) {
443
1182
  const before = text.slice(0, cursor);
444
1183
  const templateStart = before.lastIndexOf("{");
445
1184
  if (templateStart < 0) return null;
446
1185
  const inner = before.slice(templateStart + 1);
447
1186
  if (inner.includes("}")) return null;
448
- if (!inner.startsWith("scope")) return null;
449
- let body = inner.slice("scope".length);
450
- if (body === "" || body === "?") {
451
- return { templateStart, cursor, path: [], partialKey: "" };
1187
+ const rootMatch = matchRootPrefix(inner);
1188
+ if (rootMatch === "partial" || rootMatch && !inner.includes("?") && !inner.includes(".")) {
1189
+ if (!inner.includes("?") && !inner.includes(".") && !inner.includes("(")) {
1190
+ return {
1191
+ templateStart,
1192
+ cursor,
1193
+ suggestingRoot: true,
1194
+ root: typeof rootMatch === "string" && rootMatch !== "partial" ? rootMatch : null,
1195
+ path: [],
1196
+ partialKey: inner
1197
+ };
1198
+ }
452
1199
  }
453
- if (!body.startsWith("?.")) return null;
454
- body = body.slice(2);
455
- if (body === "") {
456
- return { templateStart, cursor, path: [], partialKey: "" };
1200
+ let root = null;
1201
+ let body = "";
1202
+ if (inner.startsWith("scope")) {
1203
+ root = "scope";
1204
+ body = inner.slice("scope".length);
1205
+ } else if (inner.startsWith("system")) {
1206
+ root = "system";
1207
+ body = inner.slice("system".length);
1208
+ } else {
1209
+ return null;
457
1210
  }
458
- const segments = body.split("?.");
459
- const endsWithSeparator = inner.endsWith("?.");
460
- if (endsWithSeparator) {
461
- const path = segments.filter((segment) => segment.length > 0);
462
- return { templateStart, cursor, path, partialKey: "" };
1211
+ if (body === "" || body === "?") {
1212
+ return {
1213
+ templateStart,
1214
+ cursor,
1215
+ suggestingRoot: false,
1216
+ root,
1217
+ path: [],
1218
+ partialKey: ""
1219
+ };
463
1220
  }
464
- const lastSegment = segments[segments.length - 1] ?? "";
465
- const prefixSegments = segments.slice(0, -1).filter((segment) => segment.length > 0);
466
- const parent = getValueAtPath(scope, prefixSegments);
467
- const keys = listObjectKeys(parent);
468
- if (lastSegment.length === 0) {
469
- return { templateStart, cursor, path: prefixSegments, partialKey: "" };
1221
+ if (body.startsWith("?.")) {
1222
+ body = body.slice(2);
1223
+ } else if (body.startsWith(".")) {
1224
+ body = body.slice(1);
1225
+ } else {
1226
+ return null;
1227
+ }
1228
+ if (body === "") {
1229
+ return {
1230
+ templateStart,
1231
+ cursor,
1232
+ suggestingRoot: false,
1233
+ root,
1234
+ path: [],
1235
+ partialKey: ""
1236
+ };
470
1237
  }
471
- if (keys.includes(lastSegment)) {
1238
+ const split = splitPathBody(body);
1239
+ if (!split) return null;
1240
+ if (split.endsWithSeparator) {
472
1241
  return {
473
1242
  templateStart,
474
1243
  cursor,
475
- path: [...prefixSegments, lastSegment],
1244
+ suggestingRoot: false,
1245
+ root,
1246
+ path: split.segments,
476
1247
  partialKey: ""
477
1248
  };
478
1249
  }
1250
+ const lastSegment = split.partialOrComplete;
1251
+ const prefixSegments = split.segments;
479
1252
  return {
480
1253
  templateStart,
481
1254
  cursor,
1255
+ suggestingRoot: false,
1256
+ root,
482
1257
  path: prefixSegments,
483
1258
  partialKey: lastSegment
484
1259
  };
485
1260
  }
1261
+ function resolveAutocompleteRoot(state, scope) {
1262
+ if (state.root === "system") return getSystemAutocompleteTree();
1263
+ return scope;
1264
+ }
486
1265
  function getScopeAutocompleteSuggestions(scope, state) {
487
- const parent = state.partialKey.length > 0 ? getValueAtPath(scope, state.path) : state.path.length > 0 ? getValueAtPath(scope, state.path) : scope;
488
- const keys = listObjectKeys(parent);
1266
+ if (state.suggestingRoot) {
1267
+ return TEMPLATE_ROOT_NAMES.filter(
1268
+ (name) => name.startsWith(state.partialKey)
1269
+ );
1270
+ }
1271
+ const dataRoot = resolveAutocompleteRoot(state, scope);
1272
+ if (dataRoot === void 0 || dataRoot === null) return [];
1273
+ const parent = state.path.length > 0 ? getValueAtPath(dataRoot, state.path) : dataRoot;
1274
+ let keys = listObjectKeys(parent);
489
1275
  if (state.partialKey.length === 0) return keys;
490
- return keys.filter((key) => key.startsWith(state.partialKey));
1276
+ keys = keys.filter((key) => key.startsWith(state.partialKey));
1277
+ return keys;
491
1278
  }
492
- function buildScopeExpression(path, selectedKey) {
493
- return `scope?.${[...path, selectedKey].join("?.")}`;
1279
+ function buildScopeExpression(path, selectedKey, root = "scope") {
1280
+ return `${root}?.${[...path, selectedKey].join("?.")}`;
494
1281
  }
495
1282
  function applyScopeAutocompleteSelection(text, state, selectedKey) {
496
- const expr = buildScopeExpression(state.path, selectedKey);
497
1283
  const before = text.slice(0, state.templateStart + 1);
498
1284
  const after = text.slice(state.cursor);
1285
+ let expr;
1286
+ if (state.suggestingRoot) {
1287
+ expr = `${selectedKey}?.`;
1288
+ } else {
1289
+ const root = state.root ?? "scope";
1290
+ expr = buildScopeExpression(state.path, selectedKey, root);
1291
+ }
499
1292
  const value = `${before}${expr}${after}`;
500
1293
  const cursor = before.length + expr.length;
501
1294
  return { value, cursor };
@@ -656,13 +1449,13 @@ function resolveFetchBody(body, scope) {
656
1449
  if (body === void 0) return void 0;
657
1450
  const trimmed = body.trim();
658
1451
  if (!trimmed) return body;
659
- if (scope !== void 0 && isWholeScopeExpression(trimmed)) {
1452
+ if (isWholeScopeExpression(trimmed)) {
660
1453
  const value = evaluateScopeExpression(trimmed.slice(1, -1), scope);
661
1454
  if (value === void 0) return "";
662
1455
  if (typeof value === "string") return value;
663
1456
  return stringifyScopeValue(value);
664
1457
  }
665
- if (scope === void 0 || !hasScopeTemplate(body)) return body;
1458
+ if (!hasScopeTemplate(body)) return body;
666
1459
  if (looksLikeJsonText(trimmed)) {
667
1460
  return evaluateScopeTemplateInJson(body, scope);
668
1461
  }
@@ -696,7 +1489,8 @@ function getFetchHeadersValidationError(config, scope) {
696
1489
  function isWholeScopeExpression(text) {
697
1490
  const trimmed = text.trim();
698
1491
  if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) return false;
699
- return trimmed.slice(1, -1).trim().startsWith("scope");
1492
+ const inner = trimmed.slice(1, -1).trim();
1493
+ return inner.startsWith("scope") || inner.startsWith("system");
700
1494
  }
701
1495
  function asHeaderRecord(value) {
702
1496
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
@@ -708,7 +1502,6 @@ function asHeaderRecord(value) {
708
1502
  return headers;
709
1503
  }
710
1504
  function applyScopeToHeaderRecord(headers, scope) {
711
- if (scope === void 0) return headers;
712
1505
  return Object.fromEntries(
713
1506
  Object.entries(headers).map(([key, value]) => [
714
1507
  evaluateScopeTemplate(String(key), scope),
@@ -720,12 +1513,11 @@ function parseFetchHeadersJson(text, scope) {
720
1513
  const trimmed = text.trim();
721
1514
  if (!trimmed) return {};
722
1515
  if (isWholeScopeExpression(trimmed)) {
723
- if (scope === void 0) return void 0;
724
1516
  const inner = trimmed.slice(1, -1);
725
1517
  return asHeaderRecord(evaluateScopeExpression(inner, scope));
726
1518
  }
727
1519
  let jsonText = trimmed;
728
- if (scope !== void 0 && hasScopeTemplate(trimmed) && looksLikeJsonText(trimmed)) {
1520
+ if (hasScopeTemplate(trimmed) && looksLikeJsonText(trimmed)) {
729
1521
  jsonText = evaluateScopeTemplateInJson(trimmed, scope);
730
1522
  }
731
1523
  try {
@@ -759,14 +1551,15 @@ function resolveFetchHeaders(config, scope) {
759
1551
  function applyFetchConfigScope(config, scope) {
760
1552
  const headers = resolveFetchHeaders(config, scope);
761
1553
  const body = resolveFetchBody(config.body, scope);
762
- if (scope === void 0) {
763
- if (headers === config.headers && body === config.body) return config;
764
- return { ...config, headers, body };
1554
+ const url = resolveTemplateString(config.url, scope) ?? "";
1555
+ const apiBaseUrl = resolveTemplateString(config.apiBaseUrl, scope);
1556
+ if (url === (config.url ?? "") && apiBaseUrl === config.apiBaseUrl && headers === config.headers && body === config.body) {
1557
+ return config;
765
1558
  }
766
1559
  return {
767
1560
  ...config,
768
- url: resolveTemplateString(config.url, scope) ?? "",
769
- apiBaseUrl: resolveTemplateString(config.apiBaseUrl, scope),
1561
+ url,
1562
+ apiBaseUrl,
770
1563
  body,
771
1564
  headers
772
1565
  };
@@ -782,30 +1575,322 @@ function fetchConfigHasScopeTemplate(config) {
782
1575
  );
783
1576
  }
784
1577
 
785
- // src/json-config.ts
786
- var DEFAULT_JSON_NODE_CONFIG = {
787
- jsonString: "{}"
788
- };
789
- function validateJsonString(jsonString) {
790
- const raw = jsonString?.trim();
791
- if (!raw) {
792
- return { ok: false, error: "JSON \u4E0D\u80FD\u4E3A\u7A7A" };
1578
+ // src/json-lint.ts
1579
+ var SUSPECT_CHAR_RE = /[\u201C\u201D\u2018\u2019\u300C\u300D\u300E\u300F\uFF0C\uFF1A\uFF1B\u3010\u3011\uFF08\uFF09\uFF01\uFF1F\u3001\u3002]/gu;
1580
+ function lineColToOffset(text, line, column) {
1581
+ const lines = text.split("\n");
1582
+ let offset = 0;
1583
+ const targetLine = Math.max(1, line) - 1;
1584
+ for (let i = 0; i < targetLine && i < lines.length; i += 1) {
1585
+ offset += lines[i].length + 1;
1586
+ }
1587
+ const col = Math.max(1, column) - 1;
1588
+ const lineText = lines[targetLine] ?? "";
1589
+ return offset + Math.min(col, lineText.length);
1590
+ }
1591
+ function extractJsonErrorPosition(message, text) {
1592
+ let match = /position\s+(\d+)/i.exec(message);
1593
+ if (match) {
1594
+ const pos = Number(match[1]);
1595
+ if (Number.isFinite(pos) && pos >= 0) {
1596
+ return Math.min(pos, Math.max(0, text.length - 1));
1597
+ }
1598
+ }
1599
+ match = /line\s+(\d+)\s+column\s+(\d+)/i.exec(message);
1600
+ if (match) {
1601
+ const pos = lineColToOffset(text, Number(match[1]), Number(match[2]));
1602
+ return Math.min(pos, Math.max(0, text.length - 1));
793
1603
  }
1604
+ match = /\bat\s+(\d+):(\d+)\b/.exec(message);
1605
+ if (match) {
1606
+ const pos = lineColToOffset(text, Number(match[1]), Number(match[2]));
1607
+ return Math.min(pos, Math.max(0, text.length - 1));
1608
+ }
1609
+ return null;
1610
+ }
1611
+ function findJsonSyntaxErrorOffset(text) {
1612
+ const src = text;
1613
+ const len = src.length;
1614
+ let i = 0;
1615
+ const peek = () => i < len ? src[i] : "";
1616
+ const fail = () => i < len ? i : Math.max(0, len - 1);
1617
+ const skipWs = () => {
1618
+ while (i < len && /[ \t\r\n]/.test(src[i])) i += 1;
1619
+ };
1620
+ const parseString = () => {
1621
+ if (peek() !== '"') return false;
1622
+ i += 1;
1623
+ while (i < len) {
1624
+ const c = src[i];
1625
+ if (c === '"') {
1626
+ i += 1;
1627
+ return true;
1628
+ }
1629
+ if (c === "\\") {
1630
+ i += 1;
1631
+ if (i >= len) return false;
1632
+ i += 1;
1633
+ continue;
1634
+ }
1635
+ i += 1;
1636
+ }
1637
+ return false;
1638
+ };
1639
+ const parseNumber = () => {
1640
+ const start = i;
1641
+ if (peek() === "-") i += 1;
1642
+ if (peek() === "0") {
1643
+ i += 1;
1644
+ } else if (/[1-9]/.test(peek())) {
1645
+ while (/[0-9]/.test(peek())) i += 1;
1646
+ } else {
1647
+ i = start;
1648
+ return false;
1649
+ }
1650
+ if (peek() === ".") {
1651
+ i += 1;
1652
+ if (!/[0-9]/.test(peek())) {
1653
+ return false;
1654
+ }
1655
+ while (/[0-9]/.test(peek())) i += 1;
1656
+ }
1657
+ if (peek() === "e" || peek() === "E") {
1658
+ i += 1;
1659
+ if (peek() === "+" || peek() === "-") i += 1;
1660
+ if (!/[0-9]/.test(peek())) return false;
1661
+ while (/[0-9]/.test(peek())) i += 1;
1662
+ }
1663
+ return i > start;
1664
+ };
1665
+ const parseLiteral = (word) => {
1666
+ if (src.startsWith(word, i)) {
1667
+ i += word.length;
1668
+ return true;
1669
+ }
1670
+ return false;
1671
+ };
1672
+ const parseValue = () => {
1673
+ skipWs();
1674
+ if (i >= len) return false;
1675
+ const c = peek();
1676
+ if (c === "{") return parseObject();
1677
+ if (c === "[") return parseArray();
1678
+ if (c === '"') return parseString();
1679
+ if (c === "-" || /[0-9]/.test(c)) return parseNumber();
1680
+ if (parseLiteral("true") || parseLiteral("false") || parseLiteral("null")) {
1681
+ return true;
1682
+ }
1683
+ return false;
1684
+ };
1685
+ const parseObject = () => {
1686
+ if (peek() !== "{") return false;
1687
+ i += 1;
1688
+ skipWs();
1689
+ if (peek() === "}") {
1690
+ i += 1;
1691
+ return true;
1692
+ }
1693
+ while (i < len) {
1694
+ skipWs();
1695
+ if (peek() !== '"') return false;
1696
+ if (!parseString()) return false;
1697
+ skipWs();
1698
+ if (peek() !== ":") return false;
1699
+ i += 1;
1700
+ if (!parseValue()) return false;
1701
+ skipWs();
1702
+ if (peek() === ",") {
1703
+ i += 1;
1704
+ skipWs();
1705
+ if (peek() === "}" || i >= len) return false;
1706
+ continue;
1707
+ }
1708
+ if (peek() === "}") {
1709
+ i += 1;
1710
+ return true;
1711
+ }
1712
+ return false;
1713
+ }
1714
+ return false;
1715
+ };
1716
+ const parseArray = () => {
1717
+ if (peek() !== "[") return false;
1718
+ i += 1;
1719
+ skipWs();
1720
+ if (peek() === "]") {
1721
+ i += 1;
1722
+ return true;
1723
+ }
1724
+ while (i < len) {
1725
+ if (!parseValue()) return false;
1726
+ skipWs();
1727
+ if (peek() === ",") {
1728
+ i += 1;
1729
+ skipWs();
1730
+ if (peek() === "]" || i >= len) return false;
1731
+ continue;
1732
+ }
1733
+ if (peek() === "]") {
1734
+ i += 1;
1735
+ return true;
1736
+ }
1737
+ return false;
1738
+ }
1739
+ return false;
1740
+ };
1741
+ skipWs();
1742
+ if (i >= len) return 0;
1743
+ if (!parseValue()) return fail();
1744
+ skipWs();
1745
+ if (i < len) return i;
1746
+ return null;
1747
+ }
1748
+ function expandAround(text, pos) {
1749
+ const len = text.length;
1750
+ if (len === 0) return { start: 0, end: 0, kind: "parse" };
1751
+ const clamped = Math.max(0, Math.min(pos, len - 1));
1752
+ const ch = text[clamped];
1753
+ SUSPECT_CHAR_RE.lastIndex = 0;
1754
+ if (SUSPECT_CHAR_RE.test(ch)) {
1755
+ let start = clamped;
1756
+ let end = clamped + 1;
1757
+ while (start > 0) {
1758
+ SUSPECT_CHAR_RE.lastIndex = 0;
1759
+ if (!SUSPECT_CHAR_RE.test(text[start - 1])) break;
1760
+ start -= 1;
1761
+ }
1762
+ while (end < len) {
1763
+ SUSPECT_CHAR_RE.lastIndex = 0;
1764
+ if (!SUSPECT_CHAR_RE.test(text[end])) break;
1765
+ end += 1;
1766
+ }
1767
+ return { start, end, kind: "parse" };
1768
+ }
1769
+ const isTokenChar = (c) => /[A-Za-z0-9_$.+\-]/.test(c);
1770
+ if (isTokenChar(ch)) {
1771
+ let start = clamped;
1772
+ let end = clamped + 1;
1773
+ while (start > 0 && isTokenChar(text[start - 1])) start -= 1;
1774
+ while (end < len && isTokenChar(text[end])) end += 1;
1775
+ return { start, end, kind: "parse" };
1776
+ }
1777
+ return { start: clamped, end: clamped + 1, kind: "parse" };
1778
+ }
1779
+ function findSuspectCharRanges(text) {
1780
+ const ranges = [];
1781
+ SUSPECT_CHAR_RE.lastIndex = 0;
1782
+ let match;
1783
+ while ((match = SUSPECT_CHAR_RE.exec(text)) !== null) {
1784
+ ranges.push({
1785
+ start: match.index,
1786
+ end: match.index + match[0].length,
1787
+ kind: "suspect"
1788
+ });
1789
+ }
1790
+ return ranges;
1791
+ }
1792
+ function mergeRanges(ranges) {
1793
+ if (ranges.length === 0) return [];
1794
+ const sorted = [...ranges].sort((a, b) => a.start - b.start || a.end - b.end);
1795
+ const out = [];
1796
+ for (const range of sorted) {
1797
+ const last = out[out.length - 1];
1798
+ if (!last || range.start > last.end) {
1799
+ out.push({ ...range });
1800
+ continue;
1801
+ }
1802
+ last.end = Math.max(last.end, range.end);
1803
+ if (last.kind === "parse" || range.kind === "parse") last.kind = "parse";
1804
+ }
1805
+ return out;
1806
+ }
1807
+ function lintJsonString(jsonString) {
1808
+ const raw = jsonString ?? "";
1809
+ const trimmed = raw.trim();
1810
+ if (!trimmed) {
1811
+ return { ok: false, error: "JSON \u4E0D\u80FD\u4E3A\u7A7A", ranges: [] };
1812
+ }
1813
+ const suspectRanges = findSuspectCharRanges(raw);
1814
+ const trimStart = raw.indexOf(trimmed);
1815
+ const offset = trimStart >= 0 ? trimStart : 0;
794
1816
  try {
795
- const value = JSON.parse(raw);
1817
+ const value = JSON.parse(trimmed);
796
1818
  if (value === null || typeof value !== "object") {
797
- return { ok: false, error: "JSON \u6839\u8282\u70B9\u5FC5\u987B\u662F object \u6216 array" };
1819
+ return {
1820
+ ok: false,
1821
+ error: "JSON \u6839\u8282\u70B9\u5FC5\u987B\u662F object \u6216 array",
1822
+ ranges: mergeRanges(suspectRanges)
1823
+ };
798
1824
  }
799
1825
  return { ok: true, value };
800
1826
  } catch (error) {
1827
+ const message = error instanceof Error ? error.message : "JSON \u683C\u5F0F\u65E0\u6548";
1828
+ const ranges = [...suspectRanges];
1829
+ const fromEngine = extractJsonErrorPosition(message, trimmed);
1830
+ const fromScan = findJsonSyntaxErrorOffset(trimmed);
1831
+ const pos = fromScan ?? fromEngine;
1832
+ if (pos != null) {
1833
+ ranges.push(expandAround(raw, offset + pos));
1834
+ } else if (ranges.length === 0 && raw.length > 0) {
1835
+ const first = raw.search(/\S/);
1836
+ ranges.push(expandAround(raw, first >= 0 ? first : 0));
1837
+ }
801
1838
  return {
802
1839
  ok: false,
803
- error: error instanceof Error ? error.message : "JSON \u683C\u5F0F\u65E0\u6548"
1840
+ error: message,
1841
+ ranges: mergeRanges(ranges)
804
1842
  };
805
1843
  }
806
1844
  }
807
- function parseJsonConfig(config) {
808
- const result = validateJsonString(config.jsonString ?? "");
1845
+ function renderJsonWithErrorHighlights(text, ranges, markClass = "json-lint-error") {
1846
+ const escape = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1847
+ const source = text ?? "";
1848
+ const merged = mergeRanges(
1849
+ ranges.filter((r) => r.end > r.start && r.start < source.length)
1850
+ );
1851
+ if (merged.length === 0) return escape(source) || "\n";
1852
+ let html = "";
1853
+ let cursor = 0;
1854
+ for (const range of merged) {
1855
+ const start = Math.max(0, range.start);
1856
+ const end = Math.min(source.length, range.end);
1857
+ if (start > cursor) html += escape(source.slice(cursor, start));
1858
+ if (end > start) {
1859
+ html += `<mark class="${markClass}">${escape(source.slice(start, end))}</mark>`;
1860
+ }
1861
+ cursor = Math.max(cursor, end);
1862
+ }
1863
+ if (cursor < source.length) html += escape(source.slice(cursor));
1864
+ return html;
1865
+ }
1866
+
1867
+ // src/json-config.ts
1868
+ var DEFAULT_JSON_NODE_CONFIG = {
1869
+ jsonString: "{}"
1870
+ };
1871
+ function validateJsonString(jsonString) {
1872
+ const result = lintJsonString(jsonString);
1873
+ if (!result.ok) {
1874
+ return { ok: false, error: result.error, ranges: result.ranges };
1875
+ }
1876
+ return { ok: true, value: result.value };
1877
+ }
1878
+ function validateJsonStringAllowingScope(jsonString) {
1879
+ const lint = lintJsonString(jsonString ?? "");
1880
+ if (!lint.ok) {
1881
+ return { ok: false, error: lint.error, ranges: lint.ranges };
1882
+ }
1883
+ if (hasScopeTemplate(jsonString ?? "")) {
1884
+ return { ok: true, deferred: true };
1885
+ }
1886
+ return { ok: true, value: lint.value };
1887
+ }
1888
+ function parseJsonConfig(config, scope) {
1889
+ let raw = config.jsonString ?? "";
1890
+ if (hasScopeTemplate(raw)) {
1891
+ raw = evaluateScopeTemplateInJson(raw, scope);
1892
+ }
1893
+ const result = validateJsonString(raw);
809
1894
  if (!result.ok) {
810
1895
  throw new Error(result.error);
811
1896
  }
@@ -862,6 +1947,20 @@ function resolveStorageWriteValue(template, scope) {
862
1947
  }
863
1948
  return raw;
864
1949
  }
1950
+ function resolveStorageKey(key, scope) {
1951
+ const raw = key ?? "";
1952
+ const trimmed = raw.trim();
1953
+ if (!trimmed) return "";
1954
+ if (isWholeScopeExpression(trimmed)) {
1955
+ return stringifyScopeValue(
1956
+ evaluateScopeExpression(trimmed.slice(1, -1), scope)
1957
+ );
1958
+ }
1959
+ if (hasScopeTemplate(raw)) {
1960
+ return evaluateScopeTemplate(raw, scope).trim();
1961
+ }
1962
+ return trimmed;
1963
+ }
865
1964
  function serializeStorageValue(value) {
866
1965
  if (value === void 0 || value === null) return "";
867
1966
  if (typeof value === "string") return value;
@@ -893,6 +1992,35 @@ function getDefaultStorageAccessors() {
893
1992
  return null;
894
1993
  }
895
1994
  }
1995
+ function readBrowserStorageBucket(kind) {
1996
+ if (typeof window === "undefined") return null;
1997
+ try {
1998
+ return kind === "session" ? window.sessionStorage : window.localStorage;
1999
+ } catch {
2000
+ return null;
2001
+ }
2002
+ }
2003
+ function listBrowserStorageKeys(kind) {
2004
+ const kinds = uniqueStorageKinds(Array.isArray(kind) ? kind : [kind]);
2005
+ const keys = /* @__PURE__ */ new Set();
2006
+ for (const next of kinds) {
2007
+ const storage = readBrowserStorageBucket(next);
2008
+ if (!storage) continue;
2009
+ try {
2010
+ for (let i = 0; i < storage.length; i += 1) {
2011
+ const key = storage.key(i);
2012
+ if (typeof key === "string" && key) keys.add(key);
2013
+ }
2014
+ } catch {
2015
+ }
2016
+ }
2017
+ return [...keys].sort((a, b) => a.localeCompare(b));
2018
+ }
2019
+ function filterStorageKeySuggestions(keys, query) {
2020
+ const q = query.trim().toLowerCase();
2021
+ if (!q) return [...keys];
2022
+ return keys.filter((key) => key.toLowerCase().includes(q));
2023
+ }
896
2024
  function requireStorage(accessors, kind) {
897
2025
  const target = kind === "session" ? accessors?.session : accessors?.local;
898
2026
  if (!target) {
@@ -908,7 +2036,10 @@ function executeStorageConfig(config, incomingScope, accessors) {
908
2036
  if (isStorageSetConfigured(normalized)) {
909
2037
  const value = resolveStorageWriteValue(normalized.set.value, incomingScope);
910
2038
  const serialized = serializeStorageValue(value);
911
- const key = normalized.set.key.trim();
2039
+ const key = resolveStorageKey(normalized.set.key, incomingScope);
2040
+ if (!key) {
2041
+ throw new Error("\u5B58\u50A8\u5199\u5165 key \u89E3\u6790\u4E3A\u7A7A");
2042
+ }
912
2043
  for (const kind of normalized.set.storages) {
913
2044
  requireStorage(store, kind).setItem(key, serialized);
914
2045
  }
@@ -916,10 +2047,12 @@ function executeStorageConfig(config, incomingScope, accessors) {
916
2047
  if (!isStorageReadConfigured(normalized)) {
917
2048
  return null;
918
2049
  }
2050
+ const readKey = resolveStorageKey(normalized.read.key, incomingScope);
2051
+ if (!readKey) {
2052
+ return null;
2053
+ }
919
2054
  return deserializeStorageValue(
920
- requireStorage(store, normalized.read.storage).getItem(
921
- normalized.read.key.trim()
922
- )
2055
+ requireStorage(store, normalized.read.storage).getItem(readKey)
923
2056
  );
924
2057
  }
925
2058
 
@@ -1292,16 +2425,16 @@ function parseSwaggerDocument(spec, docsUrl) {
1292
2425
  if (!spec || typeof spec !== "object") {
1293
2426
  throw new Error("Swagger \u6587\u6863\u683C\u5F0F\u65E0\u6548");
1294
2427
  }
1295
- const document = spec;
1296
- if (typeof document.openapi === "string") {
1297
- const parsed = parseOpenApiV3(document, docsUrl);
2428
+ const document2 = spec;
2429
+ if (typeof document2.openapi === "string") {
2430
+ const parsed = parseOpenApiV3(document2, docsUrl);
1298
2431
  if (parsed.endpoints.length === 0) {
1299
2432
  throw new Error("\u672A\u5728 OpenAPI \u6587\u6863\u4E2D\u627E\u5230\u63A5\u53E3");
1300
2433
  }
1301
2434
  return parsed;
1302
2435
  }
1303
- if (document.swagger === "2.0" || document.swagger === 2) {
1304
- const parsed = parseSwaggerV2(document, docsUrl);
2436
+ if (document2.swagger === "2.0" || document2.swagger === 2) {
2437
+ const parsed = parseSwaggerV2(document2, docsUrl);
1305
2438
  if (parsed.endpoints.length === 0) {
1306
2439
  throw new Error("\u672A\u5728 Swagger 2.0 \u6587\u6863\u4E2D\u627E\u5230\u63A5\u53E3");
1307
2440
  }
@@ -1336,6 +2469,329 @@ function filterEndpointSuggestions(suggestions, query) {
1336
2469
  );
1337
2470
  }
1338
2471
 
2472
+ // src/api-collection.ts
2473
+ var API_COLLECTION_DOCUMENT_VERSION = 1;
2474
+ var HTTP_METHOD_SET = new Set(FETCH_HTTP_METHODS);
2475
+ function isPlainStringRecord(value) {
2476
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
2477
+ return Object.values(value).every(
2478
+ (item) => typeof item === "string"
2479
+ );
2480
+ }
2481
+ function normalizeEndpoint(raw, index) {
2482
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
2483
+ return `apis[${index}] \u5FC5\u987B\u662F\u5BF9\u8C61`;
2484
+ }
2485
+ const item = raw;
2486
+ const name = typeof item.name === "string" ? item.name.trim() : "";
2487
+ if (!name) return `apis[${index}].name \u5FC5\u586B\u4E14\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32`;
2488
+ const url = typeof item.url === "string" ? item.url.trim() : "";
2489
+ if (!url) return `apis[${index}].url \u5FC5\u586B\u4E14\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32`;
2490
+ const methodRaw = typeof item.method === "string" ? item.method.trim().toUpperCase() : "";
2491
+ if (!HTTP_METHOD_SET.has(methodRaw)) {
2492
+ return `apis[${index}].method \u5FC5\u987B\u662F ${FETCH_HTTP_METHODS.join(" / ")} \u4E4B\u4E00`;
2493
+ }
2494
+ if (item.params !== void 0 && !isPlainStringRecord(item.params)) {
2495
+ return `apis[${index}].params \u5FC5\u987B\u662F string \u5B57\u5178`;
2496
+ }
2497
+ if (item.headers !== void 0 && !isPlainStringRecord(item.headers)) {
2498
+ return `apis[${index}].headers \u5FC5\u987B\u662F string \u5B57\u5178`;
2499
+ }
2500
+ if (item.body !== void 0 && typeof item.body !== "string") {
2501
+ return `apis[${index}].body \u5FC5\u987B\u662F\u5B57\u7B26\u4E32`;
2502
+ }
2503
+ if (item.description !== void 0 && typeof item.description !== "string") {
2504
+ return `apis[${index}].description \u5FC5\u987B\u662F\u5B57\u7B26\u4E32`;
2505
+ }
2506
+ return {
2507
+ name,
2508
+ url,
2509
+ method: methodRaw,
2510
+ ...item.params ? { params: item.params } : {},
2511
+ ...item.headers ? { headers: item.headers } : {},
2512
+ ...typeof item.body === "string" ? { body: item.body } : {},
2513
+ ...typeof item.description === "string" ? { description: item.description } : {}
2514
+ };
2515
+ }
2516
+ function validateApiCollectionDocument(input) {
2517
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
2518
+ return { ok: false, error: "\u6839\u8282\u70B9\u5FC5\u987B\u662F\u5BF9\u8C61" };
2519
+ }
2520
+ const root = input;
2521
+ const version = root.version;
2522
+ if (version !== API_COLLECTION_DOCUMENT_VERSION && version !== "1") {
2523
+ return {
2524
+ ok: false,
2525
+ error: `version \u5FC5\u987B\u4E3A ${API_COLLECTION_DOCUMENT_VERSION}`
2526
+ };
2527
+ }
2528
+ const name = typeof root.name === "string" ? root.name.trim() : "";
2529
+ if (!name) return { ok: false, error: "name \u5FC5\u586B\u4E14\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32" };
2530
+ if (root.baseUrl !== void 0 && typeof root.baseUrl !== "string") {
2531
+ return { ok: false, error: "baseUrl \u5FC5\u987B\u662F\u5B57\u7B26\u4E32" };
2532
+ }
2533
+ if (!Array.isArray(root.apis)) {
2534
+ return { ok: false, error: "apis \u5FC5\u987B\u662F\u6570\u7EC4" };
2535
+ }
2536
+ if (root.apis.length === 0) {
2537
+ return { ok: false, error: "apis \u81F3\u5C11\u5305\u542B\u4E00\u6761\u63A5\u53E3" };
2538
+ }
2539
+ const apis = [];
2540
+ const nameSet = /* @__PURE__ */ new Set();
2541
+ for (let i = 0; i < root.apis.length; i += 1) {
2542
+ const normalized = normalizeEndpoint(root.apis[i], i);
2543
+ if (typeof normalized === "string") {
2544
+ return { ok: false, error: normalized };
2545
+ }
2546
+ if (nameSet.has(normalized.name)) {
2547
+ return { ok: false, error: `\u63A5\u53E3\u540D\u79F0\u91CD\u590D\uFF1A${normalized.name}` };
2548
+ }
2549
+ nameSet.add(normalized.name);
2550
+ apis.push(normalized);
2551
+ }
2552
+ return {
2553
+ ok: true,
2554
+ document: {
2555
+ version: API_COLLECTION_DOCUMENT_VERSION,
2556
+ name,
2557
+ ...typeof root.baseUrl === "string" && root.baseUrl.trim() ? { baseUrl: root.baseUrl.trim() } : {},
2558
+ apis
2559
+ }
2560
+ };
2561
+ }
2562
+ function parseApiCollectionJson(text) {
2563
+ const trimmed = text.trim();
2564
+ if (!trimmed) return { ok: false, error: "\u5185\u5BB9\u4E3A\u7A7A" };
2565
+ let parsed;
2566
+ try {
2567
+ parsed = JSON.parse(trimmed);
2568
+ } catch (error) {
2569
+ return {
2570
+ ok: false,
2571
+ error: `\u4E0D\u662F\u6709\u6548 JSON\uFF1A${error instanceof Error ? error.message : "\u683C\u5F0F\u65E0\u6548"}`
2572
+ };
2573
+ }
2574
+ const validated = validateApiCollectionDocument(parsed);
2575
+ if (!validated.ok) return validated;
2576
+ return {
2577
+ ok: true,
2578
+ document: validated.document,
2579
+ rawJson: JSON.stringify(validated.document, null, 2)
2580
+ };
2581
+ }
2582
+ function createApiCollectionId() {
2583
+ return `api_col_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
2584
+ }
2585
+ function apiCollectionToListItem(record) {
2586
+ return {
2587
+ id: record.id,
2588
+ name: record.name,
2589
+ persistLocal: record.persistLocal,
2590
+ apiCount: record.document.apis.length,
2591
+ updatedAt: record.updatedAt
2592
+ };
2593
+ }
2594
+ function getApiCollectionTemplateDocument() {
2595
+ return {
2596
+ version: API_COLLECTION_DOCUMENT_VERSION,
2597
+ name: "\u793A\u4F8B\u63A5\u53E3\u96C6\u5408",
2598
+ baseUrl: "https://api.example.com",
2599
+ apis: [
2600
+ {
2601
+ name: "\u83B7\u53D6\u7528\u6237\u5217\u8868",
2602
+ method: "GET",
2603
+ url: "/users",
2604
+ params: {
2605
+ page: "{scope?.value?.page}",
2606
+ pageSize: "20",
2607
+ tenant: "{scope?.value?.tenant}"
2608
+ },
2609
+ headers: {
2610
+ Accept: "application/json",
2611
+ Authorization: "Bearer {scope?.value?.token}"
2612
+ },
2613
+ description: "\u5206\u9875\u67E5\u8BE2\u7528\u6237\uFF1Bpage / tenant / token \u53EF\u7528 Scope \u6A21\u7248"
2614
+ },
2615
+ {
2616
+ name: "\u521B\u5EFA\u7528\u6237",
2617
+ method: "POST",
2618
+ url: "/tenants/{scope?.value?.tenant}/users",
2619
+ headers: { "Content-Type": "application/json" },
2620
+ body: '{\n "name": "{scope?.value?.name}",\n "role": "member"\n}',
2621
+ description: "\u521B\u5EFA\u7528\u6237\uFF1BURL \u4E0E body \u5747\u652F\u6301 Scope \u6A21\u7248"
2622
+ },
2623
+ {
2624
+ name: "\u83B7\u53D6\u7528\u6237\u8BE6\u60C5",
2625
+ method: "GET",
2626
+ url: "/users/{scope?.value?.id}",
2627
+ headers: { Accept: "application/json" },
2628
+ description: "\u6309 id \u67E5\u8BE2\uFF1B\u8DEF\u5F84\u91CC\u53EF\u76F4\u63A5\u5199 Scope \u6A21\u7248"
2629
+ }
2630
+ ]
2631
+ };
2632
+ }
2633
+ function getApiCollectionTemplateJson() {
2634
+ return `${JSON.stringify(getApiCollectionTemplateDocument(), null, 2)}
2635
+ `;
2636
+ }
2637
+ function downloadApiCollectionTemplate(filename = "abuilder-api-collection-template.json") {
2638
+ if (typeof document === "undefined") return;
2639
+ const blob = new Blob([getApiCollectionTemplateJson()], {
2640
+ type: "application/json;charset=utf-8"
2641
+ });
2642
+ const url = URL.createObjectURL(blob);
2643
+ const anchor = document.createElement("a");
2644
+ anchor.href = url;
2645
+ anchor.download = filename;
2646
+ anchor.click();
2647
+ URL.revokeObjectURL(url);
2648
+ }
2649
+ function encodeQueryValuePreservingScope(value) {
2650
+ if (!hasScopeTemplate(value)) return encodeURIComponent(value);
2651
+ const re = /\{((?:scope|system)[^}]*)\}/g;
2652
+ let result = "";
2653
+ let lastIndex = 0;
2654
+ let match;
2655
+ while ((match = re.exec(value)) !== null) {
2656
+ result += encodeURIComponent(value.slice(lastIndex, match.index));
2657
+ result += match[0];
2658
+ lastIndex = match.index + match[0].length;
2659
+ }
2660
+ result += encodeURIComponent(value.slice(lastIndex));
2661
+ return result;
2662
+ }
2663
+ function buildApiCollectionEndpointUrl(endpoint) {
2664
+ const base = endpoint.url.trim();
2665
+ const params = endpoint.params;
2666
+ if (!params || Object.keys(params).length === 0) return base;
2667
+ const search = Object.entries(params).filter(([, value]) => value !== void 0 && value !== null && String(value).length > 0).map(
2668
+ ([key, value]) => `${encodeURIComponent(key)}=${encodeQueryValuePreservingScope(String(value))}`
2669
+ ).join("&");
2670
+ if (!search) return base;
2671
+ return base.includes("?") ? `${base}&${search}` : `${base}?${search}`;
2672
+ }
2673
+ function normalizeApiCollectionUrlKey(url) {
2674
+ const trimmed = url.trim();
2675
+ if (!trimmed) return "";
2676
+ const withoutHash = trimmed.split("#")[0] ?? trimmed;
2677
+ const queryIndex = withoutHash.indexOf("?");
2678
+ const pathOnly = queryIndex === -1 ? withoutHash : withoutHash.slice(0, queryIndex);
2679
+ const normalized = pathOnly.replace(/\/+$/, "");
2680
+ return normalized || "/";
2681
+ }
2682
+ function stableHeadersText(headers) {
2683
+ if (!headers || Object.keys(headers).length === 0) return "";
2684
+ const sorted = Object.keys(headers).sort().reduce((acc, key) => {
2685
+ acc[key] = headers[key] ?? "";
2686
+ return acc;
2687
+ }, {});
2688
+ return JSON.stringify(sorted);
2689
+ }
2690
+ function diffFetchConfigChanges(prev, next) {
2691
+ const changed = [];
2692
+ const prevUrl = prev?.url?.trim() ?? "";
2693
+ const nextUrl = next.url?.trim() ?? "";
2694
+ if (prevUrl !== nextUrl) changed.push("url");
2695
+ const prevMethod = (prev?.method ?? "GET").toUpperCase();
2696
+ const nextMethod = (next.method ?? "GET").toUpperCase();
2697
+ if (prevMethod !== nextMethod) changed.push("method");
2698
+ if (stableHeadersText(prev?.headers) !== stableHeadersText(next.headers)) {
2699
+ changed.push("headers");
2700
+ }
2701
+ if ((prev?.body ?? "").trim() !== (next.body ?? "").trim()) {
2702
+ changed.push("body");
2703
+ }
2704
+ if ((prev?.apiBaseUrl?.trim() ?? "") !== (next.apiBaseUrl?.trim() ?? "")) {
2705
+ changed.push("apiBaseUrl");
2706
+ }
2707
+ return changed;
2708
+ }
2709
+ function pickEndpointForNode(node, collectionId, candidates) {
2710
+ if (candidates.length === 0) return null;
2711
+ if (candidates.length === 1) return candidates[0] ?? null;
2712
+ const config = node.fetchConfig;
2713
+ if (config?.apiCollectionId === collectionId && config.apiCollectionEndpointName) {
2714
+ const byName = candidates.find(
2715
+ (item) => item.name === config.apiCollectionEndpointName
2716
+ );
2717
+ if (byName) return byName;
2718
+ }
2719
+ const method = config?.method?.toUpperCase();
2720
+ if (method) {
2721
+ const byMethod = candidates.filter((item) => item.method === method);
2722
+ if (byMethod.length === 1) return byMethod[0] ?? null;
2723
+ if (byMethod.length > 1) return byMethod[0] ?? null;
2724
+ }
2725
+ return candidates[0] ?? null;
2726
+ }
2727
+ function buildApiCollectionSyncPatches(options) {
2728
+ const { collectionId, document: document2, nodes } = options;
2729
+ const byUrl = /* @__PURE__ */ new Map();
2730
+ for (const endpoint of document2.apis) {
2731
+ const key = normalizeApiCollectionUrlKey(endpoint.url);
2732
+ if (!key) continue;
2733
+ const list = byUrl.get(key) ?? [];
2734
+ list.push(endpoint);
2735
+ byUrl.set(key, list);
2736
+ }
2737
+ const patches = [];
2738
+ const syncedAt = Date.now();
2739
+ for (const node of nodes) {
2740
+ const nodeUrl = node.fetchConfig?.url;
2741
+ if (!nodeUrl?.trim()) continue;
2742
+ const key = normalizeApiCollectionUrlKey(nodeUrl);
2743
+ if (!key) continue;
2744
+ const candidates = byUrl.get(key) ?? [];
2745
+ const endpoint = pickEndpointForNode(node, collectionId, candidates);
2746
+ if (!endpoint) continue;
2747
+ const fetchConfigPatch = applyApiCollectionEndpointToFetchConfig({
2748
+ collectionId,
2749
+ document: document2,
2750
+ endpoint
2751
+ });
2752
+ const changedFields = diffFetchConfigChanges(node.fetchConfig, fetchConfigPatch);
2753
+ fetchConfigPatch.apiCollectionSyncNotice = {
2754
+ source: "api-collection-sync",
2755
+ collectionName: document2.name,
2756
+ endpointName: endpoint.name,
2757
+ changedFields,
2758
+ updatedAt: syncedAt
2759
+ };
2760
+ patches.push({
2761
+ nodeId: node.id,
2762
+ nodeLabel: (node.label ?? "").trim() || node.id,
2763
+ changedFields,
2764
+ fetchConfigPatch
2765
+ });
2766
+ }
2767
+ return patches;
2768
+ }
2769
+ function toApiCollectionSyncResult(patches) {
2770
+ return {
2771
+ updatedCount: patches.length,
2772
+ nodes: patches.map((patch) => ({
2773
+ id: patch.nodeId,
2774
+ label: patch.nodeLabel,
2775
+ changedFields: patch.changedFields
2776
+ }))
2777
+ };
2778
+ }
2779
+ function applyApiCollectionEndpointToFetchConfig(options) {
2780
+ const { collectionId, document: document2, endpoint } = options;
2781
+ const headers = endpoint.headers ?? {};
2782
+ return {
2783
+ url: buildApiCollectionEndpointUrl(endpoint),
2784
+ method: endpoint.method,
2785
+ headers,
2786
+ headersJson: Object.keys(headers).length > 0 ? JSON.stringify(headers, null, 2) : "",
2787
+ body: endpoint.body ?? "",
2788
+ apiBaseUrl: document2.baseUrl?.trim() || void 0,
2789
+ urlInputMode: "collection",
2790
+ apiCollectionId: collectionId,
2791
+ apiCollectionEndpointName: endpoint.name
2792
+ };
2793
+ }
2794
+
1339
2795
  // src/runtime/execution-trace.ts
1340
2796
  function serializeTraceValue(value) {
1341
2797
  if (value === void 0) return void 0;
@@ -2444,7 +3900,12 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2444
3900
  ...DEFAULT_JSON_NODE_CONFIG,
2445
3901
  ...node.jsonConfig
2446
3902
  };
2447
- const value = parseJsonConfig(config);
3903
+ const incomingScope = runner.buildFetchIncomingScope(
3904
+ token.nodeId,
3905
+ "in",
3906
+ input
3907
+ );
3908
+ const value = parseJsonConfig(config, incomingScope);
2448
3909
  io.setOutput("out", createTrueSignal(value));
2449
3910
  } catch (error) {
2450
3911
  io.setOutput(
@@ -2755,6 +4216,7 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2755
4216
  };
2756
4217
 
2757
4218
  exports.AND_NODE_TYPE = AND_NODE_TYPE;
4219
+ exports.API_COLLECTION_DOCUMENT_VERSION = API_COLLECTION_DOCUMENT_VERSION;
2758
4220
  exports.BLUEPRINT_ACTIVATION_INPUT_KEY = BLUEPRINT_ACTIVATION_INPUT_KEY;
2759
4221
  exports.BLUEPRINT_CALL_STACK_KEY = BLUEPRINT_CALL_STACK_KEY;
2760
4222
  exports.BLUEPRINT_NODE_TYPE = BLUEPRINT_NODE_TYPE;
@@ -2786,6 +4248,10 @@ exports.PAGE_LIFECYCLE_LABELS = PAGE_LIFECYCLE_LABELS;
2786
4248
  exports.PAGE_LIFECYCLE_PHASES = PAGE_LIFECYCLE_PHASES;
2787
4249
  exports.STORAGE_KINDS = STORAGE_KINDS;
2788
4250
  exports.STORAGE_NODE_TYPE = STORAGE_NODE_TYPE;
4251
+ exports.SYSTEM_LOCATION_KEYS = SYSTEM_LOCATION_KEYS;
4252
+ exports.SYSTEM_MATH_KEYS = SYSTEM_MATH_KEYS;
4253
+ exports.SYSTEM_TIME_METHOD_NAMES = SYSTEM_TIME_METHOD_NAMES;
4254
+ exports.TEMPLATE_ROOT_NAMES = TEMPLATE_ROOT_NAMES;
2789
4255
  exports.UI_EVENT_PAYLOAD_KEY = UI_EVENT_PAYLOAD_KEY;
2790
4256
  exports.VIEW_EVENT_SIGNAL_KEY = VIEW_EVENT_SIGNAL_KEY;
2791
4257
  exports.VIEW_EVENT_TYPES = VIEW_EVENT_TYPES;
@@ -2793,11 +4259,15 @@ exports.VIEW_NODE_TYPE = VIEW_NODE_TYPE;
2793
4259
  exports.abortClockNode = abortClockNode;
2794
4260
  exports.abortClockSession = abortClockSession;
2795
4261
  exports.andLogicNodeDefinition = andLogicNodeDefinition;
4262
+ exports.apiCollectionToListItem = apiCollectionToListItem;
2796
4263
  exports.appStorageKey = appStorageKey;
4264
+ exports.applyApiCollectionEndpointToFetchConfig = applyApiCollectionEndpointToFetchConfig;
2797
4265
  exports.applyFetchConfigScope = applyFetchConfigScope;
2798
4266
  exports.applyScopeAutocompleteSelection = applyScopeAutocompleteSelection;
2799
4267
  exports.assertNoBlueprintReferenceCycle = assertNoBlueprintReferenceCycle;
2800
4268
  exports.blueprintNodeDefinition = blueprintNodeDefinition;
4269
+ exports.buildApiCollectionEndpointUrl = buildApiCollectionEndpointUrl;
4270
+ exports.buildApiCollectionSyncPatches = buildApiCollectionSyncPatches;
2801
4271
  exports.buildClockSessionKey = buildClockSessionKey;
2802
4272
  exports.buildClockSignalValue = buildClockSignalValue;
2803
4273
  exports.buildEndpointFullUrl = buildEndpointFullUrl;
@@ -2812,10 +4282,12 @@ exports.collectBlueprintLibraryRefs = collectBlueprintLibraryRefs;
2812
4282
  exports.collectIncomingNodeScopeEntries = collectIncomingNodeScopeEntries;
2813
4283
  exports.collectViewEventBindings = collectViewEventBindings;
2814
4284
  exports.combinePortSignalsOr = combinePortSignalsOr;
4285
+ exports.createApiCollectionId = createApiCollectionId;
2815
4286
  exports.createClockOutputValue = createClockOutputValue;
2816
4287
  exports.createFalseSignal = createFalseSignal;
2817
4288
  exports.createIncomingNodeScopeEntry = createIncomingNodeScopeEntry;
2818
4289
  exports.createLifecycleSignal = createLifecycleSignal;
4290
+ exports.createSystemRoot = createSystemRoot;
2819
4291
  exports.createTraceEntryId = createTraceEntryId;
2820
4292
  exports.createTrueSignal = createTrueSignal;
2821
4293
  exports.createViewEventSignal = createViewEventSignal;
@@ -2823,6 +4295,7 @@ exports.defaultLogicNodeDefinition = defaultLogicNodeDefinition;
2823
4295
  exports.deserializeStorageValue = deserializeStorageValue;
2824
4296
  exports.detectBlueprintReferenceCycle = detectBlueprintReferenceCycle;
2825
4297
  exports.detectRuntimeBlueprintCycle = detectRuntimeBlueprintCycle;
4298
+ exports.downloadApiCollectionTemplate = downloadApiCollectionTemplate;
2826
4299
  exports.draftFetchHeadersText = draftFetchHeadersText;
2827
4300
  exports.evaluateScopeExpression = evaluateScopeExpression;
2828
4301
  exports.evaluateScopeTemplate = evaluateScopeTemplate;
@@ -2830,22 +4303,31 @@ exports.evaluateScopeTemplateInJson = evaluateScopeTemplateInJson;
2830
4303
  exports.executeFetch = executeFetch;
2831
4304
  exports.executeLogicConfig = executeLogicConfig;
2832
4305
  exports.executeStorageConfig = executeStorageConfig;
4306
+ exports.extractJsonErrorPosition = extractJsonErrorPosition;
2833
4307
  exports.fetchConfigHasScopeTemplate = fetchConfigHasScopeTemplate;
2834
4308
  exports.fetchNodeDefinition = fetchNodeDefinition;
2835
4309
  exports.filterEndpointSuggestions = filterEndpointSuggestions;
4310
+ exports.filterStorageKeySuggestions = filterStorageKeySuggestions;
4311
+ exports.findJsonSyntaxErrorOffset = findJsonSyntaxErrorOffset;
4312
+ exports.findSuspectCharRanges = findSuspectCharRanges;
2836
4313
  exports.formatBlueprintCycleMessage = formatBlueprintCycleMessage;
2837
4314
  exports.formatClockTime = formatClockTime;
2838
4315
  exports.getActiveClockNodeIds = getActiveClockNodeIds;
4316
+ exports.getApiCollectionTemplateDocument = getApiCollectionTemplateDocument;
4317
+ exports.getApiCollectionTemplateJson = getApiCollectionTemplateJson;
2839
4318
  exports.getClockTickDelayOffsetMs = getClockTickDelayOffsetMs;
2840
4319
  exports.getClockTickWaitMs = getClockTickWaitMs;
2841
4320
  exports.getFetchBodyValidationError = getFetchBodyValidationError;
2842
4321
  exports.getFetchHeadersValidationError = getFetchHeadersValidationError;
2843
4322
  exports.getNodeDefinition = getNodeDefinition;
2844
4323
  exports.getScopeAutocompleteSuggestions = getScopeAutocompleteSuggestions;
4324
+ exports.getSystemAutocompleteTree = getSystemAutocompleteTree;
2845
4325
  exports.hasScopeTemplate = hasScopeTemplate;
4326
+ exports.hasTemplateExpression = hasTemplateExpression;
2846
4327
  exports.isClockNodeActive = isClockNodeActive;
2847
4328
  exports.isClockScheduleActive = isClockScheduleActive;
2848
4329
  exports.isClockSessionAborted = isClockSessionAborted;
4330
+ exports.isDayjsValue = isDayjsValue;
2849
4331
  exports.isFalseSignal = isFalseSignal;
2850
4332
  exports.isStorageReadConfigured = isStorageReadConfigured;
2851
4333
  exports.isStorageSetConfigured = isStorageSetConfigured;
@@ -2855,25 +4337,32 @@ exports.isWholeScopeExpression = isWholeScopeExpression;
2855
4337
  exports.jsonNodeDefinition = jsonNodeDefinition;
2856
4338
  exports.latestTraceOutputsByNode = latestTraceOutputsByNode;
2857
4339
  exports.lifecycleNodeDefinition = lifecycleNodeDefinition;
4340
+ exports.lintJsonString = lintJsonString;
4341
+ exports.listBrowserStorageKeys = listBrowserStorageKeys;
2858
4342
  exports.looksLikeJsonText = looksLikeJsonText;
2859
4343
  exports.nodeDefinitionRegistry = nodeDefinitionRegistry;
4344
+ exports.normalizeApiCollectionUrlKey = normalizeApiCollectionUrlKey;
2860
4345
  exports.normalizeAppNameSpace = normalizeAppNameSpace;
2861
4346
  exports.normalizeClockConfig = normalizeClockConfig;
2862
4347
  exports.normalizeFetchRequestConfig = normalizeFetchRequestConfig;
2863
4348
  exports.normalizeStorageConfig = normalizeStorageConfig;
2864
4349
  exports.normalizeViewEventConfig = normalizeViewEventConfig;
4350
+ exports.parseApiCollectionJson = parseApiCollectionJson;
2865
4351
  exports.parseFetchHeadersJson = parseFetchHeadersJson;
2866
4352
  exports.parseJsonConfig = parseJsonConfig;
2867
4353
  exports.parseJsonText = parseJsonText;
2868
4354
  exports.parseScopeAutocomplete = parseScopeAutocomplete;
2869
4355
  exports.parseSwaggerDocument = parseSwaggerDocument;
4356
+ exports.preserveTemplateTokensInEncode = preserveTemplateTokensInEncode;
2870
4357
  exports.registerDefaultBehaviors = registerDefaultBehaviors;
4358
+ exports.renderJsonWithErrorHighlights = renderJsonWithErrorHighlights;
2871
4359
  exports.resolveBlueprintCallStack = resolveBlueprintCallStack;
2872
4360
  exports.resolveFetchBody = resolveFetchBody;
2873
4361
  exports.resolveFetchHeaders = resolveFetchHeaders;
2874
4362
  exports.resolveFetchIncomingScope = resolveFetchIncomingScope;
2875
4363
  exports.resolveFetchRequestUrl = resolveFetchRequestUrl;
2876
4364
  exports.resolveFetchScopeAutocompleteRoot = resolveFetchScopeAutocompleteRoot;
4365
+ exports.resolveStorageKey = resolveStorageKey;
2877
4366
  exports.resolveStorageWriteValue = resolveStorageWriteValue;
2878
4367
  exports.scheduleClockOutputs = scheduleClockOutputs;
2879
4368
  exports.serializeStorageValue = serializeStorageValue;
@@ -2886,10 +4375,13 @@ exports.stopClockSchedule = stopClockSchedule;
2886
4375
  exports.storageNodeDefinition = storageNodeDefinition;
2887
4376
  exports.stringifyScopeValue = stringifyScopeValue;
2888
4377
  exports.subscribeActiveClockNodes = subscribeActiveClockNodes;
4378
+ exports.toApiCollectionSyncResult = toApiCollectionSyncResult;
2889
4379
  exports.uniqueStorageKinds = uniqueStorageKinds;
4380
+ exports.validateApiCollectionDocument = validateApiCollectionDocument;
2890
4381
  exports.validateClockScheduleConfig = validateClockScheduleConfig;
2891
4382
  exports.validateFetchJsonText = validateFetchJsonText;
2892
4383
  exports.validateJsonString = validateJsonString;
4384
+ exports.validateJsonStringAllowingScope = validateJsonStringAllowingScope;
2893
4385
  exports.validateLogicSourceCode = validateLogicSourceCode;
2894
4386
  exports.viewBindNodeDefinition = viewBindNodeDefinition;
2895
4387
  exports.viewEventNodeDefinition = viewEventNodeDefinition;