@wcstack/typescript 4.1.1 → 4.3.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.
- package/dist/index.esm.js +1 -1
- package/dist/schema-core.cjs +671 -160
- package/dist/tsc-core.cjs +78 -38
- package/dist/wcs-schema.mjs +1 -1
- package/dist/wcs-tsc.mjs +1 -1
- package/package.json +1 -1
package/dist/schema-core.cjs
CHANGED
|
@@ -68,12 +68,15 @@ var WcsDiagnosticCode = {
|
|
|
68
68
|
NestedAssign: "wcs/nested-assign",
|
|
69
69
|
// --- 意味論(構文・存在検査では捕まらない取り違え。service/semanticValidator.ts) ---
|
|
70
70
|
// `$getAll` / `$setAll` / `$resolve` の添字の本数がパスの `*` の本数と噛み合わない。
|
|
71
|
-
//
|
|
71
|
+
// ランタイムは #901 / #902 で throw する(diagnostics の後付けがあれば同じ code の文面。超過は 3.x では
|
|
72
|
+
// 黙って無視されていた)。error。
|
|
72
73
|
IndexArity: "wcs/index-arity",
|
|
73
74
|
// ワイルドカードの階数がスコープの段数を超える(`matrix.*.*` を 1 段の for で読む、
|
|
74
75
|
// `$2` を 1 段のループで読む。ランタイムの #1401)。既存の「for の外」検査の深さ方向の一般化。
|
|
75
76
|
// 4.0 は各段の `*` が**その段で囲む for のリスト**の行であることも確かめる(#1403・F32 — `for: a`
|
|
76
|
-
// の行の中の `b.*.y` は投げる)。静的側も囲む for の一覧と段ごとに比べて同じ code
|
|
77
|
+
// の行の中の `b.*.y` は投げる)。静的側も囲む for の一覧と段ごとに比べて同じ code で報告する
|
|
78
|
+
// (ランタイムの文面に code が付くのは diagnostics の後付けがあるとき)。for のスコープを組み直しきれない
|
|
79
|
+
// ので、ランタイムは初期化を失敗させるが warning のまま(vscode-wcs の README の重大度の例外)。
|
|
77
80
|
WildcardRank: "wcs/wildcard-rank",
|
|
78
81
|
// ループの添字の範囲(`$1`〜`$128`。上限は manifest の `syntax.indexParam.maxDepth`)の外。ランタイムと同じ code:
|
|
79
82
|
// for の中のマークアップの `$129`(バインディングが失敗する)と、スクリプトの `this.$0` / `this.$129` / `this.$1000`
|
|
@@ -81,7 +84,8 @@ var WcsDiagnosticCode = {
|
|
|
81
84
|
// `wcs/binding-path-missing`(ただしけっして動かないので error)。for の外の `$129` はランタイムでは #1401 なので
|
|
82
85
|
// 従来どおり「for の外のループ添字」(`wcs/template-syntax`)で報告する。
|
|
83
86
|
IndexParamRange: "wcs/index-param-range",
|
|
84
|
-
// パス getter
|
|
87
|
+
// パス getter どうしの循環参照。4.0 のランタイムは評価の時点で #701 として throw し、その getter を読む
|
|
88
|
+
// 束縛はすべて失敗する(3.x はアドレススタック上限まで再帰してから落ちた)。error。
|
|
85
89
|
GetterCycle: "wcs/getter-cycle",
|
|
86
90
|
// `$renderedCallback`(3.x の旧名 `$updatedCallback`)が、どのバインディングにも現れないパスを判定に使っている。
|
|
87
91
|
// 同コールバックは **binding 駆動**(live binding が適用された path しか報告しない)
|
|
@@ -96,8 +100,9 @@ var WcsDiagnosticCode = {
|
|
|
96
100
|
GetterUntrackedRead: "wcs/getter-untracked-read",
|
|
97
101
|
OnHandlerThis: "wcs/on-handler-this",
|
|
98
102
|
// --- <wcs-state> script: $watch declaration ---
|
|
99
|
-
//
|
|
100
|
-
//
|
|
103
|
+
// temporal の後付け(state の temporal/watch.ts)が読み込みで throw する宣言: 越境 `@` / `$` 始まり /
|
|
104
|
+
// 空キー / 明らかな非関数ハンドラ。空の段(`a..b`)はランタイムが調べず、その watch は黙って発火しない
|
|
105
|
+
// (lint だけが知らせる — docs/mistake-catalogue.md)。
|
|
101
106
|
WatchDeclarationInvalid: "wcs/watch-declaration-invalid",
|
|
102
107
|
// `$watch` のキーが状態定義に存在しない。バインディング側と違い黙って発火しない
|
|
103
108
|
// だけなので気づけない。severity は binding-path-missing に揃える(warning)。
|
|
@@ -116,8 +121,8 @@ var WcsDiagnosticCode = {
|
|
|
116
121
|
//
|
|
117
122
|
// `**` を解釈しない場所へ `**` が渡った(data-wcs / mustache / $watch キー / $listKeys
|
|
118
123
|
// キー / $resolve / $postUpdate / $dependOn(旧名 $trackDependency) / 代入)、または `$recursion` 宣言が
|
|
119
|
-
// 無いのに `**` を使った。runtime
|
|
120
|
-
//
|
|
124
|
+
// 無いのに `**` を使った。4.0 の runtime はどれも #1101 で throw する — 宣言なしの `**` getter も、
|
|
125
|
+
// アクセサを登録する時点で(3.x は黙って無視した)。error。
|
|
121
126
|
RecursionUnsupported: "wcs/recursion-unsupported",
|
|
122
127
|
// 宣言済みアンカーと合致しない `**`(綴り違い・2 つ目の `**`)、または `**` の後ろが
|
|
123
128
|
// 整形されていない(空セグメント・`**` 直後の素の `*`)。
|
|
@@ -155,7 +160,8 @@ var WcsDiagnosticCode = {
|
|
|
155
160
|
// ドットアクセスを含むチェーン代入は NestedAssign の担当(相補・二重報告なし)。
|
|
156
161
|
ArrayIndexAssign: "wcs/array-index-assign",
|
|
157
162
|
// --- built-in wcs-* tag contract (generated/builtinTags.generated.ts が正本) ---
|
|
158
|
-
// 未知メンバーへのバインド(プロパティ / command. / eventToken. キー)
|
|
163
|
+
// 未知メンバーへのバインド(プロパティ / command. / eventToken. キー)。4.0 のランタイムは #38 / #1203 /
|
|
164
|
+
// #1204 で拒み、root では初期化が、行では束縛が失敗する(3.x の「黙って無視」ではない)。error。
|
|
159
165
|
TagMemberUnknown: "wcs/tag-member-unknown",
|
|
160
166
|
// タグのメンバー名が "on" で始まる(`once` 等)のに先頭ドット無しで束縛した: ランタイムはイベント束縛にして
|
|
161
167
|
// "ce" イベントを待ち、値は届かない。明示のプロパティ形 `.once:` を提案する(@wcstack/state 3.1・要件 B5 / 3.x 計画 D36)
|
|
@@ -166,6 +172,10 @@ var WcsDiagnosticCode = {
|
|
|
166
172
|
// ランタイムは何も報告しない(root は正しい値)ので lint の code。`#direct` か `event.target.closest(...)` を
|
|
167
173
|
// 案内する。読みが実行されない分岐にあることもあるので warning。
|
|
168
174
|
DelegatedCurrentTarget: "wcs/delegated-current-target",
|
|
175
|
+
// `<form data-wcs="onsubmit: login">` の `#prevent` 忘れ(ハンドラも preventDefault を呼ばない)。ブラウザが
|
|
176
|
+
// フォームも送る — ページが読み直されるか、router があれば GET が欄(パスワードも)を URL と履歴に載せる
|
|
177
|
+
// (docs/seam-apps.md、router-auth)。warning(action 付きのフォームと、読めないハンドラでは黙る)。
|
|
178
|
+
SubmitWithoutPrevent: "wcs/submit-without-prevent",
|
|
169
179
|
// 4.0 で外れた API の旧名(`this.$trackDependency` → `$dependOn`、`$untrackDependency` → `$untracked`)。
|
|
170
180
|
// ランタイムは読んだ時点で同じ code(#1701)で throw するので error。3.x(3.2〜3.3)では「動くが 4.0 で
|
|
171
181
|
// 外れる」info だった。フィルタの旧名(`uc` など)は 4.0 のランタイムと同じく `wcs/filter-unknown` で、
|
|
@@ -213,7 +223,8 @@ var WcsDiagnosticCode = {
|
|
|
213
223
|
// (error 昇格時は packages/lint/scripts/smoke-test.mjs の対ケース更新が必須)。
|
|
214
224
|
AriaAttrUnknown: "wcs/aria-attr-unknown",
|
|
215
225
|
// --- document-level load configuration ---
|
|
216
|
-
// @wcstack/state/auto
|
|
226
|
+
// @wcstack/state/auto より後に @wcstack/devtools/auto が読まれている。info: 4.0 は後から付いた DevTools に
|
|
227
|
+
// 既存の束縛を送り直すので、欠けるのは付く前のタイムラインだけ。
|
|
217
228
|
ScriptOrder: "wcs/script-order",
|
|
218
229
|
// router/auto があるのに <base href> がない(SPA の basename 誤導出)。
|
|
219
230
|
BaseHrefMissing: "wcs/base-href-missing",
|
|
@@ -223,6 +234,13 @@ var WcsDiagnosticCode = {
|
|
|
223
234
|
RouterOutletMisplaced: "wcs/router-outlet-misplaced",
|
|
224
235
|
// @wcstack/signals と /dom エントリの同一ページ混在(リアクティブコア二重化)。
|
|
225
236
|
SignalsDualEntry: "wcs/signals-dual-entry",
|
|
237
|
+
// `<wcs-route>`(またはレイアウトのテンプレート)の直下のテキストの `{{ }}`。最初に着いたルートでしか束ねられず、
|
|
238
|
+
// 遷移で入ったルートでは書いたままの文字が出る(router の README「Where route content lives」— docs/seam-apps.md、
|
|
239
|
+
// router-admin)。warning。
|
|
240
|
+
RouteBareMustache: "wcs/route-bare-mustache",
|
|
241
|
+
// 既定の `<slot>` の無いレイアウトのテンプレートに、名前付きスロットの外の中身(入れ子のルート)を渡している。
|
|
242
|
+
// 中身は表示されない。ランタイムも同じ code で警告する(docs/seam-apps.md、router-admin)。warning。
|
|
243
|
+
LayoutSlotMissing: "wcs/layout-slot-missing",
|
|
226
244
|
// --- deprecations ---
|
|
227
245
|
// 名前付き State(`<wcs-state name>` / `path@name`)。v2 でマウント(`mount=` と接頭辞付きパス)に
|
|
228
246
|
// 置き換わる(docs/state-mount-design.md D16)。1.x では warning、v2 では parse error と同時に error。
|
|
@@ -821,7 +839,8 @@ var FORMATS_FILTER_NAMES = [
|
|
|
821
839
|
"coalesce",
|
|
822
840
|
"number",
|
|
823
841
|
"string",
|
|
824
|
-
"nullIfEmpty"
|
|
842
|
+
"nullIfEmpty",
|
|
843
|
+
"currency"
|
|
825
844
|
];
|
|
826
845
|
var definitions = /* @__PURE__ */ new Map();
|
|
827
846
|
function hasFilter(name) {
|
|
@@ -1038,6 +1057,8 @@ var codeOf = (id) => {
|
|
|
1038
1057
|
return c ? `[wcs/${c}] ` : "";
|
|
1039
1058
|
};
|
|
1040
1059
|
var MOVED = ["enableMustache", "sameValueGuard", "enableDirectionalInitialSync"];
|
|
1060
|
+
var was = (v) => v == null ? String(v) : v instanceof Date ? "a Date" : Array.isArray(v) ? "an array" : typeof v === "string" ? `a string (${JSON.stringify(v.length > 32 ? v.slice(0, 32) + "\u2026" : v)})` : typeof v === "object" ? "an object" : `a ${typeof v} (${String(v)})`;
|
|
1061
|
+
var NAMESPACES = ["", "", "class.", "attr.", "style."];
|
|
1041
1062
|
var element = (tag, at2) => `<${tag}${at2.map((a, i) => i % 2 ? `="${a}"` : ` ${a}`).join("")}>`;
|
|
1042
1063
|
var CSP_GUIDE = "https://github.com/wcstack/wcstack/blob/main/docs/csp.md";
|
|
1043
1064
|
var SENTENCES = {
|
|
@@ -1089,10 +1110,11 @@ var SENTENCES = {
|
|
|
1089
1110
|
41
|
|
1090
1111
|
/* RenderChain */
|
|
1091
1112
|
]: () => `render chain depth limit exceeded (${MAX_RENDER_CHAIN} drains that rendering itself started); bindings for this batch were not applied.`,
|
|
1113
|
+
// (named as written — `textContent: iso`, `class.active: x` — when the binding has a member; else its type)
|
|
1092
1114
|
[
|
|
1093
1115
|
12
|
|
1094
1116
|
/* BindingFailed */
|
|
1095
|
-
]: (type, p) => `binding "${type}: ${p}" failed to apply.`,
|
|
1117
|
+
]: (type, p, name, kind) => `binding "${name ? (NAMESPACES[kind] ?? "") + name : type}: ${p}" failed to apply.`,
|
|
1096
1118
|
[
|
|
1097
1119
|
13
|
|
1098
1120
|
/* LoadFailed */
|
|
@@ -1164,11 +1186,19 @@ var SENTENCES = {
|
|
|
1164
1186
|
[
|
|
1165
1187
|
28
|
|
1166
1188
|
/* FilterValueNotNumber */
|
|
1167
|
-
]: (fn) => `filter ${fn} requires a number value`,
|
|
1189
|
+
]: (fn, v) => `filter ${fn} requires a number value, not ${was(v)}${typeof v === "string" ? ` \u2014 put |number before |${fn}, or convert it where it is read` : ""}`,
|
|
1168
1190
|
[
|
|
1169
1191
|
29
|
|
1170
1192
|
/* FilterValueNotDate */
|
|
1171
|
-
]: (fn) => `filter ${fn} requires a date value`,
|
|
1193
|
+
]: (fn, v) => `filter ${fn} requires a date value (a Date), not ${was(v)}${typeof v === "string" || typeof v === "number" ? " \u2014 make the Date where it is read: a getter returning new Date(\u2026)" : ""}`,
|
|
1194
|
+
[
|
|
1195
|
+
52
|
|
1196
|
+
/* FilterStyleInvalid */
|
|
1197
|
+
]: (fn, v) => `filter ${fn} takes a style of full, long, medium or short, not "${v}"`,
|
|
1198
|
+
[
|
|
1199
|
+
53
|
|
1200
|
+
/* FilterCurrencyInvalid */
|
|
1201
|
+
]: (v) => `filter currency takes an ISO 4217 currency code (JPY, USD, EUR), not "${v}"`,
|
|
1172
1202
|
[
|
|
1173
1203
|
30
|
|
1174
1204
|
/* FilterValueNotArray */
|
|
@@ -2033,6 +2063,61 @@ function extractAttribute(tagContent, attrName) {
|
|
|
2033
2063
|
if (!match) return null;
|
|
2034
2064
|
return match[1] ?? match[2] ?? match[3] ?? null;
|
|
2035
2065
|
}
|
|
2066
|
+
var IGNORE_VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
2067
|
+
"area",
|
|
2068
|
+
"base",
|
|
2069
|
+
"br",
|
|
2070
|
+
"col",
|
|
2071
|
+
"embed",
|
|
2072
|
+
"hr",
|
|
2073
|
+
"img",
|
|
2074
|
+
"input",
|
|
2075
|
+
"link",
|
|
2076
|
+
"meta",
|
|
2077
|
+
"param",
|
|
2078
|
+
"source",
|
|
2079
|
+
"track",
|
|
2080
|
+
"wbr"
|
|
2081
|
+
]);
|
|
2082
|
+
function findIgnoredRanges(html, bindAttribute) {
|
|
2083
|
+
const marker = asciiLowerCase(`${bindAttribute}-ignore`);
|
|
2084
|
+
const lower2 = asciiLowerCase(html);
|
|
2085
|
+
if (!lower2.includes(marker)) return [];
|
|
2086
|
+
const out = [];
|
|
2087
|
+
const stack = [];
|
|
2088
|
+
const tag = /<!--[\s\S]*?(?:-->|$)|<(\/?)([a-zA-Z][^\s/>]*)((?:[^>"']|"[^"]*"|'[^']*')*)>/g;
|
|
2089
|
+
let match;
|
|
2090
|
+
while ((match = tag.exec(html)) !== null) {
|
|
2091
|
+
if (match[2] === void 0) continue;
|
|
2092
|
+
const name = asciiLowerCase(match[2]);
|
|
2093
|
+
const end = match.index + match[0].length;
|
|
2094
|
+
if (match[1] === "/") {
|
|
2095
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
2096
|
+
if (stack[i].name !== name) continue;
|
|
2097
|
+
for (const open of stack.slice(i)) if (open.start !== null) out.push([open.start, end]);
|
|
2098
|
+
stack.length = i;
|
|
2099
|
+
break;
|
|
2100
|
+
}
|
|
2101
|
+
continue;
|
|
2102
|
+
}
|
|
2103
|
+
const ignored = parseAttributeNames(match[3]).has(marker) ? match.index : null;
|
|
2104
|
+
if (IGNORE_VOID_ELEMENTS.has(name)) {
|
|
2105
|
+
if (ignored !== null) out.push([ignored, end]);
|
|
2106
|
+
continue;
|
|
2107
|
+
}
|
|
2108
|
+
if (RAW_TEXT_ELEMENTS.has(name)) {
|
|
2109
|
+
const close = name === "plaintext" ? -1 : lower2.indexOf(`</${name}`, end);
|
|
2110
|
+
const closeEnd = close === -1 ? html.length : html.indexOf(">", close) + 1 || html.length;
|
|
2111
|
+
if (ignored !== null) out.push([ignored, closeEnd]);
|
|
2112
|
+
if (close === -1) break;
|
|
2113
|
+
tag.lastIndex = closeEnd;
|
|
2114
|
+
continue;
|
|
2115
|
+
}
|
|
2116
|
+
stack.push({ name, start: ignored });
|
|
2117
|
+
}
|
|
2118
|
+
for (const open of stack) if (open.start !== null) out.push([open.start, html.length]);
|
|
2119
|
+
return out;
|
|
2120
|
+
}
|
|
2036
2121
|
|
|
2037
2122
|
// src/core/parser/quoteAware.ts
|
|
2038
2123
|
var isQuote = (c) => c === "'" || c === '"';
|
|
@@ -2108,11 +2193,17 @@ function optionsRequired(fnName) {
|
|
|
2108
2193
|
function optionMustBeNumber(fnName) {
|
|
2109
2194
|
raise2(27, [fnName]);
|
|
2110
2195
|
}
|
|
2111
|
-
function
|
|
2112
|
-
raise2(
|
|
2196
|
+
function styleInvalid(fnName, value) {
|
|
2197
|
+
raise2(52, [fnName, value]);
|
|
2198
|
+
}
|
|
2199
|
+
function currencyInvalid(value) {
|
|
2200
|
+
raise2(53, [value]);
|
|
2113
2201
|
}
|
|
2114
|
-
function
|
|
2115
|
-
raise2(
|
|
2202
|
+
function valueMustBeNumber(fnName, value) {
|
|
2203
|
+
raise2(28, [fnName, value]);
|
|
2204
|
+
}
|
|
2205
|
+
function valueMustBeDate(fnName, value) {
|
|
2206
|
+
raise2(29, [fnName, value]);
|
|
2116
2207
|
}
|
|
2117
2208
|
function valueMustBeArray(fnName) {
|
|
2118
2209
|
raise2(30, [fnName]);
|
|
@@ -2179,7 +2270,7 @@ var numeric = (name, op) => ({
|
|
|
2179
2270
|
const opt = requiredNumberOption(options, 0, name);
|
|
2180
2271
|
return (value) => {
|
|
2181
2272
|
if (typeof value !== "number") {
|
|
2182
|
-
valueMustBeNumber(name);
|
|
2273
|
+
valueMustBeNumber(name, value);
|
|
2183
2274
|
}
|
|
2184
2275
|
return op(value, opt);
|
|
2185
2276
|
};
|
|
@@ -2209,7 +2300,7 @@ var toFixed = (options) => {
|
|
|
2209
2300
|
const opt = numberOption(options?.[0] ?? "0", "toFixed");
|
|
2210
2301
|
return (value) => {
|
|
2211
2302
|
if (typeof value !== "number") {
|
|
2212
|
-
valueMustBeNumber("toFixed");
|
|
2303
|
+
valueMustBeNumber("toFixed", value);
|
|
2213
2304
|
}
|
|
2214
2305
|
return value.toFixed(opt);
|
|
2215
2306
|
};
|
|
@@ -2218,7 +2309,7 @@ var round = (options) => {
|
|
|
2218
2309
|
const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "round"));
|
|
2219
2310
|
return (value) => {
|
|
2220
2311
|
if (typeof value !== "number") {
|
|
2221
|
-
valueMustBeNumber("round");
|
|
2312
|
+
valueMustBeNumber("round", value);
|
|
2222
2313
|
}
|
|
2223
2314
|
return Math.round(value * optValue) / optValue;
|
|
2224
2315
|
};
|
|
@@ -2227,7 +2318,7 @@ var floor = (options) => {
|
|
|
2227
2318
|
const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "floor"));
|
|
2228
2319
|
return (value) => {
|
|
2229
2320
|
if (typeof value !== "number") {
|
|
2230
|
-
valueMustBeNumber("floor");
|
|
2321
|
+
valueMustBeNumber("floor", value);
|
|
2231
2322
|
}
|
|
2232
2323
|
return Math.floor(value * optValue) / optValue;
|
|
2233
2324
|
};
|
|
@@ -2236,7 +2327,7 @@ var ceil = (options) => {
|
|
|
2236
2327
|
const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "ceil"));
|
|
2237
2328
|
return (value) => {
|
|
2238
2329
|
if (typeof value !== "number") {
|
|
2239
|
-
valueMustBeNumber("ceil");
|
|
2330
|
+
valueMustBeNumber("ceil", value);
|
|
2240
2331
|
}
|
|
2241
2332
|
return Math.ceil(value * optValue) / optValue;
|
|
2242
2333
|
};
|
|
@@ -2245,7 +2336,7 @@ var percent = (options) => {
|
|
|
2245
2336
|
const opt = numberOption(options?.[0] ?? "0", "percent");
|
|
2246
2337
|
return (value) => {
|
|
2247
2338
|
if (typeof value !== "number") {
|
|
2248
|
-
valueMustBeNumber("percent");
|
|
2339
|
+
valueMustBeNumber("percent", value);
|
|
2249
2340
|
}
|
|
2250
2341
|
return `${(value * 100).toFixed(opt)}%`;
|
|
2251
2342
|
};
|
|
@@ -2272,11 +2363,29 @@ var locale = (options) => {
|
|
|
2272
2363
|
const explicit = options?.[0];
|
|
2273
2364
|
return (value) => {
|
|
2274
2365
|
if (typeof value !== "number") {
|
|
2275
|
-
valueMustBeNumber("locale");
|
|
2366
|
+
valueMustBeNumber("locale", value);
|
|
2276
2367
|
}
|
|
2277
2368
|
return value.toLocaleString(explicit ?? defaultLocale());
|
|
2278
2369
|
};
|
|
2279
2370
|
};
|
|
2371
|
+
var currency = (options) => {
|
|
2372
|
+
const code = options?.[0] ?? optionsRequired("currency");
|
|
2373
|
+
const explicit = options?.[1];
|
|
2374
|
+
const format = { style: "currency", currency: code };
|
|
2375
|
+
try {
|
|
2376
|
+
new Intl.NumberFormat("en", format);
|
|
2377
|
+
const known = Intl.supportedValuesOf?.("currency");
|
|
2378
|
+
if (known && !known.includes(code.toUpperCase())) throw 0;
|
|
2379
|
+
} catch {
|
|
2380
|
+
currencyInvalid(code);
|
|
2381
|
+
}
|
|
2382
|
+
return (value) => {
|
|
2383
|
+
if (typeof value !== "number") {
|
|
2384
|
+
valueMustBeNumber("currency", value);
|
|
2385
|
+
}
|
|
2386
|
+
return value.toLocaleString(explicit ?? defaultLocale(), format);
|
|
2387
|
+
};
|
|
2388
|
+
};
|
|
2280
2389
|
var upper = () => (value) => String(value).toUpperCase();
|
|
2281
2390
|
var lower = () => (value) => String(value).toLowerCase();
|
|
2282
2391
|
var capitalize = () => (value) => {
|
|
@@ -2333,38 +2442,48 @@ var join = (options) => {
|
|
|
2333
2442
|
return value.join(opt);
|
|
2334
2443
|
};
|
|
2335
2444
|
};
|
|
2445
|
+
var STYLES = ["full", "long", "medium", "short"];
|
|
2446
|
+
function dateOptions(options, fn) {
|
|
2447
|
+
let [loc, style] = options ?? [];
|
|
2448
|
+
if (style === void 0 && loc !== void 0 && STYLES.includes(loc)) [loc, style] = [void 0, loc];
|
|
2449
|
+
if (style !== void 0 && !STYLES.includes(style)) styleInvalid(fn, style);
|
|
2450
|
+
return [loc, style];
|
|
2451
|
+
}
|
|
2336
2452
|
var date = (options) => {
|
|
2337
|
-
const explicit = options
|
|
2453
|
+
const [explicit, style] = dateOptions(options, "date");
|
|
2454
|
+
const format = style && { dateStyle: style };
|
|
2338
2455
|
return (value) => {
|
|
2339
2456
|
if (!(value instanceof Date)) {
|
|
2340
|
-
valueMustBeDate("date");
|
|
2457
|
+
valueMustBeDate("date", value);
|
|
2341
2458
|
}
|
|
2342
|
-
return value.toLocaleDateString(explicit ?? defaultLocale());
|
|
2459
|
+
return value.toLocaleDateString(explicit ?? defaultLocale(), format);
|
|
2343
2460
|
};
|
|
2344
2461
|
};
|
|
2345
2462
|
var time = (options) => {
|
|
2346
|
-
const explicit = options
|
|
2463
|
+
const [explicit, style] = dateOptions(options, "time");
|
|
2464
|
+
const format = style && { timeStyle: style };
|
|
2347
2465
|
return (value) => {
|
|
2348
2466
|
if (!(value instanceof Date)) {
|
|
2349
|
-
valueMustBeDate("time");
|
|
2467
|
+
valueMustBeDate("time", value);
|
|
2350
2468
|
}
|
|
2351
|
-
return value.toLocaleTimeString(explicit ?? defaultLocale());
|
|
2469
|
+
return value.toLocaleTimeString(explicit ?? defaultLocale(), format);
|
|
2352
2470
|
};
|
|
2353
2471
|
};
|
|
2354
2472
|
var datetime = (options) => {
|
|
2355
|
-
const explicit = options
|
|
2473
|
+
const [explicit, style] = dateOptions(options, "datetime");
|
|
2474
|
+
const format = style && { dateStyle: style, timeStyle: style };
|
|
2356
2475
|
return (value) => {
|
|
2357
2476
|
if (!(value instanceof Date)) {
|
|
2358
|
-
valueMustBeDate("datetime");
|
|
2477
|
+
valueMustBeDate("datetime", value);
|
|
2359
2478
|
}
|
|
2360
|
-
return value.toLocaleString(explicit ?? defaultLocale());
|
|
2479
|
+
return value.toLocaleString(explicit ?? defaultLocale(), format);
|
|
2361
2480
|
};
|
|
2362
2481
|
};
|
|
2363
2482
|
var ymd = (options) => {
|
|
2364
2483
|
const opt = options?.[0] ?? "-";
|
|
2365
2484
|
return (value) => {
|
|
2366
2485
|
if (!(value instanceof Date)) {
|
|
2367
|
-
valueMustBeDate("ymd");
|
|
2486
|
+
valueMustBeDate("ymd", value);
|
|
2368
2487
|
}
|
|
2369
2488
|
const year = value.getFullYear().toString();
|
|
2370
2489
|
const month = (value.getMonth() + 1).toString().padStart(2, "0");
|
|
@@ -2376,7 +2495,7 @@ var hms = (options) => {
|
|
|
2376
2495
|
const opt = options?.[0] ?? ":";
|
|
2377
2496
|
return (value) => {
|
|
2378
2497
|
if (!(value instanceof Date)) {
|
|
2379
|
-
valueMustBeDate("hms");
|
|
2498
|
+
valueMustBeDate("hms", value);
|
|
2380
2499
|
}
|
|
2381
2500
|
const hours = value.getHours().toString().padStart(2, "0");
|
|
2382
2501
|
const minutes = value.getMinutes().toString().padStart(2, "0");
|
|
@@ -2386,7 +2505,7 @@ var hms = (options) => {
|
|
|
2386
2505
|
};
|
|
2387
2506
|
var abs = () => (value) => {
|
|
2388
2507
|
if (typeof value !== "number") {
|
|
2389
|
-
valueMustBeNumber("abs");
|
|
2508
|
+
valueMustBeNumber("abs", value);
|
|
2390
2509
|
}
|
|
2391
2510
|
return Math.abs(value);
|
|
2392
2511
|
};
|
|
@@ -2395,7 +2514,7 @@ var clamp = (options) => {
|
|
|
2395
2514
|
const max = requiredNumberOption(options, 1, "clamp");
|
|
2396
2515
|
return (value) => {
|
|
2397
2516
|
if (typeof value !== "number") {
|
|
2398
|
-
valueMustBeNumber("clamp");
|
|
2517
|
+
valueMustBeNumber("clamp", value);
|
|
2399
2518
|
}
|
|
2400
2519
|
return Math.min(Math.max(value, min), max);
|
|
2401
2520
|
};
|
|
@@ -2442,10 +2561,10 @@ var registered = {
|
|
|
2442
2561
|
ceil: { factory: ceil, arity: [0, 1] },
|
|
2443
2562
|
percent: { factory: percent, arity: [0, 1] },
|
|
2444
2563
|
unit: { factory: nullishPassthrough(unit), arity: [1, 1] },
|
|
2445
|
-
// The locale-dependent three take a locale like `locale` does (`date(ja-JP)`)
|
|
2446
|
-
date: { factory: date, arity: [0,
|
|
2447
|
-
time: { factory: time, arity: [0,
|
|
2448
|
-
datetime: { factory: datetime, arity: [0,
|
|
2564
|
+
// The locale-dependent three take a locale like `locale` does (`date(ja-JP)`), and a style (`date(ja-JP,long)`)
|
|
2565
|
+
date: { factory: date, arity: [0, 2] },
|
|
2566
|
+
time: { factory: time, arity: [0, 2] },
|
|
2567
|
+
datetime: { factory: datetime, arity: [0, 2] },
|
|
2449
2568
|
ymd: { factory: ymd, arity: [0, 1] },
|
|
2450
2569
|
hms: { factory: hms, arity: [0, 1] },
|
|
2451
2570
|
// the core set of 4.0.0-rc.3 (the core's own: eq ne not lt le gt ge falsy truthy boolean)
|
|
@@ -2472,7 +2591,9 @@ var registered = {
|
|
|
2472
2591
|
boolean: boolean2,
|
|
2473
2592
|
number: { factory: number, arity: [0, 0] },
|
|
2474
2593
|
string: { factory: string, arity: [0, 0] },
|
|
2475
|
-
nullIfEmpty: { factory: nullIfEmpty, arity: [0, 0] }
|
|
2594
|
+
nullIfEmpty: { factory: nullIfEmpty, arity: [0, 0] },
|
|
2595
|
+
// (added in 4.2: last, so the order of the others is unchanged)
|
|
2596
|
+
currency: { factory: currency, arity: [1, 2] }
|
|
2476
2597
|
};
|
|
2477
2598
|
var formatFilters = /* @__PURE__ */ Object.fromEntries(
|
|
2478
2599
|
/* @__PURE__ */ Object.entries(registered).filter(([name]) => !(name in coreFilters))
|
|
@@ -2504,10 +2625,11 @@ var builtinFilterMeta = {
|
|
|
2504
2625
|
// `not` は真偽性(truthy / falsy)の反転。`if:` が `Boolean()` で寄せるのと同じ規則で、
|
|
2505
2626
|
// `else:` はこのフィルタを足した束縛として組み立てられる(structural/createNotFilter.ts)
|
|
2506
2627
|
not: { description: "\u771F\u507D\u6027\u3092\u53CD\u8EE2\uFF08falsy \u2192 true\uFF09", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2628
|
+
// 比較は数値だけを受ける(filters/core.ts の `numeric` は数値以外の値で #28。3.x も同じで、"string" は誤りだった)
|
|
2629
|
+
lt: { description: "\u3088\u308A\u5C0F\u3055\u3044\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
2630
|
+
le: { description: "\u4EE5\u4E0B\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
2631
|
+
gt: { description: "\u3088\u308A\u5927\u304D\u3044\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
2632
|
+
ge: { description: "\u4EE5\u4E0A\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
2511
2633
|
// 算術
|
|
2512
2634
|
add: { description: "\u52A0\u7B97", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
2513
2635
|
sub: { description: "\u6E1B\u7B97", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
@@ -2543,10 +2665,11 @@ var builtinFilterMeta = {
|
|
|
2543
2665
|
unit: { description: "\u5358\u4F4D\uFF08\u63A5\u5C3E\u8F9E\uFF09\u3092\u4ED8\u52A0", hasArgs: true, resultType: "string", acceptTypes: ["number", "string"], minArgs: 1, maxArgs: 1, argTypes: ["string"] },
|
|
2544
2666
|
// 日付・時刻
|
|
2545
2667
|
// `locale` と同じくロケールを 1 つ受ける(`date(ja-JP)`)。実装は最初からこれを読んでいたが、
|
|
2546
|
-
// メタデータ側が maxArgs: 0 だったため lint
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2668
|
+
// メタデータ側が maxArgs: 0 だったため lint と補完が正しい書き方を誤りとして報告していた。
|
|
2669
|
+
// 4.2: 2 つ目は書式(full / long / medium / short — Intl の dateStyle / timeStyle)。書式だけなら既定のロケール
|
|
2670
|
+
date: { description: "\u30ED\u30B1\u30FC\u30EB\u5F62\u5F0F\u306E\u65E5\u4ED8 ([locale][, style]\u3002style \u306F full / long / medium / short\u3001\u65E2\u5B9A\u306E\u30ED\u30B1\u30FC\u30EB\u306F config.locale)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 2, argTypes: ["string", "string"] },
|
|
2671
|
+
time: { description: "\u30ED\u30B1\u30FC\u30EB\u5F62\u5F0F\u306E\u6642\u523B ([locale][, style]\u3002style \u306F full / long / medium / short\u3001\u65E2\u5B9A\u306E\u30ED\u30B1\u30FC\u30EB\u306F config.locale)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 2, argTypes: ["string", "string"] },
|
|
2672
|
+
datetime: { description: "\u30ED\u30B1\u30FC\u30EB\u5F62\u5F0F\u306E\u65E5\u6642 ([locale][, style]\u3002style \u306F full / long / medium / short\u3001\u65E2\u5B9A\u306E\u30ED\u30B1\u30FC\u30EB\u306F config.locale)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 2, argTypes: ["string", "string"] },
|
|
2550
2673
|
ymd: { description: "YYYY-MM-DD \u5F62\u5F0F ([separator]\u3002\u65E2\u5B9A\u306F -)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
2551
2674
|
hms: { description: "HH:MM:SS \u5F62\u5F0F ([separator]\u3002\u65E2\u5B9A\u306F :)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
2552
2675
|
// 真偽値・変換
|
|
@@ -2557,7 +2680,9 @@ var builtinFilterMeta = {
|
|
|
2557
2680
|
boolean: { description: "\u30D6\u30FC\u30EB\u5024\u306B\u5909\u63DB", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
2558
2681
|
number: { description: "\u6570\u5024\u306B\u5909\u63DB", hasArgs: false, resultType: "number", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
2559
2682
|
string: { description: "\u6587\u5B57\u5217\u306B\u5909\u63DB", hasArgs: false, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
2560
|
-
nullIfEmpty: { description: "\u7A7A\u6587\u5B57\u5217\u3092null\u306B\u5909\u63DB", hasArgs: false, resultType: "passthrough", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 }
|
|
2683
|
+
nullIfEmpty: { description: "\u7A7A\u6587\u5B57\u5217\u3092null\u306B\u5909\u63DB", hasArgs: false, resultType: "passthrough", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
2684
|
+
// 4.2(formats の最後に登録)
|
|
2685
|
+
currency: { description: "\u901A\u8CA8\u306E\u66F8\u5F0F (code[, locale]\u3002code \u306F ISO 4217 \u2014 JPY / USD / EUR\u3001\u65E2\u5B9A\u306E\u30ED\u30B1\u30FC\u30EB\u306F config.locale)", hasArgs: true, resultType: "string", acceptTypes: ["number"], minArgs: 1, maxArgs: 2, argTypes: ["string", "string"] }
|
|
2561
2686
|
};
|
|
2562
2687
|
var WCS_MANIFEST_VERSION = 2;
|
|
2563
2688
|
var builtinFilterAliases = Object.freeze({});
|
|
@@ -10943,6 +11068,193 @@ function findOwnThis(text3, kind) {
|
|
|
10943
11068
|
forEachChild(root, walk);
|
|
10944
11069
|
return found;
|
|
10945
11070
|
}
|
|
11071
|
+
var DESTRUCTIVE_ARRAY_METHODS = /* @__PURE__ */ new Set(["push", "pop", "shift", "unshift", "splice", "sort", "reverse", "fill", "copyWithin"]);
|
|
11072
|
+
function memberChain(node, source) {
|
|
11073
|
+
const segments = [];
|
|
11074
|
+
let cur = unwrapChain(node);
|
|
11075
|
+
while (cur.type === "MemberExpression") {
|
|
11076
|
+
const property = cur.property;
|
|
11077
|
+
let name = null;
|
|
11078
|
+
if (!cur.computed && property.type === "Identifier") name = property.name;
|
|
11079
|
+
else if (property.type === "Literal" && (typeof property.value === "string" || typeof property.value === "number")) name = String(property.value);
|
|
11080
|
+
segments.unshift({ name, raw: source(property), computed: cur.computed });
|
|
11081
|
+
cur = unwrapChain(cur.object);
|
|
11082
|
+
}
|
|
11083
|
+
return { base: cur, segments };
|
|
11084
|
+
}
|
|
11085
|
+
function assignTarget(root, segments) {
|
|
11086
|
+
if (segments.every((s) => s.name !== null)) {
|
|
11087
|
+
const path = segments.map((s) => s.name).join(".");
|
|
11088
|
+
return segments.length === 1 && /^[A-Za-z_$][\w$]*$/.test(path) ? `${root}.${path}` : `${root}["${path}"]`;
|
|
11089
|
+
}
|
|
11090
|
+
return `${root}[\`${segments.map((s) => s.name ?? `\${${s.raw}}`).join(".")}\`]`;
|
|
11091
|
+
}
|
|
11092
|
+
function findInPlaceChanges(text3, kind, root) {
|
|
11093
|
+
const prefix = kind === "body" ? PREFIX : VALUE_PREFIX;
|
|
11094
|
+
let program;
|
|
11095
|
+
try {
|
|
11096
|
+
program = parse3(prefix + text3 + (kind === "body" ? SUFFIX : VALUE_SUFFIX), { ecmaVersion: "latest", sourceType: "module" });
|
|
11097
|
+
} catch {
|
|
11098
|
+
return [];
|
|
11099
|
+
}
|
|
11100
|
+
const wrapper = unwrapWrapper(program);
|
|
11101
|
+
if (wrapper === null) return [];
|
|
11102
|
+
let body = wrapper.body;
|
|
11103
|
+
if (kind === "value") {
|
|
11104
|
+
const statement = wrapper.body.body.length === 1 ? wrapper.body.body[0] : null;
|
|
11105
|
+
const fn = statement?.type === "ExpressionStatement" ? statement.expression : null;
|
|
11106
|
+
if (fn === null || fn.type !== "FunctionExpression" && fn.type !== "ArrowFunctionExpression") return [];
|
|
11107
|
+
if (root === null) {
|
|
11108
|
+
const first = fn.params[0];
|
|
11109
|
+
if (first === void 0 || first.type !== "Identifier") return [];
|
|
11110
|
+
root = first.name;
|
|
11111
|
+
}
|
|
11112
|
+
body = fn.body;
|
|
11113
|
+
}
|
|
11114
|
+
if (root === null) return [];
|
|
11115
|
+
const stateRoot = root;
|
|
11116
|
+
const shift = prefix.length;
|
|
11117
|
+
const source = (n) => (prefix + text3).slice(n.start, n.end);
|
|
11118
|
+
const isRoot = (n) => stateRoot === "this" ? n.type === "ThisExpression" : n.type === "Identifier" && n.name === stateRoot;
|
|
11119
|
+
const bound = /* @__PURE__ */ new Map();
|
|
11120
|
+
const bind = (name) => {
|
|
11121
|
+
bound.set(name, (bound.get(name) ?? 0) + 1);
|
|
11122
|
+
};
|
|
11123
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
11124
|
+
const collect2 = (node) => {
|
|
11125
|
+
if (isFunctionNode(node)) {
|
|
11126
|
+
if (node.type === "FunctionDeclaration" && node.id !== null) bind(node.id.name);
|
|
11127
|
+
const names = /* @__PURE__ */ new Set();
|
|
11128
|
+
for (const param of node.params) bindingNames(param, names);
|
|
11129
|
+
names.forEach(bind);
|
|
11130
|
+
} else if (node.type === "VariableDeclarator") {
|
|
11131
|
+
const names = /* @__PURE__ */ new Set();
|
|
11132
|
+
bindingNames(node.id, names);
|
|
11133
|
+
names.forEach(bind);
|
|
11134
|
+
const init = node.init ? unwrapChain(node.init) : null;
|
|
11135
|
+
if (init !== null && node.id.type === "Identifier" && init.type === "MemberExpression") {
|
|
11136
|
+
const chain = memberChain(init, source);
|
|
11137
|
+
if (isRoot(chain.base) && chain.segments.length > 0 && !chain.segments[0].name?.startsWith("$")) {
|
|
11138
|
+
aliases.set(node.id.name, { source: source(init), segments: chain.segments });
|
|
11139
|
+
}
|
|
11140
|
+
} else if (init !== null && node.id.type === "ObjectPattern" && isRoot(init)) {
|
|
11141
|
+
for (const property of node.id.properties) {
|
|
11142
|
+
if (property.type !== "Property" || property.computed) continue;
|
|
11143
|
+
const key = property.key.type === "Identifier" ? property.key.name : property.key.type === "Literal" ? String(property.key.value) : null;
|
|
11144
|
+
const value = property.value.type === "AssignmentPattern" ? property.value.left : property.value;
|
|
11145
|
+
if (key === null || key.startsWith("$") || value.type !== "Identifier") continue;
|
|
11146
|
+
const segment = { name: key, raw: key, computed: false };
|
|
11147
|
+
aliases.set(value.name, { source: `${stateRoot}.${key}`, segments: [segment] });
|
|
11148
|
+
}
|
|
11149
|
+
}
|
|
11150
|
+
} else if (node.type === "CatchClause" && node.param) {
|
|
11151
|
+
const names = /* @__PURE__ */ new Set();
|
|
11152
|
+
bindingNames(node.param, names);
|
|
11153
|
+
names.forEach(bind);
|
|
11154
|
+
} else if (node.type === "ClassDeclaration" && node.id !== null) {
|
|
11155
|
+
bind(node.id.name);
|
|
11156
|
+
} else if (node.type === "AssignmentExpression" && node.left.type === "Identifier") {
|
|
11157
|
+
bind(node.left.name);
|
|
11158
|
+
}
|
|
11159
|
+
forEachChild(node, collect2);
|
|
11160
|
+
};
|
|
11161
|
+
collect2(body);
|
|
11162
|
+
const alias = (name) => bound.get(name) === 1 ? aliases.get(name) : void 0;
|
|
11163
|
+
const out = [];
|
|
11164
|
+
const report = (target, at2, form, directMin) => {
|
|
11165
|
+
const chain = memberChain(target, source);
|
|
11166
|
+
const base = chain.base;
|
|
11167
|
+
const range = { start: at2.start - shift, end: at2.end - shift };
|
|
11168
|
+
const pick = (segments) => form ?? (segments.length > 0 && segments.every((s) => s.computed) ? "index" : "property");
|
|
11169
|
+
if (base.type === "Identifier" && base.name !== stateRoot) {
|
|
11170
|
+
const a = alias(base.name);
|
|
11171
|
+
if (a === void 0) return;
|
|
11172
|
+
out.push({ form: pick(chain.segments), alias: base.name, source: a.source, target: assignTarget(stateRoot, a.segments), ...range });
|
|
11173
|
+
return;
|
|
11174
|
+
}
|
|
11175
|
+
if (!isRoot(base) || chain.segments.length < directMin || chain.segments[0].name?.startsWith("$")) return;
|
|
11176
|
+
out.push({ form: pick(chain.segments.slice(1)), alias: null, source: source(at2), target: assignTarget(stateRoot, chain.segments), ...range });
|
|
11177
|
+
};
|
|
11178
|
+
const direct = stateRoot === "this" ? Infinity : 2;
|
|
11179
|
+
const visitChanges = (node) => {
|
|
11180
|
+
if (node.type === "AssignmentExpression" && unwrapChain(node.left).type === "MemberExpression") {
|
|
11181
|
+
report(node.left, node.left, null, direct);
|
|
11182
|
+
} else if (node.type === "UpdateExpression" && unwrapChain(node.argument).type === "MemberExpression") {
|
|
11183
|
+
report(node.argument, node.argument, null, direct);
|
|
11184
|
+
} else if (node.type === "UnaryExpression" && node.operator === "delete" && unwrapChain(node.argument).type === "MemberExpression") {
|
|
11185
|
+
report(node.argument, node.argument, "property", direct);
|
|
11186
|
+
} else if (node.type === "CallExpression") {
|
|
11187
|
+
const callee = unwrapChain(node.callee);
|
|
11188
|
+
if (callee.type === "MemberExpression") {
|
|
11189
|
+
const method = !callee.computed && callee.property.type === "Identifier" ? callee.property.name : null;
|
|
11190
|
+
const object = unwrapChain(callee.object);
|
|
11191
|
+
if (method === "assign" && object.type === "Identifier" && object.name === "Object" && node.arguments.length > 0) {
|
|
11192
|
+
const first = node.arguments[0];
|
|
11193
|
+
if (first.type === "Identifier" || unwrapChain(first).type === "MemberExpression") report(first, node, "property", 1);
|
|
11194
|
+
} else if (method !== null && DESTRUCTIVE_ARRAY_METHODS.has(method)) {
|
|
11195
|
+
report(callee.object, node, "method", stateRoot === "this" ? Infinity : 1);
|
|
11196
|
+
}
|
|
11197
|
+
}
|
|
11198
|
+
}
|
|
11199
|
+
forEachChild(node, visitChanges);
|
|
11200
|
+
};
|
|
11201
|
+
visitChanges(body);
|
|
11202
|
+
return out;
|
|
11203
|
+
}
|
|
11204
|
+
var LOCATION_HOLDERS = /* @__PURE__ */ new Set(["window", "document", "globalThis", "self"]);
|
|
11205
|
+
var LOCATION_VARYING = /* @__PURE__ */ new Set(["pathname", "search", "hash", "href"]);
|
|
11206
|
+
function findLocationRead(body) {
|
|
11207
|
+
let program;
|
|
11208
|
+
try {
|
|
11209
|
+
program = parse3(PREFIX + body + SUFFIX, { ecmaVersion: "latest", sourceType: "module" });
|
|
11210
|
+
} catch {
|
|
11211
|
+
return null;
|
|
11212
|
+
}
|
|
11213
|
+
const wrapper = unwrapWrapper(program);
|
|
11214
|
+
if (wrapper === null) return null;
|
|
11215
|
+
const names = /* @__PURE__ */ new Set();
|
|
11216
|
+
const scan = (node) => {
|
|
11217
|
+
if (isFunctionNode(node)) for (const param of node.params) bindingNames(param, names);
|
|
11218
|
+
if (node.type === "VariableDeclarator") bindingNames(node.id, names);
|
|
11219
|
+
forEachChild(node, scan);
|
|
11220
|
+
};
|
|
11221
|
+
scan(wrapper.body);
|
|
11222
|
+
if (names.has("location")) return null;
|
|
11223
|
+
const isLocation = (node) => {
|
|
11224
|
+
const n = unwrapChain(node);
|
|
11225
|
+
if (n.type === "Identifier") return n.name === "location";
|
|
11226
|
+
return n.type === "MemberExpression" && !n.computed && n.property.type === "Identifier" && n.property.name === "location" && n.object.type === "Identifier" && LOCATION_HOLDERS.has(n.object.name);
|
|
11227
|
+
};
|
|
11228
|
+
let found = null;
|
|
11229
|
+
const at2 = (node) => {
|
|
11230
|
+
found = { start: node.start - PREFIX.length, end: node.end - PREFIX.length, text: (PREFIX + body).slice(node.start, node.end) };
|
|
11231
|
+
};
|
|
11232
|
+
const walk = (node) => {
|
|
11233
|
+
if (found !== null) return;
|
|
11234
|
+
if (node.type === "MemberExpression" && isLocation(node.object)) {
|
|
11235
|
+
const part = !node.computed && node.property.type === "Identifier" ? node.property.name : null;
|
|
11236
|
+
if (part === null || LOCATION_VARYING.has(part)) at2(node);
|
|
11237
|
+
return;
|
|
11238
|
+
}
|
|
11239
|
+
if (isLocation(node)) {
|
|
11240
|
+
at2(node);
|
|
11241
|
+
return;
|
|
11242
|
+
}
|
|
11243
|
+
if (node.type === "MemberExpression") {
|
|
11244
|
+
walk(node.object);
|
|
11245
|
+
if (node.computed) walk(node.property);
|
|
11246
|
+
return;
|
|
11247
|
+
}
|
|
11248
|
+
if (node.type === "Property") {
|
|
11249
|
+
if (node.computed) walk(node.key);
|
|
11250
|
+
walk(node.value);
|
|
11251
|
+
return;
|
|
11252
|
+
}
|
|
11253
|
+
forEachChild(node, walk);
|
|
11254
|
+
};
|
|
11255
|
+
walk(wrapper.body);
|
|
11256
|
+
return found;
|
|
11257
|
+
}
|
|
10946
11258
|
|
|
10947
11259
|
// src/core/messages.ts
|
|
10948
11260
|
function resolveLocale(locale2) {
|
|
@@ -10983,6 +11295,8 @@ var ja = {
|
|
|
10983
11295
|
getterCycle: (cycle) => `\u30D1\u30B9 getter \u304C\u5FAA\u74B0\u53C2\u7167\u3057\u3066\u3044\u307E\u3059: ${cycle}`,
|
|
10984
11296
|
updatedCallbackUnbound: (p) => `$renderedCallback \u306F binding \u99C6\u52D5\u3067\u3059\u3002"${p}" \u306F\u3053\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u3069\u306E\u30D0\u30A4\u30F3\u30C7\u30A3\u30F3\u30B0\u306B\u3082\u73FE\u308C\u306A\u3044\u305F\u3081\u3001\u3053\u306E\u5206\u5C90\u306F\u4E00\u5EA6\u3082\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3002\u63CF\u753B\u306B\u4F9D\u5B58\u305B\u305A\u53CD\u5FDC\u3059\u308B\u306A\u3089 $watch \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044`,
|
|
10985
11297
|
onHandlerThis: (name) => `$on \u306E\u30CF\u30F3\u30C9\u30E9 "${name}" \u304C this \u3092\u4F7F\u3063\u3066\u3044\u307E\u3059\u3002$on \u306E\u30CF\u30F3\u30C9\u30E9\u306F state \u3092\u7B2C 1 \u5F15\u6570\u3067\u53D7\u3051\u53D6\u308A\uFF08\`${name}(state, event) { state.x = \u2026 }\`\uFF09\u3001this \u306F undefined \u306A\u306E\u3067\u3001this.\u2026 \u306F\u547C\u3070\u308C\u305F\u3068\u304D\u306B\u4F8B\u5916\u306B\u306A\u308A\u307E\u3059\u3002$watch \u3084\u30E1\u30BD\u30C3\u30C9\u3068\u9055\u3046\u70B9\u306B\u6CE8\u610F`,
|
|
11298
|
+
getterReadsLocation: (read) => `\u3053\u306E getter \u306F ${read} \u3092\u8AAD\u3093\u3067\u3044\u307E\u3059\u304C\u3001location \u306F state \u3067\u306F\u306A\u3044\u306E\u3067\u3001\u6700\u521D\u306B\u8AAD\u3093\u3060 URL \u3092\u6301\u3061\u7D9A\u3051\u307E\u3059\uFF08\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3\u3067\u518D\u8A55\u4FA1\u3055\u308C\u307E\u305B\u3093\uFF09\u3002URL \u306F state \u3092\u901A\u3057\u3066\u8AAD\u3093\u3067\u304F\u3060\u3055\u3044 \u2014 <wcs-router> \u306E path / searchParams \u3092\u675F\u306D\u308B`,
|
|
11299
|
+
submitWithoutPrevent: (h) => `onsubmit \u306B #prevent \u304C\u7121\u304F\u3001"${h}" \u3082 preventDefault \u3092\u547C\u3073\u307E\u305B\u3093\u3002\u30D6\u30E9\u30A6\u30B6\u306F\u30D5\u30A9\u30FC\u30E0\u3082\u9001\u308B\u306E\u3067\u3001\u30DA\u30FC\u30B8\u304C\u8AAD\u307F\u76F4\u3055\u308C\u308B\u304B\u3001router \u304C\u3042\u308C\u3070 GET \u304C\u6B04\u306E\u5024\uFF08\u30D1\u30B9\u30EF\u30FC\u30C9\u3082\uFF09\u3092 URL \u3068\u5C65\u6B74\u306B\u8F09\u305B\u307E\u3059\u3002onsubmit#prevent: ${h} \u3068\u66F8\u304F\u304B\u3001\u30CF\u30F3\u30C9\u30E9\u3067 event.preventDefault() \u3092\u547C\u3093\u3067\u304F\u3060\u3055\u3044`,
|
|
10986
11300
|
getterUntrackedRead: (root, sp) => `\u3053\u3053\u3067\u8FFD\u8DE1\u3055\u308C\u308B\u306E\u306F "${root}" \u3060\u3051\u3067\u3059\u3002"${sp}" \u304C\u5909\u308F\u3063\u3066\u3082\u3053\u306E getter \u306F\u518D\u8A55\u4FA1\u3055\u308C\u307E\u305B\u3093\uFF08\u30D1\u30B9\u8AAD\u307F\u53D6\u308A\u306E\u5148\u306E\u7D20\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u30A2\u30AF\u30BB\u30B9\u306F\u8FFD\u8DE1\u3055\u308C\u306A\u3044\uFF09\u3002this["${sp}"] \u3067\u8AAD\u3093\u3067\u304F\u3060\u3055\u3044`,
|
|
10987
11301
|
handlerFilterNotAllowed: (prop) => `\u30A4\u30D9\u30F3\u30C8\u30CF\u30F3\u30C9\u30E9 "${prop}" \u306B\u30D5\u30A3\u30EB\u30BF\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093`,
|
|
10988
11302
|
typeExpectation: (label, expected, resultType) => `"${label}" \u306B\u306F${JA_EXPECTED_LABEL[expected]}\u304C\u5FC5\u8981\u3067\u3059\uFF08\u73FE\u5728\u306E\u578B: ${resultType}\uFF09`,
|
|
@@ -11002,13 +11316,15 @@ var ja = {
|
|
|
11002
11316
|
watchKeyEmptySegment: (k) => `$watch \u306E\u30AD\u30FC "${k}" \u306B\u7A7A\u306E\u30D1\u30B9\u30BB\u30B0\u30E1\u30F3\u30C8\u304C\u3042\u308A\u307E\u3059`,
|
|
11003
11317
|
watchHandlerNotFunction: (k) => `$watch \u306E\u30A8\u30F3\u30C8\u30EA "${k}" \u306E\u5024\u306F\u95A2\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`,
|
|
11004
11318
|
watchPathMissing: (k) => `$watch \u306E\u30AD\u30FC "${k}" \u306F\u72B6\u614B\u5B9A\u7FA9\u306B\u5B58\u5728\u3057\u307E\u305B\u3093\uFF08\u4E00\u5EA6\u3082\u767A\u706B\u3057\u307E\u305B\u3093\uFF09`,
|
|
11005
|
-
scanRemoved: (mountPath) => mountPath === null ? `$scan \u306F 4.0 \u3067\u5916\u308C\u307E\u3057\u305F\
|
|
11319
|
+
scanRemoved: (mountPath) => mountPath === null ? `$scan \u306F 4.0 \u3067\u5916\u308C\u307E\u3057\u305F\uFF08diagnostics \u306E\u5F8C\u4ED8\u3051\u3092\u5165\u308C\u305F\u5165\u53E3 \u2014 /auto \u306A\u3069 \u2014 \u306F\u8AAD\u307F\u8FBC\u307F\u6642\u306B throw \u3057\u3001/core \u3060\u3051\u3067\u306F\u9ED9\u3063\u3066\u7121\u8996\u3057\u307E\u3059\uFF09\u3002\u30D1\u30B9\u306E\u5909\u5316\u3092\u7573\u3080\u306A\u3089 $watch\u3001\u30A4\u30D9\u30F3\u30C8\u3092\u7573\u3080\u306A\u3089 $on \u306E\u30CF\u30F3\u30C9\u30E9\u3067\u3001\u51FA\u529B\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u3078\u66F8\u3044\u3066\u304F\u3060\u3055\u3044` : `$scan \u306F 4.0 \u3067\u5916\u308C\u307E\u3057\u305F\u3002\u30DC\u30EA\u30E5\u30FC\u30E0\uFF08mount="${mountPath}"\uFF09\u3067\u306F\u3001\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u63A5\u304E\u6728\u3092\u62D2\u3093\u3067 console.error \u3067\u5831\u544A\u3057\u307E\u3059\uFF08\u3053\u306E state \u306F\u6728\u306B\u8F09\u308A\u307E\u305B\u3093\uFF09\u3002root \u306E state \u306E $watch \u304B $on \u306E\u30CF\u30F3\u30C9\u30E9\u3067\u7573\u3093\u3067\u304F\u3060\u3055\u3044`,
|
|
11006
11320
|
typeAnnotationIncompatible: (vt, rt) => `\u578B "${vt}" \u306F @type {${rt}} \u3068\u4E92\u63DB\u6027\u304C\u3042\u308A\u307E\u305B\u3093`,
|
|
11007
11321
|
arrayMutation: (m, alt) => `\u914D\u5217\u306E\u7834\u58CA\u7684\u30E1\u30BD\u30C3\u30C9 "${m}" \u306F\u30EA\u30A2\u30AF\u30C6\u30A3\u30D6\u66F4\u65B0\u3092\u30C8\u30EA\u30AC\u30FC\u3057\u307E\u305B\u3093\uFF08\u540C\u4E00\u53C2\u7167\u306E\u81EA\u5DF1\u518D\u4EE3\u5165\u3067\u3082\u8981\u7D20\u306E\u8FFD\u52A0\u30FB\u524A\u9664\u306F\u53CD\u6620\u3055\u308C\u307E\u305B\u3093\uFF09\u3002\u975E\u7834\u58CA\u30E1\u30BD\u30C3\u30C9\u3068\u518D\u4EE3\u5165\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: ${alt}\uFF09\u3002`,
|
|
11008
11322
|
arrayIndexAssign: (sp) => `\u914D\u5217\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u3078\u306E\u76F4\u63A5\u4EE3\u5165\u306F\u30EA\u30A2\u30AF\u30C6\u30A3\u30D6\u66F4\u65B0\u3092\u30C8\u30EA\u30AC\u30FC\u3057\u307E\u305B\u3093\u3002this["${sp}"] \u306E\u3088\u3046\u306A\u30C9\u30C3\u30C8\u30D1\u30B9\u4EE3\u5165\u3001\u307E\u305F\u306F with() \u3068\u518D\u4EE3\u5165\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,
|
|
11009
|
-
|
|
11323
|
+
inPlaceAlias: (a, src, t) => `"${a}" \u306F ${src}\uFF08state \u306E\u5024\u305D\u306E\u3082\u306E\uFF09\u3067\u3059\u3002\u305D\u308C\u3092\u901A\u3057\u305F\u5909\u66F4\u306F\u30EA\u30A2\u30AF\u30C6\u30A3\u30D6\u66F4\u65B0\u3092\u30C8\u30EA\u30AC\u30FC\u305B\u305A\u3001\u540C\u3058\u5024\u3092\u66F8\u304D\u623B\u3057\u3066\u3082\u4E00\u89A7\u306E\u884C\u306F\u8FFD\u52A0\u30FB\u524A\u9664\u30FB\u7F6E\u304D\u63DB\u3048\u3055\u308C\u307E\u305B\u3093\u3002\u65B0\u3057\u3044\u5024\u3092\u4F5C\u3063\u3066 ${t} \u306B\u4EE3\u5165\u3057\u3066\u304F\u3060\u3055\u3044\uFF08${a}.with(i, item) / [...${a}, item] / { ...${a}, key: value }\uFF09`,
|
|
11324
|
+
inPlaceChange: (src, t) => `${src} \u306F state \u306E\u5024\u3092\u305D\u306E\u5834\u3067\u5909\u3048\u308B\u306E\u3067\u3001\u30EA\u30A2\u30AF\u30C6\u30A3\u30D6\u66F4\u65B0\u3092\u30C8\u30EA\u30AC\u30FC\u3057\u307E\u305B\u3093\u3002\u65B0\u3057\u3044\u5024\u3092\u4F5C\u3063\u3066 ${t} \u306B\u4EE3\u5165\u3057\u3066\u304F\u3060\u3055\u3044`,
|
|
11325
|
+
tagMemberUnknown: (prop, tag) => `"${prop}" \u306F <${tag}> \u306E wcBindable \u30E1\u30F3\u30D0\u30FC\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF08\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u5BA3\u8A00\u306B\u7121\u3044\u30E1\u30F3\u30D0\u30FC\u3078\u306E\u675F\u7E1B\u3092 #38 \u3067\u62D2\u307F\u3001root \u3067\u306F state \u304C\u521D\u671F\u5316\u306B\u5931\u6557\u3057\u307E\u3059\uFF09`,
|
|
11010
11326
|
nameAlias: (written, canonical) => `"${written}" \u306F 4.0 \u3067\u5916\u308C\u307E\u3057\u305F\uFF08"${canonical}" \u306E 3.x \u306E\u65E7\u540D\u3067\u3001\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u8AAD\u3093\u3060\u6642\u70B9\u3067 throw \u3057\u307E\u3059\uFF09\u3002"${canonical}" \u3068\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`,
|
|
11011
|
-
declarationAliasRead: (alias, canonical) => `"${alias}" \u306F 4.0 \u3067\u5916\u308C\u305F\u5BA3\u8A00\u30AD\u30FC\uFF08"${canonical}" \u306E 3.x \u306E\u65E7\u540D\uFF09\u306A\u306E\u3067\u3001this["${alias}"] \u306F undefined \u306B\u306A\u308A\u307E\u3059\u3002"${canonical}" \u3092\u8AAD\u3093\u3067\
|
|
11327
|
+
declarationAliasRead: (alias, canonical) => `"${alias}" \u306F 4.0 \u3067\u5916\u308C\u305F\u5BA3\u8A00\u30AD\u30FC\uFF08"${canonical}" \u306E 3.x \u306E\u65E7\u540D\uFF09\u306A\u306E\u3067\u3001this["${alias}"] \u306F undefined \u306B\u306A\u308A\u307E\u3059\u3002\u5BA3\u8A00\u306F this \u3092\u901A\u3057\u3066\u8AAD\u3081\u307E\u305B\u3093 \u2014 "${canonical}" \u3092\u8AAD\u3093\u3067\u3082 undefined \u3067\u3059${canonical === "$stream" ? "\uFF08\u30B9\u30C8\u30EA\u30FC\u30E0\u306E\u72B6\u614B\u306F $streamStatus\u30FB$streamError \u3067\u8AAD\u307F\u307E\u3059\uFF09" : ""}`,
|
|
11012
11328
|
declarationAlias: (alias, canonical) => `\u5BA3\u8A00\u30AD\u30FC "${alias}" \u306F 4.0 \u3067\u5916\u308C\u307E\u3057\u305F\uFF08"${canonical}" \u306E 3.x \u306E\u65E7\u540D\u3067\u3001\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u8AAD\u307F\u8FBC\u307F\u6642\u306B throw \u3057\u307E\u3059\uFF09\u3002"${canonical}" \u3068\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`,
|
|
11013
11329
|
declarationAliasInVolume: (alias, canonical, mountPath) => `\u5BA3\u8A00\u30AD\u30FC "${alias}" \u306F 4.0 \u3067\u5916\u308C\u307E\u3057\u305F\uFF08"${canonical}" \u306E 3.x \u306E\u65E7\u540D\uFF09\u3002\u30DC\u30EA\u30E5\u30FC\u30E0\uFF08mount="${mountPath}"\uFF09\u3067\u306F\u3001\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u63A5\u304E\u6728\u3092\u62D2\u3093\u3067 console.error \u3067\u5831\u544A\u3057\u307E\u3059\uFF08\u3053\u306E state \u306F\u6728\u306B\u8F09\u308A\u307E\u305B\u3093\uFF09\u3002"${canonical}" \u3082\u30DC\u30EA\u30E5\u30FC\u30E0\u3067\u306F\u5BA3\u8A00\u3067\u304D\u306A\u3044\u306E\u3067\u3001root \u306E state \u306B\u5BA3\u8A00\u3057\u3066\u304F\u3060\u3055\u3044`,
|
|
11014
11330
|
behaviorNotObject: (keys) => `$behavior \u306F { ${keys.map((k) => `${k}?`).join(", ")} } \u306E\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\uFF08\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u8AAD\u307F\u8FBC\u307F\u6642\u306B throw \u3057\u307E\u3059\uFF09`,
|
|
@@ -11038,22 +11354,27 @@ var ja = {
|
|
|
11038
11354
|
storagePairClobber: (path) => `<wcs-storage> \u306E value \u3092 #init=element \u306A\u3057\u3067\u30A2\u30AF\u30BB\u30B5\u30DA\u30A2 "${path}" \u306B\u675F\u306D\u3066\u3044\u307E\u3059\u3002state \u306E\u5074\u304C\u5148\u306B\u66F8\u304F\u306E\u3067\u3001\u8AAD\u307F\u8FBC\u307F\u306E\u305F\u3073\u306B getter \u306E\u6700\u521D\u306E\u5024\u304C\u4FDD\u5B58\u5024\u306E\u4E0A\u306B\u4FDD\u5B58\u3055\u308C\u3001setter \u306F\u4FDD\u5B58\u5024\u3092\u53D7\u3051\u53D6\u308C\u307E\u305B\u3093 \u2014 #init=element \u3092\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044\uFF08\`value#init=element: ${path}\`\uFF09`,
|
|
11039
11355
|
inputNestedWrite: (tag, input, path, example) => `<${tag}> \u306E\u5165\u529B "${input}" \u306B "${path}" \u3092\u675F\u306D\u3066\u3044\u307E\u3059\u304C\u3001\u30DA\u30FC\u30B8\u306F\u305D\u306E\u4E0B\uFF08"${example}"\uFF09\u3078\u66F8\u304D\u8FBC\u3093\u3067\u3044\u307E\u3059\u3002\u675F\u7E1B\u306F "${path}" \u81EA\u8EAB\u3078\u306E\u4EE3\u5165\u3067\u3057\u304B\u5F53\u3066\u76F4\u3055\u308C\u306A\u3044\u306E\u3067\u3001\u4E0B\u3078\u306E\u66F8\u304D\u8FBC\u307F\u306F <${tag}> \u306B\u5C4A\u304D\u307E\u305B\u3093 \u2014 \u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u30D1\u30B9\u3067\u8AAD\u3093\u3067\u65B0\u3057\u3044\u5024\u3092\u8FD4\u3059 getter\uFF08\`this["${example}"]\`\u30FB\`$getAll\`\uFF09\u3092\u675F\u306D\u308B\u304B\u3001\u4E0B\u3078\u66F8\u304B\u305A\u306B "${path}" \u3092\u5DEE\u3057\u66FF\u3048\u3066\u304F\u3060\u3055\u3044`,
|
|
11040
11356
|
inputNestedWriteOneShot: (tag, input, path, example) => `<${tag}> \u306E\u5165\u529B "${input}" \u306B "${path}" \u3092\u675F\u306D\u3066\u3044\u307E\u3059\u304C\u3001\u30DA\u30FC\u30B8\u306F\u305D\u306E\u4E0B\uFF08"${example}"\uFF09\u3078\u66F8\u304D\u8FBC\u3093\u3067\u3044\u307E\u3059\u3002\u675F\u7E1B\u306F "${path}" \u81EA\u8EAB\u3078\u306E\u4EE3\u5165\u3067\u3057\u304B\u5F53\u3066\u76F4\u3055\u308C\u305A\u3001<${tag}> \u306F\u8981\u6C42\u306E\u305F\u3073\u306B "${input}" \u3092 null \u306B\u623B\u3059\u306E\u3067\u3001\u6B21\u306E\u8981\u6C42\u306F "${input}" \u306A\u3057\u3067\u9001\u3089\u308C\u307E\u3059 \u2014 \u8981\u6C42\u3092\u59CB\u3081\u308B\u30CF\u30F3\u30C9\u30E9\u3067\u65B0\u3057\u3044\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3092\u4F5C\u3063\u3066\u4EE3\u5165\u3057\uFF08\`this.submitBody = { \u2026 }\`\uFF09\u3001\u305D\u308C\u3092\u675F\u306D\u3066\u304F\u3060\u3055\u3044`,
|
|
11041
|
-
devtoolsAfterState: () => `@wcstack/devtools/auto \u306F @wcstack/state/auto \u3088\u308A\u5148\u306B\u8AAD\u307F\u8FBC\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u5F8C\u3060\u3068\
|
|
11357
|
+
devtoolsAfterState: () => `@wcstack/devtools/auto \u306F @wcstack/state/auto \u3088\u308A\u5148\u306B\u8AAD\u307F\u8FBC\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u5F8C\u304B\u3089\u3060\u3068\u3001DevTools \u306E\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u306F\u4ED8\u3044\u305F\u6642\u70B9\u304B\u3089\u59CB\u307E\u308A\u307E\u3059\u3002\u65E2\u306B\u3042\u308B\u914D\u7DDA\u306F 4.0 \u304C\u9001\u308A\u76F4\u3057\u307E\u3059\uFF09`,
|
|
11042
11358
|
baseHrefMissing: () => `@wcstack/router \u3092\u4F7F\u3046 SPA \u306B\u306F <head> \u5185\u306E <base href="/"> \u304C\u5FC5\u8981\u3067\u3059\uFF08\u7121\u3044\u3068\u30C7\u30A3\u30FC\u30D7\u30EA\u30F3\u30AF\u3067 basename \u304C\u8AA4\u5C0E\u51FA\u3055\u308C\u307E\u3059\uFF09`,
|
|
11043
11359
|
routerOutletMisplaced: () => `\u3053\u306E <wcs-outlet> \u306F <wcs-router> \u306E\u76F4\u5F8C\u306B\u7121\u3044\u306E\u3067\u3001\u3069\u306E router \u3082\u4F7F\u3044\u307E\u305B\u3093\u3002router \u306F\u81EA\u5206\u306E\u76F4\u5F8C\u306E\u8981\u7D20\u3060\u3051\u3092 outlet \u3068\u3057\u3066\u4F7F\u3044\u3001\u305D\u3053\u306B <wcs-outlet> \u304C\u7121\u3051\u308C\u3070\u81EA\u524D\u306E outlet \u3092\u4F5C\u308A\u307E\u3059\u3002\u30EB\u30FC\u30C8\u306F router \u306E\u76F4\u5F8C\u306B\u63CF\u304B\u308C\u3001\u3053\u306E outlet \u306F\u7A7A\u306E\u307E\u307E\u3067\u3059 \u2014 <wcs-router> \u306E\u76F4\u5F8C\u3078\u79FB\u3057\u3066\u304F\u3060\u3055\u3044`,
|
|
11044
11360
|
signalsDualEntry: () => `@wcstack/signals \u3068 @wcstack/signals/dom \u304C\u540C\u4E00\u30DA\u30FC\u30B8\u304B\u3089 import \u3055\u308C\u3066\u3044\u307E\u3059\u3002CDN \u3067\u306F\u5404\u30A8\u30F3\u30C8\u30EA\u304C\u81EA\u5DF1\u5B8C\u7D50\u30D0\u30F3\u30C9\u30EB\u306E\u305F\u3081\u30EA\u30A2\u30AF\u30C6\u30A3\u30D6\u30B3\u30A2\u304C\u4E8C\u91CD\u5316\u3057\u3001\u5883\u754C\u3067\u53CD\u5FDC\u304C\u58CA\u308C\u307E\u3059 \u2014 \u3059\u3079\u3066 /dom \u30A8\u30F3\u30C8\u30EA\u304B\u3089 import \u3057\u3066\u304F\u3060\u3055\u3044`,
|
|
11361
|
+
signalsImportMapBoth: () => `\u3053\u306E import map \u306F @wcstack/signals \u3068 @wcstack/signals/dom \u306E\u4E21\u65B9\u3092\u5272\u308A\u5F53\u3066\u3066\u3044\u307E\u3059\u3002CDN \u3067\u306F\u5404\u30A8\u30F3\u30C8\u30EA\u304C\u30EA\u30A2\u30AF\u30C6\u30A3\u30D6\u30B3\u30A2\u3092\u6301\u3064\u306E\u3067\u3001@wcstack/signals \u3092 import \u3059\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\uFF08\u3053\u306E\u30DA\u30FC\u30B8\u306E\u3082\u306E\u3067\u3082\u3001\u8AAD\u307F\u8FBC\u3080 .js \u3067\u3082\uFF09\u304C 2 \u3064\u76EE\u306E\u30B3\u30A2\u3092\u6301\u3061\u3001\u5883\u754C\u3067\u53CD\u5FDC\u304C\u58CA\u308C\u307E\u3059\u3002@wcstack/signals/dom \u3060\u3051\u3092\u5272\u308A\u5F53\u3066\u3066\u304F\u3060\u3055\u3044\uFF08\u30B3\u30A2\u306E\u5168\u90E8\u3092 export \u3057\u307E\u3059\uFF09`,
|
|
11362
|
+
routeBareMustache: (inLayout) => inLayout ? `\u30EC\u30A4\u30A2\u30A6\u30C8\u306E\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u306E\u76F4\u4E0B\u306E\u30C6\u30AD\u30B9\u30C8\u306E {{ }} \u306F\u3001\u9077\u79FB\u3067\u306F\u675F\u306D\u3089\u308C\u307E\u305B\u3093 \u2014 \u8981\u7D20\u3067\u5305\u3093\u3067\u304F\u3060\u3055\u3044\uFF08<span>{{ \u2026 }}</span>\uFF09` : `<wcs-route> \u306E\u76F4\u4E0B\u306E\u30C6\u30AD\u30B9\u30C8\u306E {{ }} \u306F\u3001\u6700\u521D\u306B\u7740\u3044\u305F\u30EB\u30FC\u30C8\u3067\u3057\u304B\u675F\u306D\u3089\u308C\u307E\u305B\u3093\u3002\u9077\u79FB\u3067\u5165\u3063\u305F\u30EB\u30FC\u30C8\u3067\u306F\u66F8\u3044\u305F\u307E\u307E\u306E\u6587\u5B57\u304C\u51FA\u307E\u3059 \u2014 \u8981\u7D20\u3067\u5305\u3093\u3067\u304F\u3060\u3055\u3044\uFF08<h1>{{ \u2026 }}</h1>\uFF09`,
|
|
11363
|
+
layoutSlotMissing: (l) => `\u30EC\u30A4\u30A2\u30A6\u30C8 "${l}" \u306E\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u306B\u65E2\u5B9A\u306E <slot>\uFF08name \u306E\u7121\u3044\u3082\u306E\uFF09\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u3053\u306E <wcs-layout> \u306E\u540D\u524D\u4ED8\u304D\u30B9\u30ED\u30C3\u30C8\u306E\u5916\u306E\u4E2D\u8EAB\uFF08\u5165\u308C\u5B50\u306E\u30EB\u30FC\u30C8\u3068\u305D\u306E\u30DA\u30FC\u30B8\uFF09\u306F\u8868\u793A\u3055\u308C\u307E\u305B\u3093 \u2014 \u30DA\u30FC\u30B8\u3092\u7F6E\u304F\u5834\u6240\u306B <slot></slot> \u3092\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`,
|
|
11045
11364
|
namedStateAttrDeprecated: (name) => `name \u5C5E\u6027\u306F v2 \u3067\u64A4\u53BB\u3055\u308C\u307E\u3057\u305F\uFF081 root 1 \u30C4\u30EA\u30FC\uFF09\u3002\u30EB\u30FC\u30C8\u30C4\u30EA\u30FC\u3078\u306E\u30DE\u30A6\u30F3\u30C8 <wcs-state mount="${name}"> \u306B\u7F6E\u304D\u63DB\u3048\u3001\u30D1\u30B9\u306F "${name}.<path>" \u3067\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\uFF08docs/state-mount-design.md \xA79\uFF09`,
|
|
11046
11365
|
namedStatePathDeprecated: (name) => name === "default" ? `"@default" \u30BB\u30EC\u30AF\u30BF\u306F v2 \u3067\u64A4\u53BB\u3055\u308C\u307E\u3057\u305F\u3002"@default" \u3092\u5916\u3057\u3066\u304F\u3060\u3055\u3044\uFF08docs/state-mount-design.md \xA79\uFF09` : `"@name" \u30BB\u30EC\u30AF\u30BF\u306F v2 \u3067\u64A4\u53BB\u3055\u308C\u307E\u3057\u305F\uFF081 root 1 \u30C4\u30EA\u30FC\uFF09\u3002\u30DE\u30A6\u30F3\u30C8\u3057\u305F\u30C4\u30EA\u30FC\u3092 "${name}.<path>" \u3067\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\uFF08docs/state-mount-design.md \xA79\uFF09`,
|
|
11047
11366
|
mountPathInvalid: (problem, mountPath) => {
|
|
11048
11367
|
switch (problem) {
|
|
11049
11368
|
case "empty":
|
|
11050
|
-
return `"mount" \u306B\u306F\u7A7A\u3067\u306A\u3044\
|
|
11369
|
+
return `"mount" \u306B\u306F\u7A7A\u3067\u306A\u3044\u9759\u7684\u306A\u30D1\u30B9\u304C\u5FC5\u8981\u3067\u3059\uFF08\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u30DC\u30EA\u30E5\u30FC\u30E0\u3092\u62D2\u307F\u307E\u3059: has an invalid mount path\uFF09`;
|
|
11051
11370
|
case "emptySegment":
|
|
11052
|
-
return `"mount" \u30D1\u30B9 "${mountPath}" \u306B\u7A7A\u306E\
|
|
11371
|
+
return `"mount" \u30D1\u30B9 "${mountPath}" \u306B\u7A7A\u306E\u6BB5\u304C\u3042\u308A\u307E\u3059\uFF08\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u30DC\u30EA\u30E5\u30FC\u30E0\u3092\u62D2\u307F\u307E\u3059: has an invalid mount path\uFF09`;
|
|
11053
11372
|
case "wildcard":
|
|
11054
|
-
return `"mount" \u30D1\u30B9 "${mountPath}" \u306F\u9759\u7684\u3067\u306A\u3051\u308C\u3070\u306A\u308A\u307E\u305B\u3093 \u2014 \
|
|
11373
|
+
return `"mount" \u30D1\u30B9 "${mountPath}" \u306F\u9759\u7684\u3067\u306A\u3051\u308C\u3070\u306A\u308A\u307E\u305B\u3093 \u2014 "*" \u306F\u4F7F\u3048\u307E\u305B\u3093\uFF08\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u30DC\u30EA\u30E5\u30FC\u30E0\u3092\u62D2\u307F\u307E\u3059: has an invalid mount path\uFF09`;
|
|
11374
|
+
case "whitespace":
|
|
11375
|
+
return `"mount" \u30D1\u30B9 "${mountPath}" \u306B\u7A7A\u767D\u306F\u4F7F\u3048\u307E\u305B\u3093\uFF08\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u30DC\u30EA\u30E5\u30FC\u30E0\u3092\u62D2\u307F\u307E\u3059: has an invalid mount path\uFF09`;
|
|
11055
11376
|
default:
|
|
11056
|
-
return `"mount" \u30D1\u30B9 "${mountPath}" \u306B\u4E88\u7D04\u6587\u5B57\uFF08$, #, @\uFF09\u306F\u4F7F\u3048\u307E\u305B\u3093\
|
|
11377
|
+
return `"mount" \u30D1\u30B9 "${mountPath}" \u306B\u4E88\u7D04\u6587\u5B57\uFF08$, #, @\uFF09\u306F\u4F7F\u3048\u307E\u305B\u3093\uFF08\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u30DC\u30EA\u30E5\u30FC\u30E0\u3092\u62D2\u307F\u307E\u3059: has an invalid mount path\uFF09`;
|
|
11057
11378
|
}
|
|
11058
11379
|
},
|
|
11059
11380
|
recursionUnsupported: (p, where) => {
|
|
@@ -11075,7 +11396,7 @@ var ja = {
|
|
|
11075
11396
|
case "listKeys":
|
|
11076
11397
|
return `$listKeys \u306E\u30AD\u30FC "${p}" \u306B "**" \u306F\u4F7F\u3048\u307E\u305B\u3093\u3002\u30AD\u30FC\u4ED8\u304D\u30EA\u30B9\u30C8\u306F 1 \u672C\u306E\u5177\u4F53\u30EA\u30B9\u30C8\u30D1\u30B9\u3067\u3059 \u2014 \u6DF1\u3055\u3054\u3068\u306B\u5BA3\u8A00\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: "nodes.*.children"\uFF09`;
|
|
11077
11398
|
default:
|
|
11078
|
-
return `"${p}" \u306F "**" \u3092\u542B\u307F\u307E\u3059\u304C\u3001\u3053\u306E state \u306B\u306F $recursion \u5BA3\u8A00\u304C\u3042\u308A\u307E\u305B\u3093\u3002$recursion = { "<anchor>": "<repeat>" }\uFF08\u4F8B: { "nodes.*": "children.*" }\uFF09\u3092\u5BA3\u8A00\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u5BA3\u8A00\u304C\u7121\u3044\u3068
|
|
11399
|
+
return `"${p}" \u306F "**" \u3092\u542B\u307F\u307E\u3059\u304C\u3001\u3053\u306E state \u306B\u306F $recursion \u5BA3\u8A00\u304C\u3042\u308A\u307E\u305B\u3093\u3002$recursion = { "<anchor>": "<repeat>" }\uFF08\u4F8B: { "nodes.*": "children.*" }\uFF09\u3092\u5BA3\u8A00\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u5BA3\u8A00\u304C\u7121\u3044\u3068\u3001\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u8AAD\u307F\u8FBC\u307F\u6642\u306B #1101 \u3067 throw \u3057\u3001state \u306F\u521D\u671F\u5316\u306B\u5931\u6557\u3057\u307E\u3059\uFF09`;
|
|
11079
11400
|
}
|
|
11080
11401
|
},
|
|
11081
11402
|
recursionAnchorMismatch: (p, anchor) => `"${p}" \u306F\u5BA3\u8A00\u6E08\u307F\u306E\u518D\u5E30\u30A2\u30F3\u30AB\u30FC "${anchor}" \u3068\u5408\u81F4\u3057\u307E\u305B\u3093\uFF08\u521D\u7248\u306F state \u3054\u3068\u306B 1 \u3064\u306E\u81EA\u5DF1\u518D\u5E30\u306E\u307F\u3002"**" \u306E\u5F8C\u308D\u306F\u6574\u5F62\u3055\u308C\u305F\u63A5\u5C3E\u8F9E \u2014 2 \u3064\u76EE\u306E "**"\u30FB\u7A7A\u30BB\u30B0\u30E1\u30F3\u30C8\u30FB"**" \u76F4\u5F8C\u306E\u7D20\u306E "*" \u306F\u7F6E\u3051\u307E\u305B\u3093\uFF09`,
|
|
@@ -11175,6 +11496,8 @@ var en = {
|
|
|
11175
11496
|
getterCycle: (cycle) => `Path getters form a dependency cycle: ${cycle}`,
|
|
11176
11497
|
updatedCallbackUnbound: (p) => `$renderedCallback is binding-driven. "${p}" is not bound anywhere in this document, so this branch never runs. Use $watch to react without depending on what is rendered`,
|
|
11177
11498
|
onHandlerThis: (name) => `The $on handler "${name}" uses this. A $on handler receives the state as its first argument (\`${name}(state, event) { state.x = \u2026 }\`) and this is undefined, so this.\u2026 throws when it is called \u2014 unlike $watch handlers and methods`,
|
|
11499
|
+
getterReadsLocation: (read) => `This getter reads ${read}, which is not state: it keeps the URL it first read (a navigation does not re-evaluate it). Read the URL through state \u2014 bind <wcs-router>'s path / searchParams`,
|
|
11500
|
+
submitWithoutPrevent: (h) => `onsubmit has no #prevent and "${h}" does not call preventDefault, so the browser submits the form too: the page reloads, or with the router a GET puts the fields (a password too) in the URL and the history. Write onsubmit#prevent: ${h}, or call event.preventDefault() in the handler`,
|
|
11178
11501
|
getterUntrackedRead: (root, sp) => `Only "${root}" is tracked here: the getter is not re-evaluated when "${sp}" changes (plain property access after a path read is not tracked). Read this["${sp}"] instead`,
|
|
11179
11502
|
handlerFilterNotAllowed: (prop) => `Filters cannot be applied to event handler "${prop}"`,
|
|
11180
11503
|
typeExpectation: (label, expected, resultType) => `"${label}" requires ${EN_EXPECTED_LABEL[expected]} (current type: ${resultType})`,
|
|
@@ -11194,13 +11517,15 @@ var en = {
|
|
|
11194
11517
|
watchKeyEmptySegment: (k) => `$watch key "${k}" has an empty path segment`,
|
|
11195
11518
|
watchHandlerNotFunction: (k) => `The value of $watch entry "${k}" must be a function`,
|
|
11196
11519
|
watchPathMissing: (k) => `$watch key "${k}" does not exist in the state definition (it will never fire)`,
|
|
11197
|
-
scanRemoved: (mountPath) => mountPath === null ? `$scan was removed in 4.0 (the
|
|
11520
|
+
scanRemoved: (mountPath) => mountPath === null ? `$scan was removed in 4.0 (the entries with the diagnostics add-on, such as /auto, throw at load; /core alone ignores it). Fold a path's changes in a $watch handler, or events in an $on handler, and write the output property there` : `$scan was removed in 4.0. In a volume (mount="${mountPath}") the runtime refuses to graft it and reports that with console.error (this state is not on the tree). Fold in a $watch or $on handler on the root state`,
|
|
11198
11521
|
typeAnnotationIncompatible: (vt, rt) => `Type "${vt}" is not compatible with @type {${rt}}`,
|
|
11199
11522
|
arrayMutation: (m, alt) => `Destructive array method "${m}" does not trigger a reactive update (re-assigning the same reference does not reflect added/removed elements either). Use a non-destructive method with reassignment (e.g. ${alt}).`,
|
|
11200
11523
|
arrayIndexAssign: (sp) => `Assigning directly to an array index does not trigger a reactive update. Use a dot-path assignment like this["${sp}"], or with() plus reassignment.`,
|
|
11201
|
-
|
|
11524
|
+
inPlaceAlias: (a, src, t) => `"${a}" is ${src} \u2014 the state's own value. A change through it does not trigger a reactive update, and writing the same value back does not add, remove or replace a list's rows. Build a new value and assign it to ${t} (${a}.with(i, item), [...${a}, item], { ...${a}, key: value })`,
|
|
11525
|
+
inPlaceChange: (src, t) => `${src} changes the state's value in place, which does not trigger a reactive update. Build a new value and assign it to ${t}`,
|
|
11526
|
+
tagMemberUnknown: (prop, tag) => `"${prop}" is not a wcBindable member of <${tag}> (the runtime refuses a binding to an undeclared member with #38; at the root the state fails to initialize)`,
|
|
11202
11527
|
nameAlias: (written, canonical) => `"${written}" was removed in 4.0 (the 3.x old name of "${canonical}"; the runtime throws when it is read) \u2014 write "${canonical}"`,
|
|
11203
|
-
declarationAliasRead: (alias, canonical) => `"${alias}" is a declaration key 4.0 removed (the 3.x old name of "${canonical}"), so this["${alias}"] is undefined.
|
|
11528
|
+
declarationAliasRead: (alias, canonical) => `"${alias}" is a declaration key 4.0 removed (the 3.x old name of "${canonical}"), so this["${alias}"] is undefined. A declaration cannot be read through this \u2014 reading "${canonical}" is undefined too${canonical === "$stream" ? " (read a stream's state from $streamStatus / $streamError)" : ""}`,
|
|
11204
11529
|
declarationAlias: (alias, canonical) => `The declaration key "${alias}" was removed in 4.0 (the 3.x old name of "${canonical}"; the runtime throws at load time) \u2014 write "${canonical}"`,
|
|
11205
11530
|
declarationAliasInVolume: (alias, canonical, mountPath) => `The declaration key "${alias}" was removed in 4.0 (the 3.x old name of "${canonical}"). In a volume (mount="${mountPath}") the runtime refuses to graft it and reports that with console.error (this state is not on the tree). "${canonical}" cannot be declared in a volume either \u2014 declare it on the root state`,
|
|
11206
11531
|
behaviorNotObject: (keys) => `$behavior must be an object { ${keys.map((k) => `${k}?`).join(", ")} } (the runtime throws at load time)`,
|
|
@@ -11230,22 +11555,27 @@ var en = {
|
|
|
11230
11555
|
storagePairClobber: (path) => `The <wcs-storage> value is bound to the accessor pair "${path}" without #init=element. The state's side goes first, so on every load the getter's starting value is saved over the stored one, and the setter never receives it \u2014 add #init=element (\`value#init=element: ${path}\`)`,
|
|
11231
11556
|
inputNestedWrite: (tag, input, path, example) => `"${path}" is bound to the input "${input}" of <${tag}>, but the page writes below it ("${example}"). A binding is re-applied only when "${path}" itself is assigned, so those writes never reach <${tag}> \u2014 bind a getter that reads the fields by path (\`this["${example}"]\`, \`$getAll\`) and returns a new value, or replace "${path}" instead of writing below it`,
|
|
11232
11557
|
inputNestedWriteOneShot: (tag, input, path, example) => `"${path}" is bound to the input "${input}" of <${tag}>, but the page writes below it ("${example}"). A binding is re-applied only when "${path}" itself is assigned, and <${tag}> resets "${input}" to null after every request, so the next request goes without it \u2014 build a new object in the handler that starts the request (\`this.submitBody = { \u2026 }\`) and bind that`,
|
|
11233
|
-
devtoolsAfterState: () => `Load @wcstack/devtools/auto
|
|
11558
|
+
devtoolsAfterState: () => `Load @wcstack/devtools/auto before @wcstack/state/auto (loaded later, the DevTools timeline starts when it attaches; 4.0 sends it the wiring that is there already)`,
|
|
11234
11559
|
baseHrefMissing: () => `An SPA using @wcstack/router needs <base href="/"> in <head> (without it, deep links misderive the basename)`,
|
|
11235
11560
|
routerOutletMisplaced: () => `This <wcs-outlet> is not right after a <wcs-router>, so no router uses it: a router uses only the element right after it as its outlet, and makes an outlet of its own there when that is not a <wcs-outlet>. The routes render right after the router and this outlet stays empty \u2014 move it right after the <wcs-router>`,
|
|
11236
11561
|
signalsDualEntry: () => `Both @wcstack/signals and @wcstack/signals/dom are imported on this page. On a CDN each entry is a self-contained bundle, so the reactive core is duplicated and reactivity breaks at the seam \u2014 import everything from the single /dom entry`,
|
|
11562
|
+
signalsImportMapBoth: () => `This import map maps both @wcstack/signals and @wcstack/signals/dom. On a CDN each entry carries its own reactive core, so a module that imports @wcstack/signals \u2014 this page's, or a .js file it loads \u2014 gets a second core and reactivity breaks at the seam. Map only @wcstack/signals/dom (it exports the whole core)`,
|
|
11563
|
+
routeBareMustache: (inLayout) => inLayout ? `{{ }} in text directly under a layout template is not bound on a navigation. Wrap it in an element (<span>{{ \u2026 }}</span>)` : `{{ }} in text directly under <wcs-route> is bound only on the landing route: a route entered by navigation shows it as written. Wrap it in an element (<h1>{{ \u2026 }}</h1>)`,
|
|
11564
|
+
layoutSlotMissing: (l) => `The template of layout "${l}" has no default <slot> (one without a name), so what this <wcs-layout> holds outside the named slots \u2014 the nested routes and their pages \u2014 is not shown. Put a <slot></slot> where the page goes`,
|
|
11237
11565
|
namedStateAttrDeprecated: (name) => `The "name" attribute was removed in v2 \u2014 there is a single state tree per root. Mount this state onto the tree instead: <wcs-state mount="${name}"> and read it as "${name}.<path>" (docs/state-mount-design.md \xA79)`,
|
|
11238
11566
|
namedStatePathDeprecated: (name) => name === "default" ? `The "@default" selector was removed in v2 \u2014 drop it (docs/state-mount-design.md \xA79)` : `The "@name" selector was removed in v2 \u2014 there is a single state tree. Mount the named state onto the tree (<wcs-state mount="...">) and read it as "${name}.<path>" (docs/state-mount-design.md \xA79)`,
|
|
11239
11567
|
mountPathInvalid: (problem, mountPath) => {
|
|
11240
11568
|
switch (problem) {
|
|
11241
11569
|
case "empty":
|
|
11242
|
-
return `"mount"
|
|
11570
|
+
return `"mount" needs a non-empty static path (the runtime refuses the volume: "has an invalid mount path").`;
|
|
11243
11571
|
case "emptySegment":
|
|
11244
|
-
return `"mount" path "${mountPath}" has an empty segment.`;
|
|
11572
|
+
return `"mount" path "${mountPath}" has an empty segment (the runtime refuses the volume: "has an invalid mount path").`;
|
|
11245
11573
|
case "wildcard":
|
|
11246
|
-
return `"mount" path "${mountPath}" must be static (
|
|
11574
|
+
return `"mount" path "${mountPath}" must be static \u2014 no "*" (the runtime refuses the volume: "has an invalid mount path").`;
|
|
11575
|
+
case "whitespace":
|
|
11576
|
+
return `"mount" path "${mountPath}" must not contain whitespace (the runtime refuses the volume: "has an invalid mount path").`;
|
|
11247
11577
|
default:
|
|
11248
|
-
return `"mount" path "${mountPath}" must not use reserved characters
|
|
11578
|
+
return `"mount" path "${mountPath}" must not use the reserved characters $, #, @ (the runtime refuses the volume: "has an invalid mount path").`;
|
|
11249
11579
|
}
|
|
11250
11580
|
},
|
|
11251
11581
|
recursionUnsupported: (p, where) => {
|
|
@@ -11267,7 +11597,7 @@ var en = {
|
|
|
11267
11597
|
case "listKeys":
|
|
11268
11598
|
return `$listKeys key "${p}" cannot contain "**" \u2014 a keyed list is one concrete list path. Declare the key per depth instead (for example "nodes.*.children")`;
|
|
11269
11599
|
default:
|
|
11270
|
-
return `"${p}" contains "**" but this state declares no $recursion anchor. Declare $recursion = { "<anchor>": "<repeat>" } (for example { "nodes.*": "children.*" }) \u2014 without it
|
|
11600
|
+
return `"${p}" contains "**" but this state declares no $recursion anchor. Declare $recursion = { "<anchor>": "<repeat>" } (for example { "nodes.*": "children.*" }) \u2014 without it the runtime throws #1101 at load and the state fails to initialize`;
|
|
11271
11601
|
}
|
|
11272
11602
|
},
|
|
11273
11603
|
recursionAnchorMismatch: (p, anchor) => `"${p}" does not match the declared recursion anchor "${anchor}" (this version supports exactly one self-recursive anchor per state, and "**" must be followed by a well-formed suffix: no second "**", no empty segment, no bare "*" right after "**")`,
|
|
@@ -11456,6 +11786,19 @@ var DELEGATED_EVENTS = /* @__PURE__ */ new Set([
|
|
|
11456
11786
|
var CUSTOM_ELEMENT_OWN_EVENTS = /* @__PURE__ */ new Set(["input", "change", "submit"]);
|
|
11457
11787
|
function collectCurrentTargetHandlers(elements, html, fileReader) {
|
|
11458
11788
|
const names = /* @__PURE__ */ new Set();
|
|
11789
|
+
forEachStateMethod(elements, html, fileReader, "currentTarget", (name, params, body) => {
|
|
11790
|
+
if (readsEventCurrentTarget(params, body)) names.add(name);
|
|
11791
|
+
});
|
|
11792
|
+
return names;
|
|
11793
|
+
}
|
|
11794
|
+
function collectPreventDefaultHandlers(elements, html, fileReader) {
|
|
11795
|
+
const handlers = /* @__PURE__ */ new Map();
|
|
11796
|
+
forEachStateMethod(elements, html, fileReader, null, (name, _params, body) => {
|
|
11797
|
+
handlers.set(name, /\bpreventDefault\b/.test(body));
|
|
11798
|
+
});
|
|
11799
|
+
return handlers;
|
|
11800
|
+
}
|
|
11801
|
+
function forEachStateMethod(elements, html, fileReader, spelling, fn) {
|
|
11459
11802
|
let insideTemplate = null;
|
|
11460
11803
|
for (const element2 of elements) {
|
|
11461
11804
|
if (element2.bindComponent) continue;
|
|
@@ -11465,20 +11808,19 @@ function collectCurrentTargetHandlers(elements, html, fileReader) {
|
|
|
11465
11808
|
const script = readStateScript(element2.srcAttr, fileReader);
|
|
11466
11809
|
if (script !== void 0) scripts = [script];
|
|
11467
11810
|
}
|
|
11468
|
-
scripts = scripts.filter((script) => script.includes(
|
|
11811
|
+
if (spelling !== null) scripts = scripts.filter((script) => script.includes(spelling));
|
|
11469
11812
|
if (scripts.length === 0) continue;
|
|
11470
11813
|
if ((insideTemplate ??= createTemplateTester(html))(element2.tagStart)) continue;
|
|
11471
11814
|
for (const script of scripts) {
|
|
11472
11815
|
for (const callable of analyzeCallableBodies(script)) {
|
|
11473
|
-
if (callable.kind !== "method" || !callable.body.includes(
|
|
11816
|
+
if (callable.kind !== "method" || spelling !== null && !callable.body.includes(spelling)) continue;
|
|
11474
11817
|
const head = script.slice(callable.end, callable.bodyStart - 1);
|
|
11475
11818
|
const params = /\(([^)]*)\)\s*$/.exec(head);
|
|
11476
11819
|
if (params === null) continue;
|
|
11477
|
-
|
|
11820
|
+
fn(volume === null ? callable.name : `${volume}.${callable.name}`, params[1], callable.body);
|
|
11478
11821
|
}
|
|
11479
11822
|
}
|
|
11480
11823
|
}
|
|
11481
|
-
return names;
|
|
11482
11824
|
}
|
|
11483
11825
|
function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, fileReader, applicationSchema) {
|
|
11484
11826
|
const diagnostics = [];
|
|
@@ -11486,11 +11828,6 @@ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, f
|
|
|
11486
11828
|
const pathIndex = getStatePathIndex(html, stateTagName, fileReader);
|
|
11487
11829
|
const statePaths = mergeSchemaCandidates(pathIndex.paths, applicationSchema);
|
|
11488
11830
|
const attrs = findAllBindAttributes(html, attrName);
|
|
11489
|
-
let structuralTemplates = null;
|
|
11490
|
-
const getStructuralTemplates = () => {
|
|
11491
|
-
structuralTemplates ??= collectStructuralTemplates(html, attrName);
|
|
11492
|
-
return structuralTemplates;
|
|
11493
|
-
};
|
|
11494
11831
|
const outerCandidates = [];
|
|
11495
11832
|
const currentTargetCandidates = [];
|
|
11496
11833
|
let currentTargetHandlers = null;
|
|
@@ -11498,6 +11835,11 @@ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, f
|
|
|
11498
11835
|
currentTargetHandlers ??= collectCurrentTargetHandlers(pathIndex.elements, html, fileReader);
|
|
11499
11836
|
return currentTargetHandlers;
|
|
11500
11837
|
};
|
|
11838
|
+
let preventDefaultHandlers = null;
|
|
11839
|
+
const getPreventDefaultHandlers = () => {
|
|
11840
|
+
preventDefaultHandlers ??= collectPreventDefaultHandlers(pathIndex.elements, html, fileReader);
|
|
11841
|
+
return preventDefaultHandlers;
|
|
11842
|
+
};
|
|
11501
11843
|
for (const attr of attrs) {
|
|
11502
11844
|
const bindings = splitBindingExpressions(attr.value);
|
|
11503
11845
|
const nonEmptyCount = bindings.filter((b) => b.trim().length > 0).length;
|
|
@@ -11559,6 +11901,15 @@ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, f
|
|
|
11559
11901
|
const eventName = propNoMod.slice(2);
|
|
11560
11902
|
const handler = parsed.path.trim();
|
|
11561
11903
|
const modifiers = modifiersOf(parsed.property);
|
|
11904
|
+
if (eventName === "submit" && attr.tagName === "form" && !modifiers.includes("prevent") && getPreventDefaultHandlers().get(handler) === false && !/\saction\s*=/i.test(openTagBefore(html, attr.valueStart))) {
|
|
11905
|
+
diagnostics.push({
|
|
11906
|
+
code: WcsDiagnosticCode.SubmitWithoutPrevent,
|
|
11907
|
+
start: bindingStart + leadingSpace,
|
|
11908
|
+
end: bindingStart + leadingSpace + propNoMod.length,
|
|
11909
|
+
message: msgs.submitWithoutPrevent(handler),
|
|
11910
|
+
severity: "warning"
|
|
11911
|
+
});
|
|
11912
|
+
}
|
|
11562
11913
|
if (DELEGATED_EVENTS.has(eventName) && !modifiers.includes(DIRECT_MODIFIER) && attr.tagName !== void 0 && !(attr.tagName.includes("-") && CUSTOM_ELEMENT_OWN_EVENTS.has(eventName)) && /^[A-Za-z_][\w$]*(?:\.[A-Za-z_][\w$]*)*$/.test(handler) && getCurrentTargetHandlers().has(handler)) {
|
|
11563
11914
|
currentTargetCandidates.push({
|
|
11564
11915
|
offset: attr.valueStart,
|
|
@@ -11636,7 +11987,8 @@ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, f
|
|
|
11636
11987
|
start: pathStart,
|
|
11637
11988
|
end: pathStart + tokenPath.length,
|
|
11638
11989
|
message: msgs.commandRhsFormat(),
|
|
11639
|
-
|
|
11990
|
+
// ランタイムは束縛の計画で #1201 として throw し、root では初期化が失敗する
|
|
11991
|
+
severity: "error"
|
|
11640
11992
|
});
|
|
11641
11993
|
} else if (commandNames.size > 0 && !commandNames.has(tokenPath)) {
|
|
11642
11994
|
diagnostics.push({
|
|
@@ -11644,7 +11996,9 @@ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, f
|
|
|
11644
11996
|
start: pathStart,
|
|
11645
11997
|
end: pathStart + tokenPath.length,
|
|
11646
11998
|
message: msgs.commandTokenUndeclared(tokenPath),
|
|
11647
|
-
|
|
11999
|
+
// ランタイムは取り付けで #1302 として throw し、root では初期化が失敗する
|
|
12000
|
+
// (eventToken. と `on*: $command.x` はイベントのたびに #1301 を記録するだけなので warning のまま)
|
|
12001
|
+
severity: "error"
|
|
11648
12002
|
});
|
|
11649
12003
|
}
|
|
11650
12004
|
}
|
|
@@ -11814,10 +12168,7 @@ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, f
|
|
|
11814
12168
|
const typePath = candidateKeyOf(pathTrimmed, (c) => scopedPathSet.has(c));
|
|
11815
12169
|
const resultType = resolveResultType(typePath, parsed.filters, scopedPaths);
|
|
11816
12170
|
if (resultType !== null) {
|
|
11817
|
-
const typeReq = getExpectedType(
|
|
11818
|
-
parsed.property,
|
|
11819
|
-
() => isNegatedByElseChain(getStructuralTemplates(), attr.valueStart)
|
|
11820
|
-
);
|
|
12171
|
+
const typeReq = getExpectedType(parsed.property);
|
|
11821
12172
|
if (typeReq && resultType !== typeReq.expected) {
|
|
11822
12173
|
const pathOffset = binding.indexOf(parsed.path);
|
|
11823
12174
|
const pathStart = bindingStart + pathOffset;
|
|
@@ -11867,6 +12218,10 @@ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, f
|
|
|
11867
12218
|
}
|
|
11868
12219
|
return diagnostics;
|
|
11869
12220
|
}
|
|
12221
|
+
function openTagBefore(html, valueStart) {
|
|
12222
|
+
const lt2 = html.lastIndexOf("<", valueStart);
|
|
12223
|
+
return lt2 === -1 ? "" : html.slice(lt2, valueStart);
|
|
12224
|
+
}
|
|
11870
12225
|
function findAllBindAttributes(html, attrName) {
|
|
11871
12226
|
const attrs = [];
|
|
11872
12227
|
const escaped = attrName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -11971,14 +12326,16 @@ function validateFilterUsage(filter, bindingStart, msgs) {
|
|
|
11971
12326
|
for (let i = 0; i < Math.min(argCount, info.argTypes.length); i++) {
|
|
11972
12327
|
const expectedArgType = info.argTypes[i];
|
|
11973
12328
|
if (expectedArgType === "any") continue;
|
|
11974
|
-
const
|
|
11975
|
-
|
|
12329
|
+
const arg = filter.args[i];
|
|
12330
|
+
const numericFails = expectedArgType === "number" && !readsAsNumber(arg);
|
|
12331
|
+
const actualArgType = inferArgType(arg);
|
|
12332
|
+
if (expectedArgType === "number" ? numericFails : actualArgType !== expectedArgType) {
|
|
11976
12333
|
diagnostics.push({
|
|
11977
12334
|
code: WcsDiagnosticCode.FilterArgType,
|
|
11978
12335
|
start: bindingStart + filter.argsOffset,
|
|
11979
12336
|
end: bindingStart + filter.argsOffset + filter.name.length,
|
|
11980
|
-
message: msgs.filterArgType(filter.name, i + 1, expectedArgType,
|
|
11981
|
-
severity: "warning"
|
|
12337
|
+
message: msgs.filterArgType(filter.name, i + 1, expectedArgType, arg, actualArgType),
|
|
12338
|
+
severity: numericFails ? "error" : "warning"
|
|
11982
12339
|
});
|
|
11983
12340
|
}
|
|
11984
12341
|
}
|
|
@@ -12043,57 +12400,11 @@ function validateSchemaPathExistence(checkPath, displayPath, scopedPaths, scoped
|
|
|
12043
12400
|
}
|
|
12044
12401
|
return null;
|
|
12045
12402
|
}
|
|
12046
|
-
function
|
|
12047
|
-
const escaped = attrName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
12048
|
-
const attrRegex = new RegExp(`${escaped}\\s*=\\s*(["'])`, "i");
|
|
12049
|
-
const tagRegex = /<template(?:\s[^>]*)?>|<\/template\s*>/gi;
|
|
12050
|
-
const templates = [];
|
|
12051
|
-
let depth = 0;
|
|
12052
|
-
let match;
|
|
12053
|
-
while ((match = tagRegex.exec(html)) !== null) {
|
|
12054
|
-
if (match[0].startsWith("</")) {
|
|
12055
|
-
depth = Math.max(0, depth - 1);
|
|
12056
|
-
continue;
|
|
12057
|
-
}
|
|
12058
|
-
const attrMatch = attrRegex.exec(match[0]);
|
|
12059
|
-
if (attrMatch) {
|
|
12060
|
-
const quote = attrMatch[1];
|
|
12061
|
-
const valueStart = match.index + attrMatch.index + attrMatch[0].length;
|
|
12062
|
-
const valueEnd = html.indexOf(quote, valueStart);
|
|
12063
|
-
if (valueEnd !== -1) {
|
|
12064
|
-
const first = splitBindingExpressions(html.slice(valueStart, valueEnd))[0] ?? "";
|
|
12065
|
-
const firstColon = indexOfOutsideQuotes2(first, ":");
|
|
12066
|
-
const prop = (firstColon === -1 ? first : first.slice(0, firstColon)).replace(/#.*$/, "").trim();
|
|
12067
|
-
const type = prop === "if" || prop === "elseif" || prop === "else" ? prop : "other";
|
|
12068
|
-
templates.push({ valueStart, depth, type });
|
|
12069
|
-
}
|
|
12070
|
-
}
|
|
12071
|
-
depth++;
|
|
12072
|
-
}
|
|
12073
|
-
return templates;
|
|
12074
|
-
}
|
|
12075
|
-
function isNegatedByElseChain(templates, valueStart) {
|
|
12076
|
-
const index = templates.findIndex((t) => t.valueStart === valueStart);
|
|
12077
|
-
if (index === -1) return false;
|
|
12078
|
-
const selfDepth = templates[index].depth;
|
|
12079
|
-
for (let i = index + 1; i < templates.length; i++) {
|
|
12080
|
-
const next = templates[i];
|
|
12081
|
-
if (next.depth > selfDepth) continue;
|
|
12082
|
-
if (next.depth < selfDepth) return false;
|
|
12083
|
-
if (next.type === "elseif" || next.type === "else") return true;
|
|
12084
|
-
if (next.type === "if") return false;
|
|
12085
|
-
}
|
|
12086
|
-
return false;
|
|
12087
|
-
}
|
|
12088
|
-
function getExpectedType(property, isNegatedIf) {
|
|
12403
|
+
function getExpectedType(property) {
|
|
12089
12404
|
const prop = property.replace(/#.*$/, "");
|
|
12090
12405
|
if (prop === "for") {
|
|
12091
12406
|
return { label: "for", expected: "array", severity: "error" };
|
|
12092
12407
|
}
|
|
12093
|
-
if (prop === "if" || prop === "elseif") {
|
|
12094
|
-
if (!isNegatedIf()) return null;
|
|
12095
|
-
return { label: prop, expected: "boolean", severity: "warning" };
|
|
12096
|
-
}
|
|
12097
12408
|
if (prop.startsWith("class.")) {
|
|
12098
12409
|
return { label: prop, expected: "boolean", severity: "warning" };
|
|
12099
12410
|
}
|
|
@@ -12149,6 +12460,10 @@ function inferArgType(arg) {
|
|
|
12149
12460
|
if (/^-?\d+(\.\d+)?$/.test(v)) return "number";
|
|
12150
12461
|
return "string";
|
|
12151
12462
|
}
|
|
12463
|
+
function readsAsNumber(arg) {
|
|
12464
|
+
const v = arg.trim().replace(/^(["'])([\s\S]*)\1$/, "$2");
|
|
12465
|
+
return v !== "" && !Number.isNaN(Number(v));
|
|
12466
|
+
}
|
|
12152
12467
|
function isLiteral(value) {
|
|
12153
12468
|
return /^-?\d/.test(value) || /^["'`]/.test(value) || value === "true" || value === "false" || value === "null";
|
|
12154
12469
|
}
|
|
@@ -14073,20 +14388,7 @@ var BUILTIN_TAGS = {
|
|
|
14073
14388
|
};
|
|
14074
14389
|
|
|
14075
14390
|
// src/service/ioNodeValidator.ts
|
|
14076
|
-
var
|
|
14077
|
-
"textContent",
|
|
14078
|
-
"innerHTML",
|
|
14079
|
-
"innerText",
|
|
14080
|
-
"hidden",
|
|
14081
|
-
"title",
|
|
14082
|
-
"id",
|
|
14083
|
-
"slot",
|
|
14084
|
-
"dir",
|
|
14085
|
-
"lang",
|
|
14086
|
-
"role",
|
|
14087
|
-
"tabIndex",
|
|
14088
|
-
"className"
|
|
14089
|
-
]);
|
|
14391
|
+
var HTML_SINK_PROPERTIES = /* @__PURE__ */ new Set(["html", "innerHTML", "outerHTML", "srcdoc"]);
|
|
14090
14392
|
var STRUCTURAL_DIRECTIVES3 = /* @__PURE__ */ new Set(["for", "if", "elseif", "else"]);
|
|
14091
14393
|
var EXPLICIT_PROPERTY_REJECTED_HEADS2 = /* @__PURE__ */ new Set([
|
|
14092
14394
|
...Object.values(getWcsManifest().syntax.bindingTypes.propNamespaces),
|
|
@@ -14188,7 +14490,7 @@ function validateBindingAgainstContract(tagName, contract, parsed, property, sta
|
|
|
14188
14490
|
code: WcsDiagnosticCode.TagMemberUnknown,
|
|
14189
14491
|
start,
|
|
14190
14492
|
end,
|
|
14191
|
-
severity: "
|
|
14493
|
+
severity: "error",
|
|
14192
14494
|
tag: tagName,
|
|
14193
14495
|
member: name,
|
|
14194
14496
|
message: msgs.tagCommandUnknown(name, tagName, contract.commands.join(", ") || msgs.none()) + suggestion(name, contract.commands, msgs)
|
|
@@ -14203,7 +14505,7 @@ function validateBindingAgainstContract(tagName, contract, parsed, property, sta
|
|
|
14203
14505
|
code: WcsDiagnosticCode.TagMemberUnknown,
|
|
14204
14506
|
start,
|
|
14205
14507
|
end,
|
|
14206
|
-
severity: "
|
|
14508
|
+
severity: "error",
|
|
14207
14509
|
tag: tagName,
|
|
14208
14510
|
member: name,
|
|
14209
14511
|
message: msgs.tagEventTokenKeyUnknown(name, tagName, contract.properties.join(", ")) + suggestion(name, contract.properties, msgs)
|
|
@@ -14211,13 +14513,13 @@ function validateBindingAgainstContract(tagName, contract, parsed, property, sta
|
|
|
14211
14513
|
}
|
|
14212
14514
|
return;
|
|
14213
14515
|
}
|
|
14214
|
-
if (!contract.properties.includes(property) && !(property in contract.inputs) && !
|
|
14516
|
+
if (!contract.properties.includes(property) && !(property in contract.inputs) && !HTML_SINK_PROPERTIES.has(property)) {
|
|
14215
14517
|
const members = [...contract.properties, ...inputNames];
|
|
14216
14518
|
diagnostics.push({
|
|
14217
14519
|
code: WcsDiagnosticCode.TagMemberUnknown,
|
|
14218
14520
|
start,
|
|
14219
14521
|
end,
|
|
14220
|
-
severity: "
|
|
14522
|
+
severity: "error",
|
|
14221
14523
|
tag: tagName,
|
|
14222
14524
|
member: property,
|
|
14223
14525
|
message: msgs.tagMemberUnknown(property, tagName) + suggestion(property, members, msgs)
|
|
@@ -14422,7 +14724,7 @@ function validateDocumentEnv(html, locale2) {
|
|
|
14422
14724
|
code: WcsDiagnosticCode.ScriptOrder,
|
|
14423
14725
|
start: later.start,
|
|
14424
14726
|
end: later.end,
|
|
14425
|
-
severity: "
|
|
14727
|
+
severity: "info",
|
|
14426
14728
|
message: msgs.devtoolsAfterState()
|
|
14427
14729
|
});
|
|
14428
14730
|
}
|
|
@@ -14459,9 +14761,63 @@ function validateDocumentEnv(html, locale2) {
|
|
|
14459
14761
|
severity: "error",
|
|
14460
14762
|
message: msgs.signalsDualEntry()
|
|
14461
14763
|
});
|
|
14764
|
+
} else {
|
|
14765
|
+
const both = findSignalsImportMapBoth(scanText);
|
|
14766
|
+
if (both) {
|
|
14767
|
+
diagnostics.push({
|
|
14768
|
+
code: WcsDiagnosticCode.SignalsDualEntry,
|
|
14769
|
+
start: both.start,
|
|
14770
|
+
end: both.end,
|
|
14771
|
+
severity: "warning",
|
|
14772
|
+
message: msgs.signalsImportMapBoth()
|
|
14773
|
+
});
|
|
14774
|
+
}
|
|
14775
|
+
}
|
|
14776
|
+
const structure = scanStructure(scanText);
|
|
14777
|
+
for (const at2 of structure.bareMustaches) {
|
|
14778
|
+
diagnostics.push({
|
|
14779
|
+
code: WcsDiagnosticCode.RouteBareMustache,
|
|
14780
|
+
start: at2.start,
|
|
14781
|
+
end: at2.end,
|
|
14782
|
+
severity: "warning",
|
|
14783
|
+
message: msgs.routeBareMustache(at2.inLayout)
|
|
14784
|
+
});
|
|
14785
|
+
}
|
|
14786
|
+
for (const layout of structure.layoutsWithoutDefaultSlot) {
|
|
14787
|
+
diagnostics.push({
|
|
14788
|
+
code: WcsDiagnosticCode.LayoutSlotMissing,
|
|
14789
|
+
start: layout.start,
|
|
14790
|
+
end: layout.end,
|
|
14791
|
+
severity: "warning",
|
|
14792
|
+
message: msgs.layoutSlotMissing(layout.id)
|
|
14793
|
+
});
|
|
14462
14794
|
}
|
|
14463
14795
|
return diagnostics;
|
|
14464
14796
|
}
|
|
14797
|
+
function findSignalsImportMapBoth(html) {
|
|
14798
|
+
const mapRegex = /<script\b((?:"[^"]*"|'[^']*'|[^>"'])*)>([\s\S]*?)<\/script\s*>/gi;
|
|
14799
|
+
let match;
|
|
14800
|
+
while ((match = mapRegex.exec(html)) !== null) {
|
|
14801
|
+
if (!/\btype\s*=\s*(["'])importmap\1/i.test(match[1])) continue;
|
|
14802
|
+
let imports;
|
|
14803
|
+
try {
|
|
14804
|
+
imports = JSON.parse(match[2]).imports;
|
|
14805
|
+
} catch {
|
|
14806
|
+
continue;
|
|
14807
|
+
}
|
|
14808
|
+
if (imports === null || typeof imports !== "object") continue;
|
|
14809
|
+
const core = imports["@wcstack/signals"];
|
|
14810
|
+
const dom = imports["@wcstack/signals/dom"] ?? imports["@wcstack/signals/"];
|
|
14811
|
+
if (typeof core !== "string" || typeof dom !== "string") continue;
|
|
14812
|
+
if (core.includes("/dist/") && dom.includes("/dist/")) continue;
|
|
14813
|
+
const key = '"@wcstack/signals"';
|
|
14814
|
+
const at2 = match[2].indexOf(key);
|
|
14815
|
+
const bodyStart = match.index + match[0].indexOf(">") + 1;
|
|
14816
|
+
const start = bodyStart + (at2 === -1 ? 0 : at2 + 1);
|
|
14817
|
+
return { start, end: start + key.length - 2 };
|
|
14818
|
+
}
|
|
14819
|
+
return null;
|
|
14820
|
+
}
|
|
14465
14821
|
var SCOPED_AUTO = /@wcstack\/([a-z0-9-]+)(?:@[^/"'\s]+)?\/(?:auto\b|dist\/(?:split\/)?auto(?:\.min)?\.js\b)/;
|
|
14466
14822
|
var BUNDLE_AUTO = /(?:^|\/)wcstack(?:@[^/"'\s]+)?\/(?:auto\b|dist\/auto\.min\.js\b)/;
|
|
14467
14823
|
var BUNDLE_PACKAGES = ["state", "router", "fetch", "storage", "autoloader"];
|
|
@@ -14540,6 +14896,88 @@ function blankHtmlComments(html) {
|
|
|
14540
14896
|
function blankJsComments(code) {
|
|
14541
14897
|
return code.replace(/\/\*[\s\S]*?\*\//g, (m) => " ".repeat(m.length)).replace(/(^|[^:])\/\/[^\n]*/g, (m, pre) => pre + " ".repeat(m.length - pre.length));
|
|
14542
14898
|
}
|
|
14899
|
+
var VOID_TAGS = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "source", "track", "wbr"]);
|
|
14900
|
+
var ROUTE_TAG = "wcs-route";
|
|
14901
|
+
var LAYOUT_TAG2 = "wcs-layout";
|
|
14902
|
+
function attrValue(attrs, name) {
|
|
14903
|
+
const m = new RegExp(`(?:^|\\s)${name}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s>]+))`, "i").exec(attrs);
|
|
14904
|
+
return m === null ? null : m[1] ?? m[2] ?? m[3] ?? "";
|
|
14905
|
+
}
|
|
14906
|
+
function scanStructure(html) {
|
|
14907
|
+
const scan = html.replace(
|
|
14908
|
+
/(<(script|style)\b[^>]*>)([\s\S]*?)(<\/\2\s*>)/gi,
|
|
14909
|
+
(_m, open, _name, body, close) => open + " ".repeat(body.length) + close
|
|
14910
|
+
);
|
|
14911
|
+
const tagRegex = /<(\/?)([a-zA-Z][\w-]*)((?:"[^"]*"|'[^']*'|[^>"'])*)>/g;
|
|
14912
|
+
const layoutIds = /* @__PURE__ */ new Set();
|
|
14913
|
+
for (const m of scan.matchAll(/<wcs-layout\b((?:"[^"]*"|'[^']*'|[^>"'])*)>/gi)) {
|
|
14914
|
+
const id = attrValue(m[1], "layout");
|
|
14915
|
+
if (id !== null && id !== "") layoutIds.add(id);
|
|
14916
|
+
}
|
|
14917
|
+
const bareMustaches = [];
|
|
14918
|
+
const layouts = [];
|
|
14919
|
+
const templateHasDefaultSlot = /* @__PURE__ */ new Map();
|
|
14920
|
+
const stack = [];
|
|
14921
|
+
let last = 0;
|
|
14922
|
+
let match;
|
|
14923
|
+
const text3 = (from, to) => {
|
|
14924
|
+
const top = stack[stack.length - 1];
|
|
14925
|
+
if (top === void 0 || to <= from) return;
|
|
14926
|
+
const chunk = scan.slice(from, to);
|
|
14927
|
+
if (top.name === LAYOUT_TAG2 && chunk.trim() !== "") top.unslotted = true;
|
|
14928
|
+
if (top.name !== ROUTE_TAG && !top.layoutTemplate) return;
|
|
14929
|
+
for (const m of chunk.matchAll(/\{\{[\s\S]*?\}\}/g)) {
|
|
14930
|
+
bareMustaches.push({ start: from + m.index, end: from + m.index + m[0].length, inLayout: top.layoutTemplate });
|
|
14931
|
+
}
|
|
14932
|
+
};
|
|
14933
|
+
while ((match = tagRegex.exec(scan)) !== null) {
|
|
14934
|
+
text3(last, match.index);
|
|
14935
|
+
last = match.index + match[0].length;
|
|
14936
|
+
const name = match[2].toLowerCase();
|
|
14937
|
+
const nameStart = match.index + 1 + match[1].length;
|
|
14938
|
+
if (match[1] === "/") {
|
|
14939
|
+
const at2 = stack.map((e) => e.name).lastIndexOf(name);
|
|
14940
|
+
if (at2 === -1) continue;
|
|
14941
|
+
for (const closed of stack.splice(at2)) {
|
|
14942
|
+
if (closed.name === LAYOUT_TAG2 && closed.unslotted && closed.layoutId !== void 0) {
|
|
14943
|
+
layouts.push({ start: closed.nameStart, end: closed.nameEnd, id: closed.layoutId });
|
|
14944
|
+
}
|
|
14945
|
+
}
|
|
14946
|
+
continue;
|
|
14947
|
+
}
|
|
14948
|
+
const attrs = match[3];
|
|
14949
|
+
const parent = stack[stack.length - 1];
|
|
14950
|
+
if (parent?.name === LAYOUT_TAG2 && !attrValue(attrs, "slot")) parent.unslotted = true;
|
|
14951
|
+
for (const open of stack) {
|
|
14952
|
+
if (open.layoutTemplate && name === "slot" && !attrValue(attrs, "name")) templateHasDefaultSlot.set(open.layoutId, true);
|
|
14953
|
+
}
|
|
14954
|
+
if (VOID_TAGS.has(name) || /\/\s*$/.test(attrs)) continue;
|
|
14955
|
+
const id = name === "template" ? attrValue(attrs, "id") : null;
|
|
14956
|
+
const element2 = {
|
|
14957
|
+
name,
|
|
14958
|
+
layoutTemplate: id !== null && layoutIds.has(id),
|
|
14959
|
+
nameStart,
|
|
14960
|
+
nameEnd: nameStart + match[2].length
|
|
14961
|
+
};
|
|
14962
|
+
if (element2.layoutTemplate) {
|
|
14963
|
+
element2.layoutId = id;
|
|
14964
|
+
if (!templateHasDefaultSlot.has(id)) templateHasDefaultSlot.set(id, false);
|
|
14965
|
+
}
|
|
14966
|
+
if (name === LAYOUT_TAG2 && attrValue(attrs, "src") === null) {
|
|
14967
|
+
const layoutId = attrValue(attrs, "layout");
|
|
14968
|
+
if (layoutId !== null && layoutId !== "") element2.layoutId = layoutId;
|
|
14969
|
+
}
|
|
14970
|
+
stack.push(element2);
|
|
14971
|
+
}
|
|
14972
|
+
text3(last, scan.length);
|
|
14973
|
+
for (const closed of stack) {
|
|
14974
|
+
if (closed.name === LAYOUT_TAG2 && closed.unslotted && closed.layoutId !== void 0) {
|
|
14975
|
+
layouts.push({ start: closed.nameStart, end: closed.nameEnd, id: closed.layoutId });
|
|
14976
|
+
}
|
|
14977
|
+
}
|
|
14978
|
+
const layoutsWithoutDefaultSlot = layouts.filter((l) => templateHasDefaultSlot.get(l.id) === false);
|
|
14979
|
+
return { bareMustaches, layoutsWithoutDefaultSlot };
|
|
14980
|
+
}
|
|
14543
14981
|
var ROUTER_TAG2 = "wcs-router";
|
|
14544
14982
|
var OUTLET_TAG = "wcs-outlet";
|
|
14545
14983
|
function findMisplacedOutlets(html) {
|
|
@@ -14982,7 +15420,7 @@ function validateRecursiveGetters(script, offset2, spec, undeclared, msgs, out)
|
|
|
14982
15420
|
start,
|
|
14983
15421
|
end,
|
|
14984
15422
|
msgs.recursionUnsupported(span.name, "undeclared"),
|
|
14985
|
-
"
|
|
15423
|
+
"error"
|
|
14986
15424
|
);
|
|
14987
15425
|
}
|
|
14988
15426
|
continue;
|
|
@@ -15506,7 +15944,8 @@ function findMountPathProblem(mountPath) {
|
|
|
15506
15944
|
if (mountPath.length === 0) return "empty";
|
|
15507
15945
|
for (const segment of mountPath.split(".")) {
|
|
15508
15946
|
if (segment.length === 0) return "emptySegment";
|
|
15509
|
-
if (segment
|
|
15947
|
+
if (segment.includes("*")) return "wildcard";
|
|
15948
|
+
if (/\s/.test(segment)) return "whitespace";
|
|
15510
15949
|
if (segment.includes("$") || segment.includes("#") || segment.includes("@")) return "reserved";
|
|
15511
15950
|
}
|
|
15512
15951
|
return null;
|
|
@@ -15878,7 +16317,7 @@ function validateIndexArity(script, scriptStart, locale2) {
|
|
|
15878
16317
|
start: scriptStart + parsed.starts[1] + leading,
|
|
15879
16318
|
end: scriptStart + parsed.starts[1] + argText.trimEnd().length,
|
|
15880
16319
|
message: msgs.indexArity(api, path, requirement, wildcardCount, actual),
|
|
15881
|
-
severity: "
|
|
16320
|
+
severity: "error"
|
|
15882
16321
|
});
|
|
15883
16322
|
}
|
|
15884
16323
|
return out;
|
|
@@ -15934,7 +16373,7 @@ function validateGetterCycles(script, scriptStart, locale2) {
|
|
|
15934
16373
|
start: scriptStart + getter.start,
|
|
15935
16374
|
end: scriptStart + getter.end,
|
|
15936
16375
|
message: msgs.getterCycle(cycle),
|
|
15937
|
-
severity: "
|
|
16376
|
+
severity: "error"
|
|
15938
16377
|
});
|
|
15939
16378
|
}
|
|
15940
16379
|
return out;
|
|
@@ -15969,6 +16408,54 @@ function validateGetterUntrackedReads(script, scriptStart, nestedWriteRoots, loc
|
|
|
15969
16408
|
}
|
|
15970
16409
|
return out;
|
|
15971
16410
|
}
|
|
16411
|
+
function validateGetterLocationReads(script, scriptStart, locale2) {
|
|
16412
|
+
if (!script.includes("location")) return [];
|
|
16413
|
+
const msgs = getMessages(locale2);
|
|
16414
|
+
const out = [];
|
|
16415
|
+
for (const getter of analyzeCallableBodies(script)) {
|
|
16416
|
+
if (getter.kind !== "getter" || getter.accessor !== "get" || !getter.body.includes("location")) continue;
|
|
16417
|
+
const read = findLocationRead(getter.body);
|
|
16418
|
+
if (read === null) continue;
|
|
16419
|
+
out.push({
|
|
16420
|
+
code: WcsDiagnosticCode.GetterUntrackedRead,
|
|
16421
|
+
start: scriptStart + getter.bodyStart + read.start,
|
|
16422
|
+
end: scriptStart + getter.bodyStart + read.end,
|
|
16423
|
+
message: msgs.getterReadsLocation(read.text),
|
|
16424
|
+
severity: "warning"
|
|
16425
|
+
});
|
|
16426
|
+
}
|
|
16427
|
+
return out;
|
|
16428
|
+
}
|
|
16429
|
+
function onHandlerStateParam(script, handler) {
|
|
16430
|
+
if (handler.kind === "body") {
|
|
16431
|
+
const head = script.slice(Math.max(0, handler.start - 400), handler.start);
|
|
16432
|
+
return /\(\s*([A-Za-z_$][\w$]*)[^()]*\)\s*\{\s*$/.exec(head)?.[1] ?? null;
|
|
16433
|
+
}
|
|
16434
|
+
return /^\s*(?:async\s+)?(?:function\b[^(]*\(\s*([A-Za-z_$][\w$]*)|\(\s*([A-Za-z_$][\w$]*)|([A-Za-z_$][\w$]*)\s*=>)/.exec(handler.text)?.slice(1).find((name) => name !== void 0) ?? null;
|
|
16435
|
+
}
|
|
16436
|
+
function validateInPlaceChanges(script, scriptStart, locale2) {
|
|
16437
|
+
const msgs = getMessages(locale2);
|
|
16438
|
+
const out = [];
|
|
16439
|
+
const push3 = (text3, kind, textStart, root) => {
|
|
16440
|
+
for (const change of findInPlaceChanges(text3, kind, root)) {
|
|
16441
|
+
out.push({
|
|
16442
|
+
code: change.form === "method" ? WcsDiagnosticCode.ArrayMutation : change.form === "index" ? WcsDiagnosticCode.ArrayIndexAssign : WcsDiagnosticCode.NestedAssign,
|
|
16443
|
+
start: scriptStart + textStart + change.start,
|
|
16444
|
+
end: scriptStart + textStart + change.end,
|
|
16445
|
+
severity: "error",
|
|
16446
|
+
message: change.alias !== null ? msgs.inPlaceAlias(change.alias, change.source, change.target) : msgs.inPlaceChange(change.source, change.target)
|
|
16447
|
+
});
|
|
16448
|
+
}
|
|
16449
|
+
};
|
|
16450
|
+
for (const callable of analyzeCallableBodies(script)) push3(callable.body, "body", callable.bodyStart, "this");
|
|
16451
|
+
for (const handler of analyzeWatchHandlerSources(script)) push3(handler.text, handler.kind, handler.start, "this");
|
|
16452
|
+
for (const handler of analyzeOnHandlerSources(script)) {
|
|
16453
|
+
const root = handler.kind === "body" ? onHandlerStateParam(script, handler) : null;
|
|
16454
|
+
if (handler.kind === "body" && root === null) continue;
|
|
16455
|
+
push3(handler.text, handler.kind, handler.start, root);
|
|
16456
|
+
}
|
|
16457
|
+
return out;
|
|
16458
|
+
}
|
|
15972
16459
|
var NESTED_WRITE_INPUTS = {
|
|
15973
16460
|
"wcs-storage": { inputs: ["value"], exemptWhenManual: true },
|
|
15974
16461
|
"wcs-fetch": { inputs: ["body"], exemptWhenManual: false, oneShot: true }
|
|
@@ -15998,7 +16485,7 @@ function validateInputNestedWrites(html, stateTagName, bindAttrName, nestedWrite
|
|
|
15998
16485
|
code: WcsDiagnosticCode.InputNestedWrite,
|
|
15999
16486
|
start: occ.pathRange.start,
|
|
16000
16487
|
end: occ.pathRange.end,
|
|
16001
|
-
severity: "
|
|
16488
|
+
severity: "error",
|
|
16002
16489
|
tag: tag.tagName,
|
|
16003
16490
|
statePath: occ.path,
|
|
16004
16491
|
message
|
|
@@ -16080,6 +16567,26 @@ function collectNestedWriteRoots(html, stateTagName, bindAttrName, blocks) {
|
|
|
16080
16567
|
if (path !== null) addPrefixes(path, false);
|
|
16081
16568
|
}
|
|
16082
16569
|
}
|
|
16570
|
+
for (const handler of analyzeOnHandlerSources(block.content)) {
|
|
16571
|
+
const param = onHandlerStateParam(block.content, handler);
|
|
16572
|
+
if (param === null) continue;
|
|
16573
|
+
const name = param.replace(/\$/g, "\\$");
|
|
16574
|
+
const region = { start: handler.start, end: handler.start + handler.text.length };
|
|
16575
|
+
const bracket = `\\b${name}\\s*(?:\\?\\.)?\\s*\\[\\s*["']([^"']+)["']\\s*\\]`;
|
|
16576
|
+
const template = `\\b${name}\\s*(?:\\?\\.)?\\s*\\[\\s*\`([^\`]*)\`` + String.raw`\s*\]`;
|
|
16577
|
+
for (const [pattern, quote] of [[bracket, /["']/], [template, /`/]]) {
|
|
16578
|
+
for (const regex of [new RegExp(`${pattern}${ASSIGN_TAIL}`, "g"), new RegExp(`${PRE_INCDEC}${pattern}`, "g")]) {
|
|
16579
|
+
let match;
|
|
16580
|
+
const part = scan.slice(region.start, region.end);
|
|
16581
|
+
while ((match = regex.exec(part)) !== null) {
|
|
16582
|
+
const keyStart = region.start + match.index + match[0].search(quote) + 1;
|
|
16583
|
+
const raw = block.content.slice(keyStart, keyStart + match[1].length);
|
|
16584
|
+
const path = quote.source === "`" ? templateKeyPath(raw) : raw;
|
|
16585
|
+
if (path !== null) addPrefixes(path, false);
|
|
16586
|
+
}
|
|
16587
|
+
}
|
|
16588
|
+
}
|
|
16589
|
+
}
|
|
16083
16590
|
API_CALL.lastIndex = 0;
|
|
16084
16591
|
let call;
|
|
16085
16592
|
while ((call = API_CALL.exec(scan)) !== null) {
|
|
@@ -16210,7 +16717,9 @@ function validateSemantics(html, stateTagName = "wcs-state", locale2, bindAttrNa
|
|
|
16210
16717
|
out.push(...validateIndexParamReads(block.content, block.contentStart, locale2));
|
|
16211
16718
|
out.push(...validateGetterCycles(block.content, block.contentStart, locale2));
|
|
16212
16719
|
out.push(...validateGetterUntrackedReads(block.content, block.contentStart, getNestedWriteRoots, locale2));
|
|
16720
|
+
out.push(...validateGetterLocationReads(block.content, block.contentStart, locale2));
|
|
16213
16721
|
out.push(...validateOnHandlerThis(block.content, block.contentStart, locale2));
|
|
16722
|
+
out.push(...validateInPlaceChanges(block.content, block.contentStart, locale2));
|
|
16214
16723
|
}
|
|
16215
16724
|
out.push(...validateInputNestedWrites(html, stateTagName, bindAttrName, getNestedWriteRoots, locale2));
|
|
16216
16725
|
out.push(...validateUpdatedCallbackDemand(html, stateTagName, bindAttrName, locale2));
|
|
@@ -16270,7 +16779,9 @@ function validateDocument(text3, options = {}) {
|
|
|
16270
16779
|
for (const d of validateNestedAssigns(text3, stateTagName, locale2)) {
|
|
16271
16780
|
out.push({ code: WcsDiagnosticCode.NestedAssign, start: d.start, end: d.end, message: d.message, severity: d.severity });
|
|
16272
16781
|
}
|
|
16273
|
-
|
|
16782
|
+
const ignored = findIgnoredRanges(text3, bindAttribute);
|
|
16783
|
+
const kept = ignored.length === 0 ? out : out.filter((d) => !ignored.some(([start, end]) => d.start >= start && d.start < end));
|
|
16784
|
+
return sortDiagnostics(kept);
|
|
16274
16785
|
}
|
|
16275
16786
|
// Annotate the CommonJS export names for ESM import in node:
|
|
16276
16787
|
0 && (module.exports = {
|