@wcstack/typescript 2.6.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,7 @@ var __copyProps = (to, from, except, desc) => {
15
15
  }
16
16
  return to;
17
17
  };
18
- var __toCommonJS = (mod3) => __copyProps(__defProp({}, "__esModule", { value: true }), mod3);
18
+ var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
19
19
 
20
20
  // src/schemaCore.ts
21
21
  var schemaCore_exports = {};
@@ -133,9 +133,10 @@ var WcsDiagnosticCode = {
133
133
  RecursionDeclarationInvalid: "wcs/recursion-declaration-invalid",
134
134
  TypeAnnotation: "wcs/type-annotation",
135
135
  TemplateSyntax: "wcs/template-syntax",
136
- // @wcstack/state 3.0 が拒否する(または読み方を変える)書き方の予告(info)。判定はランタイムの
137
- // [wcs/v3-migration] と同じ正本(@wcstack/state/parser の findV3MigrationIssues)。2.x 系だけの code。
138
- V3Migration: "wcs/v3-migration",
136
+ // ランタイムの正本パーサが [wcs/binding-syntax] で拒否する書き方(@wcstack/state 3.0 の文法の
137
+ // 厳格化: 閉じていない引用符・2 つ目の '#'・else: の値・構造ディレクティブの修飾子・空のフィルタ)。
138
+ // 判定は正本パーサに委ねる(service/bindingSyntaxValidator.ts)。
139
+ BindingSyntax: "wcs/binding-syntax",
139
140
  // --- <wcs-state> script: array reactivity hazards ---
140
141
  // 配列破壊的メソッド呼び出し(push 等 9 種)。Proxy を素通りしリアクティブ更新されない。
141
142
  // 同一参照の自己再代入でも要素の追加・削除は反映されない(docs/array-mutation-diagnostic-design.md §3)。
@@ -690,22 +691,15 @@ function valueMustBeDate(fnName) {
690
691
  function valueMustBeArray(fnName) {
691
692
  raiseError(`filter ${fnName} requires an array value`);
692
693
  }
693
- var warned = /* @__PURE__ */ new Set();
694
- function warnV3Migration(message) {
695
- if (warned.has(message)) {
696
- return;
697
- }
698
- warned.add(message);
699
- console.warn(`[@wcstack/state] [wcs/v3-migration] ${message} See "Preparing for 3.0" in the @wcstack/state README.`);
700
- }
701
694
  function validateNumberString(value) {
702
695
  if (!value || isNaN(Number(value))) {
703
696
  return false;
704
697
  }
705
698
  return true;
706
699
  }
707
- var eq = (options) => {
700
+ var eq = (options, literals) => {
708
701
  const opt = options?.[0] ?? optionsRequired("eq");
702
+ const literal2 = literals !== void 0 && literals.length > 0 ? literals[0] : opt;
709
703
  return (value) => {
710
704
  if (typeof value === "number") {
711
705
  if (!validateNumberString(opt)) {
@@ -716,11 +710,12 @@ var eq = (options) => {
716
710
  if (typeof value === "string") {
717
711
  return value === opt;
718
712
  }
719
- return value === opt;
713
+ return value === literal2;
720
714
  };
721
715
  };
722
- var ne = (options) => {
716
+ var ne = (options, literals) => {
723
717
  const opt = options?.[0] ?? optionsRequired("ne");
718
+ const literal2 = literals !== void 0 && literals.length > 0 ? literals[0] : opt;
724
719
  return (value) => {
725
720
  if (typeof value === "number") {
726
721
  if (!validateNumberString(opt)) {
@@ -731,7 +726,7 @@ var ne = (options) => {
731
726
  if (typeof value === "string") {
732
727
  return value !== opt;
733
728
  }
734
- return value !== opt;
729
+ return value !== literal2;
735
730
  };
736
731
  };
737
732
  var not = (_options) => {
@@ -1124,29 +1119,18 @@ var hms = (options) => {
1124
1119
  return `${hours}${opt}${minutes}${opt}${seconds}`;
1125
1120
  };
1126
1121
  };
1127
- function warnBigIntZero(fnName, value) {
1128
- if (value === 0n) {
1129
- warnV3Migration(`"${fnName}" got 0n: 3.0 treats it as falsy.`);
1130
- }
1131
- }
1132
1122
  var falsy = (_options) => {
1133
- return (value) => {
1134
- warnBigIntZero("falsy", value);
1135
- return value === false || value === null || value === void 0 || value === 0 || value === "" || Number.isNaN(value);
1136
- };
1123
+ return (value) => !value;
1137
1124
  };
1138
1125
  var truthy = (_options) => {
1139
- return (value) => {
1140
- warnBigIntZero("truthy", value);
1141
- return value !== false && value !== null && value !== void 0 && value !== 0 && value !== "" && !Number.isNaN(value);
1142
- };
1126
+ return (value) => !!value;
1143
1127
  };
1144
- var defaults = (options) => {
1128
+ var defaults = (options, literals) => {
1145
1129
  const opt = options?.[0] ?? optionsRequired("defaults");
1130
+ const fallback = literals !== void 0 && literals.length > 0 ? literals[0] : opt;
1146
1131
  return (value) => {
1147
- warnBigIntZero("defaults", value);
1148
- if (value === false || value === null || value === void 0 || value === 0 || value === "" || Number.isNaN(value)) {
1149
- return opt;
1132
+ if (!value) {
1133
+ return fallback;
1150
1134
  }
1151
1135
  return value;
1152
1136
  };
@@ -1461,11 +1445,11 @@ function foldSuffixIndexes(suffix) {
1461
1445
  }
1462
1446
  function foldRecursion(spec, path) {
1463
1447
  if (!path.startsWith(spec.anchor)) return null;
1464
- const unit3 = "." + spec.repeat;
1448
+ const unit2 = "." + spec.repeat;
1465
1449
  let cursor = spec.anchor.length;
1466
1450
  let depth = 0;
1467
- while (path.startsWith(unit3, cursor)) {
1468
- cursor += unit3.length;
1451
+ while (path.startsWith(unit2, cursor)) {
1452
+ cursor += unit2.length;
1469
1453
  depth++;
1470
1454
  }
1471
1455
  if (cursor !== path.length && path.charCodeAt(cursor) !== 46) return null;
@@ -1475,9 +1459,9 @@ function matchesRecursion(specs, path, has) {
1475
1459
  for (const spec of specs) {
1476
1460
  const folded = foldRecursion(spec, path);
1477
1461
  if (folded === null) continue;
1478
- const unit3 = "." + spec.repeat;
1462
+ const unit2 = "." + spec.repeat;
1479
1463
  for (let depth = folded.depth; depth >= 0; depth--) {
1480
- const rest = unit3.repeat(folded.depth - depth) + folded.rest;
1464
+ const rest = unit2.repeat(folded.depth - depth) + folded.rest;
1481
1465
  if (has(spec.anchor + rest)) return true;
1482
1466
  if (has(spec.recursiveAnchor + rest)) return true;
1483
1467
  for (let dot = rest.lastIndexOf("."); dot > 0; dot = rest.lastIndexOf(".", dot - 1)) {
@@ -1491,10 +1475,10 @@ function owningGetterSuffix(spec, getterSuffixes, path) {
1491
1475
  const pattern = indexSegmentsToWildcard(path);
1492
1476
  const folded = foldRecursion(spec, pattern);
1493
1477
  if (folded === null) return null;
1494
- const unit3 = "." + spec.repeat;
1478
+ const unit2 = "." + spec.repeat;
1495
1479
  for (const suffix of getterSuffixes) {
1496
1480
  for (let depth = folded.depth; depth >= 0; depth--) {
1497
- const expansion = spec.anchor + unit3.repeat(depth) + suffix;
1481
+ const expansion = spec.anchor + unit2.repeat(depth) + suffix;
1498
1482
  if (pattern === expansion || pattern.startsWith(expansion + ".")) return suffix;
1499
1483
  }
1500
1484
  }
@@ -1506,10 +1490,10 @@ function indexSegmentsToWildcard(path) {
1506
1490
  function concreteExpansionSuffix(spec, getterSuffixes, key) {
1507
1491
  const folded = foldRecursion(spec, key);
1508
1492
  if (folded === null) return null;
1509
- const unit3 = "." + spec.repeat;
1493
+ const unit2 = "." + spec.repeat;
1510
1494
  for (const suffix of getterSuffixes) {
1511
1495
  for (let depth = folded.depth; depth >= 0; depth--) {
1512
- if (key === spec.anchor + unit3.repeat(depth) + suffix) return suffix;
1496
+ if (key === spec.anchor + unit2.repeat(depth) + suffix) return suffix;
1513
1497
  }
1514
1498
  }
1515
1499
  return null;
@@ -1541,9 +1525,9 @@ function impliedStructurePaths(spec) {
1541
1525
  return out;
1542
1526
  }
1543
1527
  function structuralWriteTarget(spec, suffix) {
1544
- const unit3 = "." + spec.repeat;
1528
+ const unit2 = "." + spec.repeat;
1545
1529
  let rest = suffix;
1546
- while (rest.startsWith(unit3)) rest = rest.slice(unit3.length);
1530
+ while (rest.startsWith(unit2)) rest = rest.slice(unit2.length);
1547
1531
  if (rest.length === 0) return "node";
1548
1532
  if (rest === "." + spec.repeatList + ".length") return "length";
1549
1533
  const segments = spec.repeatList.split(".");
@@ -1553,15 +1537,15 @@ function structuralWriteTarget(spec, suffix) {
1553
1537
  return null;
1554
1538
  }
1555
1539
  function sameFamily(spec, a, b) {
1556
- const unit3 = "." + spec.repeat;
1540
+ const unit2 = "." + spec.repeat;
1557
1541
  const shorter = a.length <= b.length ? a : b;
1558
1542
  const longer = a.length <= b.length ? b : a;
1559
1543
  if (!longer.endsWith(shorter)) return false;
1560
1544
  const gap = longer.slice(0, longer.length - shorter.length);
1561
1545
  if (gap.length === 0) return true;
1562
- if (gap.length % unit3.length !== 0) return false;
1563
- for (let cursor = 0; cursor < gap.length; cursor += unit3.length) {
1564
- if (!gap.startsWith(unit3, cursor)) return false;
1546
+ if (gap.length % unit2.length !== 0) return false;
1547
+ for (let cursor = 0; cursor < gap.length; cursor += unit2.length) {
1548
+ if (!gap.startsWith(unit2, cursor)) return false;
1565
1549
  }
1566
1550
  return true;
1567
1551
  }
@@ -2751,8 +2735,8 @@ function matchOpenTag(html, pos, tagName) {
2751
2735
  const nameStart = pos + 1;
2752
2736
  const nameEnd = nameStart + tagName.length;
2753
2737
  if (nameEnd > html.length) return null;
2754
- const slice3 = html.slice(nameStart, nameEnd);
2755
- if (slice3.toLowerCase() !== tagName.toLowerCase()) return null;
2738
+ const slice2 = html.slice(nameStart, nameEnd);
2739
+ if (slice2.toLowerCase() !== tagName.toLowerCase()) return null;
2756
2740
  const charAfter = html[nameEnd];
2757
2741
  if (charAfter !== ">" && charAfter !== " " && charAfter !== " " && charAfter !== "\n" && charAfter !== "\r" && charAfter !== "/") {
2758
2742
  return null;
@@ -3002,8 +2986,8 @@ function getForTemplateDepthAt(html, openPos, offset2, bindAttrName) {
3002
2986
  }
3003
2987
 
3004
2988
  // src/core/messages.ts
3005
- function resolveLocale(locale3) {
3006
- if (locale3 === void 0 || locale3 === "" || /^ja\b|^ja[-_]/i.test(locale3) || locale3.toLowerCase() === "ja") return "ja";
2989
+ function resolveLocale(locale2) {
2990
+ if (locale2 === void 0 || locale2 === "" || /^ja\b|^ja[-_]/i.test(locale2) || locale2.toLowerCase() === "ja") return "ja";
3007
2991
  return "en";
3008
2992
  }
3009
2993
  var JA_EXPECTED_LABEL = {
@@ -3014,8 +2998,8 @@ var JA_EXPECTED_LABEL = {
3014
2998
  var ja = {
3015
2999
  spreadFilterNotAllowed: () => `\u30B9\u30D7\u30EC\u30C3\u30C9\u306E\u30BF\u30FC\u30B2\u30C3\u30C8\u306B\u30D5\u30A3\u30EB\u30BF\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093`,
3016
3000
  spreadTargetRequired: () => `\u30B9\u30D7\u30EC\u30C3\u30C9\u306B\u306F\u30BF\u30FC\u30B2\u30C3\u30C8\u30D1\u30B9\u304C\u5FC5\u8981\u3067\u3059`,
3017
- v3Migration: (detail) => `3.0 \u3078\u306E\u6E96\u5099\uFF082.x \u3067\u306F\u3053\u306E\u307E\u307E\u52D5\u304D\u307E\u3059\uFF09: ${detail}`,
3018
3001
  structuralMustBeSingle: (d) => `'${d}' \u30D0\u30A4\u30F3\u30C7\u30A3\u30F3\u30B0\u306F\u5358\u72EC\u3067\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\uFF08';' \u3067\u4ED6\u306E\u30D0\u30A4\u30F3\u30C7\u30A3\u30F3\u30B0\u3068\u4F75\u8A18\u3067\u304D\u307E\u305B\u3093\u3002\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u8AAD\u307F\u8FBC\u307F\u6642\u306B throw \u3057\u307E\u3059\uFF09`,
3002
+ bindingSyntax: (detail) => `\u30D0\u30A4\u30F3\u30C7\u30A3\u30F3\u30B0\u306E\u69CB\u6587\u30A8\u30E9\u30FC\uFF08\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u8AAD\u307F\u8FBC\u307F\u6642\u306B throw \u3057\u307E\u3059\uFF09: ${detail}`,
3019
3003
  eventTokenUndeclared: (t) => `\u30A4\u30D9\u30F3\u30C8\u30C8\u30FC\u30AF\u30F3 "${t}" \u306F $eventTokens \u306B\u5BA3\u8A00\u3055\u308C\u3066\u3044\u307E\u305B\u3093`,
3020
3004
  commandRhsFormat: () => `command \u30D0\u30A4\u30F3\u30C7\u30A3\u30F3\u30B0\u306E\u53F3\u8FBA\u306B\u306F $command.<name>\uFF08$commandTokens \u3067\u5BA3\u8A00\uFF09\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`,
3021
3005
  commandTokenUndeclared: (t) => `\u30B3\u30DE\u30F3\u30C9\u30C8\u30FC\u30AF\u30F3 "${t}" \u306F $commandTokens \u306B\u5BA3\u8A00\u3055\u308C\u3066\u3044\u307E\u305B\u3093`,
@@ -3203,8 +3187,8 @@ var EN_EXPECTED_LABEL = {
3203
3187
  var en = {
3204
3188
  spreadFilterNotAllowed: () => `Filters cannot be applied to a spread target`,
3205
3189
  spreadTargetRequired: () => `Spread requires a target path`,
3206
- v3Migration: (detail) => `Preparing for 3.0 (this still runs on 2.x): ${detail}`,
3207
3190
  structuralMustBeSingle: (d) => `'${d}' must be the only binding in this attribute (it cannot be combined with ';'; the runtime throws at load time)`,
3191
+ bindingSyntax: (detail) => `Binding syntax error (the runtime throws at load time): ${detail}`,
3208
3192
  eventTokenUndeclared: (t) => `Event token "${t}" is not declared in $eventTokens`,
3209
3193
  commandRhsFormat: () => `The right side of a command binding must be $command.<name> (declared in $commandTokens)`,
3210
3194
  commandTokenUndeclared: (t) => `Command token "${t}" is not declared in $commandTokens`,
@@ -3385,15 +3369,15 @@ var en = {
3385
3369
  recursionInMountedComponent: (subject) => `${subject} is not run by a mounted component (bind-component); the runtime warns with wcs/mount-dollar-declaration and drops it. Declare $recursion and "**" getters on the root state \u2014 the anchor path is resolved against the root tree`
3386
3370
  };
3387
3371
  var CATALOGS = { ja, en };
3388
- function getMessages(locale3) {
3389
- return CATALOGS[resolveLocale(locale3)];
3372
+ function getMessages(locale2) {
3373
+ return CATALOGS[resolveLocale(locale2)];
3390
3374
  }
3391
3375
 
3392
3376
  // src/service/bindingValidator.ts
3393
3377
  var filterMap = new Map(BUILTIN_FILTERS.map((f) => [f.name, f]));
3394
- function validateBindings(html, attrName, stateTagName = "wcs-state", locale3, fileReader, applicationSchema) {
3378
+ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, fileReader, applicationSchema) {
3395
3379
  const diagnostics = [];
3396
- const msgs = getMessages(locale3);
3380
+ const msgs = getMessages(locale2);
3397
3381
  const statePaths = mergeSchemaCandidates(getStatePathsFromHtml(html, stateTagName, fileReader), applicationSchema);
3398
3382
  const attrs = findAllBindAttributes(html, attrName);
3399
3383
  let structuralTemplates = null;
@@ -3950,8 +3934,8 @@ function isLiteral(value) {
3950
3934
  }
3951
3935
 
3952
3936
  // src/service/stateTypeValidator.ts
3953
- function validateStateTypes(html, stateTagName = "wcs-state", locale3) {
3954
- const msgs = getMessages(locale3);
3937
+ function validateStateTypes(html, stateTagName = "wcs-state", locale2) {
3938
+ const msgs = getMessages(locale2);
3955
3939
  const blocks = parseWcsScriptBlocks(html, stateTagName);
3956
3940
  const diagnostics = [];
3957
3941
  for (const block of blocks) {
@@ -4078,8 +4062,8 @@ function isApiRoot(root) {
4078
4062
  // src/service/nestedAssignValidator.ts
4079
4063
  var NESTED_ASSIGN = new RegExp(`${ROOT_DOT}(${CHAIN_ONE_PLUS})${ASSIGN_TAIL}`, "g");
4080
4064
  var PRE_NESTED_INCDEC = new RegExp(`${PRE_INCDEC}${ROOT_DOT}(${CHAIN_ONE_PLUS})`, "g");
4081
- function validateNestedAssigns(html, stateTagName = "wcs-state", locale3) {
4082
- const msgs = getMessages(locale3);
4065
+ function validateNestedAssigns(html, stateTagName = "wcs-state", locale2) {
4066
+ const msgs = getMessages(locale2);
4083
4067
  const blocks = parseWcsScriptBlocks(html, stateTagName);
4084
4068
  const diagnostics = [];
4085
4069
  for (const block of blocks) {
@@ -4130,8 +4114,8 @@ var PRE_BRACKET_INDEX = new RegExp(`${PRE_INCDEC}${ROOT_BRACKET}(${BRACKETS_ONLY
4130
4114
  function toAccessor(path) {
4131
4115
  return /^[A-Za-z_]\w*$/.test(path) ? `this.${path}` : `this["${path}"]`;
4132
4116
  }
4133
- function validateArrayMutations(html, stateTagName = "wcs-state", locale3) {
4134
- const msgs = getMessages(locale3);
4117
+ function validateArrayMutations(html, stateTagName = "wcs-state", locale2) {
4118
+ const msgs = getMessages(locale2);
4135
4119
  const blocks = parseWcsScriptBlocks(html, stateTagName);
4136
4120
  const diagnostics = [];
4137
4121
  for (const block of blocks) {
@@ -4241,9 +4225,9 @@ function isInsideTag(html, offset2, tagName) {
4241
4225
  }
4242
4226
 
4243
4227
  // src/service/templateSyntaxValidator.ts
4244
- function validateTemplateSyntax(html, stateTagName, bindAttrName = "data-wcs", locale3, fileReader, applicationSchema) {
4228
+ function validateTemplateSyntax(html, stateTagName, bindAttrName = "data-wcs", locale2, fileReader, applicationSchema) {
4245
4229
  const diagnostics = [];
4246
- const msgs = getMessages(locale3);
4230
+ const msgs = getMessages(locale2);
4247
4231
  const allPaths = mergeSchemaCandidates(getStatePathsFromHtml(html, stateTagName, fileReader), applicationSchema);
4248
4232
  const defaultSchema = applicationSchema;
4249
4233
  const missingVerdict = (path, displayPath, pathSet2, scoped) => {
@@ -4509,43 +4493,6 @@ var PathInfo = class {
4509
4493
  this.wildcardCount = wildcardCount;
4510
4494
  }
4511
4495
  };
4512
- function editDistance(a, b, max) {
4513
- if (Math.abs(a.length - b.length) > max) {
4514
- return max + 1;
4515
- }
4516
- const prev = new Array(b.length + 1);
4517
- const curr = new Array(b.length + 1);
4518
- for (let j = 0; j <= b.length; j++) {
4519
- prev[j] = j;
4520
- }
4521
- for (let i = 1; i <= a.length; i++) {
4522
- curr[0] = i;
4523
- for (let j = 1; j <= b.length; j++) {
4524
- const cost = a[i - 1] === b[j - 1] ? 0 : 1;
4525
- curr[j] = Math.min(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost);
4526
- }
4527
- for (let j = 0; j <= b.length; j++) {
4528
- prev[j] = curr[j];
4529
- }
4530
- }
4531
- return prev[b.length];
4532
- }
4533
- function didYouMean(input, candidates) {
4534
- if (input.length === 0) {
4535
- return "";
4536
- }
4537
- const folded = input.toLowerCase();
4538
- let best = null;
4539
- let bestDistance = 3;
4540
- for (const candidate of candidates) {
4541
- const distance = editDistance(folded, candidate.toLowerCase(), 2);
4542
- if (distance < bestDistance) {
4543
- best = candidate;
4544
- bestDistance = distance;
4545
- }
4546
- }
4547
- return best !== null ? ` Did you mean "${best}"?` : "";
4548
- }
4549
4496
  var LINT_HINT = " Validate statically: npx @wcstack/lint <file>.";
4550
4497
  var STRUCTURAL_BINDING_TYPE_SET2 = /* @__PURE__ */ new Set([
4551
4498
  "if",
@@ -4553,660 +4500,10 @@ var STRUCTURAL_BINDING_TYPE_SET2 = /* @__PURE__ */ new Set([
4553
4500
  "else",
4554
4501
  "for"
4555
4502
  ]);
4556
- var _config2 = {
4557
- locale: "en"
4558
- };
4559
- var config2 = _config2;
4560
- function optionsRequired2(fnName) {
4561
- raiseError2(`filter ${fnName} requires at least one option`);
4562
- }
4563
- function optionMustBeNumber2(fnName) {
4564
- raiseError2(`filter ${fnName} requires a number as option`);
4565
- }
4566
- function valueMustBeNumber2(fnName) {
4567
- raiseError2(`filter ${fnName} requires a number value`);
4568
- }
4569
- function valueMustBeBoolean2(fnName) {
4570
- raiseError2(`filter ${fnName} requires a boolean value`);
4571
- }
4572
- function valueMustBeDate2(fnName) {
4573
- raiseError2(`filter ${fnName} requires a date value`);
4574
- }
4575
- function valueMustBeArray2(fnName) {
4576
- raiseError2(`filter ${fnName} requires an array value`);
4577
- }
4578
- var NO_ARGS = /* @__PURE__ */ new Set([
4579
- "not",
4580
- "abs",
4581
- "uc",
4582
- "lc",
4583
- "cap",
4584
- "trim",
4585
- "rev",
4586
- "int",
4587
- "float",
4588
- "date",
4589
- "time",
4590
- "datetime",
4591
- "falsy",
4592
- "truthy",
4593
- "boolean",
4594
- "number",
4595
- "string",
4596
- "null"
4597
- ]);
4598
- var TWO_ARGS = /* @__PURE__ */ new Set(["clamp", "slice", "substr", "pad", "truncate"]);
4599
- function maxFilterArgs(name) {
4600
- return NO_ARGS.has(name) ? 0 : TWO_ARGS.has(name) ? 2 : 1;
4601
- }
4602
- var STRUCTURAL_KEYWORDS = /* @__PURE__ */ new Set(["for", "if", "elseif", "else", "..."]);
4603
- var TYPED_LITERAL = /(?:^|\|)\s*(eq|ne|defaults)\s*\(\s*(true|false|null)\s*\)/g;
4604
- function hasUnterminatedQuote(text) {
4605
- let quote = null;
4606
- for (let i = 0; i < text.length; i++) {
4607
- const c = text[i];
4608
- if (quote !== null) {
4609
- if (c === quote)
4610
- quote = null;
4611
- } else if (c === "'" || c === '"') {
4612
- quote = c;
4613
- }
4614
- }
4615
- return quote !== null;
4616
- }
4617
- function checkStatePart(text, parsed, issues) {
4618
- if (hasUnterminatedQuote(text)) {
4619
- issues.push(`"${text}": 3.0 rejects the unterminated quote.`);
4620
- }
4621
- for (const [, fnName, literal2] of text.matchAll(TYPED_LITERAL)) {
4622
- issues.push(`"${fnName}(${literal2})": 3.0 reads an unquoted ${literal2} as a ${literal2 === "null" ? "null" : "boolean"}, not the text. Write ${fnName}('${literal2}') to keep the text.`);
4623
- }
4624
- if (parsed !== null) {
4625
- issues.push(...findFilterArityIssues([parsed]));
4626
- }
4627
- }
4628
- function findFilterArityIssues(results) {
4629
- const issues = [];
4630
- for (const result of results) {
4631
- for (const filter of [...result.inFilters, ...result.outFilters]) {
4632
- const max = maxFilterArgs(filter.filterName);
4633
- if (filter.args.length > max) {
4634
- issues.push(`"${filter.filterName}" takes at most ${max} argument(s); 3.0 rejects more.`);
4635
- }
4636
- }
4637
- }
4638
- return issues;
4639
- }
4640
- function findV3MigrationIssues(expr, parsed = null) {
4641
- const issues = [];
4642
- const colon = expr.indexOf(":");
4643
- if (colon === -1)
4644
- return issues;
4645
- const propPart = expr.slice(0, colon).trim();
4646
- const modifierParts = propPart.split("#");
4647
- const keyword = modifierParts[0].split("|")[0].trim();
4648
- if (modifierParts.length > 2) {
4649
- issues.push(`"${propPart}": 3.0 rejects a second "#". Write "${modifierParts[0].trim()}#${modifierParts.slice(1).map((m) => m.trim()).join(",")}".`);
4650
- }
4651
- if (keyword === "else" && expr.slice(colon + 1).trim().length > 0) {
4652
- issues.push(`"${expr}": 3.0 rejects a value after "else:".`);
4653
- }
4654
- if (STRUCTURAL_KEYWORDS.has(keyword) && keyword !== propPart) {
4655
- issues.push(`"${propPart}": 3.0 rejects modifiers and filters on "${keyword}". Write "${keyword}:".`);
4656
- }
4657
- if ((keyword === "radio" || keyword === "checkbox") && keyword !== propPart) {
4658
- issues.push(`"${propPart}": 3.0 keeps this a ${keyword} binding that honours the modifiers (2.x binds a property named "${keyword}").`);
4659
- }
4660
- checkStatePart(expr.slice(colon + 1).trim(), parsed, issues);
4661
- return issues;
4662
- }
4663
- function findEmbeddedV3MigrationIssues(expression, parsed = null) {
4664
- const issues = [];
4665
- checkStatePart(expression, parsed, issues);
4666
- return issues;
4667
- }
4668
- var warned2 = /* @__PURE__ */ new Set();
4669
- function warnV3Migration2(message) {
4670
- if (warned2.has(message)) {
4671
- return;
4672
- }
4673
- warned2.add(message);
4674
- console.warn(`[@wcstack/state] [wcs/v3-migration] ${message} See "Preparing for 3.0" in the @wcstack/state README.`);
4675
- }
4676
- function validateNumberString2(value) {
4677
- if (!value || isNaN(Number(value))) {
4678
- return false;
4679
- }
4680
- return true;
4681
- }
4682
- var eq2 = (options) => {
4683
- const opt = options?.[0] ?? optionsRequired2("eq");
4684
- return (value) => {
4685
- if (typeof value === "number") {
4686
- if (!validateNumberString2(opt)) {
4687
- optionMustBeNumber2("eq");
4688
- }
4689
- return value === Number(opt);
4690
- }
4691
- if (typeof value === "string") {
4692
- return value === opt;
4693
- }
4694
- return value === opt;
4695
- };
4696
- };
4697
- var ne2 = (options) => {
4698
- const opt = options?.[0] ?? optionsRequired2("ne");
4699
- return (value) => {
4700
- if (typeof value === "number") {
4701
- if (!validateNumberString2(opt)) {
4702
- optionMustBeNumber2("ne");
4703
- }
4704
- return value !== Number(opt);
4705
- }
4706
- if (typeof value === "string") {
4707
- return value !== opt;
4708
- }
4709
- return value !== opt;
4710
- };
4711
- };
4712
- var not2 = (_options) => {
4713
- return (value) => {
4714
- if (typeof value !== "boolean") {
4715
- valueMustBeBoolean2("not");
4716
- }
4717
- return !value;
4718
- };
4719
- };
4720
- var lt2 = (options) => {
4721
- const opt = options?.[0] ?? optionsRequired2("lt");
4722
- if (!validateNumberString2(opt)) {
4723
- optionMustBeNumber2("lt");
4724
- }
4725
- return (value) => {
4726
- if (typeof value !== "number") {
4727
- valueMustBeNumber2("lt");
4728
- }
4729
- return value < Number(opt);
4730
- };
4731
- };
4732
- var le2 = (options) => {
4733
- const opt = options?.[0] ?? optionsRequired2("le");
4734
- if (!validateNumberString2(opt)) {
4735
- optionMustBeNumber2("le");
4736
- }
4737
- return (value) => {
4738
- if (typeof value !== "number") {
4739
- valueMustBeNumber2("le");
4740
- }
4741
- return value <= Number(opt);
4742
- };
4743
- };
4744
- var gt2 = (options) => {
4745
- const opt = options?.[0] ?? optionsRequired2("gt");
4746
- if (!validateNumberString2(opt)) {
4747
- optionMustBeNumber2("gt");
4748
- }
4749
- return (value) => {
4750
- if (typeof value !== "number") {
4751
- valueMustBeNumber2("gt");
4752
- }
4753
- return value > Number(opt);
4754
- };
4755
- };
4756
- var ge2 = (options) => {
4757
- const opt = options?.[0] ?? optionsRequired2("ge");
4758
- if (!validateNumberString2(opt)) {
4759
- optionMustBeNumber2("ge");
4760
- }
4761
- return (value) => {
4762
- if (typeof value !== "number") {
4763
- valueMustBeNumber2("ge");
4764
- }
4765
- return value >= Number(opt);
4766
- };
4767
- };
4768
- var inc2 = (options) => {
4769
- const opt = options?.[0] ?? optionsRequired2("inc");
4770
- if (!validateNumberString2(opt)) {
4771
- optionMustBeNumber2("inc");
4772
- }
4773
- return (value) => {
4774
- if (typeof value !== "number") {
4775
- valueMustBeNumber2("inc");
4776
- }
4777
- return value + Number(opt);
4778
- };
4779
- };
4780
- var dec2 = (options) => {
4781
- const opt = options?.[0] ?? optionsRequired2("dec");
4782
- if (!validateNumberString2(opt)) {
4783
- optionMustBeNumber2("dec");
4784
- }
4785
- return (value) => {
4786
- if (typeof value !== "number") {
4787
- valueMustBeNumber2("dec");
4788
- }
4789
- return value - Number(opt);
4790
- };
4791
- };
4792
- var mul2 = (options) => {
4793
- const opt = options?.[0] ?? optionsRequired2("mul");
4794
- if (!validateNumberString2(opt)) {
4795
- optionMustBeNumber2("mul");
4796
- }
4797
- return (value) => {
4798
- if (typeof value !== "number") {
4799
- valueMustBeNumber2("mul");
4800
- }
4801
- return value * Number(opt);
4802
- };
4803
- };
4804
- var div2 = (options) => {
4805
- const opt = options?.[0] ?? optionsRequired2("div");
4806
- if (!validateNumberString2(opt)) {
4807
- optionMustBeNumber2("div");
4808
- }
4809
- return (value) => {
4810
- if (typeof value !== "number") {
4811
- valueMustBeNumber2("div");
4812
- }
4813
- return value / Number(opt);
4814
- };
4815
- };
4816
- var mod2 = (options) => {
4817
- const opt = options?.[0] ?? optionsRequired2("mod");
4818
- if (!validateNumberString2(opt)) {
4819
- optionMustBeNumber2("mod");
4820
- }
4821
- return (value) => {
4822
- if (typeof value !== "number") {
4823
- valueMustBeNumber2("mod");
4824
- }
4825
- return value % Number(opt);
4826
- };
4827
- };
4828
- var abs2 = (_options) => {
4829
- return (value) => {
4830
- if (typeof value !== "number") {
4831
- valueMustBeNumber2("abs");
4832
- }
4833
- return Math.abs(value);
4834
- };
4835
- };
4836
- var clamp2 = (options) => {
4837
- const opt1 = options?.[0] ?? optionsRequired2("clamp");
4838
- if (!validateNumberString2(opt1)) {
4839
- optionMustBeNumber2("clamp");
4840
- }
4841
- const opt2 = options?.[1] ?? optionsRequired2("clamp");
4842
- if (!validateNumberString2(opt2)) {
4843
- optionMustBeNumber2("clamp");
4844
- }
4845
- const min = Number(opt1);
4846
- const max = Number(opt2);
4847
- return (value) => {
4848
- if (typeof value !== "number") {
4849
- valueMustBeNumber2("clamp");
4850
- }
4851
- return Math.min(Math.max(value, min), max);
4852
- };
4853
- };
4854
- var fix2 = (options) => {
4855
- const opt = options?.[0] ?? "0";
4856
- if (!validateNumberString2(opt)) {
4857
- optionMustBeNumber2("fix");
4858
- }
4859
- return (value) => {
4860
- if (typeof value !== "number") {
4861
- valueMustBeNumber2("fix");
4862
- }
4863
- return value.toFixed(Number(opt));
4864
- };
4865
- };
4866
- var locale2 = (options) => {
4867
- const explicit = options?.[0];
4868
- return (value) => {
4869
- if (typeof value !== "number") {
4870
- valueMustBeNumber2("locale");
4871
- }
4872
- return value.toLocaleString(explicit ?? config2.locale);
4873
- };
4874
- };
4875
- var uc2 = (_options) => {
4876
- return (value) => {
4877
- return String(value).toUpperCase();
4878
- };
4879
- };
4880
- var lc2 = (_options) => {
4881
- return (value) => {
4882
- return String(value).toLowerCase();
4883
- };
4884
- };
4885
- var cap2 = (_options) => {
4886
- return (value) => {
4887
- const v = String(value);
4888
- if (v.length === 0) {
4889
- return v;
4890
- }
4891
- if (v.length === 1) {
4892
- return v.toUpperCase();
4893
- }
4894
- return v.charAt(0).toUpperCase() + v.slice(1);
4895
- };
4896
- };
4897
- var trim2 = (_options) => {
4898
- return (value) => {
4899
- return String(value).trim();
4900
- };
4901
- };
4902
- var slice2 = (options) => {
4903
- const numberedOpts = [];
4904
- const opt1 = options?.[0] ?? optionsRequired2("slice");
4905
- if (!validateNumberString2(opt1)) {
4906
- optionMustBeNumber2("slice");
4907
- }
4908
- numberedOpts.push(Number(opt1));
4909
- const opt2 = options?.[1];
4910
- if (typeof opt2 !== "undefined") {
4911
- if (!validateNumberString2(opt2)) {
4912
- optionMustBeNumber2("slice");
4913
- }
4914
- numberedOpts.push(Number(opt2));
4915
- }
4916
- return (value) => {
4917
- return String(value).slice(...numberedOpts);
4918
- };
4919
- };
4920
- var substr2 = (options) => {
4921
- const opt1 = options?.[0] ?? optionsRequired2("substr");
4922
- if (!validateNumberString2(opt1)) {
4923
- optionMustBeNumber2("substr");
4924
- }
4925
- const opt2 = options?.[1] ?? optionsRequired2("substr");
4926
- if (!validateNumberString2(opt2)) {
4927
- optionMustBeNumber2("substr");
4928
- }
4929
- return (value) => {
4930
- return String(value).substr(Number(opt1), Number(opt2));
4931
- };
4932
- };
4933
- var pad2 = (options) => {
4934
- const opt1 = options?.[0] ?? optionsRequired2("pad");
4935
- if (!validateNumberString2(opt1)) {
4936
- optionMustBeNumber2("pad");
4937
- }
4938
- const opt2 = options?.[1] ?? "0";
4939
- return (value) => {
4940
- return String(value).padStart(Number(opt1), opt2);
4941
- };
4942
- };
4943
- var rep2 = (options) => {
4944
- const opt = options?.[0] ?? optionsRequired2("rep");
4945
- if (!validateNumberString2(opt)) {
4946
- optionMustBeNumber2("rep");
4947
- }
4948
- return (value) => {
4949
- return String(value).repeat(Number(opt));
4950
- };
4951
- };
4952
- var rev2 = (_options) => {
4953
- return (value) => {
4954
- return String(value).split("").reverse().join("");
4955
- };
4956
- };
4957
- var int2 = (_options) => {
4958
- return (value) => {
4959
- return parseInt(String(value), 10);
4960
- };
4961
- };
4962
- var float2 = (_options) => {
4963
- return (value) => {
4964
- return parseFloat(String(value));
4965
- };
4966
- };
4967
- var round2 = (options) => {
4968
- const opt = options?.[0] ?? "0";
4969
- if (!validateNumberString2(opt)) {
4970
- optionMustBeNumber2("round");
4971
- }
4972
- return (value) => {
4973
- if (typeof value !== "number") {
4974
- valueMustBeNumber2("round");
4975
- }
4976
- const optValue = Math.pow(10, Number(opt));
4977
- return Math.round(value * optValue) / optValue;
4978
- };
4979
- };
4980
- var floor2 = (options) => {
4981
- const opt = options?.[0] ?? "0";
4982
- if (!validateNumberString2(opt)) {
4983
- optionMustBeNumber2("floor");
4984
- }
4985
- return (value) => {
4986
- if (typeof value !== "number") {
4987
- valueMustBeNumber2("floor");
4988
- }
4989
- const optValue = Math.pow(10, Number(opt));
4990
- return Math.floor(value * optValue) / optValue;
4991
- };
4992
- };
4993
- var ceil2 = (options) => {
4994
- const opt = options?.[0] ?? "0";
4995
- if (!validateNumberString2(opt)) {
4996
- optionMustBeNumber2("ceil");
4997
- }
4998
- return (value) => {
4999
- if (typeof value !== "number") {
5000
- valueMustBeNumber2("ceil");
5001
- }
5002
- const optValue = Math.pow(10, Number(opt));
5003
- return Math.ceil(value * optValue) / optValue;
5004
- };
5005
- };
5006
- var percent2 = (options) => {
5007
- const opt = options?.[0] ?? "0";
5008
- if (!validateNumberString2(opt)) {
5009
- optionMustBeNumber2("percent");
5010
- }
5011
- return (value) => {
5012
- if (typeof value !== "number") {
5013
- valueMustBeNumber2("percent");
5014
- }
5015
- return `${(value * 100).toFixed(Number(opt))}%`;
5016
- };
5017
- };
5018
- var unit2 = (options) => {
5019
- const opt = options?.[0] ?? optionsRequired2("unit");
5020
- return (value) => {
5021
- if (value === null || typeof value === "undefined") {
5022
- return value;
5023
- }
5024
- return String(value) + opt;
5025
- };
5026
- };
5027
- var join2 = (options) => {
5028
- const opt = options?.[0] ?? ", ";
5029
- return (value) => {
5030
- if (!Array.isArray(value)) {
5031
- valueMustBeArray2("join");
5032
- }
5033
- return value.join(opt);
5034
- };
5035
- };
5036
- var truncate2 = (options) => {
5037
- const opt1 = options?.[0] ?? optionsRequired2("truncate");
5038
- if (!validateNumberString2(opt1)) {
5039
- optionMustBeNumber2("truncate");
5040
- }
5041
- const maxLength = Number(opt1);
5042
- const suffix = options?.[1] ?? "\u2026";
5043
- return (value) => {
5044
- const v = String(value);
5045
- if (v.length <= maxLength) {
5046
- return v;
5047
- }
5048
- return v.slice(0, maxLength) + suffix;
5049
- };
5050
- };
5051
- var date2 = (options) => {
5052
- const explicit = options?.[0];
5053
- return (value) => {
5054
- if (!(value instanceof Date)) {
5055
- valueMustBeDate2("date");
5056
- }
5057
- return value.toLocaleDateString(explicit ?? config2.locale);
5058
- };
5059
- };
5060
- var time2 = (options) => {
5061
- const explicit = options?.[0];
5062
- return (value) => {
5063
- if (!(value instanceof Date)) {
5064
- valueMustBeDate2("time");
5065
- }
5066
- return value.toLocaleTimeString(explicit ?? config2.locale);
5067
- };
5068
- };
5069
- var datetime2 = (options) => {
5070
- const explicit = options?.[0];
5071
- return (value) => {
5072
- if (!(value instanceof Date)) {
5073
- valueMustBeDate2("datetime");
5074
- }
5075
- return value.toLocaleString(explicit ?? config2.locale);
5076
- };
5077
- };
5078
- var ymd2 = (options) => {
5079
- const opt = options?.[0] ?? "-";
5080
- return (value) => {
5081
- if (!(value instanceof Date)) {
5082
- valueMustBeDate2("ymd");
5083
- }
5084
- const year = value.getFullYear().toString();
5085
- const month = (value.getMonth() + 1).toString().padStart(2, "0");
5086
- const day = value.getDate().toString().padStart(2, "0");
5087
- return `${year}${opt}${month}${opt}${day}`;
5088
- };
5089
- };
5090
- var hms2 = (options) => {
5091
- const opt = options?.[0] ?? ":";
5092
- return (value) => {
5093
- if (!(value instanceof Date)) {
5094
- valueMustBeDate2("hms");
5095
- }
5096
- const hours = value.getHours().toString().padStart(2, "0");
5097
- const minutes = value.getMinutes().toString().padStart(2, "0");
5098
- const seconds = value.getSeconds().toString().padStart(2, "0");
5099
- return `${hours}${opt}${minutes}${opt}${seconds}`;
5100
- };
5101
- };
5102
- function warnBigIntZero2(fnName, value) {
5103
- if (value === 0n) {
5104
- warnV3Migration2(`"${fnName}" got 0n: 3.0 treats it as falsy.`);
5105
- }
4503
+ var resolvedByKey = /* @__PURE__ */ new Map();
4504
+ function clearFilterResolutionCache() {
4505
+ resolvedByKey.clear();
5106
4506
  }
5107
- var falsy2 = (_options) => {
5108
- return (value) => {
5109
- warnBigIntZero2("falsy", value);
5110
- return value === false || value === null || value === void 0 || value === 0 || value === "" || Number.isNaN(value);
5111
- };
5112
- };
5113
- var truthy2 = (_options) => {
5114
- return (value) => {
5115
- warnBigIntZero2("truthy", value);
5116
- return value !== false && value !== null && value !== void 0 && value !== 0 && value !== "" && !Number.isNaN(value);
5117
- };
5118
- };
5119
- var defaults2 = (options) => {
5120
- const opt = options?.[0] ?? optionsRequired2("defaults");
5121
- return (value) => {
5122
- warnBigIntZero2("defaults", value);
5123
- if (value === false || value === null || value === void 0 || value === 0 || value === "" || Number.isNaN(value)) {
5124
- return opt;
5125
- }
5126
- return value;
5127
- };
5128
- };
5129
- var boolean2 = (_options) => {
5130
- return (value) => {
5131
- return Boolean(value);
5132
- };
5133
- };
5134
- var number2 = (_options) => {
5135
- return (value) => {
5136
- return Number(value);
5137
- };
5138
- };
5139
- var string2 = (_options) => {
5140
- return (value) => {
5141
- return String(value);
5142
- };
5143
- };
5144
- var _null2 = (_options) => {
5145
- return (value) => {
5146
- return value === "" ? null : value;
5147
- };
5148
- };
5149
- var builtinFilters2 = {
5150
- "eq": eq2,
5151
- "ne": ne2,
5152
- "not": not2,
5153
- "lt": lt2,
5154
- "le": le2,
5155
- "gt": gt2,
5156
- "ge": ge2,
5157
- "inc": inc2,
5158
- "dec": dec2,
5159
- "mul": mul2,
5160
- "div": div2,
5161
- "mod": mod2,
5162
- "abs": abs2,
5163
- "clamp": clamp2,
5164
- "fix": fix2,
5165
- "locale": locale2,
5166
- "uc": uc2,
5167
- "lc": lc2,
5168
- "cap": cap2,
5169
- "trim": trim2,
5170
- "slice": slice2,
5171
- "substr": substr2,
5172
- "pad": pad2,
5173
- "rep": rep2,
5174
- "rev": rev2,
5175
- "truncate": truncate2,
5176
- "join": join2,
5177
- "int": int2,
5178
- "float": float2,
5179
- "round": round2,
5180
- "floor": floor2,
5181
- "ceil": ceil2,
5182
- "percent": percent2,
5183
- "unit": unit2,
5184
- "date": date2,
5185
- "time": time2,
5186
- "datetime": datetime2,
5187
- "ymd": ymd2,
5188
- "hms": hms2,
5189
- "falsy": falsy2,
5190
- "truthy": truthy2,
5191
- "defaults": defaults2,
5192
- "boolean": boolean2,
5193
- "number": number2,
5194
- "string": string2,
5195
- "null": _null2
5196
- };
5197
- var outputBuiltinFilters2 = builtinFilters2;
5198
- var inputBuiltinFilters = builtinFilters2;
5199
- var builtinFiltersByFilterIOType = {
5200
- "input": inputBuiltinFilters,
5201
- "output": outputBuiltinFilters2
5202
- };
5203
- var builtinFilterFn = (name, options) => (filters) => {
5204
- const filter = filters[name];
5205
- if (!filter) {
5206
- raiseError2(`[wcs/filter-unknown] filter not found: ${name}.${didYouMean(name, Object.keys(filters))}${LINT_HINT}`);
5207
- }
5208
- return filter(options);
5209
- };
5210
4507
  function finalizeArg(text, firstQuoteStart, lastQuoteEnd) {
5211
4508
  const startLimit = firstQuoteStart === -1 ? text.length : firstQuoteStart;
5212
4509
  let start = 0;
@@ -5220,15 +4517,30 @@ function finalizeArg(text, firstQuoteStart, lastQuoteEnd) {
5220
4517
  }
5221
4518
  return text.slice(start, end);
5222
4519
  }
5223
- function parseFilterArgs(argsText) {
4520
+ var NUMBER_LITERAL = /^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/;
4521
+ function toLiteral(text, quoted) {
4522
+ if (quoted)
4523
+ return text;
4524
+ if (text === "true")
4525
+ return true;
4526
+ if (text === "false")
4527
+ return false;
4528
+ if (text === "null")
4529
+ return null;
4530
+ return NUMBER_LITERAL.test(text) ? Number(text) : text;
4531
+ }
4532
+ function parseFilterArgsWithLiterals(argsText) {
5224
4533
  const args = [];
4534
+ const literals = [];
5225
4535
  let current2 = "";
5226
4536
  let inQuote = null;
5227
4537
  let hasQuote = false;
5228
4538
  let firstQuoteStart = -1;
5229
4539
  let lastQuoteEnd = -1;
5230
4540
  const flush = () => {
5231
- args.push(finalizeArg(current2, firstQuoteStart, lastQuoteEnd));
4541
+ const arg = finalizeArg(current2, firstQuoteStart, lastQuoteEnd);
4542
+ args.push(arg);
4543
+ literals.push(toLiteral(arg, hasQuote));
5232
4544
  current2 = "";
5233
4545
  hasQuote = false;
5234
4546
  firstQuoteStart = -1;
@@ -5255,19 +4567,21 @@ function parseFilterArgs(argsText) {
5255
4567
  current2 += char;
5256
4568
  }
5257
4569
  }
4570
+ if (inQuote !== null) {
4571
+ raiseError2(`[wcs/binding-syntax] unterminated ${inQuote} quote in the filter arguments "(${argsText})". Close the quote.${LINT_HINT}`);
4572
+ }
5258
4573
  const last = finalizeArg(current2, firstQuoteStart, lastQuoteEnd);
5259
4574
  if (last || hasQuote) {
5260
4575
  args.push(last);
4576
+ literals.push(toLiteral(last, hasQuote));
5261
4577
  }
5262
- return args;
4578
+ return { args, literals };
5263
4579
  }
5264
- var filterFnByKey = /* @__PURE__ */ new Map();
5265
4580
  function clearFilterFnCacheForTooling() {
5266
- filterFnByKey.clear();
4581
+ clearFilterResolutionCache();
5267
4582
  }
5268
- function parseFilters(filterTextList, filterIOType) {
5269
- const builtinFilters3 = builtinFiltersByFilterIOType[filterIOType];
5270
- const filters = filterTextList.map((filterText) => {
4583
+ function parseFilters(filterTextList, _filterIOType) {
4584
+ return filterTextList.map((filterText) => {
5271
4585
  const openParenIndex = filterText.indexOf("(");
5272
4586
  const closeParenIndex = filterText.lastIndexOf(")");
5273
4587
  if (openParenIndex !== -1 && closeParenIndex === -1) {
@@ -5276,45 +4590,59 @@ function parseFilters(filterTextList, filterIOType) {
5276
4590
  if (closeParenIndex !== -1 && openParenIndex === -1) {
5277
4591
  raiseError2(`Invalid filter format: missing opening parenthesis in "${filterText}"`);
5278
4592
  }
4593
+ const filterName = (openParenIndex === -1 ? filterText : filterText.substring(0, openParenIndex)).trim();
4594
+ if (filterName.length === 0) {
4595
+ raiseError2(`[wcs/binding-syntax] an empty filter in "${filterTextList.join("|")}" \u2014 remove the extra "|" or name the filter.${LINT_HINT}`);
4596
+ }
5279
4597
  if (openParenIndex === -1) {
5280
- const filterName = filterText.trim();
5281
- const filterKey = `${filterName}():${filterIOType}`;
5282
- let filterFn = filterFnByKey.get(filterKey);
5283
- if (typeof filterFn === "undefined") {
5284
- filterFn = builtinFilterFn(filterName, [])(builtinFilters3);
5285
- filterFnByKey.set(filterKey, filterFn);
5286
- }
5287
- return {
5288
- filterName,
5289
- args: [],
5290
- filterFn
5291
- };
5292
- } else {
5293
- const argsText = filterText.substring(openParenIndex + 1, closeParenIndex);
5294
- const filterName = filterText.substring(0, openParenIndex).trim();
5295
- const args = parseFilterArgs(argsText);
5296
- const filterKey = `${filterName}(${args.join(",")}):${filterIOType}`;
5297
- let filterFn = filterFnByKey.get(filterKey);
5298
- if (typeof filterFn === "undefined") {
5299
- filterFn = builtinFilterFn(filterName, args)(builtinFilters3);
5300
- filterFnByKey.set(filterKey, filterFn);
5301
- }
5302
- return {
5303
- filterName,
5304
- args,
5305
- filterFn
5306
- };
4598
+ return { filterName, args: [], literals: [] };
5307
4599
  }
4600
+ const argsText = filterText.substring(openParenIndex + 1, closeParenIndex);
4601
+ return { filterName, ...parseFilterArgsWithLiterals(argsText) };
5308
4602
  });
5309
- return filters;
5310
4603
  }
5311
4604
  var trimFn = (s) => s.trim();
4605
+ var isQuote = (c) => c === "'" || c === '"';
4606
+ function indexOfOutsideQuotes(text, char) {
4607
+ let quote = null;
4608
+ for (let i = 0; i < text.length; i++) {
4609
+ const c = text[i];
4610
+ if (quote !== null) {
4611
+ if (c === quote)
4612
+ quote = null;
4613
+ } else if (isQuote(c)) {
4614
+ quote = c;
4615
+ } else if (c === char) {
4616
+ return i;
4617
+ }
4618
+ }
4619
+ return -1;
4620
+ }
4621
+ function splitOutsideQuotes(text, separator) {
4622
+ const parts = [];
4623
+ let quote = null;
4624
+ let start = 0;
4625
+ for (let i = 0; i < text.length; i++) {
4626
+ const c = text[i];
4627
+ if (quote !== null) {
4628
+ if (c === quote)
4629
+ quote = null;
4630
+ } else if (isQuote(c)) {
4631
+ quote = c;
4632
+ } else if (c === separator) {
4633
+ parts.push(text.slice(start, i));
4634
+ start = i + 1;
4635
+ }
4636
+ }
4637
+ parts.push(text.slice(start));
4638
+ return parts;
4639
+ }
5312
4640
  var cacheFilterInfos$1 = /* @__PURE__ */ new Map();
5313
4641
  function clearPropPartCacheForTooling() {
5314
4642
  cacheFilterInfos$1.clear();
5315
4643
  }
5316
4644
  function parsePropPart(propPart) {
5317
- const pos = propPart.indexOf(FILTER_SEPARATOR2);
4645
+ const pos = indexOfOutsideQuotes(propPart, FILTER_SEPARATOR2);
5318
4646
  let propText = "";
5319
4647
  let filterTexts = [];
5320
4648
  let filtersText = "";
@@ -5325,14 +4653,18 @@ function parsePropPart(propPart) {
5325
4653
  if (cacheFilterInfos$1.has(filtersText)) {
5326
4654
  filters = cacheFilterInfos$1.get(filtersText);
5327
4655
  } else {
5328
- filterTexts = filtersText.split(FILTER_SEPARATOR2).map(trimFn);
5329
- filters = parseFilters(filterTexts, "input");
4656
+ filterTexts = splitOutsideQuotes(filtersText, FILTER_SEPARATOR2).map(trimFn);
4657
+ filters = parseFilters(filterTexts);
5330
4658
  cacheFilterInfos$1.set(filtersText, filters);
5331
4659
  }
5332
4660
  } else {
5333
4661
  propText = propPart.trim();
5334
4662
  }
5335
- const [propName, propModifiersText] = propText.split(MODIFIER_SEPARATOR2).map(trimFn);
4663
+ const modifierParts = propText.split(MODIFIER_SEPARATOR2).map(trimFn);
4664
+ if (modifierParts.length > 2) {
4665
+ raiseError2(`[wcs/binding-syntax] "${propText}": a binding takes one modifier list after a single "${MODIFIER_SEPARATOR2}" \u2014 write "${modifierParts[0]}${MODIFIER_SEPARATOR2}${modifierParts.slice(1).join(",")}".${LINT_HINT}`);
4666
+ }
4667
+ const [propName, propModifiersText] = modifierParts;
5336
4668
  const propSegments = propName.split(DELIMITER2).map(trimFn);
5337
4669
  const propModifiers = propModifiersText ? propModifiersText.split(",").map(trimFn) : [];
5338
4670
  return {
@@ -5347,7 +4679,7 @@ function clearStatePartCacheForTooling() {
5347
4679
  cacheFilterInfos.clear();
5348
4680
  }
5349
4681
  function parseStatePart(statePart) {
5350
- const pos = statePart.indexOf(FILTER_SEPARATOR2);
4682
+ const pos = indexOfOutsideQuotes(statePart, FILTER_SEPARATOR2);
5351
4683
  let stateAndPath = "";
5352
4684
  let filterTexts = [];
5353
4685
  let filtersText = "";
@@ -5358,8 +4690,8 @@ function parseStatePart(statePart) {
5358
4690
  if (cacheFilterInfos.has(filtersText)) {
5359
4691
  filters = cacheFilterInfos.get(filtersText);
5360
4692
  } else {
5361
- filterTexts = filtersText.split(FILTER_SEPARATOR2).map(trimFn);
5362
- filters = parseFilters(filterTexts, "output");
4693
+ filterTexts = splitOutsideQuotes(filtersText, FILTER_SEPARATOR2).map(trimFn);
4694
+ filters = parseFilters(filterTexts);
5363
4695
  cacheFilterInfos.set(filtersText, filters);
5364
4696
  }
5365
4697
  } else {
@@ -5376,8 +4708,12 @@ function parseStatePart(statePart) {
5376
4708
  outFilters: filters
5377
4709
  };
5378
4710
  }
4711
+ var KEYWORDS_WITHOUT_MODIFIERS = /* @__PURE__ */ new Set([ELSE_KEYWORD2, "if", "elseif", "for", SPREAD_PROP2]);
4712
+ function splitBindTexts(bindText) {
4713
+ return splitOutsideQuotes(bindText, BINDING_SEPARATOR2);
4714
+ }
5379
4715
  function parseBindTextsForElement(bindText) {
5380
- const [...bindTexts] = bindText.split(BINDING_SEPARATOR2).map(trimFn).filter((s) => s.length > 0);
4716
+ const [...bindTexts] = splitBindTexts(bindText).map(trimFn).filter((s) => s.length > 0);
5381
4717
  const results = bindTexts.map((bindText2) => {
5382
4718
  const separatorIndex = bindText2.indexOf(PROP_VALUE_SEPARATOR2);
5383
4719
  if (separatorIndex === -1) {
@@ -5385,7 +4721,14 @@ function parseBindTextsForElement(bindText) {
5385
4721
  }
5386
4722
  const propPart = bindText2.slice(0, separatorIndex).trim();
5387
4723
  const statePart = bindText2.slice(separatorIndex + 1).trim();
4724
+ const keyword = propPart.split(MODIFIER_SEPARATOR2)[0].split(FILTER_SEPARATOR2)[0].trim();
4725
+ if (keyword !== propPart && KEYWORDS_WITHOUT_MODIFIERS.has(keyword)) {
4726
+ raiseError2(`[wcs/binding-syntax] "${bindText2}": "${keyword}" takes no modifiers or filters on its left side \u2014 write "${keyword}:".${LINT_HINT}`);
4727
+ }
5388
4728
  if (propPart === ELSE_KEYWORD2) {
4729
+ if (statePart.length > 0) {
4730
+ raiseError2(`[wcs/binding-syntax] "${bindText2}": "else" takes no value \u2014 write "else:".${LINT_HINT}`);
4731
+ }
5389
4732
  const pathInfo = getPathInfo("#else");
5390
4733
  return {
5391
4734
  propName: ELSE_KEYWORD2,
@@ -5413,7 +4756,7 @@ function parseBindTextsForElement(bindText) {
5413
4756
  ...stateResult,
5414
4757
  bindingType: "spread"
5415
4758
  };
5416
- } else if (propPart === "if" || propPart === "elseif" || propPart === "for" || propPart === "radio" || propPart === "checkbox") {
4759
+ } else if (propPart === "if" || propPart === "elseif" || propPart === "for") {
5417
4760
  const stateResult = parseStatePart(statePart);
5418
4761
  return {
5419
4762
  propName: propPart,
@@ -5423,6 +4766,14 @@ function parseBindTextsForElement(bindText) {
5423
4766
  ...stateResult,
5424
4767
  bindingType: propPart
5425
4768
  };
4769
+ } else if (keyword === "radio" || keyword === "checkbox") {
4770
+ const stateResult = parseStatePart(statePart);
4771
+ const propResult = parsePropPart(propPart);
4772
+ return {
4773
+ ...propResult,
4774
+ ...stateResult,
4775
+ bindingType: keyword
4776
+ };
5426
4777
  } else {
5427
4778
  const stateResult = parseStatePart(statePart);
5428
4779
  const propResult = parsePropPart(propPart);
@@ -5508,7 +4859,7 @@ function parseEmbeddedTextWithPositions(expression) {
5508
4859
  }
5509
4860
  function parseBindTextWithPositions(bindText) {
5510
4861
  const results = [];
5511
- const segments = bindText.split(delimiters.binding);
4862
+ const segments = splitBindTexts(bindText);
5512
4863
  let segmentStart = 0;
5513
4864
  for (const segment of segments) {
5514
4865
  const leading = segment.length - segment.trimStart().length;
@@ -5551,24 +4902,42 @@ function parseBindTextWithPositions(bindText) {
5551
4902
  return results;
5552
4903
  }
5553
4904
 
5554
- // src/service/v3MigrationValidator.ts
5555
- function validateV3Migration(html, bindAttrName = "data-wcs", locale3) {
4905
+ // src/service/bindingSyntaxValidator.ts
4906
+ var CODE_MARKER = "[wcs/binding-syntax]";
4907
+ function bindingSyntaxDetail(error) {
4908
+ if (error === null) return null;
4909
+ const at2 = error.indexOf(CODE_MARKER);
4910
+ if (at2 === -1) return null;
4911
+ const detail = error.slice(at2 + CODE_MARKER.length).trim();
4912
+ const hint = detail.indexOf(" Validate statically:");
4913
+ return hint === -1 ? detail : detail.slice(0, hint);
4914
+ }
4915
+ function validateBindingSyntax(html, bindAttrName = "data-wcs", locale2) {
5556
4916
  const diagnostics = [];
5557
- const msgs = getMessages(locale3);
5558
- const push2 = (detail, start, end) => {
5559
- diagnostics.push({ code: WcsDiagnosticCode.V3Migration, start, end, message: msgs.v3Migration(detail), severity: "info" });
5560
- };
4917
+ const msgs = getMessages(locale2);
5561
4918
  for (const attr of findAllBindAttributes(html, bindAttrName)) {
5562
4919
  for (const binding of parseBindTextWithPositions(attr.value)) {
5563
- for (const detail of findV3MigrationIssues(binding.exprText)) {
5564
- push2(detail, attr.valueStart + binding.exprRange.start, attr.valueStart + binding.exprRange.end);
5565
- }
4920
+ const detail = bindingSyntaxDetail(binding.error);
4921
+ if (detail === null) continue;
4922
+ diagnostics.push({
4923
+ code: WcsDiagnosticCode.BindingSyntax,
4924
+ start: attr.valueStart + binding.exprRange.start,
4925
+ end: attr.valueStart + binding.exprRange.end,
4926
+ message: msgs.bindingSyntax(detail),
4927
+ severity: "error"
4928
+ });
5566
4929
  }
5567
4930
  }
5568
- for (const item of [...findAllMustacheSyntax(html), ...findAllCommentBindings(html)]) {
5569
- for (const detail of findEmbeddedV3MigrationIssues(item.expression)) {
5570
- push2(detail, item.exprStart, item.exprEnd);
5571
- }
4931
+ for (const mustache of findAllMustacheSyntax(html)) {
4932
+ const detail = bindingSyntaxDetail(parseEmbeddedTextWithPositions(mustache.expression).error);
4933
+ if (detail === null) continue;
4934
+ diagnostics.push({
4935
+ code: WcsDiagnosticCode.BindingSyntax,
4936
+ start: mustache.exprStart,
4937
+ end: mustache.exprStart + mustache.expression.length,
4938
+ message: msgs.bindingSyntax(detail),
4939
+ severity: "error"
4940
+ });
5572
4941
  }
5573
4942
  return diagnostics;
5574
4943
  }
@@ -6861,9 +6230,9 @@ var DOM_COMMON_PROPERTIES = /* @__PURE__ */ new Set([
6861
6230
  ]);
6862
6231
  var STRUCTURAL_DIRECTIVES2 = /* @__PURE__ */ new Set(["for", "if", "elseif", "else"]);
6863
6232
  var EMPTYISH_SEEDS = /* @__PURE__ */ new Set(["''", '""', "``", "null", "[]", "{}"]);
6864
- function validateIoNodes(html, bindAttribute = "data-wcs", stateTagName = "wcs-state", locale3, fileReader) {
6233
+ function validateIoNodes(html, bindAttribute = "data-wcs", stateTagName = "wcs-state", locale2, fileReader) {
6865
6234
  const diagnostics = [];
6866
- const msgs = getMessages(locale3);
6235
+ const msgs = getMessages(locale2);
6867
6236
  const occurrences = findBuiltinTagOccurrences(html);
6868
6237
  if (occurrences.length === 0) return diagnostics;
6869
6238
  let statePaths = null;
@@ -7011,7 +6380,7 @@ function suggestion(input, candidates, msgs) {
7011
6380
  let best = null;
7012
6381
  let bestDistance = 3;
7013
6382
  for (const c of candidates) {
7014
- const d = editDistance2(input.toLowerCase(), c.toLowerCase(), bestDistance);
6383
+ const d = editDistance(input.toLowerCase(), c.toLowerCase(), bestDistance);
7015
6384
  if (d < bestDistance) {
7016
6385
  best = c;
7017
6386
  bestDistance = d;
@@ -7019,7 +6388,7 @@ function suggestion(input, candidates, msgs) {
7019
6388
  }
7020
6389
  return best !== null ? msgs.didYouMean(best) : "";
7021
6390
  }
7022
- function editDistance2(a, b, bound) {
6391
+ function editDistance(a, b, bound) {
7023
6392
  if (Math.abs(a.length - b.length) >= bound) return bound;
7024
6393
  const prev = new Array(b.length + 1);
7025
6394
  const curr = new Array(b.length + 1);
@@ -7133,9 +6502,9 @@ var ARIA_ATTRIBUTES = /* @__PURE__ */ new Set([
7133
6502
  "aria-brailleroledescription",
7134
6503
  "aria-description"
7135
6504
  ]);
7136
- function validateAriaAttributes(html, bindAttribute = "data-wcs", locale3) {
6505
+ function validateAriaAttributes(html, bindAttribute = "data-wcs", locale2) {
7137
6506
  const diagnostics = [];
7138
- const msgs = getMessages(locale3);
6507
+ const msgs = getMessages(locale2);
7139
6508
  for (const attr of findAllBindAttributes(html, bindAttribute)) {
7140
6509
  let exprOffset = 0;
7141
6510
  for (const expr of splitBindingExpressions(attr.value)) {
@@ -7164,9 +6533,9 @@ function validateAriaAttributes(html, bindAttribute = "data-wcs", locale3) {
7164
6533
  }
7165
6534
 
7166
6535
  // src/service/documentEnvValidator.ts
7167
- function validateDocumentEnv(html, locale3) {
6536
+ function validateDocumentEnv(html, locale2) {
7168
6537
  const diagnostics = [];
7169
- const msgs = getMessages(locale3);
6538
+ const msgs = getMessages(locale2);
7170
6539
  const scanText = blankHtmlComments(html);
7171
6540
  const autos = findWcstackAutoScripts(scanText);
7172
6541
  const stateIndex = autos.findIndex((a) => a.pkg === "state");
@@ -7277,8 +6646,8 @@ function blankJsComments(code) {
7277
6646
 
7278
6647
  // src/service/watchDeclarationValidator.ts
7279
6648
  var STATE_NAME_SEPARATOR = "@";
7280
- function validateWatchDeclarations(html, stateTagName = "wcs-state", locale3) {
7281
- const msgs = getMessages(locale3);
6649
+ function validateWatchDeclarations(html, stateTagName = "wcs-state", locale2) {
6650
+ const msgs = getMessages(locale2);
7282
6651
  const out = [];
7283
6652
  for (const block of parseWcsScriptBlocks(html, stateTagName)) {
7284
6653
  const nonObject = findNonObjectWatch(block.content);
@@ -7342,8 +6711,8 @@ function validateEntry(entry, pathSet, paths, msgs) {
7342
6711
  }
7343
6712
 
7344
6713
  // src/service/scanDeclarationValidator.ts
7345
- function validateScanDeclarations(html, stateTagName = "wcs-state", locale3) {
7346
- const msgs = getMessages(locale3);
6714
+ function validateScanDeclarations(html, stateTagName = "wcs-state", locale2) {
6715
+ const msgs = getMessages(locale2);
7347
6716
  const out = [];
7348
6717
  for (const element of parseWcsStateElements(html, stateTagName)) {
7349
6718
  const mounted = element.bindComponent;
@@ -7701,8 +7070,8 @@ var UNSUPPORTED_API_SITE = {
7701
7070
  };
7702
7071
  var BRACKET_ASSIGNMENT = new RegExp(`${ROOT_BRACKET}${ASSIGN_TAIL}`, "g");
7703
7072
  var PRE_BRACKET_INCDEC = new RegExp(`${PRE_INCDEC}${ROOT_BRACKET}`, "g");
7704
- function validateRecursion(html, stateTagName = "wcs-state", locale3) {
7705
- const msgs = getMessages(locale3);
7073
+ function validateRecursion(html, stateTagName = "wcs-state", locale2) {
7074
+ const msgs = getMessages(locale2);
7706
7075
  const out = [];
7707
7076
  for (const element of parseWcsStateElements(html, stateTagName)) {
7708
7077
  const mounted = element.bindComponent;
@@ -8133,8 +7502,8 @@ function findStateSelector(expr, embedded = false) {
8133
7502
  const nameStart = at2 + 1 + (raw.length - raw.trimStart().length);
8134
7503
  return { start: at2, end: name.length === 0 ? at2 + 1 : nameStart + name.length, name: name.length === 0 ? "default" : name };
8135
7504
  }
8136
- function validateNamedState(html, attrName, stateTagName = "wcs-state", locale3) {
8137
- const msgs = getMessages(locale3);
7505
+ function validateNamedState(html, attrName, stateTagName = "wcs-state", locale2) {
7506
+ const msgs = getMessages(locale2);
8138
7507
  const diagnostics = [];
8139
7508
  for (const element of parseWcsStateElements(html, stateTagName)) {
8140
7509
  const tagText = html.slice(element.tagStart, element.tagEnd);
@@ -8192,8 +7561,8 @@ function findMountPathProblem(mountPath) {
8192
7561
  }
8193
7562
  return null;
8194
7563
  }
8195
- function validateMountAttributes(html, stateTagName = "wcs-state", locale3) {
8196
- const msgs = getMessages(locale3);
7564
+ function validateMountAttributes(html, stateTagName = "wcs-state", locale2) {
7565
+ const msgs = getMessages(locale2);
8197
7566
  const diagnostics = [];
8198
7567
  for (const element of parseWcsStateElements(html, stateTagName)) {
8199
7568
  if (element.mountPath === null) continue;
@@ -14336,8 +13705,8 @@ function buildReferenceIndex(html, options = {}) {
14336
13705
  // src/service/semanticValidator.ts
14337
13706
  var STATE_UPDATED_CALLBACK = "$updatedCallback";
14338
13707
  var API_CALL = /\.\s*\$(getAll|setAll|resolve)\s*\(/g;
14339
- function validateIndexArity(script, scriptStart, locale3) {
14340
- const msgs = getMessages(locale3);
13708
+ function validateIndexArity(script, scriptStart, locale2) {
13709
+ const msgs = getMessages(locale2);
14341
13710
  const out = [];
14342
13711
  API_CALL.lastIndex = 0;
14343
13712
  let match;
@@ -14368,8 +13737,8 @@ function validateIndexArity(script, scriptStart, locale3) {
14368
13737
  }
14369
13738
  return out;
14370
13739
  }
14371
- function validateGetterCycles(script, scriptStart, locale3) {
14372
- const msgs = getMessages(locale3);
13740
+ function validateGetterCycles(script, scriptStart, locale2) {
13741
+ const msgs = getMessages(locale2);
14373
13742
  const getters = analyzeCallableBodies(script).filter((entry) => entry.kind === "getter");
14374
13743
  if (getters.length === 0) return [];
14375
13744
  const declared = new Set(getters.map((getter) => getter.name));
@@ -14424,7 +13793,7 @@ function validateGetterCycles(script, scriptStart, locale3) {
14424
13793
  }
14425
13794
  return out;
14426
13795
  }
14427
- function validateGetterUntrackedReads(script, scriptStart, nestedWriteRoots, locale3) {
13796
+ function validateGetterUntrackedReads(script, scriptStart, nestedWriteRoots, locale2) {
14428
13797
  const getters = analyzeCallableBodies(script).filter((entry) => entry.kind === "getter" && entry.accessor === "get");
14429
13798
  if (getters.length === 0) return [];
14430
13799
  const objectRoots = /* @__PURE__ */ new Set();
@@ -14434,7 +13803,7 @@ function validateGetterUntrackedReads(script, scriptStart, nestedWriteRoots, loc
14434
13803
  }
14435
13804
  }
14436
13805
  if (objectRoots.size === 0) return [];
14437
- const msgs = getMessages(locale3);
13806
+ const msgs = getMessages(locale2);
14438
13807
  const out = [];
14439
13808
  for (const getter of getters) {
14440
13809
  for (const read of collectGetterReads(getter.body) ?? []) {
@@ -14513,12 +13882,12 @@ function collectNestedWriteRoots(html, stateTagName, bindAttrName, blocks) {
14513
13882
  return roots;
14514
13883
  }
14515
13884
  var PATH_TEST_LITERAL = /(?:\.\s*(?:includes|indexOf)\s*\(\s*|[!=]==\s*)(["'])((?:\\.|(?!\1)[^\\])*)\1/g;
14516
- function validateUpdatedCallbackDemand(html, stateTagName, bindAttrName, locale3) {
13885
+ function validateUpdatedCallbackDemand(html, stateTagName, bindAttrName, locale2) {
14517
13886
  const blocks = parseWcsScriptBlocks(html, stateTagName);
14518
13887
  if (blocks.length === 0) return [];
14519
13888
  const hasCallback = blocks.some((block) => block.content.includes(STATE_UPDATED_CALLBACK));
14520
13889
  if (!hasCallback) return [];
14521
- const msgs = getMessages(locale3);
13890
+ const msgs = getMessages(locale2);
14522
13891
  const boundPaths = collectBoundPaths(html, stateTagName, bindAttrName);
14523
13892
  const out = [];
14524
13893
  for (const block of blocks) {
@@ -14562,17 +13931,17 @@ function collectBoundPaths(html, stateTagName, bindAttrName) {
14562
13931
  }
14563
13932
  return bound;
14564
13933
  }
14565
- function validateSemantics(html, stateTagName = "wcs-state", locale3, bindAttrName = "data-wcs") {
13934
+ function validateSemantics(html, stateTagName = "wcs-state", locale2, bindAttrName = "data-wcs") {
14566
13935
  const out = [];
14567
13936
  const blocks = parseWcsScriptBlocks(html, stateTagName);
14568
13937
  let nestedWriteRoots = null;
14569
13938
  const getNestedWriteRoots = () => nestedWriteRoots ??= collectNestedWriteRoots(html, stateTagName, bindAttrName, blocks);
14570
13939
  for (const block of blocks) {
14571
- out.push(...validateIndexArity(block.content, block.contentStart, locale3));
14572
- out.push(...validateGetterCycles(block.content, block.contentStart, locale3));
14573
- out.push(...validateGetterUntrackedReads(block.content, block.contentStart, getNestedWriteRoots, locale3));
13940
+ out.push(...validateIndexArity(block.content, block.contentStart, locale2));
13941
+ out.push(...validateGetterCycles(block.content, block.contentStart, locale2));
13942
+ out.push(...validateGetterUntrackedReads(block.content, block.contentStart, getNestedWriteRoots, locale2));
14574
13943
  }
14575
- out.push(...validateUpdatedCallbackDemand(html, stateTagName, bindAttrName, locale3));
13944
+ out.push(...validateUpdatedCallbackDemand(html, stateTagName, bindAttrName, locale2));
14576
13945
  return out;
14577
13946
  }
14578
13947
 
@@ -14604,27 +13973,27 @@ function applicationSchemaOf(loaded) {
14604
13973
  function validateDocument(text, options = {}) {
14605
13974
  const bindAttribute = options.bindAttribute ?? "data-wcs";
14606
13975
  const stateTagName = options.stateTagName ?? "wcs-state";
14607
- const locale3 = options.locale;
13976
+ const locale2 = options.locale;
14608
13977
  const fileReader = options.fileReader;
14609
13978
  const applicationSchema = options.applicationSchema ?? (fileReader !== void 0 ? discoverApplicationManifest(fileReader)?.schema : void 0);
14610
13979
  const out = [];
14611
- out.push(...validateBindings(text, bindAttribute, stateTagName, locale3, fileReader, applicationSchema));
14612
- out.push(...validateTemplateSyntax(text, stateTagName, bindAttribute, locale3, fileReader, applicationSchema));
14613
- out.push(...validateV3Migration(text, bindAttribute, locale3));
14614
- out.push(...validateIoNodes(text, bindAttribute, stateTagName, locale3, fileReader));
14615
- out.push(...validateAriaAttributes(text, bindAttribute, locale3));
14616
- out.push(...validateDocumentEnv(text, locale3));
14617
- out.push(...validateSemantics(text, stateTagName, locale3, bindAttribute));
14618
- out.push(...validateArrayMutations(text, stateTagName, locale3));
14619
- out.push(...validateWatchDeclarations(text, stateTagName, locale3));
14620
- out.push(...validateScanDeclarations(text, stateTagName, locale3));
14621
- out.push(...validateRecursion(text, stateTagName, locale3));
14622
- out.push(...validateNamedState(text, bindAttribute, stateTagName, locale3));
14623
- out.push(...validateMountAttributes(text, stateTagName, locale3));
14624
- for (const d of validateStateTypes(text, stateTagName, locale3)) {
13980
+ out.push(...validateBindings(text, bindAttribute, stateTagName, locale2, fileReader, applicationSchema));
13981
+ out.push(...validateTemplateSyntax(text, stateTagName, bindAttribute, locale2, fileReader, applicationSchema));
13982
+ out.push(...validateBindingSyntax(text, bindAttribute, locale2));
13983
+ out.push(...validateIoNodes(text, bindAttribute, stateTagName, locale2, fileReader));
13984
+ out.push(...validateAriaAttributes(text, bindAttribute, locale2));
13985
+ out.push(...validateDocumentEnv(text, locale2));
13986
+ out.push(...validateSemantics(text, stateTagName, locale2, bindAttribute));
13987
+ out.push(...validateArrayMutations(text, stateTagName, locale2));
13988
+ out.push(...validateWatchDeclarations(text, stateTagName, locale2));
13989
+ out.push(...validateScanDeclarations(text, stateTagName, locale2));
13990
+ out.push(...validateRecursion(text, stateTagName, locale2));
13991
+ out.push(...validateNamedState(text, bindAttribute, stateTagName, locale2));
13992
+ out.push(...validateMountAttributes(text, stateTagName, locale2));
13993
+ for (const d of validateStateTypes(text, stateTagName, locale2)) {
14625
13994
  out.push({ code: WcsDiagnosticCode.TypeAnnotation, start: d.start, end: d.end, message: d.message, severity: d.severity });
14626
13995
  }
14627
- for (const d of validateNestedAssigns(text, stateTagName, locale3)) {
13996
+ for (const d of validateNestedAssigns(text, stateTagName, locale2)) {
14628
13997
  out.push({ code: WcsDiagnosticCode.NestedAssign, start: d.start, end: d.end, message: d.message, severity: d.severity });
14629
13998
  }
14630
13999
  return sortDiagnostics(out);