@arronqzy/blueprint-dsl 1.0.15 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,3 +1,144 @@
1
+ // src/messages.ts
2
+ var ZH_CN = {
3
+ invalidJson: "\u4E0D\u662F\u6709\u6548 JSON\uFF1A{reason}",
4
+ invalidFormat: "\u683C\u5F0F\u65E0\u6548",
5
+ jsonInvalid: "JSON \u683C\u5F0F\u65E0\u6548",
6
+ jsonEmpty: "JSON \u4E0D\u80FD\u4E3A\u7A7A",
7
+ jsonRootMustBeContainer: "JSON \u6839\u8282\u70B9\u5FC5\u987B\u662F object \u6216 array",
8
+ contentEmpty: "\u5185\u5BB9\u4E3A\u7A7A",
9
+ contentRequired: "\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A",
10
+ codeRequired: "\u4EE3\u7801\u4E0D\u80FD\u4E3A\u7A7A",
11
+ javascriptSyntaxError: "JavaScript \u8BED\u6CD5\u9519\u8BEF",
12
+ logicUpdateRequired: "\u9700\u8981\u5B9A\u4E49 update(input) \u51FD\u6570",
13
+ apiItemMustBeObject: "apis[{index}] \u5FC5\u987B\u662F\u5BF9\u8C61",
14
+ apiItemFieldRequired: "apis[{index}].{field} \u5FC5\u586B\u4E14\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32",
15
+ apiItemMethodInvalid: "apis[{index}].method \u5FC5\u987B\u662F {methods} \u4E4B\u4E00",
16
+ apiItemFieldStringMap: "apis[{index}].{field} \u5FC5\u987B\u662F string \u5B57\u5178",
17
+ apiItemFieldString: "apis[{index}].{field} \u5FC5\u987B\u662F\u5B57\u7B26\u4E32",
18
+ apiRootMustBeObject: "\u6839\u8282\u70B9\u5FC5\u987B\u662F\u5BF9\u8C61",
19
+ apiVersionMismatch: "version \u5FC5\u987B\u4E3A {version}",
20
+ apiNameRequired: "name \u5FC5\u586B\u4E14\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32",
21
+ apiBaseUrlString: "baseUrl \u5FC5\u987B\u662F\u5B57\u7B26\u4E32",
22
+ apiListMustBeArray: "apis \u5FC5\u987B\u662F\u6570\u7EC4",
23
+ apiListEmpty: "apis \u81F3\u5C11\u5305\u542B\u4E00\u6761\u63A5\u53E3",
24
+ apiNameDuplicated: "\u63A5\u53E3\u540D\u79F0\u91CD\u590D\uFF1A{name}",
25
+ apiTemplateName: "\u793A\u4F8B\u63A5\u53E3\u96C6\u5408",
26
+ apiTemplateListUsers: "\u83B7\u53D6\u7528\u6237\u5217\u8868",
27
+ apiTemplateListUsersDesc: "\u5206\u9875\u67E5\u8BE2\u7528\u6237\uFF1Bpage / tenant / token \u53EF\u7528 Scope \u6A21\u7248",
28
+ apiTemplateCreateUser: "\u521B\u5EFA\u7528\u6237",
29
+ apiTemplateCreateUserDesc: "\u521B\u5EFA\u7528\u6237\uFF1BURL \u4E0E body \u5747\u652F\u6301 Scope \u6A21\u7248",
30
+ apiTemplateGetUser: "\u83B7\u53D6\u7528\u6237\u8BE6\u60C5",
31
+ apiTemplateGetUserDesc: "\u6309 id \u67E5\u8BE2\uFF1B\u8DEF\u5F84\u91CC\u53EF\u76F4\u63A5\u5199 Scope \u6A21\u7248",
32
+ fetchUrlMissing: "\u8BF7\u6C42 URL \u672A\u914D\u7F6E",
33
+ fetchBodyInvalidJson: "\u8BF7\u6C42\u4F53\u4E0D\u662F\u6709\u6548 JSON\uFF1A{reason}",
34
+ fetchResponseInvalidJson: "\u54CD\u5E94\u4E0D\u662F\u6709\u6548\u7684 JSON",
35
+ fetchAborted: "\u8BF7\u6C42\u5DF2\u4E2D\u6B62",
36
+ fetchTimeout: "\u8BF7\u6C42\u8D85\u65F6\uFF08{ms}ms\uFF09",
37
+ headersTemplateNotObject: "\u8BF7\u6C42\u5934\u6A21\u677F\u89E3\u6790\u540E\u4E0D\u662F\u6709\u6548\u7684 JSON \u5BF9\u8C61",
38
+ headersNotObject: "\u8BF7\u6C42\u5934\u4E0D\u662F\u6709\u6548\u7684 JSON \u5BF9\u8C61",
39
+ swaggerInvalid: "Swagger \u6587\u6863\u683C\u5F0F\u65E0\u6548",
40
+ openApiNoOperations: "\u672A\u5728 OpenAPI \u6587\u6863\u4E2D\u627E\u5230\u63A5\u53E3",
41
+ swagger2NoOperations: "\u672A\u5728 Swagger 2.0 \u6587\u6863\u4E2D\u627E\u5230\u63A5\u53E3",
42
+ swaggerUnsupported: "\u4EC5\u652F\u6301 OpenAPI 3.x \u4E0E Swagger 2.0 \u6587\u6863",
43
+ storageUnsupported: "\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301 {storage}",
44
+ storageKeyEmpty: "\u5B58\u50A8\u5199\u5165 key \u89E3\u6790\u4E3A\u7A7A",
45
+ clockCountPositive: "\u8F93\u51FA\u6B21\u6570\u987B\u5927\u4E8E 0",
46
+ clockIntervalPositive: "\u5F53\u524D\u914D\u7F6E\u4E0B\u65F6\u949F\u4FE1\u53F7\u95F4\u9694\u987B\u5927\u4E8E 0 \u79D2",
47
+ lifecycleSignalMissing: "\u751F\u547D\u5468\u671F\u4FE1\u53F7\u7F3A\u5931",
48
+ blueprintCycle: "\u84DD\u56FE\u5F15\u7528\u5B58\u5728\u6B7B\u5FAA\u73AF\uFF1A{path}",
49
+ debugMustStartFromLifecycle: "\u8C03\u8BD5\u4F1A\u8BDD\u53EA\u80FD\u4ECE\u751F\u547D\u5468\u671F\u8282\u70B9\u5F00\u59CB",
50
+ nodeRemoved: "\u8282\u70B9\u5DF2\u4ECE\u84DD\u56FE\u4E2D\u79FB\u9664",
51
+ clockNeedsTrue: "\u65F6\u949F\u8282\u70B9\u9700\u8981\u6536\u5230\u771F\u4FE1\u53F7\u540E\u624D\u4F1A\u542F\u52A8",
52
+ blueprintNeedsTrue: "\u84DD\u56FE\u8282\u70B9\u9700\u8981\u6536\u5230\u771F\u4FE1\u53F7\u540E\u624D\u4F1A\u6267\u884C",
53
+ blueprintNotSelected: "\u672A\u9009\u62E9\u84DD\u56FE\u5E93\u4E2D\u7684\u84DD\u56FE",
54
+ blueprintResolverMissing: "\u84DD\u56FE\u5E93\u89E3\u6790\u5668\u672A\u914D\u7F6E",
55
+ blueprintRecordMissing: "\u84DD\u56FE\u5E93\u8BB0\u5F55\u4E0D\u5B58\u5728: {id}",
56
+ fetchNoUpstream: "\u6570\u636E\u6E90\u8282\u70B9\u672A\u6536\u5230\u4E0A\u6E38\u8F93\u51FA\uFF0C\u8BF7\u786E\u8BA4\u8FDE\u7EBF\u4E0E\u4E0A\u6E38\u8282\u70B9\u5DF2\u6267\u884C",
57
+ fetchNeedsTrue: "\u6570\u636E\u6E90\u8282\u70B9\u9700\u8981\u6536\u5230\u771F\u4FE1\u53F7\u540E\u624D\u4F1A\u53D1\u8D77\u8BF7\u6C42",
58
+ jsonNeedsTrue: "JSON \u8282\u70B9\u9700\u8981\u6536\u5230\u771F\u4FE1\u53F7\u540E\u624D\u4F1A\u89E3\u6790",
59
+ storageNeedsTrue: "\u5B58\u50A8\u8282\u70B9\u9700\u8981\u6536\u5230\u771F\u4FE1\u53F7\u540E\u624D\u4F1A\u8BFB\u5199\u7F13\u5B58",
60
+ andNeedsBothTrue: "\u5E76\u8FD0\u7B97\uFF1A\u4E24\u4E2A\u8F93\u5165\u987B\u5747\u4E3A\u771F\u4FE1\u53F7"
61
+ };
62
+ var EN_US = {
63
+ invalidJson: "Invalid JSON: {reason}",
64
+ invalidFormat: "invalid format",
65
+ jsonInvalid: "Invalid JSON",
66
+ jsonEmpty: "JSON cannot be empty",
67
+ jsonRootMustBeContainer: "JSON root must be an object or array",
68
+ contentEmpty: "Content is empty",
69
+ contentRequired: "Content cannot be empty",
70
+ codeRequired: "Code cannot be empty",
71
+ javascriptSyntaxError: "JavaScript syntax error",
72
+ logicUpdateRequired: "An update(input) function is required",
73
+ apiItemMustBeObject: "apis[{index}] must be an object",
74
+ apiItemFieldRequired: "apis[{index}].{field} is required and must be a non-empty string",
75
+ apiItemMethodInvalid: "apis[{index}].method must be one of {methods}",
76
+ apiItemFieldStringMap: "apis[{index}].{field} must be a string map",
77
+ apiItemFieldString: "apis[{index}].{field} must be a string",
78
+ apiRootMustBeObject: "Root must be an object",
79
+ apiVersionMismatch: "version must be {version}",
80
+ apiNameRequired: "name is required and must be a non-empty string",
81
+ apiBaseUrlString: "baseUrl must be a string",
82
+ apiListMustBeArray: "apis must be an array",
83
+ apiListEmpty: "apis must contain at least one API",
84
+ apiNameDuplicated: "Duplicate API name: {name}",
85
+ apiTemplateName: "Sample API collection",
86
+ apiTemplateListUsers: "List users",
87
+ apiTemplateListUsersDesc: "Paged user query; page / tenant / token accept Scope templates",
88
+ apiTemplateCreateUser: "Create user",
89
+ apiTemplateCreateUserDesc: "Create a user; URL and body both accept Scope templates",
90
+ apiTemplateGetUser: "Get user detail",
91
+ apiTemplateGetUserDesc: "Query by id; Scope templates can be used directly in the path",
92
+ fetchUrlMissing: "Request URL is not configured",
93
+ fetchBodyInvalidJson: "Request body is not valid JSON: {reason}",
94
+ fetchResponseInvalidJson: "Response is not valid JSON",
95
+ fetchAborted: "Request aborted",
96
+ fetchTimeout: "Request timed out ({ms}ms)",
97
+ headersTemplateNotObject: "Headers template does not resolve to a JSON object",
98
+ headersNotObject: "Headers are not a valid JSON object",
99
+ swaggerInvalid: "Invalid Swagger document",
100
+ openApiNoOperations: "No operations found in the OpenAPI document",
101
+ swagger2NoOperations: "No operations found in the Swagger 2.0 document",
102
+ swaggerUnsupported: "Only OpenAPI 3.x and Swagger 2.0 documents are supported",
103
+ storageUnsupported: "{storage} is not available in this environment",
104
+ storageKeyEmpty: "Storage write key resolved to empty",
105
+ clockCountPositive: "Output count must be greater than 0",
106
+ clockIntervalPositive: "Clock interval must be greater than 0 seconds with the current config",
107
+ lifecycleSignalMissing: "Lifecycle signal is missing",
108
+ blueprintCycle: "Blueprint references form a cycle: {path}",
109
+ debugMustStartFromLifecycle: "A debug session can only start from a lifecycle node",
110
+ nodeRemoved: "Node was removed from the blueprint",
111
+ clockNeedsTrue: "Clock node starts only after receiving a true signal",
112
+ blueprintNeedsTrue: "Blueprint node runs only after receiving a true signal",
113
+ blueprintNotSelected: "No blueprint selected from the library",
114
+ blueprintResolverMissing: "Blueprint library resolver is not configured",
115
+ blueprintRecordMissing: "Blueprint library record not found: {id}",
116
+ fetchNoUpstream: "Data source node received no upstream output; check the connection and that upstream nodes ran",
117
+ fetchNeedsTrue: "Data source node sends the request only after receiving a true signal",
118
+ jsonNeedsTrue: "JSON node parses only after receiving a true signal",
119
+ storageNeedsTrue: "Storage node reads/writes only after receiving a true signal",
120
+ andNeedsBothTrue: "AND: both inputs must be true signals"
121
+ };
122
+ var CATALOGS = {
123
+ "zh-CN": ZH_CN,
124
+ "en-US": EN_US
125
+ };
126
+ var currentLocale = "zh-CN";
127
+ function setBlueprintDslLocale(locale) {
128
+ currentLocale = locale;
129
+ }
130
+ function getBlueprintDslLocale() {
131
+ return currentLocale;
132
+ }
133
+ function dslMessage(key, params) {
134
+ const template = CATALOGS[currentLocale][key];
135
+ if (!params) return template;
136
+ return template.replace(
137
+ /\{(\w+)\}/g,
138
+ (match, name) => name in params ? String(params[name]) : match
139
+ );
140
+ }
141
+
1
142
  // src/lifecycle.ts
2
143
  var PAGE_LIFECYCLE_PHASES = [
3
144
  "created",
@@ -137,7 +278,7 @@ function registerDefaultBehaviors(registry) {
137
278
  registry.registerJS("lifecycle-emit", async ({ token, io }) => {
138
279
  const lifecycle = token.scope.vars.get(LIFECYCLE_SIGNAL_KEY);
139
280
  if (!lifecycle) {
140
- io.setOutput("out", createFalseSignal("\u751F\u547D\u5468\u671F\u4FE1\u53F7\u7F3A\u5931"));
281
+ io.setOutput("out", createFalseSignal(dslMessage("lifecycleSignalMissing")));
141
282
  } else if (lifecycle.phase === "blueprintActivated") {
142
283
  io.setOutput(
143
284
  "out",
@@ -158,18 +299,668 @@ function registerDefaultBehaviors(registry) {
158
299
  });
159
300
  }
160
301
 
302
+ // vendor/dayjs/esm/constant.js
303
+ var SECONDS_A_MINUTE = 60;
304
+ var SECONDS_A_HOUR = SECONDS_A_MINUTE * 60;
305
+ var SECONDS_A_DAY = SECONDS_A_HOUR * 24;
306
+ var SECONDS_A_WEEK = SECONDS_A_DAY * 7;
307
+ var MILLISECONDS_A_SECOND = 1e3;
308
+ var MILLISECONDS_A_MINUTE = SECONDS_A_MINUTE * MILLISECONDS_A_SECOND;
309
+ var MILLISECONDS_A_HOUR = SECONDS_A_HOUR * MILLISECONDS_A_SECOND;
310
+ var MILLISECONDS_A_DAY = SECONDS_A_DAY * MILLISECONDS_A_SECOND;
311
+ var MILLISECONDS_A_WEEK = SECONDS_A_WEEK * MILLISECONDS_A_SECOND;
312
+ var MS = "millisecond";
313
+ var S = "second";
314
+ var MIN = "minute";
315
+ var H = "hour";
316
+ var D = "day";
317
+ var W = "week";
318
+ var M = "month";
319
+ var Q = "quarter";
320
+ var Y = "year";
321
+ var DATE = "date";
322
+ var FORMAT_DEFAULT = "YYYY-MM-DDTHH:mm:ssZ";
323
+ var INVALID_DATE_STRING = "Invalid Date";
324
+ var REGEX_PARSE = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/;
325
+ 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;
326
+
327
+ // vendor/dayjs/esm/locale/en.js
328
+ var en_default = {
329
+ name: "en",
330
+ weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
331
+ months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
332
+ ordinal: function ordinal(n) {
333
+ var s = ["th", "st", "nd", "rd"];
334
+ var v = n % 100;
335
+ return "[" + n + (s[(v - 20) % 10] || s[v] || s[0]) + "]";
336
+ }
337
+ };
338
+
339
+ // vendor/dayjs/esm/utils.js
340
+ var padStart = function padStart2(string, length, pad) {
341
+ var s = String(string);
342
+ if (!s || s.length >= length) return string;
343
+ return "" + Array(length + 1 - s.length).join(pad) + string;
344
+ };
345
+ var padZoneStr = function padZoneStr2(instance) {
346
+ var negMinutes = -instance.utcOffset();
347
+ var minutes = Math.abs(negMinutes);
348
+ var hourOffset = Math.floor(minutes / 60);
349
+ var minuteOffset = minutes % 60;
350
+ return (negMinutes <= 0 ? "+" : "-") + padStart(hourOffset, 2, "0") + ":" + padStart(minuteOffset, 2, "0");
351
+ };
352
+ var monthDiff = function monthDiff2(a, b) {
353
+ if (a.date() < b.date()) return -monthDiff2(b, a);
354
+ var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month());
355
+ var anchor = a.clone().add(wholeMonthDiff, M);
356
+ var c = b - anchor < 0;
357
+ var anchor2 = a.clone().add(wholeMonthDiff + (c ? -1 : 1), M);
358
+ return +(-(wholeMonthDiff + (b - anchor) / (c ? anchor - anchor2 : anchor2 - anchor)) || 0);
359
+ };
360
+ var absFloor = function absFloor2(n) {
361
+ return n < 0 ? Math.ceil(n) || 0 : Math.floor(n);
362
+ };
363
+ var prettyUnit = function prettyUnit2(u) {
364
+ var special = {
365
+ M,
366
+ y: Y,
367
+ w: W,
368
+ d: D,
369
+ D: DATE,
370
+ h: H,
371
+ m: MIN,
372
+ s: S,
373
+ ms: MS,
374
+ Q
375
+ };
376
+ return special[u] || String(u || "").toLowerCase().replace(/s$/, "");
377
+ };
378
+ var isUndefined = function isUndefined2(s) {
379
+ return s === void 0;
380
+ };
381
+ var utils_default = {
382
+ s: padStart,
383
+ z: padZoneStr,
384
+ m: monthDiff,
385
+ a: absFloor,
386
+ p: prettyUnit,
387
+ u: isUndefined
388
+ };
389
+
390
+ // vendor/dayjs/esm/index.js
391
+ var L = "en";
392
+ var Ls = {};
393
+ Ls[L] = en_default;
394
+ var IS_DAYJS = "$isDayjsObject";
395
+ var isDayjs = function isDayjs2(d) {
396
+ return d instanceof Dayjs || !!(d && d[IS_DAYJS]);
397
+ };
398
+ var parseLocale = function parseLocale2(preset, object, isLocal) {
399
+ var l;
400
+ if (!preset) return L;
401
+ if (typeof preset === "string") {
402
+ var presetLower = preset.toLowerCase();
403
+ if (Ls[presetLower]) {
404
+ l = presetLower;
405
+ }
406
+ if (object) {
407
+ Ls[presetLower] = object;
408
+ l = presetLower;
409
+ }
410
+ var presetSplit = preset.split("-");
411
+ if (!l && presetSplit.length > 1) {
412
+ return parseLocale2(presetSplit[0]);
413
+ }
414
+ } else {
415
+ var name = preset.name;
416
+ Ls[name] = preset;
417
+ l = name;
418
+ }
419
+ if (!isLocal && l) L = l;
420
+ return l || !isLocal && L;
421
+ };
422
+ var dayjs = function dayjs2(date, c) {
423
+ if (isDayjs(date)) {
424
+ return date.clone();
425
+ }
426
+ var cfg = typeof c === "object" ? c : {};
427
+ cfg.date = date;
428
+ cfg.args = arguments;
429
+ return new Dayjs(cfg);
430
+ };
431
+ var wrapper = function wrapper2(date, instance) {
432
+ return dayjs(date, {
433
+ locale: instance.$L,
434
+ utc: instance.$u,
435
+ x: instance.$x,
436
+ $offset: instance.$offset
437
+ // todo: refactor; do not use this.$offset in you code
438
+ });
439
+ };
440
+ var Utils = utils_default;
441
+ Utils.l = parseLocale;
442
+ Utils.i = isDayjs;
443
+ Utils.w = wrapper;
444
+ var parseDate = function parseDate2(cfg) {
445
+ var date = cfg.date, utc = cfg.utc;
446
+ if (date === null) return /* @__PURE__ */ new Date(NaN);
447
+ if (Utils.u(date)) return /* @__PURE__ */ new Date();
448
+ if (date instanceof Date) return new Date(date);
449
+ if (typeof date === "string" && !/Z$/i.test(date)) {
450
+ var d = date.match(REGEX_PARSE);
451
+ if (d) {
452
+ var m = d[2] - 1 || 0;
453
+ var ms = (d[7] || "0").substring(0, 3);
454
+ if (utc) {
455
+ return new Date(Date.UTC(d[1], m, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms));
456
+ }
457
+ return new Date(d[1], m, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms);
458
+ }
459
+ }
460
+ return new Date(date);
461
+ };
462
+ var Dayjs = /* @__PURE__ */ (function() {
463
+ function Dayjs2(cfg) {
464
+ this.$L = parseLocale(cfg.locale, null, true);
465
+ this.parse(cfg);
466
+ this.$x = this.$x || cfg.x || {};
467
+ this[IS_DAYJS] = true;
468
+ }
469
+ var _proto = Dayjs2.prototype;
470
+ _proto.parse = function parse(cfg) {
471
+ this.$d = parseDate(cfg);
472
+ this.init();
473
+ };
474
+ _proto.init = function init() {
475
+ var $d = this.$d;
476
+ this.$y = $d.getFullYear();
477
+ this.$M = $d.getMonth();
478
+ this.$D = $d.getDate();
479
+ this.$W = $d.getDay();
480
+ this.$H = $d.getHours();
481
+ this.$m = $d.getMinutes();
482
+ this.$s = $d.getSeconds();
483
+ this.$ms = $d.getMilliseconds();
484
+ };
485
+ _proto.$utils = function $utils() {
486
+ return Utils;
487
+ };
488
+ _proto.isValid = function isValid() {
489
+ return !(this.$d.toString() === INVALID_DATE_STRING);
490
+ };
491
+ _proto.isSame = function isSame(that, units) {
492
+ var other = dayjs(that);
493
+ return this.startOf(units) <= other && other <= this.endOf(units);
494
+ };
495
+ _proto.isAfter = function isAfter(that, units) {
496
+ return dayjs(that) < this.startOf(units);
497
+ };
498
+ _proto.isBefore = function isBefore(that, units) {
499
+ return this.endOf(units) < dayjs(that);
500
+ };
501
+ _proto.$g = function $g(input, get, set) {
502
+ if (Utils.u(input)) return this[get];
503
+ return this.set(set, input);
504
+ };
505
+ _proto.unix = function unix() {
506
+ return Math.floor(this.valueOf() / 1e3);
507
+ };
508
+ _proto.valueOf = function valueOf() {
509
+ return this.$d.getTime();
510
+ };
511
+ _proto.startOf = function startOf(units, _startOf) {
512
+ var _this = this;
513
+ var isStartOf = !Utils.u(_startOf) ? _startOf : true;
514
+ var unit = Utils.p(units);
515
+ var instanceFactory = function instanceFactory2(d, m) {
516
+ var ins = Utils.w(_this.$u ? Date.UTC(_this.$y, m, d) : new Date(_this.$y, m, d), _this);
517
+ return isStartOf ? ins : ins.endOf(D);
518
+ };
519
+ var instanceFactorySet = function instanceFactorySet2(method, slice) {
520
+ var argumentStart = [0, 0, 0, 0];
521
+ var argumentEnd = [23, 59, 59, 999];
522
+ return Utils.w(_this.toDate()[method].apply(
523
+ // eslint-disable-line prefer-spread
524
+ _this.toDate("s"),
525
+ (isStartOf ? argumentStart : argumentEnd).slice(slice)
526
+ ), _this);
527
+ };
528
+ var $W = this.$W, $M = this.$M, $D = this.$D;
529
+ var utcPad = "set" + (this.$u ? "UTC" : "");
530
+ switch (unit) {
531
+ case Y:
532
+ return isStartOf ? instanceFactory(1, 0) : instanceFactory(31, 11);
533
+ case M:
534
+ return isStartOf ? instanceFactory(1, $M) : instanceFactory(0, $M + 1);
535
+ case W: {
536
+ var weekStart = this.$locale().weekStart || 0;
537
+ var gap = ($W < weekStart ? $W + 7 : $W) - weekStart;
538
+ return instanceFactory(isStartOf ? $D - gap : $D + (6 - gap), $M);
539
+ }
540
+ case D:
541
+ case DATE:
542
+ return instanceFactorySet(utcPad + "Hours", 0);
543
+ case H:
544
+ return instanceFactorySet(utcPad + "Minutes", 1);
545
+ case MIN:
546
+ return instanceFactorySet(utcPad + "Seconds", 2);
547
+ case S:
548
+ return instanceFactorySet(utcPad + "Milliseconds", 3);
549
+ default:
550
+ return this.clone();
551
+ }
552
+ };
553
+ _proto.endOf = function endOf(arg) {
554
+ return this.startOf(arg, false);
555
+ };
556
+ _proto.$set = function $set(units, _int) {
557
+ var _C$D$C$DATE$C$M$C$Y$C;
558
+ var unit = Utils.p(units);
559
+ var utcPad = "set" + (this.$u ? "UTC" : "");
560
+ 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];
561
+ var arg = unit === D ? this.$D + (_int - this.$W) : _int;
562
+ if (unit === M || unit === Y) {
563
+ var date = this.clone().set(DATE, 1);
564
+ date.$d[name](arg);
565
+ date.init();
566
+ this.$d = date.set(DATE, Math.min(this.$D, date.daysInMonth())).$d;
567
+ } else if (name) this.$d[name](arg);
568
+ this.init();
569
+ return this;
570
+ };
571
+ _proto.set = function set(string, _int2) {
572
+ return this.clone().$set(string, _int2);
573
+ };
574
+ _proto.get = function get(unit) {
575
+ return this[Utils.p(unit)]();
576
+ };
577
+ _proto.add = function add(number, units) {
578
+ var _this2 = this, _C$MIN$C$H$C$S$unit;
579
+ number = Number(number);
580
+ var unit = Utils.p(units);
581
+ var instanceFactorySet = function instanceFactorySet2(n) {
582
+ var d = dayjs(_this2);
583
+ return Utils.w(d.date(d.date() + Math.round(n * number)), _this2);
584
+ };
585
+ if (unit === M) {
586
+ return this.set(M, this.$M + number);
587
+ }
588
+ if (unit === Y) {
589
+ return this.set(Y, this.$y + number);
590
+ }
591
+ if (unit === D) {
592
+ return instanceFactorySet(1);
593
+ }
594
+ if (unit === W) {
595
+ return instanceFactorySet(7);
596
+ }
597
+ 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;
598
+ var nextTimeStamp = this.$d.getTime() + number * step;
599
+ return Utils.w(nextTimeStamp, this);
600
+ };
601
+ _proto.subtract = function subtract(number, string) {
602
+ return this.add(number * -1, string);
603
+ };
604
+ _proto.format = function format(formatStr) {
605
+ var _this3 = this;
606
+ var locale = this.$locale();
607
+ if (!this.isValid()) return locale.invalidDate || INVALID_DATE_STRING;
608
+ var str = formatStr || FORMAT_DEFAULT;
609
+ var zoneStr = Utils.z(this);
610
+ var $H = this.$H, $m = this.$m, $M = this.$M;
611
+ var weekdays = locale.weekdays, months = locale.months, meridiem = locale.meridiem;
612
+ var getShort = function getShort2(arr, index, full, length) {
613
+ return arr && (arr[index] || arr(_this3, str)) || full[index].slice(0, length);
614
+ };
615
+ var get$H = function get$H2(num) {
616
+ return Utils.s($H % 12 || 12, num, "0");
617
+ };
618
+ var meridiemFunc = meridiem || function(hour, minute, isLowercase) {
619
+ var m = hour < 12 ? "AM" : "PM";
620
+ return isLowercase ? m.toLowerCase() : m;
621
+ };
622
+ var matches = function matches2(match) {
623
+ switch (match) {
624
+ case "YY":
625
+ return String(_this3.$y).slice(-2);
626
+ case "YYYY":
627
+ return Utils.s(_this3.$y, 4, "0");
628
+ case "M":
629
+ return $M + 1;
630
+ case "MM":
631
+ return Utils.s($M + 1, 2, "0");
632
+ case "MMM":
633
+ return getShort(locale.monthsShort, $M, months, 3);
634
+ case "MMMM":
635
+ return getShort(months, $M);
636
+ case "D":
637
+ return _this3.$D;
638
+ case "DD":
639
+ return Utils.s(_this3.$D, 2, "0");
640
+ case "d":
641
+ return String(_this3.$W);
642
+ case "dd":
643
+ return getShort(locale.weekdaysMin, _this3.$W, weekdays, 2);
644
+ case "ddd":
645
+ return getShort(locale.weekdaysShort, _this3.$W, weekdays, 3);
646
+ case "dddd":
647
+ return weekdays[_this3.$W];
648
+ case "H":
649
+ return String($H);
650
+ case "HH":
651
+ return Utils.s($H, 2, "0");
652
+ case "h":
653
+ return get$H(1);
654
+ case "hh":
655
+ return get$H(2);
656
+ case "a":
657
+ return meridiemFunc($H, $m, true);
658
+ case "A":
659
+ return meridiemFunc($H, $m, false);
660
+ case "m":
661
+ return String($m);
662
+ case "mm":
663
+ return Utils.s($m, 2, "0");
664
+ case "s":
665
+ return String(_this3.$s);
666
+ case "ss":
667
+ return Utils.s(_this3.$s, 2, "0");
668
+ case "SSS":
669
+ return Utils.s(_this3.$ms, 3, "0");
670
+ case "Z":
671
+ return zoneStr;
672
+ }
673
+ return null;
674
+ };
675
+ return str.replace(REGEX_FORMAT, function(match, $1) {
676
+ return $1 || matches(match) || zoneStr.replace(":", "");
677
+ });
678
+ };
679
+ _proto.utcOffset = function utcOffset() {
680
+ return -Math.round(this.$d.getTimezoneOffset() / 15) * 15;
681
+ };
682
+ _proto.diff = function diff(input, units, _float) {
683
+ var _this4 = this;
684
+ var unit = Utils.p(units);
685
+ var that = dayjs(input);
686
+ var zoneDelta = (that.utcOffset() - this.utcOffset()) * MILLISECONDS_A_MINUTE;
687
+ var diff2 = this - that;
688
+ var getMonth = function getMonth2() {
689
+ return Utils.m(_this4, that);
690
+ };
691
+ var result;
692
+ switch (unit) {
693
+ case Y:
694
+ result = getMonth() / 12;
695
+ break;
696
+ case M:
697
+ result = getMonth();
698
+ break;
699
+ case Q:
700
+ result = getMonth() / 3;
701
+ break;
702
+ case W:
703
+ result = (diff2 - zoneDelta) / MILLISECONDS_A_WEEK;
704
+ break;
705
+ case D:
706
+ result = (diff2 - zoneDelta) / MILLISECONDS_A_DAY;
707
+ break;
708
+ case H:
709
+ result = diff2 / MILLISECONDS_A_HOUR;
710
+ break;
711
+ case MIN:
712
+ result = diff2 / MILLISECONDS_A_MINUTE;
713
+ break;
714
+ case S:
715
+ result = diff2 / MILLISECONDS_A_SECOND;
716
+ break;
717
+ default:
718
+ result = diff2;
719
+ break;
720
+ }
721
+ return _float ? result : Utils.a(result);
722
+ };
723
+ _proto.daysInMonth = function daysInMonth() {
724
+ return this.endOf(M).$D;
725
+ };
726
+ _proto.$locale = function $locale() {
727
+ return Ls[this.$L];
728
+ };
729
+ _proto.locale = function locale(preset, object) {
730
+ if (!preset) return this.$L;
731
+ var that = this.clone();
732
+ var nextLocaleName = parseLocale(preset, object, true);
733
+ if (nextLocaleName) that.$L = nextLocaleName;
734
+ return that;
735
+ };
736
+ _proto.clone = function clone() {
737
+ return Utils.w(this.$d, this);
738
+ };
739
+ _proto.toDate = function toDate() {
740
+ return new Date(this.valueOf());
741
+ };
742
+ _proto.toJSON = function toJSON() {
743
+ return this.isValid() ? this.toISOString() : null;
744
+ };
745
+ _proto.toISOString = function toISOString() {
746
+ return this.$d.toISOString();
747
+ };
748
+ _proto.toString = function toString() {
749
+ return this.$d.toUTCString();
750
+ };
751
+ return Dayjs2;
752
+ })();
753
+ var proto = Dayjs.prototype;
754
+ dayjs.prototype = proto;
755
+ [["$ms", MS], ["$s", S], ["$m", MIN], ["$H", H], ["$W", D], ["$M", M], ["$y", Y], ["$D", DATE]].forEach(function(g) {
756
+ proto[g[1]] = function(input) {
757
+ return this.$g(input, g[0], g[1]);
758
+ };
759
+ });
760
+ dayjs.extend = function(plugin, option) {
761
+ if (!plugin.$i) {
762
+ plugin(option, Dayjs, dayjs);
763
+ plugin.$i = true;
764
+ }
765
+ return dayjs;
766
+ };
767
+ dayjs.locale = parseLocale;
768
+ dayjs.isDayjs = isDayjs;
769
+ dayjs.unix = function(timestamp) {
770
+ return dayjs(timestamp * 1e3);
771
+ };
772
+ dayjs.en = Ls[L];
773
+ dayjs.Ls = Ls;
774
+ dayjs.p = {};
775
+ var esm_default = dayjs;
776
+
777
+ // src/system-root.ts
778
+ var TEMPLATE_ROOT_NAMES = ["scope", "system"];
779
+ var SYSTEM_TIME_METHOD_NAMES = [
780
+ "add",
781
+ "subtract",
782
+ "set",
783
+ "get",
784
+ "millisecond",
785
+ "second",
786
+ "minute",
787
+ "hour",
788
+ "date",
789
+ "day",
790
+ "weekday",
791
+ "isoWeekday",
792
+ "dayOfYear",
793
+ "week",
794
+ "isoWeek",
795
+ "month",
796
+ "quarter",
797
+ "year",
798
+ "weekYear",
799
+ "isoWeekYear",
800
+ "startOf",
801
+ "endOf",
802
+ "format",
803
+ "fromNow",
804
+ "toNow",
805
+ "from",
806
+ "to",
807
+ "calendar",
808
+ "diff",
809
+ "valueOf",
810
+ "unix",
811
+ "daysInMonth",
812
+ "toDate",
813
+ "toArray",
814
+ "toJSON",
815
+ "toISOString",
816
+ "toObject",
817
+ "toString",
818
+ "isBefore",
819
+ "isSame",
820
+ "isAfter",
821
+ "isSameOrBefore",
822
+ "isSameOrAfter",
823
+ "isBetween",
824
+ "isLeapYear",
825
+ "isValid",
826
+ "clone",
827
+ "locale",
828
+ "utcOffset",
829
+ "local",
830
+ "utc",
831
+ "isUTC"
832
+ ];
833
+ var SYSTEM_MATH_KEYS = [
834
+ "E",
835
+ "LN10",
836
+ "LN2",
837
+ "LOG10E",
838
+ "LOG2E",
839
+ "PI",
840
+ "SQRT1_2",
841
+ "SQRT2",
842
+ "abs",
843
+ "acos",
844
+ "acosh",
845
+ "asin",
846
+ "asinh",
847
+ "atan",
848
+ "atan2",
849
+ "atanh",
850
+ "cbrt",
851
+ "ceil",
852
+ "clz32",
853
+ "cos",
854
+ "cosh",
855
+ "exp",
856
+ "expm1",
857
+ "floor",
858
+ "fround",
859
+ "hypot",
860
+ "imul",
861
+ "log",
862
+ "log10",
863
+ "log1p",
864
+ "log2",
865
+ "max",
866
+ "min",
867
+ "pow",
868
+ "random",
869
+ "round",
870
+ "sign",
871
+ "sin",
872
+ "sinh",
873
+ "sqrt",
874
+ "tan",
875
+ "tanh",
876
+ "trunc"
877
+ ];
878
+ var SYSTEM_LOCATION_KEYS = [
879
+ "href",
880
+ "protocol",
881
+ "host",
882
+ "hostname",
883
+ "port",
884
+ "pathname",
885
+ "search",
886
+ "hash",
887
+ "origin",
888
+ "ancestorOrigins",
889
+ "assign",
890
+ "reload",
891
+ "replace",
892
+ "toString"
893
+ ];
894
+ function createLocationStub() {
895
+ return {
896
+ href: "",
897
+ protocol: "",
898
+ host: "",
899
+ hostname: "",
900
+ port: "",
901
+ pathname: "",
902
+ search: "",
903
+ hash: "",
904
+ origin: "",
905
+ assign() {
906
+ },
907
+ reload() {
908
+ },
909
+ replace() {
910
+ },
911
+ toString() {
912
+ return "";
913
+ }
914
+ };
915
+ }
916
+ function createSystemRoot() {
917
+ const locationValue = typeof globalThis !== "undefined" && "location" in globalThis && globalThis.location ? globalThis.location : createLocationStub();
918
+ return {
919
+ time: esm_default(),
920
+ math: Math,
921
+ location: locationValue
922
+ };
923
+ }
924
+ function getSystemAutocompleteTree() {
925
+ const timeMethods = {};
926
+ for (const name of SYSTEM_TIME_METHOD_NAMES) {
927
+ timeMethods[name] = /* @__PURE__ */ Object.create(null);
928
+ }
929
+ const mathKeys = {};
930
+ for (const name of SYSTEM_MATH_KEYS) {
931
+ mathKeys[name] = /* @__PURE__ */ Object.create(null);
932
+ }
933
+ const locationKeys = {};
934
+ for (const name of SYSTEM_LOCATION_KEYS) {
935
+ locationKeys[name] = /* @__PURE__ */ Object.create(null);
936
+ }
937
+ return {
938
+ time: timeMethods,
939
+ math: mathKeys,
940
+ location: locationKeys
941
+ };
942
+ }
943
+ function isDayjsValue(value) {
944
+ return esm_default.isDayjs(value);
945
+ }
946
+
161
947
  // src/scope-template.ts
162
- var SCOPE_TOKEN_RE = /\{(scope[^}]*)\}/g;
948
+ var TEMPLATE_TOKEN_RE = /\{((?:scope|system)[^}]*)\}/g;
163
949
  function hasScopeTemplate(value) {
164
- SCOPE_TOKEN_RE.lastIndex = 0;
165
- return SCOPE_TOKEN_RE.test(value);
950
+ TEMPLATE_TOKEN_RE.lastIndex = 0;
951
+ return TEMPLATE_TOKEN_RE.test(value);
166
952
  }
167
- function evaluateScopeExpression(expression, scope) {
953
+ var hasTemplateExpression = hasScopeTemplate;
954
+ function evaluateScopeExpression(expression, scope, system = createSystemRoot()) {
168
955
  const trimmed = expression.trim();
169
956
  if (!trimmed) return void 0;
170
957
  try {
171
- const fn = new Function("scope", `"use strict"; return (${trimmed});`);
172
- return fn(scope);
958
+ const fn = new Function(
959
+ "scope",
960
+ "system",
961
+ `"use strict"; return (${trimmed});`
962
+ );
963
+ return fn(scope, system);
173
964
  } catch {
174
965
  return void 0;
175
966
  }
@@ -180,6 +971,9 @@ function stringifyScopeValue(value) {
180
971
  if (typeof value === "number" || typeof value === "boolean") {
181
972
  return String(value);
182
973
  }
974
+ if (isDayjsValue(value)) {
975
+ return value.toISOString();
976
+ }
183
977
  try {
184
978
  return JSON.stringify(value);
185
979
  } catch {
@@ -206,24 +1000,30 @@ function isInsideJsonString(before) {
206
1000
  }
207
1001
  return inString;
208
1002
  }
209
- function replaceScopeTokens(template, scope, replacer) {
210
- SCOPE_TOKEN_RE.lastIndex = 0;
1003
+ function replaceTemplateTokens(template, scope, system, replacer) {
1004
+ TEMPLATE_TOKEN_RE.lastIndex = 0;
211
1005
  return template.replace(
212
- SCOPE_TOKEN_RE,
213
- (_match, rawExpr, offset) => replacer(evaluateScopeExpression(rawExpr, scope), offset)
1006
+ TEMPLATE_TOKEN_RE,
1007
+ (_match, rawExpr, offset) => replacer(evaluateScopeExpression(rawExpr, scope, system), offset)
214
1008
  );
215
1009
  }
216
- function evaluateScopeTemplate(template, scope) {
1010
+ function evaluateScopeTemplate(template, scope, system = createSystemRoot()) {
217
1011
  if (!hasScopeTemplate(template)) return template;
218
- return replaceScopeTokens(template, scope, (value) => stringifyScopeValue(value));
1012
+ return replaceTemplateTokens(
1013
+ template,
1014
+ scope,
1015
+ system,
1016
+ (value) => stringifyScopeValue(value)
1017
+ );
219
1018
  }
220
- function evaluateScopeTemplateInJson(template, scope) {
1019
+ function evaluateScopeTemplateInJson(template, scope, system = createSystemRoot()) {
221
1020
  if (!hasScopeTemplate(template)) return template;
222
- return replaceScopeTokens(template, scope, (value, offset) => {
1021
+ return replaceTemplateTokens(template, scope, system, (value, offset) => {
223
1022
  if (isInsideJsonString(template.slice(0, offset))) {
224
1023
  return JSON.stringify(stringifyScopeValue(value)).slice(1, -1);
225
1024
  }
226
1025
  if (value === void 0) return "null";
1026
+ if (isDayjsValue(value)) return JSON.stringify(value.toISOString());
227
1027
  return JSON.stringify(value);
228
1028
  });
229
1029
  }
@@ -231,6 +1031,9 @@ function looksLikeJsonText(text) {
231
1031
  const trimmed = text.trim();
232
1032
  return trimmed.startsWith("{") || trimmed.startsWith("[");
233
1033
  }
1034
+ function preserveTemplateTokensInEncode(value) {
1035
+ return hasScopeTemplate(value);
1036
+ }
234
1037
 
235
1038
  // src/fetch-config.ts
236
1039
  var FETCH_HTTP_METHODS = [
@@ -275,7 +1078,8 @@ function normalizeFetchRequestConfig(config) {
275
1078
  ...config?.headers
276
1079
  },
277
1080
  headersJson: config?.headersJson,
278
- swaggerEndpoints: config?.swaggerEndpoints
1081
+ swaggerEndpoints: config?.swaggerEndpoints,
1082
+ apiCollectionSyncNotice: config?.apiCollectionSyncNotice
279
1083
  };
280
1084
  }
281
1085
  function joinFetchUrl(base, path) {
@@ -309,7 +1113,7 @@ function hasExplicitUrlScheme(url) {
309
1113
  function resolveFetchRequestUrl(config) {
310
1114
  const rawUrl = config.url?.trim() ?? "";
311
1115
  if (!rawUrl) {
312
- throw new Error("\u8BF7\u6C42 URL \u672A\u914D\u7F6E");
1116
+ throw new Error(dslMessage("fetchUrlMissing"));
313
1117
  }
314
1118
  if (hasExplicitUrlScheme(rawUrl)) {
315
1119
  return rawUrl;
@@ -339,7 +1143,7 @@ function linkAbortSignal(controller, external) {
339
1143
  async function executeFetch(config, options) {
340
1144
  const rawUrl = config.url?.trim();
341
1145
  if (!rawUrl) {
342
- throw new Error("\u8BF7\u6C42 URL \u672A\u914D\u7F6E");
1146
+ throw new Error(dslMessage("fetchUrlMissing"));
343
1147
  }
344
1148
  const url = resolveFetchRequestUrl(config);
345
1149
  const method = config.method ?? "GET";
@@ -350,7 +1154,9 @@ async function executeFetch(config, options) {
350
1154
  JSON.parse(body);
351
1155
  } catch (error) {
352
1156
  throw new Error(
353
- `\u8BF7\u6C42\u4F53\u4E0D\u662F\u6709\u6548 JSON\uFF1A${error instanceof Error ? error.message : "\u683C\u5F0F\u65E0\u6548"}`
1157
+ dslMessage("fetchBodyInvalidJson", {
1158
+ reason: error instanceof Error ? error.message : dslMessage("invalidFormat")
1159
+ })
354
1160
  );
355
1161
  }
356
1162
  }
@@ -391,7 +1197,7 @@ async function executeFetch(config, options) {
391
1197
  if (options?.allowHttpError) {
392
1198
  data = text;
393
1199
  } else {
394
- throw new Error("\u54CD\u5E94\u4E0D\u662F\u6709\u6548\u7684 JSON");
1200
+ throw new Error(dslMessage("fetchResponseInvalidJson"));
395
1201
  }
396
1202
  }
397
1203
  }
@@ -411,9 +1217,9 @@ async function executeFetch(config, options) {
411
1217
  } catch (error) {
412
1218
  if (error instanceof Error && error.name === "AbortError") {
413
1219
  if (options?.signal?.aborted) {
414
- throw new Error("\u8BF7\u6C42\u5DF2\u4E2D\u6B62");
1220
+ throw new Error(dslMessage("fetchAborted"));
415
1221
  }
416
- throw new Error(`\u8BF7\u6C42\u8D85\u65F6\uFF08${timeoutMs}ms\uFF09`);
1222
+ throw new Error(dslMessage("fetchTimeout", { ms: timeoutMs }));
417
1223
  }
418
1224
  throw error;
419
1225
  } finally {
@@ -423,8 +1229,8 @@ async function executeFetch(config, options) {
423
1229
  }
424
1230
 
425
1231
  // src/scope-autocomplete.ts
426
- function getValueAtPath(scope, path) {
427
- let current = scope;
1232
+ function getValueAtPath(root, path) {
1233
+ let current = root;
428
1234
  for (const part of path) {
429
1235
  if (current === null || typeof current !== "object") return void 0;
430
1236
  current = current[part];
@@ -437,63 +1243,193 @@ function listObjectKeys(value) {
437
1243
  }
438
1244
  return Object.keys(value);
439
1245
  }
1246
+ function matchRootPrefix(inner) {
1247
+ if (!inner) return "partial";
1248
+ for (const name of TEMPLATE_ROOT_NAMES) {
1249
+ if (inner === name) return name;
1250
+ if (name.startsWith(inner) && !inner.includes("?") && !inner.includes(".")) {
1251
+ return "partial";
1252
+ }
1253
+ }
1254
+ return null;
1255
+ }
1256
+ function splitPathBody(body) {
1257
+ let depth = 0;
1258
+ let current = "";
1259
+ const segments = [];
1260
+ let i = 0;
1261
+ while (i < body.length) {
1262
+ const ch = body[i];
1263
+ if (ch === "(" || ch === "[" || ch === "{") {
1264
+ depth += 1;
1265
+ current += ch;
1266
+ i += 1;
1267
+ continue;
1268
+ }
1269
+ if (ch === ")" || ch === "]" || ch === "}") {
1270
+ depth = Math.max(0, depth - 1);
1271
+ current += ch;
1272
+ i += 1;
1273
+ continue;
1274
+ }
1275
+ if (depth > 0) {
1276
+ current += ch;
1277
+ i += 1;
1278
+ continue;
1279
+ }
1280
+ if (body.startsWith("?.", i)) {
1281
+ segments.push(current);
1282
+ current = "";
1283
+ i += 2;
1284
+ continue;
1285
+ }
1286
+ if (ch === ".") {
1287
+ segments.push(current);
1288
+ current = "";
1289
+ i += 1;
1290
+ continue;
1291
+ }
1292
+ current += ch;
1293
+ i += 1;
1294
+ }
1295
+ if (depth > 0) return null;
1296
+ const endsWithSeparator = body.endsWith("?.") || body.endsWith(".") && !body.endsWith("?.") && !body.endsWith("..");
1297
+ if (endsWithSeparator) {
1298
+ const path = segments.map((s) => stripCallSuffix(s)).filter((s) => s.length > 0);
1299
+ return { segments: path, endsWithSeparator: true, partialOrComplete: "" };
1300
+ }
1301
+ const cleaned = segments.map((s) => stripCallSuffix(s)).filter((s) => s.length > 0);
1302
+ const lastRaw = current;
1303
+ const lastClean = stripCallSuffix(lastRaw);
1304
+ if (lastRaw.includes("(") && lastRaw.endsWith(")")) {
1305
+ return {
1306
+ segments: [...cleaned, lastClean].filter(Boolean),
1307
+ endsWithSeparator: false,
1308
+ partialOrComplete: lastClean
1309
+ };
1310
+ }
1311
+ return {
1312
+ segments: cleaned,
1313
+ endsWithSeparator: false,
1314
+ partialOrComplete: lastClean
1315
+ };
1316
+ }
1317
+ function stripCallSuffix(segment) {
1318
+ const idx = segment.indexOf("(");
1319
+ if (idx < 0) return segment.trim();
1320
+ return segment.slice(0, idx).trim();
1321
+ }
440
1322
  function parseScopeAutocomplete(text, cursor, scope) {
441
1323
  const before = text.slice(0, cursor);
442
1324
  const templateStart = before.lastIndexOf("{");
443
1325
  if (templateStart < 0) return null;
444
1326
  const inner = before.slice(templateStart + 1);
445
1327
  if (inner.includes("}")) return null;
446
- if (!inner.startsWith("scope")) return null;
447
- let body = inner.slice("scope".length);
448
- if (body === "" || body === "?") {
449
- return { templateStart, cursor, path: [], partialKey: "" };
1328
+ const rootMatch = matchRootPrefix(inner);
1329
+ if (rootMatch === "partial" || rootMatch && !inner.includes("?") && !inner.includes(".")) {
1330
+ if (!inner.includes("?") && !inner.includes(".") && !inner.includes("(")) {
1331
+ return {
1332
+ templateStart,
1333
+ cursor,
1334
+ suggestingRoot: true,
1335
+ root: typeof rootMatch === "string" && rootMatch !== "partial" ? rootMatch : null,
1336
+ path: [],
1337
+ partialKey: inner
1338
+ };
1339
+ }
450
1340
  }
451
- if (!body.startsWith("?.")) return null;
452
- body = body.slice(2);
453
- if (body === "") {
454
- return { templateStart, cursor, path: [], partialKey: "" };
1341
+ let root = null;
1342
+ let body = "";
1343
+ if (inner.startsWith("scope")) {
1344
+ root = "scope";
1345
+ body = inner.slice("scope".length);
1346
+ } else if (inner.startsWith("system")) {
1347
+ root = "system";
1348
+ body = inner.slice("system".length);
1349
+ } else {
1350
+ return null;
455
1351
  }
456
- const segments = body.split("?.");
457
- const endsWithSeparator = inner.endsWith("?.");
458
- if (endsWithSeparator) {
459
- const path = segments.filter((segment) => segment.length > 0);
460
- return { templateStart, cursor, path, partialKey: "" };
1352
+ if (body === "" || body === "?") {
1353
+ return {
1354
+ templateStart,
1355
+ cursor,
1356
+ suggestingRoot: false,
1357
+ root,
1358
+ path: [],
1359
+ partialKey: ""
1360
+ };
461
1361
  }
462
- const lastSegment = segments[segments.length - 1] ?? "";
463
- const prefixSegments = segments.slice(0, -1).filter((segment) => segment.length > 0);
464
- const parent = getValueAtPath(scope, prefixSegments);
465
- const keys = listObjectKeys(parent);
466
- if (lastSegment.length === 0) {
467
- return { templateStart, cursor, path: prefixSegments, partialKey: "" };
1362
+ if (body.startsWith("?.")) {
1363
+ body = body.slice(2);
1364
+ } else if (body.startsWith(".")) {
1365
+ body = body.slice(1);
1366
+ } else {
1367
+ return null;
468
1368
  }
469
- if (keys.includes(lastSegment)) {
1369
+ if (body === "") {
470
1370
  return {
471
1371
  templateStart,
472
1372
  cursor,
473
- path: [...prefixSegments, lastSegment],
1373
+ suggestingRoot: false,
1374
+ root,
1375
+ path: [],
474
1376
  partialKey: ""
475
1377
  };
476
1378
  }
1379
+ const split = splitPathBody(body);
1380
+ if (!split) return null;
1381
+ if (split.endsWithSeparator) {
1382
+ return {
1383
+ templateStart,
1384
+ cursor,
1385
+ suggestingRoot: false,
1386
+ root,
1387
+ path: split.segments,
1388
+ partialKey: ""
1389
+ };
1390
+ }
1391
+ const lastSegment = split.partialOrComplete;
1392
+ const prefixSegments = split.segments;
477
1393
  return {
478
1394
  templateStart,
479
1395
  cursor,
1396
+ suggestingRoot: false,
1397
+ root,
480
1398
  path: prefixSegments,
481
1399
  partialKey: lastSegment
482
1400
  };
483
1401
  }
1402
+ function resolveAutocompleteRoot(state, scope) {
1403
+ if (state.root === "system") return getSystemAutocompleteTree();
1404
+ return scope;
1405
+ }
484
1406
  function getScopeAutocompleteSuggestions(scope, state) {
485
- const parent = state.partialKey.length > 0 ? getValueAtPath(scope, state.path) : state.path.length > 0 ? getValueAtPath(scope, state.path) : scope;
486
- const keys = listObjectKeys(parent);
1407
+ if (state.suggestingRoot) {
1408
+ return TEMPLATE_ROOT_NAMES.filter(
1409
+ (name) => name.startsWith(state.partialKey)
1410
+ );
1411
+ }
1412
+ const dataRoot = resolveAutocompleteRoot(state, scope);
1413
+ if (dataRoot === void 0 || dataRoot === null) return [];
1414
+ const parent = state.path.length > 0 ? getValueAtPath(dataRoot, state.path) : dataRoot;
1415
+ let keys = listObjectKeys(parent);
487
1416
  if (state.partialKey.length === 0) return keys;
488
- return keys.filter((key) => key.startsWith(state.partialKey));
1417
+ keys = keys.filter((key) => key.startsWith(state.partialKey));
1418
+ return keys;
489
1419
  }
490
- function buildScopeExpression(path, selectedKey) {
491
- return `scope?.${[...path, selectedKey].join("?.")}`;
1420
+ function buildScopeExpression(path, selectedKey, root = "scope") {
1421
+ return `${root}?.${[...path, selectedKey].join("?.")}`;
492
1422
  }
493
1423
  function applyScopeAutocompleteSelection(text, state, selectedKey) {
494
- const expr = buildScopeExpression(state.path, selectedKey);
495
1424
  const before = text.slice(0, state.templateStart + 1);
496
1425
  const after = text.slice(state.cursor);
1426
+ let expr;
1427
+ if (state.suggestingRoot) {
1428
+ expr = `${selectedKey}?.`;
1429
+ } else {
1430
+ const root = state.root ?? "scope";
1431
+ expr = buildScopeExpression(state.path, selectedKey, root);
1432
+ }
497
1433
  const value = `${before}${expr}${after}`;
498
1434
  const cursor = before.length + expr.length;
499
1435
  return { value, cursor };
@@ -629,7 +1565,7 @@ function parseJsonText(text) {
629
1565
  } catch (error) {
630
1566
  return {
631
1567
  ok: false,
632
- error: error instanceof Error ? error.message : "JSON \u683C\u5F0F\u65E0\u6548"
1568
+ error: error instanceof Error ? error.message : dslMessage("jsonInvalid")
633
1569
  };
634
1570
  }
635
1571
  }
@@ -637,7 +1573,7 @@ function validateFetchJsonText(text, options) {
637
1573
  const trimmed = text.trim();
638
1574
  if (!trimmed) {
639
1575
  if (options?.allowEmpty === false) {
640
- return { ok: false, error: "\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A" };
1576
+ return { ok: false, error: dslMessage("contentRequired") };
641
1577
  }
642
1578
  return { ok: true };
643
1579
  }
@@ -654,13 +1590,13 @@ function resolveFetchBody(body, scope) {
654
1590
  if (body === void 0) return void 0;
655
1591
  const trimmed = body.trim();
656
1592
  if (!trimmed) return body;
657
- if (scope !== void 0 && isWholeScopeExpression(trimmed)) {
1593
+ if (isWholeScopeExpression(trimmed)) {
658
1594
  const value = evaluateScopeExpression(trimmed.slice(1, -1), scope);
659
1595
  if (value === void 0) return "";
660
1596
  if (typeof value === "string") return value;
661
1597
  return stringifyScopeValue(value);
662
1598
  }
663
- if (scope === void 0 || !hasScopeTemplate(body)) return body;
1599
+ if (!hasScopeTemplate(body)) return body;
664
1600
  if (looksLikeJsonText(trimmed)) {
665
1601
  return evaluateScopeTemplateInJson(body, scope);
666
1602
  }
@@ -682,19 +1618,20 @@ function getFetchHeadersValidationError(config, scope) {
682
1618
  if (isWholeScopeExpression(raw) || hasScopeTemplate(raw)) {
683
1619
  if (scope === void 0) return null;
684
1620
  const parsed2 = parseFetchHeadersJson(raw, scope);
685
- if (!parsed2) return "\u8BF7\u6C42\u5934\u6A21\u677F\u89E3\u6790\u540E\u4E0D\u662F\u6709\u6548\u7684 JSON \u5BF9\u8C61";
1621
+ if (!parsed2) return dslMessage("headersTemplateNotObject");
686
1622
  return null;
687
1623
  }
688
1624
  const result = validateFetchJsonText(raw);
689
1625
  if (!result.ok) return result.error;
690
1626
  const parsed = parseFetchHeadersJson(raw, scope);
691
- if (!parsed) return "\u8BF7\u6C42\u5934\u4E0D\u662F\u6709\u6548\u7684 JSON \u5BF9\u8C61";
1627
+ if (!parsed) return dslMessage("headersNotObject");
692
1628
  return null;
693
1629
  }
694
1630
  function isWholeScopeExpression(text) {
695
1631
  const trimmed = text.trim();
696
1632
  if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) return false;
697
- return trimmed.slice(1, -1).trim().startsWith("scope");
1633
+ const inner = trimmed.slice(1, -1).trim();
1634
+ return inner.startsWith("scope") || inner.startsWith("system");
698
1635
  }
699
1636
  function asHeaderRecord(value) {
700
1637
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
@@ -706,7 +1643,6 @@ function asHeaderRecord(value) {
706
1643
  return headers;
707
1644
  }
708
1645
  function applyScopeToHeaderRecord(headers, scope) {
709
- if (scope === void 0) return headers;
710
1646
  return Object.fromEntries(
711
1647
  Object.entries(headers).map(([key, value]) => [
712
1648
  evaluateScopeTemplate(String(key), scope),
@@ -718,12 +1654,11 @@ function parseFetchHeadersJson(text, scope) {
718
1654
  const trimmed = text.trim();
719
1655
  if (!trimmed) return {};
720
1656
  if (isWholeScopeExpression(trimmed)) {
721
- if (scope === void 0) return void 0;
722
1657
  const inner = trimmed.slice(1, -1);
723
1658
  return asHeaderRecord(evaluateScopeExpression(inner, scope));
724
1659
  }
725
1660
  let jsonText = trimmed;
726
- if (scope !== void 0 && hasScopeTemplate(trimmed) && looksLikeJsonText(trimmed)) {
1661
+ if (hasScopeTemplate(trimmed) && looksLikeJsonText(trimmed)) {
727
1662
  jsonText = evaluateScopeTemplateInJson(trimmed, scope);
728
1663
  }
729
1664
  try {
@@ -757,14 +1692,15 @@ function resolveFetchHeaders(config, scope) {
757
1692
  function applyFetchConfigScope(config, scope) {
758
1693
  const headers = resolveFetchHeaders(config, scope);
759
1694
  const body = resolveFetchBody(config.body, scope);
760
- if (scope === void 0) {
761
- if (headers === config.headers && body === config.body) return config;
762
- return { ...config, headers, body };
1695
+ const url = resolveTemplateString(config.url, scope) ?? "";
1696
+ const apiBaseUrl = resolveTemplateString(config.apiBaseUrl, scope);
1697
+ if (url === (config.url ?? "") && apiBaseUrl === config.apiBaseUrl && headers === config.headers && body === config.body) {
1698
+ return config;
763
1699
  }
764
1700
  return {
765
1701
  ...config,
766
- url: resolveTemplateString(config.url, scope) ?? "",
767
- apiBaseUrl: resolveTemplateString(config.apiBaseUrl, scope),
1702
+ url,
1703
+ apiBaseUrl,
768
1704
  body,
769
1705
  headers
770
1706
  };
@@ -780,39 +1716,319 @@ function fetchConfigHasScopeTemplate(config) {
780
1716
  );
781
1717
  }
782
1718
 
783
- // src/json-config.ts
784
- var DEFAULT_JSON_NODE_CONFIG = {
785
- jsonString: "{}"
786
- };
787
- function validateJsonString(jsonString) {
788
- const raw = jsonString?.trim();
789
- if (!raw) {
790
- return { ok: false, error: "JSON \u4E0D\u80FD\u4E3A\u7A7A" };
1719
+ // src/json-lint.ts
1720
+ var SUSPECT_CHAR_RE = /[\u201C\u201D\u2018\u2019\u300C\u300D\u300E\u300F\uFF0C\uFF1A\uFF1B\u3010\u3011\uFF08\uFF09\uFF01\uFF1F\u3001\u3002]/gu;
1721
+ function lineColToOffset(text, line, column) {
1722
+ const lines = text.split("\n");
1723
+ let offset = 0;
1724
+ const targetLine = Math.max(1, line) - 1;
1725
+ for (let i = 0; i < targetLine && i < lines.length; i += 1) {
1726
+ offset += lines[i].length + 1;
1727
+ }
1728
+ const col = Math.max(1, column) - 1;
1729
+ const lineText = lines[targetLine] ?? "";
1730
+ return offset + Math.min(col, lineText.length);
1731
+ }
1732
+ function extractJsonErrorPosition(message, text) {
1733
+ let match = /position\s+(\d+)/i.exec(message);
1734
+ if (match) {
1735
+ const pos = Number(match[1]);
1736
+ if (Number.isFinite(pos) && pos >= 0) {
1737
+ return Math.min(pos, Math.max(0, text.length - 1));
1738
+ }
1739
+ }
1740
+ match = /line\s+(\d+)\s+column\s+(\d+)/i.exec(message);
1741
+ if (match) {
1742
+ const pos = lineColToOffset(text, Number(match[1]), Number(match[2]));
1743
+ return Math.min(pos, Math.max(0, text.length - 1));
791
1744
  }
1745
+ match = /\bat\s+(\d+):(\d+)\b/.exec(message);
1746
+ if (match) {
1747
+ const pos = lineColToOffset(text, Number(match[1]), Number(match[2]));
1748
+ return Math.min(pos, Math.max(0, text.length - 1));
1749
+ }
1750
+ return null;
1751
+ }
1752
+ function findJsonSyntaxErrorOffset(text) {
1753
+ const src = text;
1754
+ const len = src.length;
1755
+ let i = 0;
1756
+ const peek = () => i < len ? src[i] : "";
1757
+ const fail = () => i < len ? i : Math.max(0, len - 1);
1758
+ const skipWs = () => {
1759
+ while (i < len && /[ \t\r\n]/.test(src[i])) i += 1;
1760
+ };
1761
+ const parseString = () => {
1762
+ if (peek() !== '"') return false;
1763
+ i += 1;
1764
+ while (i < len) {
1765
+ const c = src[i];
1766
+ if (c === '"') {
1767
+ i += 1;
1768
+ return true;
1769
+ }
1770
+ if (c === "\\") {
1771
+ i += 1;
1772
+ if (i >= len) return false;
1773
+ i += 1;
1774
+ continue;
1775
+ }
1776
+ i += 1;
1777
+ }
1778
+ return false;
1779
+ };
1780
+ const parseNumber = () => {
1781
+ const start = i;
1782
+ if (peek() === "-") i += 1;
1783
+ if (peek() === "0") {
1784
+ i += 1;
1785
+ } else if (/[1-9]/.test(peek())) {
1786
+ while (/[0-9]/.test(peek())) i += 1;
1787
+ } else {
1788
+ i = start;
1789
+ return false;
1790
+ }
1791
+ if (peek() === ".") {
1792
+ i += 1;
1793
+ if (!/[0-9]/.test(peek())) {
1794
+ return false;
1795
+ }
1796
+ while (/[0-9]/.test(peek())) i += 1;
1797
+ }
1798
+ if (peek() === "e" || peek() === "E") {
1799
+ i += 1;
1800
+ if (peek() === "+" || peek() === "-") i += 1;
1801
+ if (!/[0-9]/.test(peek())) return false;
1802
+ while (/[0-9]/.test(peek())) i += 1;
1803
+ }
1804
+ return i > start;
1805
+ };
1806
+ const parseLiteral = (word) => {
1807
+ if (src.startsWith(word, i)) {
1808
+ i += word.length;
1809
+ return true;
1810
+ }
1811
+ return false;
1812
+ };
1813
+ const parseValue = () => {
1814
+ skipWs();
1815
+ if (i >= len) return false;
1816
+ const c = peek();
1817
+ if (c === "{") return parseObject();
1818
+ if (c === "[") return parseArray();
1819
+ if (c === '"') return parseString();
1820
+ if (c === "-" || /[0-9]/.test(c)) return parseNumber();
1821
+ if (parseLiteral("true") || parseLiteral("false") || parseLiteral("null")) {
1822
+ return true;
1823
+ }
1824
+ return false;
1825
+ };
1826
+ const parseObject = () => {
1827
+ if (peek() !== "{") return false;
1828
+ i += 1;
1829
+ skipWs();
1830
+ if (peek() === "}") {
1831
+ i += 1;
1832
+ return true;
1833
+ }
1834
+ while (i < len) {
1835
+ skipWs();
1836
+ if (peek() !== '"') return false;
1837
+ if (!parseString()) return false;
1838
+ skipWs();
1839
+ if (peek() !== ":") return false;
1840
+ i += 1;
1841
+ if (!parseValue()) return false;
1842
+ skipWs();
1843
+ if (peek() === ",") {
1844
+ i += 1;
1845
+ skipWs();
1846
+ if (peek() === "}" || i >= len) return false;
1847
+ continue;
1848
+ }
1849
+ if (peek() === "}") {
1850
+ i += 1;
1851
+ return true;
1852
+ }
1853
+ return false;
1854
+ }
1855
+ return false;
1856
+ };
1857
+ const parseArray = () => {
1858
+ if (peek() !== "[") return false;
1859
+ i += 1;
1860
+ skipWs();
1861
+ if (peek() === "]") {
1862
+ i += 1;
1863
+ return true;
1864
+ }
1865
+ while (i < len) {
1866
+ if (!parseValue()) return false;
1867
+ skipWs();
1868
+ if (peek() === ",") {
1869
+ i += 1;
1870
+ skipWs();
1871
+ if (peek() === "]" || i >= len) return false;
1872
+ continue;
1873
+ }
1874
+ if (peek() === "]") {
1875
+ i += 1;
1876
+ return true;
1877
+ }
1878
+ return false;
1879
+ }
1880
+ return false;
1881
+ };
1882
+ skipWs();
1883
+ if (i >= len) return 0;
1884
+ if (!parseValue()) return fail();
1885
+ skipWs();
1886
+ if (i < len) return i;
1887
+ return null;
1888
+ }
1889
+ function expandAround(text, pos) {
1890
+ const len = text.length;
1891
+ if (len === 0) return { start: 0, end: 0, kind: "parse" };
1892
+ const clamped = Math.max(0, Math.min(pos, len - 1));
1893
+ const ch = text[clamped];
1894
+ SUSPECT_CHAR_RE.lastIndex = 0;
1895
+ if (SUSPECT_CHAR_RE.test(ch)) {
1896
+ let start = clamped;
1897
+ let end = clamped + 1;
1898
+ while (start > 0) {
1899
+ SUSPECT_CHAR_RE.lastIndex = 0;
1900
+ if (!SUSPECT_CHAR_RE.test(text[start - 1])) break;
1901
+ start -= 1;
1902
+ }
1903
+ while (end < len) {
1904
+ SUSPECT_CHAR_RE.lastIndex = 0;
1905
+ if (!SUSPECT_CHAR_RE.test(text[end])) break;
1906
+ end += 1;
1907
+ }
1908
+ return { start, end, kind: "parse" };
1909
+ }
1910
+ const isTokenChar = (c) => /[A-Za-z0-9_$.+\-]/.test(c);
1911
+ if (isTokenChar(ch)) {
1912
+ let start = clamped;
1913
+ let end = clamped + 1;
1914
+ while (start > 0 && isTokenChar(text[start - 1])) start -= 1;
1915
+ while (end < len && isTokenChar(text[end])) end += 1;
1916
+ return { start, end, kind: "parse" };
1917
+ }
1918
+ return { start: clamped, end: clamped + 1, kind: "parse" };
1919
+ }
1920
+ function findSuspectCharRanges(text) {
1921
+ const ranges = [];
1922
+ SUSPECT_CHAR_RE.lastIndex = 0;
1923
+ let match;
1924
+ while ((match = SUSPECT_CHAR_RE.exec(text)) !== null) {
1925
+ ranges.push({
1926
+ start: match.index,
1927
+ end: match.index + match[0].length,
1928
+ kind: "suspect"
1929
+ });
1930
+ }
1931
+ return ranges;
1932
+ }
1933
+ function mergeRanges(ranges) {
1934
+ if (ranges.length === 0) return [];
1935
+ const sorted = [...ranges].sort((a, b) => a.start - b.start || a.end - b.end);
1936
+ const out = [];
1937
+ for (const range of sorted) {
1938
+ const last = out[out.length - 1];
1939
+ if (!last || range.start > last.end) {
1940
+ out.push({ ...range });
1941
+ continue;
1942
+ }
1943
+ last.end = Math.max(last.end, range.end);
1944
+ if (last.kind === "parse" || range.kind === "parse") last.kind = "parse";
1945
+ }
1946
+ return out;
1947
+ }
1948
+ function lintJsonString(jsonString) {
1949
+ const raw = jsonString ?? "";
1950
+ const trimmed = raw.trim();
1951
+ if (!trimmed) {
1952
+ return { ok: false, error: dslMessage("jsonEmpty"), ranges: [] };
1953
+ }
1954
+ const suspectRanges = findSuspectCharRanges(raw);
1955
+ const trimStart = raw.indexOf(trimmed);
1956
+ const offset = trimStart >= 0 ? trimStart : 0;
792
1957
  try {
793
- const value = JSON.parse(raw);
1958
+ const value = JSON.parse(trimmed);
794
1959
  if (value === null || typeof value !== "object") {
795
- return { ok: false, error: "JSON \u6839\u8282\u70B9\u5FC5\u987B\u662F object \u6216 array" };
1960
+ return {
1961
+ ok: false,
1962
+ error: dslMessage("jsonRootMustBeContainer"),
1963
+ ranges: mergeRanges(suspectRanges)
1964
+ };
796
1965
  }
797
1966
  return { ok: true, value };
798
1967
  } catch (error) {
1968
+ const message = error instanceof Error ? error.message : dslMessage("jsonInvalid");
1969
+ const ranges = [...suspectRanges];
1970
+ const fromEngine = extractJsonErrorPosition(message, trimmed);
1971
+ const fromScan = findJsonSyntaxErrorOffset(trimmed);
1972
+ const pos = fromScan ?? fromEngine;
1973
+ if (pos != null) {
1974
+ ranges.push(expandAround(raw, offset + pos));
1975
+ } else if (ranges.length === 0 && raw.length > 0) {
1976
+ const first = raw.search(/\S/);
1977
+ ranges.push(expandAround(raw, first >= 0 ? first : 0));
1978
+ }
799
1979
  return {
800
1980
  ok: false,
801
- error: error instanceof Error ? error.message : "JSON \u683C\u5F0F\u65E0\u6548"
1981
+ error: message,
1982
+ ranges: mergeRanges(ranges)
802
1983
  };
803
1984
  }
804
1985
  }
1986
+ function renderJsonWithErrorHighlights(text, ranges, markClass = "json-lint-error") {
1987
+ const escape = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1988
+ const source = text ?? "";
1989
+ const merged = mergeRanges(
1990
+ ranges.filter((r) => r.end > r.start && r.start < source.length)
1991
+ );
1992
+ if (merged.length === 0) return escape(source) || "\n";
1993
+ let html = "";
1994
+ let cursor = 0;
1995
+ for (const range of merged) {
1996
+ const start = Math.max(0, range.start);
1997
+ const end = Math.min(source.length, range.end);
1998
+ if (start > cursor) html += escape(source.slice(cursor, start));
1999
+ if (end > start) {
2000
+ html += `<mark class="${markClass}">${escape(source.slice(start, end))}</mark>`;
2001
+ }
2002
+ cursor = Math.max(cursor, end);
2003
+ }
2004
+ if (cursor < source.length) html += escape(source.slice(cursor));
2005
+ return html;
2006
+ }
2007
+
2008
+ // src/json-config.ts
2009
+ var DEFAULT_JSON_NODE_CONFIG = {
2010
+ jsonString: "{}"
2011
+ };
2012
+ function validateJsonString(jsonString) {
2013
+ const result = lintJsonString(jsonString);
2014
+ if (!result.ok) {
2015
+ return { ok: false, error: result.error, ranges: result.ranges };
2016
+ }
2017
+ return { ok: true, value: result.value };
2018
+ }
805
2019
  function validateJsonStringAllowingScope(jsonString) {
2020
+ const lint = lintJsonString(jsonString ?? "");
2021
+ if (!lint.ok) {
2022
+ return { ok: false, error: lint.error, ranges: lint.ranges };
2023
+ }
806
2024
  if (hasScopeTemplate(jsonString ?? "")) {
807
2025
  return { ok: true, deferred: true };
808
2026
  }
809
- const result = validateJsonString(jsonString);
810
- if (!result.ok) return result;
811
- return { ok: true, value: result.value };
2027
+ return { ok: true, value: lint.value };
812
2028
  }
813
2029
  function parseJsonConfig(config, scope) {
814
2030
  let raw = config.jsonString ?? "";
815
- if (scope !== void 0 && hasScopeTemplate(raw)) {
2031
+ if (hasScopeTemplate(raw)) {
816
2032
  raw = evaluateScopeTemplateInJson(raw, scope);
817
2033
  }
818
2034
  const result = validateJsonString(raw);
@@ -950,7 +2166,7 @@ function requireStorage(accessors, kind) {
950
2166
  const target = kind === "session" ? accessors?.session : accessors?.local;
951
2167
  if (!target) {
952
2168
  throw new Error(
953
- kind === "session" ? "\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301 sessionStorage" : "\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301 localStorage"
2169
+ kind === "session" ? dslMessage("storageUnsupported", { storage: "sessionStorage" }) : dslMessage("storageUnsupported", { storage: "localStorage" })
954
2170
  );
955
2171
  }
956
2172
  return target;
@@ -963,7 +2179,7 @@ function executeStorageConfig(config, incomingScope, accessors) {
963
2179
  const serialized = serializeStorageValue(value);
964
2180
  const key = resolveStorageKey(normalized.set.key, incomingScope);
965
2181
  if (!key) {
966
- throw new Error("\u5B58\u50A8\u5199\u5165 key \u89E3\u6790\u4E3A\u7A7A");
2182
+ throw new Error(dslMessage("storageKeyEmpty"));
967
2183
  }
968
2184
  for (const kind of normalized.set.storages) {
969
2185
  requireStorage(store, kind).setItem(key, serialized);
@@ -1003,7 +2219,7 @@ function compileLogicRunner(sourceCode) {
1003
2219
  `"use strict";
1004
2220
  ${sourceCode}
1005
2221
  if (typeof update !== "function") {
1006
- throw new TypeError("\u9700\u8981\u5B9A\u4E49 update(input) \u51FD\u6570");
2222
+ throw new TypeError(dslMessage("logicUpdateRequired"));
1007
2223
  }
1008
2224
  return update(input);`
1009
2225
  );
@@ -1011,7 +2227,7 @@ return update(input);`
1011
2227
  function validateLogicSourceCode(sourceCode) {
1012
2228
  const raw = sourceCode?.trim();
1013
2229
  if (!raw) {
1014
- return { ok: false, error: "\u4EE3\u7801\u4E0D\u80FD\u4E3A\u7A7A" };
2230
+ return { ok: false, error: dslMessage("codeRequired") };
1015
2231
  }
1016
2232
  try {
1017
2233
  compileLogicRunner(raw);
@@ -1019,7 +2235,7 @@ function validateLogicSourceCode(sourceCode) {
1019
2235
  } catch (error) {
1020
2236
  return {
1021
2237
  ok: false,
1022
- error: error instanceof Error ? error.message : "JavaScript \u8BED\u6CD5\u9519\u8BEF"
2238
+ error: error instanceof Error ? error.message : dslMessage("javascriptSyntaxError")
1023
2239
  };
1024
2240
  }
1025
2241
  }
@@ -1055,11 +2271,11 @@ function normalizeClockConfig(config) {
1055
2271
  function validateClockScheduleConfig(config) {
1056
2272
  const normalized = normalizeClockConfig(config);
1057
2273
  if (normalized.outputCount <= 0) {
1058
- return { ok: false, error: "\u8F93\u51FA\u6B21\u6570\u987B\u5927\u4E8E 0" };
2274
+ return { ok: false, error: dslMessage("clockCountPositive") };
1059
2275
  }
1060
2276
  const needsInterval = normalized.outputCount > 1 || normalized.outputCount === 1 && !normalized.emitImmediately;
1061
2277
  if (needsInterval && normalized.intervalSeconds <= 0) {
1062
- return { ok: false, error: "\u5F53\u524D\u914D\u7F6E\u4E0B\u65F6\u949F\u4FE1\u53F7\u95F4\u9694\u987B\u5927\u4E8E 0 \u79D2" };
2278
+ return { ok: false, error: dslMessage("clockIntervalPositive") };
1063
2279
  }
1064
2280
  return { ok: true };
1065
2281
  }
@@ -1348,24 +2564,24 @@ function parseSwaggerV2(spec, docsUrl) {
1348
2564
  }
1349
2565
  function parseSwaggerDocument(spec, docsUrl) {
1350
2566
  if (!spec || typeof spec !== "object") {
1351
- throw new Error("Swagger \u6587\u6863\u683C\u5F0F\u65E0\u6548");
2567
+ throw new Error(dslMessage("swaggerInvalid"));
1352
2568
  }
1353
- const document = spec;
1354
- if (typeof document.openapi === "string") {
1355
- const parsed = parseOpenApiV3(document, docsUrl);
2569
+ const document2 = spec;
2570
+ if (typeof document2.openapi === "string") {
2571
+ const parsed = parseOpenApiV3(document2, docsUrl);
1356
2572
  if (parsed.endpoints.length === 0) {
1357
- throw new Error("\u672A\u5728 OpenAPI \u6587\u6863\u4E2D\u627E\u5230\u63A5\u53E3");
2573
+ throw new Error(dslMessage("openApiNoOperations"));
1358
2574
  }
1359
2575
  return parsed;
1360
2576
  }
1361
- if (document.swagger === "2.0" || document.swagger === 2) {
1362
- const parsed = parseSwaggerV2(document, docsUrl);
2577
+ if (document2.swagger === "2.0" || document2.swagger === 2) {
2578
+ const parsed = parseSwaggerV2(document2, docsUrl);
1363
2579
  if (parsed.endpoints.length === 0) {
1364
- throw new Error("\u672A\u5728 Swagger 2.0 \u6587\u6863\u4E2D\u627E\u5230\u63A5\u53E3");
2580
+ throw new Error(dslMessage("swagger2NoOperations"));
1365
2581
  }
1366
2582
  return parsed;
1367
2583
  }
1368
- throw new Error("\u4EC5\u652F\u6301 OpenAPI 3.x \u4E0E Swagger 2.0 \u6587\u6863");
2584
+ throw new Error(dslMessage("swaggerUnsupported"));
1369
2585
  }
1370
2586
  function buildEndpointFullUrl(apiBaseUrl, pathOrEndpoint) {
1371
2587
  const path = typeof pathOrEndpoint === "string" ? pathOrEndpoint : pathOrEndpoint.path;
@@ -1394,6 +2610,331 @@ function filterEndpointSuggestions(suggestions, query) {
1394
2610
  );
1395
2611
  }
1396
2612
 
2613
+ // src/api-collection.ts
2614
+ var API_COLLECTION_DOCUMENT_VERSION = 1;
2615
+ var HTTP_METHOD_SET = new Set(FETCH_HTTP_METHODS);
2616
+ function isPlainStringRecord(value) {
2617
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
2618
+ return Object.values(value).every(
2619
+ (item) => typeof item === "string"
2620
+ );
2621
+ }
2622
+ function normalizeEndpoint(raw, index) {
2623
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
2624
+ return dslMessage("apiItemMustBeObject", { index });
2625
+ }
2626
+ const item = raw;
2627
+ const name = typeof item.name === "string" ? item.name.trim() : "";
2628
+ if (!name) return dslMessage("apiItemFieldRequired", { index, field: "name" });
2629
+ const url = typeof item.url === "string" ? item.url.trim() : "";
2630
+ if (!url) return dslMessage("apiItemFieldRequired", { index, field: "url" });
2631
+ const methodRaw = typeof item.method === "string" ? item.method.trim().toUpperCase() : "";
2632
+ if (!HTTP_METHOD_SET.has(methodRaw)) {
2633
+ return dslMessage("apiItemMethodInvalid", { index, methods: FETCH_HTTP_METHODS.join(" / ") });
2634
+ }
2635
+ if (item.params !== void 0 && !isPlainStringRecord(item.params)) {
2636
+ return dslMessage("apiItemFieldStringMap", { index, field: "params" });
2637
+ }
2638
+ if (item.headers !== void 0 && !isPlainStringRecord(item.headers)) {
2639
+ return dslMessage("apiItemFieldStringMap", { index, field: "headers" });
2640
+ }
2641
+ if (item.body !== void 0 && typeof item.body !== "string") {
2642
+ return dslMessage("apiItemFieldString", { index, field: "body" });
2643
+ }
2644
+ if (item.description !== void 0 && typeof item.description !== "string") {
2645
+ return dslMessage("apiItemFieldString", { index, field: "description" });
2646
+ }
2647
+ return {
2648
+ name,
2649
+ url,
2650
+ method: methodRaw,
2651
+ ...item.params ? { params: item.params } : {},
2652
+ ...item.headers ? { headers: item.headers } : {},
2653
+ ...typeof item.body === "string" ? { body: item.body } : {},
2654
+ ...typeof item.description === "string" ? { description: item.description } : {}
2655
+ };
2656
+ }
2657
+ function validateApiCollectionDocument(input) {
2658
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
2659
+ return { ok: false, error: dslMessage("apiRootMustBeObject") };
2660
+ }
2661
+ const root = input;
2662
+ const version = root.version;
2663
+ if (version !== API_COLLECTION_DOCUMENT_VERSION && version !== "1") {
2664
+ return {
2665
+ ok: false,
2666
+ error: dslMessage("apiVersionMismatch", { version: API_COLLECTION_DOCUMENT_VERSION })
2667
+ };
2668
+ }
2669
+ const name = typeof root.name === "string" ? root.name.trim() : "";
2670
+ if (!name) return { ok: false, error: dslMessage("apiNameRequired") };
2671
+ if (root.baseUrl !== void 0 && typeof root.baseUrl !== "string") {
2672
+ return { ok: false, error: dslMessage("apiBaseUrlString") };
2673
+ }
2674
+ if (!Array.isArray(root.apis)) {
2675
+ return { ok: false, error: dslMessage("apiListMustBeArray") };
2676
+ }
2677
+ if (root.apis.length === 0) {
2678
+ return { ok: false, error: dslMessage("apiListEmpty") };
2679
+ }
2680
+ const apis = [];
2681
+ const nameSet = /* @__PURE__ */ new Set();
2682
+ for (let i = 0; i < root.apis.length; i += 1) {
2683
+ const normalized = normalizeEndpoint(root.apis[i], i);
2684
+ if (typeof normalized === "string") {
2685
+ return { ok: false, error: normalized };
2686
+ }
2687
+ if (nameSet.has(normalized.name)) {
2688
+ return { ok: false, error: dslMessage("apiNameDuplicated", { name: normalized.name }) };
2689
+ }
2690
+ nameSet.add(normalized.name);
2691
+ apis.push(normalized);
2692
+ }
2693
+ return {
2694
+ ok: true,
2695
+ document: {
2696
+ version: API_COLLECTION_DOCUMENT_VERSION,
2697
+ name,
2698
+ ...typeof root.baseUrl === "string" && root.baseUrl.trim() ? { baseUrl: root.baseUrl.trim() } : {},
2699
+ apis
2700
+ }
2701
+ };
2702
+ }
2703
+ function parseApiCollectionJson(text) {
2704
+ const trimmed = text.trim();
2705
+ if (!trimmed) return { ok: false, error: dslMessage("contentEmpty") };
2706
+ let parsed;
2707
+ try {
2708
+ parsed = JSON.parse(trimmed);
2709
+ } catch (error) {
2710
+ return {
2711
+ ok: false,
2712
+ error: dslMessage("invalidJson", {
2713
+ reason: error instanceof Error ? error.message : dslMessage("invalidFormat")
2714
+ })
2715
+ };
2716
+ }
2717
+ const validated = validateApiCollectionDocument(parsed);
2718
+ if (!validated.ok) return validated;
2719
+ return {
2720
+ ok: true,
2721
+ document: validated.document,
2722
+ rawJson: JSON.stringify(validated.document, null, 2)
2723
+ };
2724
+ }
2725
+ function createApiCollectionId() {
2726
+ return `api_col_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
2727
+ }
2728
+ function apiCollectionToListItem(record) {
2729
+ return {
2730
+ id: record.id,
2731
+ name: record.name,
2732
+ persistLocal: record.persistLocal,
2733
+ apiCount: record.document.apis.length,
2734
+ updatedAt: record.updatedAt
2735
+ };
2736
+ }
2737
+ function getApiCollectionTemplateDocument() {
2738
+ return {
2739
+ version: API_COLLECTION_DOCUMENT_VERSION,
2740
+ name: dslMessage("apiTemplateName"),
2741
+ baseUrl: "https://api.example.com",
2742
+ apis: [
2743
+ {
2744
+ name: dslMessage("apiTemplateListUsers"),
2745
+ method: "GET",
2746
+ url: "/users",
2747
+ params: {
2748
+ page: "{scope?.value?.page}",
2749
+ pageSize: "20",
2750
+ tenant: "{scope?.value?.tenant}"
2751
+ },
2752
+ headers: {
2753
+ Accept: "application/json",
2754
+ Authorization: "Bearer {scope?.value?.token}"
2755
+ },
2756
+ description: dslMessage("apiTemplateListUsersDesc")
2757
+ },
2758
+ {
2759
+ name: dslMessage("apiTemplateCreateUser"),
2760
+ method: "POST",
2761
+ url: "/tenants/{scope?.value?.tenant}/users",
2762
+ headers: { "Content-Type": "application/json" },
2763
+ body: '{\n "name": "{scope?.value?.name}",\n "role": "member"\n}',
2764
+ description: dslMessage("apiTemplateCreateUserDesc")
2765
+ },
2766
+ {
2767
+ name: dslMessage("apiTemplateGetUser"),
2768
+ method: "GET",
2769
+ url: "/users/{scope?.value?.id}",
2770
+ headers: { Accept: "application/json" },
2771
+ description: dslMessage("apiTemplateGetUserDesc")
2772
+ }
2773
+ ]
2774
+ };
2775
+ }
2776
+ function getApiCollectionTemplateJson() {
2777
+ return `${JSON.stringify(getApiCollectionTemplateDocument(), null, 2)}
2778
+ `;
2779
+ }
2780
+ function downloadApiCollectionTemplate(filename = "abuilder-api-collection-template.json") {
2781
+ if (typeof document === "undefined") return;
2782
+ const blob = new Blob([getApiCollectionTemplateJson()], {
2783
+ type: "application/json;charset=utf-8"
2784
+ });
2785
+ const url = URL.createObjectURL(blob);
2786
+ const anchor = document.createElement("a");
2787
+ anchor.href = url;
2788
+ anchor.download = filename;
2789
+ anchor.click();
2790
+ URL.revokeObjectURL(url);
2791
+ }
2792
+ function encodeQueryValuePreservingScope(value) {
2793
+ if (!hasScopeTemplate(value)) return encodeURIComponent(value);
2794
+ const re = /\{((?:scope|system)[^}]*)\}/g;
2795
+ let result = "";
2796
+ let lastIndex = 0;
2797
+ let match;
2798
+ while ((match = re.exec(value)) !== null) {
2799
+ result += encodeURIComponent(value.slice(lastIndex, match.index));
2800
+ result += match[0];
2801
+ lastIndex = match.index + match[0].length;
2802
+ }
2803
+ result += encodeURIComponent(value.slice(lastIndex));
2804
+ return result;
2805
+ }
2806
+ function buildApiCollectionEndpointUrl(endpoint) {
2807
+ const base = endpoint.url.trim();
2808
+ const params = endpoint.params;
2809
+ if (!params || Object.keys(params).length === 0) return base;
2810
+ const search = Object.entries(params).filter(([, value]) => value !== void 0 && value !== null && String(value).length > 0).map(
2811
+ ([key, value]) => `${encodeURIComponent(key)}=${encodeQueryValuePreservingScope(String(value))}`
2812
+ ).join("&");
2813
+ if (!search) return base;
2814
+ return base.includes("?") ? `${base}&${search}` : `${base}?${search}`;
2815
+ }
2816
+ function normalizeApiCollectionUrlKey(url) {
2817
+ const trimmed = url.trim();
2818
+ if (!trimmed) return "";
2819
+ const withoutHash = trimmed.split("#")[0] ?? trimmed;
2820
+ const queryIndex = withoutHash.indexOf("?");
2821
+ const pathOnly = queryIndex === -1 ? withoutHash : withoutHash.slice(0, queryIndex);
2822
+ const normalized = pathOnly.replace(/\/+$/, "");
2823
+ return normalized || "/";
2824
+ }
2825
+ function stableHeadersText(headers) {
2826
+ if (!headers || Object.keys(headers).length === 0) return "";
2827
+ const sorted = Object.keys(headers).sort().reduce((acc, key) => {
2828
+ acc[key] = headers[key] ?? "";
2829
+ return acc;
2830
+ }, {});
2831
+ return JSON.stringify(sorted);
2832
+ }
2833
+ function diffFetchConfigChanges(prev, next) {
2834
+ const changed = [];
2835
+ const prevUrl = prev?.url?.trim() ?? "";
2836
+ const nextUrl = next.url?.trim() ?? "";
2837
+ if (prevUrl !== nextUrl) changed.push("url");
2838
+ const prevMethod = (prev?.method ?? "GET").toUpperCase();
2839
+ const nextMethod = (next.method ?? "GET").toUpperCase();
2840
+ if (prevMethod !== nextMethod) changed.push("method");
2841
+ if (stableHeadersText(prev?.headers) !== stableHeadersText(next.headers)) {
2842
+ changed.push("headers");
2843
+ }
2844
+ if ((prev?.body ?? "").trim() !== (next.body ?? "").trim()) {
2845
+ changed.push("body");
2846
+ }
2847
+ if ((prev?.apiBaseUrl?.trim() ?? "") !== (next.apiBaseUrl?.trim() ?? "")) {
2848
+ changed.push("apiBaseUrl");
2849
+ }
2850
+ return changed;
2851
+ }
2852
+ function pickEndpointForNode(node, collectionId, candidates) {
2853
+ if (candidates.length === 0) return null;
2854
+ if (candidates.length === 1) return candidates[0] ?? null;
2855
+ const config = node.fetchConfig;
2856
+ if (config?.apiCollectionId === collectionId && config.apiCollectionEndpointName) {
2857
+ const byName = candidates.find(
2858
+ (item) => item.name === config.apiCollectionEndpointName
2859
+ );
2860
+ if (byName) return byName;
2861
+ }
2862
+ const method = config?.method?.toUpperCase();
2863
+ if (method) {
2864
+ const byMethod = candidates.filter((item) => item.method === method);
2865
+ if (byMethod.length === 1) return byMethod[0] ?? null;
2866
+ if (byMethod.length > 1) return byMethod[0] ?? null;
2867
+ }
2868
+ return candidates[0] ?? null;
2869
+ }
2870
+ function buildApiCollectionSyncPatches(options) {
2871
+ const { collectionId, document: document2, nodes } = options;
2872
+ const byUrl = /* @__PURE__ */ new Map();
2873
+ for (const endpoint of document2.apis) {
2874
+ const key = normalizeApiCollectionUrlKey(endpoint.url);
2875
+ if (!key) continue;
2876
+ const list = byUrl.get(key) ?? [];
2877
+ list.push(endpoint);
2878
+ byUrl.set(key, list);
2879
+ }
2880
+ const patches = [];
2881
+ const syncedAt = Date.now();
2882
+ for (const node of nodes) {
2883
+ const nodeUrl = node.fetchConfig?.url;
2884
+ if (!nodeUrl?.trim()) continue;
2885
+ const key = normalizeApiCollectionUrlKey(nodeUrl);
2886
+ if (!key) continue;
2887
+ const candidates = byUrl.get(key) ?? [];
2888
+ const endpoint = pickEndpointForNode(node, collectionId, candidates);
2889
+ if (!endpoint) continue;
2890
+ const fetchConfigPatch = applyApiCollectionEndpointToFetchConfig({
2891
+ collectionId,
2892
+ document: document2,
2893
+ endpoint
2894
+ });
2895
+ const changedFields = diffFetchConfigChanges(node.fetchConfig, fetchConfigPatch);
2896
+ fetchConfigPatch.apiCollectionSyncNotice = {
2897
+ source: "api-collection-sync",
2898
+ collectionName: document2.name,
2899
+ endpointName: endpoint.name,
2900
+ changedFields,
2901
+ updatedAt: syncedAt
2902
+ };
2903
+ patches.push({
2904
+ nodeId: node.id,
2905
+ nodeLabel: (node.label ?? "").trim() || node.id,
2906
+ changedFields,
2907
+ fetchConfigPatch
2908
+ });
2909
+ }
2910
+ return patches;
2911
+ }
2912
+ function toApiCollectionSyncResult(patches) {
2913
+ return {
2914
+ updatedCount: patches.length,
2915
+ nodes: patches.map((patch) => ({
2916
+ id: patch.nodeId,
2917
+ label: patch.nodeLabel,
2918
+ changedFields: patch.changedFields
2919
+ }))
2920
+ };
2921
+ }
2922
+ function applyApiCollectionEndpointToFetchConfig(options) {
2923
+ const { collectionId, document: document2, endpoint } = options;
2924
+ const headers = endpoint.headers ?? {};
2925
+ return {
2926
+ url: buildApiCollectionEndpointUrl(endpoint),
2927
+ method: endpoint.method,
2928
+ headers,
2929
+ headersJson: Object.keys(headers).length > 0 ? JSON.stringify(headers, null, 2) : "",
2930
+ body: endpoint.body ?? "",
2931
+ apiBaseUrl: document2.baseUrl?.trim() || void 0,
2932
+ urlInputMode: "collection",
2933
+ apiCollectionId: collectionId,
2934
+ apiCollectionEndpointName: endpoint.name
2935
+ };
2936
+ }
2937
+
1397
2938
  // src/runtime/execution-trace.ts
1398
2939
  function serializeTraceValue(value) {
1399
2940
  if (value === void 0) return void 0;
@@ -1532,7 +3073,7 @@ function collectBlueprintLibraryRefs(graph) {
1532
3073
  }
1533
3074
  function formatBlueprintCycleMessage(cycleIds, resolveName) {
1534
3075
  const labels = cycleIds.map((id) => resolveName?.(id) ?? id);
1535
- return `\u84DD\u56FE\u5F15\u7528\u5B58\u5728\u6B7B\u5FAA\u73AF\uFF1A${labels.join(" \u2192 ")}`;
3076
+ return dslMessage("blueprintCycle", { path: labels.join(" \u2192 ") });
1536
3077
  }
1537
3078
  async function detectBlueprintReferenceCycle(options) {
1538
3079
  const {
@@ -1992,7 +3533,7 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
1992
3533
  stopAllClockSchedules();
1993
3534
  const node = this.requireNode(lifecycleNodeId);
1994
3535
  if (node.nodeType !== LIFECYCLE_NODE_TYPE) {
1995
- throw new Error("\u8C03\u8BD5\u4F1A\u8BDD\u53EA\u80FD\u4ECE\u751F\u547D\u5468\u671F\u8282\u70B9\u5F00\u59CB");
3536
+ throw new Error(dslMessage("debugMustStartFromLifecycle"));
1996
3537
  }
1997
3538
  this.outputs.clear();
1998
3539
  this.traceEntries = [];
@@ -2193,7 +3734,7 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2193
3734
  const runExecutor = executor ?? this.debugExecutor ?? this.createExecutor(this.debugQueue ?? []);
2194
3735
  if (!this.syncTokenFromGraph(token)) {
2195
3736
  return this.appendDebugTraceEntry(token, nodeLabelById, startedAt, {
2196
- error: "\u8282\u70B9\u5DF2\u4ECE\u84DD\u56FE\u4E2D\u79FB\u9664"
3737
+ error: dslMessage("nodeRemoved")
2197
3738
  });
2198
3739
  }
2199
3740
  try {
@@ -2254,7 +3795,7 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2254
3795
  }
2255
3796
  if (!isTrueSignal(input)) {
2256
3797
  return finishWithOutput(
2257
- createFalseSignal("\u65F6\u949F\u8282\u70B9\u9700\u8981\u6536\u5230\u771F\u4FE1\u53F7\u540E\u624D\u4F1A\u542F\u52A8")
3798
+ createFalseSignal(dslMessage("clockNeedsTrue"))
2258
3799
  );
2259
3800
  }
2260
3801
  const validation = validateClockScheduleConfig(normalized);
@@ -2329,19 +3870,19 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2329
3870
  if (!isTrueSignal(input)) {
2330
3871
  io.setOutput(
2331
3872
  "out",
2332
- createFalseSignal("\u84DD\u56FE\u8282\u70B9\u9700\u8981\u6536\u5230\u771F\u4FE1\u53F7\u540E\u624D\u4F1A\u6267\u884C")
3873
+ createFalseSignal(dslMessage("blueprintNeedsTrue"))
2333
3874
  );
2334
3875
  io.emitFlow("out");
2335
3876
  return;
2336
3877
  }
2337
3878
  const libraryId = node.libraryBlueprintId;
2338
3879
  if (!libraryId) {
2339
- io.setOutput("out", createFalseSignal("\u672A\u9009\u62E9\u84DD\u56FE\u5E93\u4E2D\u7684\u84DD\u56FE"));
3880
+ io.setOutput("out", createFalseSignal(dslMessage("blueprintNotSelected")));
2340
3881
  io.emitFlow("out");
2341
3882
  return;
2342
3883
  }
2343
3884
  if (!runner.resolveLibraryBlueprint) {
2344
- io.setOutput("out", createFalseSignal("\u84DD\u56FE\u5E93\u89E3\u6790\u5668\u672A\u914D\u7F6E"));
3885
+ io.setOutput("out", createFalseSignal(dslMessage("blueprintResolverMissing")));
2345
3886
  io.emitFlow("out");
2346
3887
  return;
2347
3888
  }
@@ -2364,7 +3905,7 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2364
3905
  if (!nestedGraph) {
2365
3906
  io.setOutput(
2366
3907
  "out",
2367
- createFalseSignal(`\u84DD\u56FE\u5E93\u8BB0\u5F55\u4E0D\u5B58\u5728: ${libraryId}`)
3908
+ createFalseSignal(dslMessage("blueprintRecordMissing", { id: libraryId }))
2368
3909
  );
2369
3910
  io.emitFlow("out");
2370
3911
  return;
@@ -2416,7 +3957,7 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2416
3957
  io.setOutput(
2417
3958
  "out",
2418
3959
  createFalseSignal(
2419
- input === void 0 ? "\u6570\u636E\u6E90\u8282\u70B9\u672A\u6536\u5230\u4E0A\u6E38\u8F93\u51FA\uFF0C\u8BF7\u786E\u8BA4\u8FDE\u7EBF\u4E0E\u4E0A\u6E38\u8282\u70B9\u5DF2\u6267\u884C" : "\u6570\u636E\u6E90\u8282\u70B9\u9700\u8981\u6536\u5230\u771F\u4FE1\u53F7\u540E\u624D\u4F1A\u53D1\u8D77\u8BF7\u6C42"
3960
+ input === void 0 ? dslMessage("fetchNoUpstream") : dslMessage("fetchNeedsTrue")
2420
3961
  )
2421
3962
  );
2422
3963
  io.emitFlow("out");
@@ -2437,7 +3978,7 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2437
3978
  }
2438
3979
  const bodyError = getFetchBodyValidationError(config.body, config.body);
2439
3980
  if (bodyError) {
2440
- throw new Error(`\u8BF7\u6C42\u4F53\u4E0D\u662F\u6709\u6548 JSON\uFF1A${bodyError}`);
3981
+ throw new Error(dslMessage("fetchBodyInvalidJson", { reason: bodyError }));
2441
3982
  }
2442
3983
  resolveFetchRequestUrl(config);
2443
3984
  const result = await executeFetch(config, {
@@ -2493,7 +4034,7 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2493
4034
  if (!isTrueSignal(input)) {
2494
4035
  io.setOutput(
2495
4036
  "out",
2496
- createFalseSignal("JSON \u8282\u70B9\u9700\u8981\u6536\u5230\u771F\u4FE1\u53F7\u540E\u624D\u4F1A\u89E3\u6790")
4037
+ createFalseSignal(dslMessage("jsonNeedsTrue"))
2497
4038
  );
2498
4039
  io.emitFlow("out");
2499
4040
  return;
@@ -2535,7 +4076,7 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2535
4076
  if (!isTrueSignal(input)) {
2536
4077
  io.setOutput(
2537
4078
  "out",
2538
- createFalseSignal("\u5B58\u50A8\u8282\u70B9\u9700\u8981\u6536\u5230\u771F\u4FE1\u53F7\u540E\u624D\u4F1A\u8BFB\u5199\u7F13\u5B58")
4079
+ createFalseSignal(dslMessage("storageNeedsTrue"))
2539
4080
  );
2540
4081
  io.emitFlow("out");
2541
4082
  return;
@@ -2580,7 +4121,7 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2580
4121
  if (!isTrueSignal(input)) {
2581
4122
  io.setOutput(
2582
4123
  "out",
2583
- createFalseSignal("\u65F6\u949F\u8282\u70B9\u9700\u8981\u6536\u5230\u771F\u4FE1\u53F7\u540E\u624D\u4F1A\u542F\u52A8")
4124
+ createFalseSignal(dslMessage("clockNeedsTrue"))
2584
4125
  );
2585
4126
  io.emitFlow("out");
2586
4127
  return;
@@ -2618,7 +4159,7 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2618
4159
  } else {
2619
4160
  io.setOutput(
2620
4161
  "out",
2621
- createFalseSignal("\u5E76\u8FD0\u7B97\uFF1A\u4E24\u4E2A\u8F93\u5165\u987B\u5747\u4E3A\u771F\u4FE1\u53F7")
4162
+ createFalseSignal(dslMessage("andNeedsBothTrue"))
2622
4163
  );
2623
4164
  }
2624
4165
  io.emitFlow("out");
@@ -2817,6 +4358,6 @@ var BlueprintGraphRunner = class _BlueprintGraphRunner {
2817
4358
  }
2818
4359
  };
2819
4360
 
2820
- export { AND_NODE_TYPE, BLUEPRINT_ACTIVATION_INPUT_KEY, BLUEPRINT_CALL_STACK_KEY, BLUEPRINT_NODE_TYPE, BehaviorRegistry, BlueprintCycleError, BlueprintGraphRunner, CLOCK_NODE_TYPE, DEFAULT_CLOCK_NODE_CONFIG, DEFAULT_FETCH_REQUEST_CONFIG, DEFAULT_JSON_NODE_CONFIG, DEFAULT_LOGIC_NODE_CONFIG, DEFAULT_LOGIC_NODE_TYPE, DEFAULT_STORAGE_NODE_CONFIG, DEFAULT_VIEW_EVENT_NODE_CONFIG, EVENT_NODE_TYPE, Executor, FETCH_CACHES, FETCH_CREDENTIALS, FETCH_HTTP_METHODS, FETCH_MODES, FETCH_NODE_TYPE, FETCH_REDIRECTS, FETCH_RESPONSE_TYPES, FETCH_SCOPE_AUTOCOMPLETE_FALLBACK, JSON_NODE_TYPE, LIFECYCLE_NODE_TYPE, LIFECYCLE_SIGNAL_KEY, PAGE_LIFECYCLE_LABELS, PAGE_LIFECYCLE_PHASES, STORAGE_KINDS, STORAGE_NODE_TYPE, UI_EVENT_PAYLOAD_KEY, VIEW_EVENT_SIGNAL_KEY, VIEW_EVENT_TYPES, VIEW_NODE_TYPE, abortClockNode, abortClockSession, andLogicNodeDefinition, appStorageKey, applyFetchConfigScope, applyScopeAutocompleteSelection, assertNoBlueprintReferenceCycle, blueprintNodeDefinition, buildClockSessionKey, buildClockSignalValue, buildEndpointFullUrl, buildEndpointSuggestions, buildIncomingNodeScope, buildScopeExpression, clearClockSessionAbort, clockNodeDefinition, collectArmedViewEventBindings, collectArmedViewEventNodeIds, collectBlueprintLibraryRefs, collectIncomingNodeScopeEntries, collectViewEventBindings, combinePortSignalsOr, createClockOutputValue, createFalseSignal, createIncomingNodeScopeEntry, createLifecycleSignal, createTraceEntryId, createTrueSignal, createViewEventSignal, defaultLogicNodeDefinition, deserializeStorageValue, detectBlueprintReferenceCycle, detectRuntimeBlueprintCycle, draftFetchHeadersText, evaluateScopeExpression, evaluateScopeTemplate, evaluateScopeTemplateInJson, executeFetch, executeLogicConfig, executeStorageConfig, fetchConfigHasScopeTemplate, fetchNodeDefinition, filterEndpointSuggestions, filterStorageKeySuggestions, formatBlueprintCycleMessage, formatClockTime, getActiveClockNodeIds, getClockTickDelayOffsetMs, getClockTickWaitMs, getFetchBodyValidationError, getFetchHeadersValidationError, getNodeDefinition, getScopeAutocompleteSuggestions, hasScopeTemplate, isClockNodeActive, isClockScheduleActive, isClockSessionAborted, isFalseSignal, isStorageReadConfigured, isStorageSetConfigured, isTrueSignal, isViewEventType, isWholeScopeExpression, jsonNodeDefinition, latestTraceOutputsByNode, lifecycleNodeDefinition, listBrowserStorageKeys, looksLikeJsonText, nodeDefinitionRegistry, normalizeAppNameSpace, normalizeClockConfig, normalizeFetchRequestConfig, normalizeStorageConfig, normalizeViewEventConfig, parseFetchHeadersJson, parseJsonConfig, parseJsonText, parseScopeAutocomplete, parseSwaggerDocument, registerDefaultBehaviors, resolveBlueprintCallStack, resolveFetchBody, resolveFetchHeaders, resolveFetchIncomingScope, resolveFetchRequestUrl, resolveFetchScopeAutocompleteRoot, resolveStorageKey, resolveStorageWriteValue, scheduleClockOutputs, serializeStorageValue, serializeTraceValue, snapshotDomEvent, snapshotViewEventNode, startClockSchedule, stopAllClockSchedules, stopClockSchedule, storageNodeDefinition, stringifyScopeValue, subscribeActiveClockNodes, uniqueStorageKinds, validateClockScheduleConfig, validateFetchJsonText, validateJsonString, validateJsonStringAllowingScope, validateLogicSourceCode, viewBindNodeDefinition, viewEventNodeDefinition };
4361
+ export { AND_NODE_TYPE, API_COLLECTION_DOCUMENT_VERSION, BLUEPRINT_ACTIVATION_INPUT_KEY, BLUEPRINT_CALL_STACK_KEY, BLUEPRINT_NODE_TYPE, BehaviorRegistry, BlueprintCycleError, BlueprintGraphRunner, CLOCK_NODE_TYPE, DEFAULT_CLOCK_NODE_CONFIG, DEFAULT_FETCH_REQUEST_CONFIG, DEFAULT_JSON_NODE_CONFIG, DEFAULT_LOGIC_NODE_CONFIG, DEFAULT_LOGIC_NODE_TYPE, DEFAULT_STORAGE_NODE_CONFIG, DEFAULT_VIEW_EVENT_NODE_CONFIG, EVENT_NODE_TYPE, Executor, FETCH_CACHES, FETCH_CREDENTIALS, FETCH_HTTP_METHODS, FETCH_MODES, FETCH_NODE_TYPE, FETCH_REDIRECTS, FETCH_RESPONSE_TYPES, FETCH_SCOPE_AUTOCOMPLETE_FALLBACK, JSON_NODE_TYPE, LIFECYCLE_NODE_TYPE, LIFECYCLE_SIGNAL_KEY, PAGE_LIFECYCLE_LABELS, PAGE_LIFECYCLE_PHASES, STORAGE_KINDS, STORAGE_NODE_TYPE, SYSTEM_LOCATION_KEYS, SYSTEM_MATH_KEYS, SYSTEM_TIME_METHOD_NAMES, TEMPLATE_ROOT_NAMES, UI_EVENT_PAYLOAD_KEY, VIEW_EVENT_SIGNAL_KEY, VIEW_EVENT_TYPES, VIEW_NODE_TYPE, abortClockNode, abortClockSession, andLogicNodeDefinition, apiCollectionToListItem, appStorageKey, applyApiCollectionEndpointToFetchConfig, applyFetchConfigScope, applyScopeAutocompleteSelection, assertNoBlueprintReferenceCycle, blueprintNodeDefinition, buildApiCollectionEndpointUrl, buildApiCollectionSyncPatches, buildClockSessionKey, buildClockSignalValue, buildEndpointFullUrl, buildEndpointSuggestions, buildIncomingNodeScope, buildScopeExpression, clearClockSessionAbort, clockNodeDefinition, collectArmedViewEventBindings, collectArmedViewEventNodeIds, collectBlueprintLibraryRefs, collectIncomingNodeScopeEntries, collectViewEventBindings, combinePortSignalsOr, createApiCollectionId, createClockOutputValue, createFalseSignal, createIncomingNodeScopeEntry, createLifecycleSignal, createSystemRoot, createTraceEntryId, createTrueSignal, createViewEventSignal, defaultLogicNodeDefinition, deserializeStorageValue, detectBlueprintReferenceCycle, detectRuntimeBlueprintCycle, downloadApiCollectionTemplate, draftFetchHeadersText, dslMessage, evaluateScopeExpression, evaluateScopeTemplate, evaluateScopeTemplateInJson, executeFetch, executeLogicConfig, executeStorageConfig, extractJsonErrorPosition, fetchConfigHasScopeTemplate, fetchNodeDefinition, filterEndpointSuggestions, filterStorageKeySuggestions, findJsonSyntaxErrorOffset, findSuspectCharRanges, formatBlueprintCycleMessage, formatClockTime, getActiveClockNodeIds, getApiCollectionTemplateDocument, getApiCollectionTemplateJson, getBlueprintDslLocale, getClockTickDelayOffsetMs, getClockTickWaitMs, getFetchBodyValidationError, getFetchHeadersValidationError, getNodeDefinition, getScopeAutocompleteSuggestions, getSystemAutocompleteTree, hasScopeTemplate, hasTemplateExpression, isClockNodeActive, isClockScheduleActive, isClockSessionAborted, isDayjsValue, isFalseSignal, isStorageReadConfigured, isStorageSetConfigured, isTrueSignal, isViewEventType, isWholeScopeExpression, jsonNodeDefinition, latestTraceOutputsByNode, lifecycleNodeDefinition, lintJsonString, listBrowserStorageKeys, looksLikeJsonText, nodeDefinitionRegistry, normalizeApiCollectionUrlKey, normalizeAppNameSpace, normalizeClockConfig, normalizeFetchRequestConfig, normalizeStorageConfig, normalizeViewEventConfig, parseApiCollectionJson, parseFetchHeadersJson, parseJsonConfig, parseJsonText, parseScopeAutocomplete, parseSwaggerDocument, preserveTemplateTokensInEncode, registerDefaultBehaviors, renderJsonWithErrorHighlights, resolveBlueprintCallStack, resolveFetchBody, resolveFetchHeaders, resolveFetchIncomingScope, resolveFetchRequestUrl, resolveFetchScopeAutocompleteRoot, resolveStorageKey, resolveStorageWriteValue, scheduleClockOutputs, serializeStorageValue, serializeTraceValue, setBlueprintDslLocale, snapshotDomEvent, snapshotViewEventNode, startClockSchedule, stopAllClockSchedules, stopClockSchedule, storageNodeDefinition, stringifyScopeValue, subscribeActiveClockNodes, toApiCollectionSyncResult, uniqueStorageKinds, validateApiCollectionDocument, validateClockScheduleConfig, validateFetchJsonText, validateJsonString, validateJsonStringAllowingScope, validateLogicSourceCode, viewBindNodeDefinition, viewEventNodeDefinition };
2821
4362
  //# sourceMappingURL=index.js.map
2822
4363
  //# sourceMappingURL=index.js.map