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