@wcstack/typescript 4.1.1 → 4.2.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 +541 -42
- package/dist/tsc-core.cjs +73 -34
- package/dist/wcs-schema.mjs +1 -1
- package/dist/wcs-tsc.mjs +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
package/dist/schema-core.cjs
CHANGED
|
@@ -166,6 +166,10 @@ var WcsDiagnosticCode = {
|
|
|
166
166
|
// ランタイムは何も報告しない(root は正しい値)ので lint の code。`#direct` か `event.target.closest(...)` を
|
|
167
167
|
// 案内する。読みが実行されない分岐にあることもあるので warning。
|
|
168
168
|
DelegatedCurrentTarget: "wcs/delegated-current-target",
|
|
169
|
+
// `<form data-wcs="onsubmit: login">` の `#prevent` 忘れ(ハンドラも preventDefault を呼ばない)。ブラウザが
|
|
170
|
+
// フォームも送る — ページが読み直されるか、router があれば GET が欄(パスワードも)を URL と履歴に載せる
|
|
171
|
+
// (docs/seam-apps.md、router-auth)。warning(action 付きのフォームと、読めないハンドラでは黙る)。
|
|
172
|
+
SubmitWithoutPrevent: "wcs/submit-without-prevent",
|
|
169
173
|
// 4.0 で外れた API の旧名(`this.$trackDependency` → `$dependOn`、`$untrackDependency` → `$untracked`)。
|
|
170
174
|
// ランタイムは読んだ時点で同じ code(#1701)で throw するので error。3.x(3.2〜3.3)では「動くが 4.0 で
|
|
171
175
|
// 外れる」info だった。フィルタの旧名(`uc` など)は 4.0 のランタイムと同じく `wcs/filter-unknown` で、
|
|
@@ -223,6 +227,13 @@ var WcsDiagnosticCode = {
|
|
|
223
227
|
RouterOutletMisplaced: "wcs/router-outlet-misplaced",
|
|
224
228
|
// @wcstack/signals と /dom エントリの同一ページ混在(リアクティブコア二重化)。
|
|
225
229
|
SignalsDualEntry: "wcs/signals-dual-entry",
|
|
230
|
+
// `<wcs-route>`(またはレイアウトのテンプレート)の直下のテキストの `{{ }}`。最初に着いたルートでしか束ねられず、
|
|
231
|
+
// 遷移で入ったルートでは書いたままの文字が出る(router の README「Where route content lives」— docs/seam-apps.md、
|
|
232
|
+
// router-admin)。warning。
|
|
233
|
+
RouteBareMustache: "wcs/route-bare-mustache",
|
|
234
|
+
// 既定の `<slot>` の無いレイアウトのテンプレートに、名前付きスロットの外の中身(入れ子のルート)を渡している。
|
|
235
|
+
// 中身は表示されない。ランタイムも同じ code で警告する(docs/seam-apps.md、router-admin)。warning。
|
|
236
|
+
LayoutSlotMissing: "wcs/layout-slot-missing",
|
|
226
237
|
// --- deprecations ---
|
|
227
238
|
// 名前付き State(`<wcs-state name>` / `path@name`)。v2 でマウント(`mount=` と接頭辞付きパス)に
|
|
228
239
|
// 置き換わる(docs/state-mount-design.md D16)。1.x では warning、v2 では parse error と同時に error。
|
|
@@ -821,7 +832,8 @@ var FORMATS_FILTER_NAMES = [
|
|
|
821
832
|
"coalesce",
|
|
822
833
|
"number",
|
|
823
834
|
"string",
|
|
824
|
-
"nullIfEmpty"
|
|
835
|
+
"nullIfEmpty",
|
|
836
|
+
"currency"
|
|
825
837
|
];
|
|
826
838
|
var definitions = /* @__PURE__ */ new Map();
|
|
827
839
|
function hasFilter(name) {
|
|
@@ -1038,6 +1050,8 @@ var codeOf = (id) => {
|
|
|
1038
1050
|
return c ? `[wcs/${c}] ` : "";
|
|
1039
1051
|
};
|
|
1040
1052
|
var MOVED = ["enableMustache", "sameValueGuard", "enableDirectionalInitialSync"];
|
|
1053
|
+
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)})`;
|
|
1054
|
+
var NAMESPACES = ["", "", "class.", "attr.", "style."];
|
|
1041
1055
|
var element = (tag, at2) => `<${tag}${at2.map((a, i) => i % 2 ? `="${a}"` : ` ${a}`).join("")}>`;
|
|
1042
1056
|
var CSP_GUIDE = "https://github.com/wcstack/wcstack/blob/main/docs/csp.md";
|
|
1043
1057
|
var SENTENCES = {
|
|
@@ -1089,10 +1103,11 @@ var SENTENCES = {
|
|
|
1089
1103
|
41
|
|
1090
1104
|
/* RenderChain */
|
|
1091
1105
|
]: () => `render chain depth limit exceeded (${MAX_RENDER_CHAIN} drains that rendering itself started); bindings for this batch were not applied.`,
|
|
1106
|
+
// (named as written — `textContent: iso`, `class.active: x` — when the binding has a member; else its type)
|
|
1092
1107
|
[
|
|
1093
1108
|
12
|
|
1094
1109
|
/* BindingFailed */
|
|
1095
|
-
]: (type, p) => `binding "${type}: ${p}" failed to apply.`,
|
|
1110
|
+
]: (type, p, name, kind) => `binding "${name ? (NAMESPACES[kind] ?? "") + name : type}: ${p}" failed to apply.`,
|
|
1096
1111
|
[
|
|
1097
1112
|
13
|
|
1098
1113
|
/* LoadFailed */
|
|
@@ -1164,11 +1179,19 @@ var SENTENCES = {
|
|
|
1164
1179
|
[
|
|
1165
1180
|
28
|
|
1166
1181
|
/* FilterValueNotNumber */
|
|
1167
|
-
]: (fn) => `filter ${fn} requires a number value`,
|
|
1182
|
+
]: (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
1183
|
[
|
|
1169
1184
|
29
|
|
1170
1185
|
/* FilterValueNotDate */
|
|
1171
|
-
]: (fn) => `filter ${fn} requires a date value`,
|
|
1186
|
+
]: (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)" : ""}`,
|
|
1187
|
+
[
|
|
1188
|
+
52
|
|
1189
|
+
/* FilterStyleInvalid */
|
|
1190
|
+
]: (fn, v) => `filter ${fn} takes a style of full, long, medium or short, not "${v}"`,
|
|
1191
|
+
[
|
|
1192
|
+
53
|
|
1193
|
+
/* FilterCurrencyInvalid */
|
|
1194
|
+
]: (v) => `filter currency takes an ISO 4217 currency code (JPY, USD, EUR), not "${v}"`,
|
|
1172
1195
|
[
|
|
1173
1196
|
30
|
|
1174
1197
|
/* FilterValueNotArray */
|
|
@@ -2108,11 +2131,17 @@ function optionsRequired(fnName) {
|
|
|
2108
2131
|
function optionMustBeNumber(fnName) {
|
|
2109
2132
|
raise2(27, [fnName]);
|
|
2110
2133
|
}
|
|
2111
|
-
function
|
|
2112
|
-
raise2(
|
|
2134
|
+
function styleInvalid(fnName, value) {
|
|
2135
|
+
raise2(52, [fnName, value]);
|
|
2136
|
+
}
|
|
2137
|
+
function currencyInvalid(value) {
|
|
2138
|
+
raise2(53, [value]);
|
|
2113
2139
|
}
|
|
2114
|
-
function
|
|
2115
|
-
raise2(
|
|
2140
|
+
function valueMustBeNumber(fnName, value) {
|
|
2141
|
+
raise2(28, [fnName, value]);
|
|
2142
|
+
}
|
|
2143
|
+
function valueMustBeDate(fnName, value) {
|
|
2144
|
+
raise2(29, [fnName, value]);
|
|
2116
2145
|
}
|
|
2117
2146
|
function valueMustBeArray(fnName) {
|
|
2118
2147
|
raise2(30, [fnName]);
|
|
@@ -2179,7 +2208,7 @@ var numeric = (name, op) => ({
|
|
|
2179
2208
|
const opt = requiredNumberOption(options, 0, name);
|
|
2180
2209
|
return (value) => {
|
|
2181
2210
|
if (typeof value !== "number") {
|
|
2182
|
-
valueMustBeNumber(name);
|
|
2211
|
+
valueMustBeNumber(name, value);
|
|
2183
2212
|
}
|
|
2184
2213
|
return op(value, opt);
|
|
2185
2214
|
};
|
|
@@ -2209,7 +2238,7 @@ var toFixed = (options) => {
|
|
|
2209
2238
|
const opt = numberOption(options?.[0] ?? "0", "toFixed");
|
|
2210
2239
|
return (value) => {
|
|
2211
2240
|
if (typeof value !== "number") {
|
|
2212
|
-
valueMustBeNumber("toFixed");
|
|
2241
|
+
valueMustBeNumber("toFixed", value);
|
|
2213
2242
|
}
|
|
2214
2243
|
return value.toFixed(opt);
|
|
2215
2244
|
};
|
|
@@ -2218,7 +2247,7 @@ var round = (options) => {
|
|
|
2218
2247
|
const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "round"));
|
|
2219
2248
|
return (value) => {
|
|
2220
2249
|
if (typeof value !== "number") {
|
|
2221
|
-
valueMustBeNumber("round");
|
|
2250
|
+
valueMustBeNumber("round", value);
|
|
2222
2251
|
}
|
|
2223
2252
|
return Math.round(value * optValue) / optValue;
|
|
2224
2253
|
};
|
|
@@ -2227,7 +2256,7 @@ var floor = (options) => {
|
|
|
2227
2256
|
const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "floor"));
|
|
2228
2257
|
return (value) => {
|
|
2229
2258
|
if (typeof value !== "number") {
|
|
2230
|
-
valueMustBeNumber("floor");
|
|
2259
|
+
valueMustBeNumber("floor", value);
|
|
2231
2260
|
}
|
|
2232
2261
|
return Math.floor(value * optValue) / optValue;
|
|
2233
2262
|
};
|
|
@@ -2236,7 +2265,7 @@ var ceil = (options) => {
|
|
|
2236
2265
|
const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "ceil"));
|
|
2237
2266
|
return (value) => {
|
|
2238
2267
|
if (typeof value !== "number") {
|
|
2239
|
-
valueMustBeNumber("ceil");
|
|
2268
|
+
valueMustBeNumber("ceil", value);
|
|
2240
2269
|
}
|
|
2241
2270
|
return Math.ceil(value * optValue) / optValue;
|
|
2242
2271
|
};
|
|
@@ -2245,7 +2274,7 @@ var percent = (options) => {
|
|
|
2245
2274
|
const opt = numberOption(options?.[0] ?? "0", "percent");
|
|
2246
2275
|
return (value) => {
|
|
2247
2276
|
if (typeof value !== "number") {
|
|
2248
|
-
valueMustBeNumber("percent");
|
|
2277
|
+
valueMustBeNumber("percent", value);
|
|
2249
2278
|
}
|
|
2250
2279
|
return `${(value * 100).toFixed(opt)}%`;
|
|
2251
2280
|
};
|
|
@@ -2272,11 +2301,29 @@ var locale = (options) => {
|
|
|
2272
2301
|
const explicit = options?.[0];
|
|
2273
2302
|
return (value) => {
|
|
2274
2303
|
if (typeof value !== "number") {
|
|
2275
|
-
valueMustBeNumber("locale");
|
|
2304
|
+
valueMustBeNumber("locale", value);
|
|
2276
2305
|
}
|
|
2277
2306
|
return value.toLocaleString(explicit ?? defaultLocale());
|
|
2278
2307
|
};
|
|
2279
2308
|
};
|
|
2309
|
+
var currency = (options) => {
|
|
2310
|
+
const code = options?.[0] ?? optionsRequired("currency");
|
|
2311
|
+
const explicit = options?.[1];
|
|
2312
|
+
const format = { style: "currency", currency: code };
|
|
2313
|
+
try {
|
|
2314
|
+
new Intl.NumberFormat("en", format);
|
|
2315
|
+
const known = Intl.supportedValuesOf?.("currency");
|
|
2316
|
+
if (known && !known.includes(code.toUpperCase())) throw 0;
|
|
2317
|
+
} catch {
|
|
2318
|
+
currencyInvalid(code);
|
|
2319
|
+
}
|
|
2320
|
+
return (value) => {
|
|
2321
|
+
if (typeof value !== "number") {
|
|
2322
|
+
valueMustBeNumber("currency", value);
|
|
2323
|
+
}
|
|
2324
|
+
return value.toLocaleString(explicit ?? defaultLocale(), format);
|
|
2325
|
+
};
|
|
2326
|
+
};
|
|
2280
2327
|
var upper = () => (value) => String(value).toUpperCase();
|
|
2281
2328
|
var lower = () => (value) => String(value).toLowerCase();
|
|
2282
2329
|
var capitalize = () => (value) => {
|
|
@@ -2333,38 +2380,48 @@ var join = (options) => {
|
|
|
2333
2380
|
return value.join(opt);
|
|
2334
2381
|
};
|
|
2335
2382
|
};
|
|
2383
|
+
var STYLES = ["full", "long", "medium", "short"];
|
|
2384
|
+
function dateOptions(options, fn) {
|
|
2385
|
+
let [loc, style] = options ?? [];
|
|
2386
|
+
if (style === void 0 && loc !== void 0 && STYLES.includes(loc)) [loc, style] = [void 0, loc];
|
|
2387
|
+
if (style !== void 0 && !STYLES.includes(style)) styleInvalid(fn, style);
|
|
2388
|
+
return [loc, style];
|
|
2389
|
+
}
|
|
2336
2390
|
var date = (options) => {
|
|
2337
|
-
const explicit = options
|
|
2391
|
+
const [explicit, style] = dateOptions(options, "date");
|
|
2392
|
+
const format = style && { dateStyle: style };
|
|
2338
2393
|
return (value) => {
|
|
2339
2394
|
if (!(value instanceof Date)) {
|
|
2340
|
-
valueMustBeDate("date");
|
|
2395
|
+
valueMustBeDate("date", value);
|
|
2341
2396
|
}
|
|
2342
|
-
return value.toLocaleDateString(explicit ?? defaultLocale());
|
|
2397
|
+
return value.toLocaleDateString(explicit ?? defaultLocale(), format);
|
|
2343
2398
|
};
|
|
2344
2399
|
};
|
|
2345
2400
|
var time = (options) => {
|
|
2346
|
-
const explicit = options
|
|
2401
|
+
const [explicit, style] = dateOptions(options, "time");
|
|
2402
|
+
const format = style && { timeStyle: style };
|
|
2347
2403
|
return (value) => {
|
|
2348
2404
|
if (!(value instanceof Date)) {
|
|
2349
|
-
valueMustBeDate("time");
|
|
2405
|
+
valueMustBeDate("time", value);
|
|
2350
2406
|
}
|
|
2351
|
-
return value.toLocaleTimeString(explicit ?? defaultLocale());
|
|
2407
|
+
return value.toLocaleTimeString(explicit ?? defaultLocale(), format);
|
|
2352
2408
|
};
|
|
2353
2409
|
};
|
|
2354
2410
|
var datetime = (options) => {
|
|
2355
|
-
const explicit = options
|
|
2411
|
+
const [explicit, style] = dateOptions(options, "datetime");
|
|
2412
|
+
const format = style && { dateStyle: style, timeStyle: style };
|
|
2356
2413
|
return (value) => {
|
|
2357
2414
|
if (!(value instanceof Date)) {
|
|
2358
|
-
valueMustBeDate("datetime");
|
|
2415
|
+
valueMustBeDate("datetime", value);
|
|
2359
2416
|
}
|
|
2360
|
-
return value.toLocaleString(explicit ?? defaultLocale());
|
|
2417
|
+
return value.toLocaleString(explicit ?? defaultLocale(), format);
|
|
2361
2418
|
};
|
|
2362
2419
|
};
|
|
2363
2420
|
var ymd = (options) => {
|
|
2364
2421
|
const opt = options?.[0] ?? "-";
|
|
2365
2422
|
return (value) => {
|
|
2366
2423
|
if (!(value instanceof Date)) {
|
|
2367
|
-
valueMustBeDate("ymd");
|
|
2424
|
+
valueMustBeDate("ymd", value);
|
|
2368
2425
|
}
|
|
2369
2426
|
const year = value.getFullYear().toString();
|
|
2370
2427
|
const month = (value.getMonth() + 1).toString().padStart(2, "0");
|
|
@@ -2376,7 +2433,7 @@ var hms = (options) => {
|
|
|
2376
2433
|
const opt = options?.[0] ?? ":";
|
|
2377
2434
|
return (value) => {
|
|
2378
2435
|
if (!(value instanceof Date)) {
|
|
2379
|
-
valueMustBeDate("hms");
|
|
2436
|
+
valueMustBeDate("hms", value);
|
|
2380
2437
|
}
|
|
2381
2438
|
const hours = value.getHours().toString().padStart(2, "0");
|
|
2382
2439
|
const minutes = value.getMinutes().toString().padStart(2, "0");
|
|
@@ -2386,7 +2443,7 @@ var hms = (options) => {
|
|
|
2386
2443
|
};
|
|
2387
2444
|
var abs = () => (value) => {
|
|
2388
2445
|
if (typeof value !== "number") {
|
|
2389
|
-
valueMustBeNumber("abs");
|
|
2446
|
+
valueMustBeNumber("abs", value);
|
|
2390
2447
|
}
|
|
2391
2448
|
return Math.abs(value);
|
|
2392
2449
|
};
|
|
@@ -2395,7 +2452,7 @@ var clamp = (options) => {
|
|
|
2395
2452
|
const max = requiredNumberOption(options, 1, "clamp");
|
|
2396
2453
|
return (value) => {
|
|
2397
2454
|
if (typeof value !== "number") {
|
|
2398
|
-
valueMustBeNumber("clamp");
|
|
2455
|
+
valueMustBeNumber("clamp", value);
|
|
2399
2456
|
}
|
|
2400
2457
|
return Math.min(Math.max(value, min), max);
|
|
2401
2458
|
};
|
|
@@ -2442,10 +2499,10 @@ var registered = {
|
|
|
2442
2499
|
ceil: { factory: ceil, arity: [0, 1] },
|
|
2443
2500
|
percent: { factory: percent, arity: [0, 1] },
|
|
2444
2501
|
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,
|
|
2502
|
+
// The locale-dependent three take a locale like `locale` does (`date(ja-JP)`), and a style (`date(ja-JP,long)`)
|
|
2503
|
+
date: { factory: date, arity: [0, 2] },
|
|
2504
|
+
time: { factory: time, arity: [0, 2] },
|
|
2505
|
+
datetime: { factory: datetime, arity: [0, 2] },
|
|
2449
2506
|
ymd: { factory: ymd, arity: [0, 1] },
|
|
2450
2507
|
hms: { factory: hms, arity: [0, 1] },
|
|
2451
2508
|
// 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 +2529,9 @@ var registered = {
|
|
|
2472
2529
|
boolean: boolean2,
|
|
2473
2530
|
number: { factory: number, arity: [0, 0] },
|
|
2474
2531
|
string: { factory: string, arity: [0, 0] },
|
|
2475
|
-
nullIfEmpty: { factory: nullIfEmpty, arity: [0, 0] }
|
|
2532
|
+
nullIfEmpty: { factory: nullIfEmpty, arity: [0, 0] },
|
|
2533
|
+
// (added in 4.2: last, so the order of the others is unchanged)
|
|
2534
|
+
currency: { factory: currency, arity: [1, 2] }
|
|
2476
2535
|
};
|
|
2477
2536
|
var formatFilters = /* @__PURE__ */ Object.fromEntries(
|
|
2478
2537
|
/* @__PURE__ */ Object.entries(registered).filter(([name]) => !(name in coreFilters))
|
|
@@ -2543,10 +2602,11 @@ var builtinFilterMeta = {
|
|
|
2543
2602
|
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
2603
|
// 日付・時刻
|
|
2545
2604
|
// `locale` と同じくロケールを 1 つ受ける(`date(ja-JP)`)。実装は最初からこれを読んでいたが、
|
|
2546
|
-
// メタデータ側が maxArgs: 0 だったため lint
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2605
|
+
// メタデータ側が maxArgs: 0 だったため lint と補完が正しい書き方を誤りとして報告していた。
|
|
2606
|
+
// 4.2: 2 つ目は書式(full / long / medium / short — Intl の dateStyle / timeStyle)。書式だけなら既定のロケール
|
|
2607
|
+
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"] },
|
|
2608
|
+
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"] },
|
|
2609
|
+
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
2610
|
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
2611
|
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
2612
|
// 真偽値・変換
|
|
@@ -2557,7 +2617,9 @@ var builtinFilterMeta = {
|
|
|
2557
2617
|
boolean: { description: "\u30D6\u30FC\u30EB\u5024\u306B\u5909\u63DB", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
2558
2618
|
number: { description: "\u6570\u5024\u306B\u5909\u63DB", hasArgs: false, resultType: "number", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
2559
2619
|
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 }
|
|
2620
|
+
nullIfEmpty: { description: "\u7A7A\u6587\u5B57\u5217\u3092null\u306B\u5909\u63DB", hasArgs: false, resultType: "passthrough", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
2621
|
+
// 4.2(formats の最後に登録)
|
|
2622
|
+
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
2623
|
};
|
|
2562
2624
|
var WCS_MANIFEST_VERSION = 2;
|
|
2563
2625
|
var builtinFilterAliases = Object.freeze({});
|
|
@@ -10943,6 +11005,193 @@ function findOwnThis(text3, kind) {
|
|
|
10943
11005
|
forEachChild(root, walk);
|
|
10944
11006
|
return found;
|
|
10945
11007
|
}
|
|
11008
|
+
var DESTRUCTIVE_ARRAY_METHODS = /* @__PURE__ */ new Set(["push", "pop", "shift", "unshift", "splice", "sort", "reverse", "fill", "copyWithin"]);
|
|
11009
|
+
function memberChain(node, source) {
|
|
11010
|
+
const segments = [];
|
|
11011
|
+
let cur = unwrapChain(node);
|
|
11012
|
+
while (cur.type === "MemberExpression") {
|
|
11013
|
+
const property = cur.property;
|
|
11014
|
+
let name = null;
|
|
11015
|
+
if (!cur.computed && property.type === "Identifier") name = property.name;
|
|
11016
|
+
else if (property.type === "Literal" && (typeof property.value === "string" || typeof property.value === "number")) name = String(property.value);
|
|
11017
|
+
segments.unshift({ name, raw: source(property), computed: cur.computed });
|
|
11018
|
+
cur = unwrapChain(cur.object);
|
|
11019
|
+
}
|
|
11020
|
+
return { base: cur, segments };
|
|
11021
|
+
}
|
|
11022
|
+
function assignTarget(root, segments) {
|
|
11023
|
+
if (segments.every((s) => s.name !== null)) {
|
|
11024
|
+
const path = segments.map((s) => s.name).join(".");
|
|
11025
|
+
return segments.length === 1 && /^[A-Za-z_$][\w$]*$/.test(path) ? `${root}.${path}` : `${root}["${path}"]`;
|
|
11026
|
+
}
|
|
11027
|
+
return `${root}[\`${segments.map((s) => s.name ?? `\${${s.raw}}`).join(".")}\`]`;
|
|
11028
|
+
}
|
|
11029
|
+
function findInPlaceChanges(text3, kind, root) {
|
|
11030
|
+
const prefix = kind === "body" ? PREFIX : VALUE_PREFIX;
|
|
11031
|
+
let program;
|
|
11032
|
+
try {
|
|
11033
|
+
program = parse3(prefix + text3 + (kind === "body" ? SUFFIX : VALUE_SUFFIX), { ecmaVersion: "latest", sourceType: "module" });
|
|
11034
|
+
} catch {
|
|
11035
|
+
return [];
|
|
11036
|
+
}
|
|
11037
|
+
const wrapper = unwrapWrapper(program);
|
|
11038
|
+
if (wrapper === null) return [];
|
|
11039
|
+
let body = wrapper.body;
|
|
11040
|
+
if (kind === "value") {
|
|
11041
|
+
const statement = wrapper.body.body.length === 1 ? wrapper.body.body[0] : null;
|
|
11042
|
+
const fn = statement?.type === "ExpressionStatement" ? statement.expression : null;
|
|
11043
|
+
if (fn === null || fn.type !== "FunctionExpression" && fn.type !== "ArrowFunctionExpression") return [];
|
|
11044
|
+
if (root === null) {
|
|
11045
|
+
const first = fn.params[0];
|
|
11046
|
+
if (first === void 0 || first.type !== "Identifier") return [];
|
|
11047
|
+
root = first.name;
|
|
11048
|
+
}
|
|
11049
|
+
body = fn.body;
|
|
11050
|
+
}
|
|
11051
|
+
if (root === null) return [];
|
|
11052
|
+
const stateRoot = root;
|
|
11053
|
+
const shift = prefix.length;
|
|
11054
|
+
const source = (n) => (prefix + text3).slice(n.start, n.end);
|
|
11055
|
+
const isRoot = (n) => stateRoot === "this" ? n.type === "ThisExpression" : n.type === "Identifier" && n.name === stateRoot;
|
|
11056
|
+
const bound = /* @__PURE__ */ new Map();
|
|
11057
|
+
const bind = (name) => {
|
|
11058
|
+
bound.set(name, (bound.get(name) ?? 0) + 1);
|
|
11059
|
+
};
|
|
11060
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
11061
|
+
const collect2 = (node) => {
|
|
11062
|
+
if (isFunctionNode(node)) {
|
|
11063
|
+
if (node.type === "FunctionDeclaration" && node.id !== null) bind(node.id.name);
|
|
11064
|
+
const names = /* @__PURE__ */ new Set();
|
|
11065
|
+
for (const param of node.params) bindingNames(param, names);
|
|
11066
|
+
names.forEach(bind);
|
|
11067
|
+
} else if (node.type === "VariableDeclarator") {
|
|
11068
|
+
const names = /* @__PURE__ */ new Set();
|
|
11069
|
+
bindingNames(node.id, names);
|
|
11070
|
+
names.forEach(bind);
|
|
11071
|
+
const init = node.init ? unwrapChain(node.init) : null;
|
|
11072
|
+
if (init !== null && node.id.type === "Identifier" && init.type === "MemberExpression") {
|
|
11073
|
+
const chain = memberChain(init, source);
|
|
11074
|
+
if (isRoot(chain.base) && chain.segments.length > 0 && !chain.segments[0].name?.startsWith("$")) {
|
|
11075
|
+
aliases.set(node.id.name, { source: source(init), segments: chain.segments });
|
|
11076
|
+
}
|
|
11077
|
+
} else if (init !== null && node.id.type === "ObjectPattern" && isRoot(init)) {
|
|
11078
|
+
for (const property of node.id.properties) {
|
|
11079
|
+
if (property.type !== "Property" || property.computed) continue;
|
|
11080
|
+
const key = property.key.type === "Identifier" ? property.key.name : property.key.type === "Literal" ? String(property.key.value) : null;
|
|
11081
|
+
const value = property.value.type === "AssignmentPattern" ? property.value.left : property.value;
|
|
11082
|
+
if (key === null || key.startsWith("$") || value.type !== "Identifier") continue;
|
|
11083
|
+
const segment = { name: key, raw: key, computed: false };
|
|
11084
|
+
aliases.set(value.name, { source: `${stateRoot}.${key}`, segments: [segment] });
|
|
11085
|
+
}
|
|
11086
|
+
}
|
|
11087
|
+
} else if (node.type === "CatchClause" && node.param) {
|
|
11088
|
+
const names = /* @__PURE__ */ new Set();
|
|
11089
|
+
bindingNames(node.param, names);
|
|
11090
|
+
names.forEach(bind);
|
|
11091
|
+
} else if (node.type === "ClassDeclaration" && node.id !== null) {
|
|
11092
|
+
bind(node.id.name);
|
|
11093
|
+
} else if (node.type === "AssignmentExpression" && node.left.type === "Identifier") {
|
|
11094
|
+
bind(node.left.name);
|
|
11095
|
+
}
|
|
11096
|
+
forEachChild(node, collect2);
|
|
11097
|
+
};
|
|
11098
|
+
collect2(body);
|
|
11099
|
+
const alias = (name) => bound.get(name) === 1 ? aliases.get(name) : void 0;
|
|
11100
|
+
const out = [];
|
|
11101
|
+
const report = (target, at2, form, directMin) => {
|
|
11102
|
+
const chain = memberChain(target, source);
|
|
11103
|
+
const base = chain.base;
|
|
11104
|
+
const range = { start: at2.start - shift, end: at2.end - shift };
|
|
11105
|
+
const pick = (segments) => form ?? (segments.length > 0 && segments.every((s) => s.computed) ? "index" : "property");
|
|
11106
|
+
if (base.type === "Identifier" && base.name !== stateRoot) {
|
|
11107
|
+
const a = alias(base.name);
|
|
11108
|
+
if (a === void 0) return;
|
|
11109
|
+
out.push({ form: pick(chain.segments), alias: base.name, source: a.source, target: assignTarget(stateRoot, a.segments), ...range });
|
|
11110
|
+
return;
|
|
11111
|
+
}
|
|
11112
|
+
if (!isRoot(base) || chain.segments.length < directMin || chain.segments[0].name?.startsWith("$")) return;
|
|
11113
|
+
out.push({ form: pick(chain.segments.slice(1)), alias: null, source: source(at2), target: assignTarget(stateRoot, chain.segments), ...range });
|
|
11114
|
+
};
|
|
11115
|
+
const direct = stateRoot === "this" ? Infinity : 2;
|
|
11116
|
+
const visitChanges = (node) => {
|
|
11117
|
+
if (node.type === "AssignmentExpression" && unwrapChain(node.left).type === "MemberExpression") {
|
|
11118
|
+
report(node.left, node.left, null, direct);
|
|
11119
|
+
} else if (node.type === "UpdateExpression" && unwrapChain(node.argument).type === "MemberExpression") {
|
|
11120
|
+
report(node.argument, node.argument, null, direct);
|
|
11121
|
+
} else if (node.type === "UnaryExpression" && node.operator === "delete" && unwrapChain(node.argument).type === "MemberExpression") {
|
|
11122
|
+
report(node.argument, node.argument, "property", direct);
|
|
11123
|
+
} else if (node.type === "CallExpression") {
|
|
11124
|
+
const callee = unwrapChain(node.callee);
|
|
11125
|
+
if (callee.type === "MemberExpression") {
|
|
11126
|
+
const method = !callee.computed && callee.property.type === "Identifier" ? callee.property.name : null;
|
|
11127
|
+
const object = unwrapChain(callee.object);
|
|
11128
|
+
if (method === "assign" && object.type === "Identifier" && object.name === "Object" && node.arguments.length > 0) {
|
|
11129
|
+
const first = node.arguments[0];
|
|
11130
|
+
if (first.type === "Identifier" || unwrapChain(first).type === "MemberExpression") report(first, node, "property", 1);
|
|
11131
|
+
} else if (method !== null && DESTRUCTIVE_ARRAY_METHODS.has(method)) {
|
|
11132
|
+
report(callee.object, node, "method", stateRoot === "this" ? Infinity : 1);
|
|
11133
|
+
}
|
|
11134
|
+
}
|
|
11135
|
+
}
|
|
11136
|
+
forEachChild(node, visitChanges);
|
|
11137
|
+
};
|
|
11138
|
+
visitChanges(body);
|
|
11139
|
+
return out;
|
|
11140
|
+
}
|
|
11141
|
+
var LOCATION_HOLDERS = /* @__PURE__ */ new Set(["window", "document", "globalThis", "self"]);
|
|
11142
|
+
var LOCATION_VARYING = /* @__PURE__ */ new Set(["pathname", "search", "hash", "href"]);
|
|
11143
|
+
function findLocationRead(body) {
|
|
11144
|
+
let program;
|
|
11145
|
+
try {
|
|
11146
|
+
program = parse3(PREFIX + body + SUFFIX, { ecmaVersion: "latest", sourceType: "module" });
|
|
11147
|
+
} catch {
|
|
11148
|
+
return null;
|
|
11149
|
+
}
|
|
11150
|
+
const wrapper = unwrapWrapper(program);
|
|
11151
|
+
if (wrapper === null) return null;
|
|
11152
|
+
const names = /* @__PURE__ */ new Set();
|
|
11153
|
+
const scan = (node) => {
|
|
11154
|
+
if (isFunctionNode(node)) for (const param of node.params) bindingNames(param, names);
|
|
11155
|
+
if (node.type === "VariableDeclarator") bindingNames(node.id, names);
|
|
11156
|
+
forEachChild(node, scan);
|
|
11157
|
+
};
|
|
11158
|
+
scan(wrapper.body);
|
|
11159
|
+
if (names.has("location")) return null;
|
|
11160
|
+
const isLocation = (node) => {
|
|
11161
|
+
const n = unwrapChain(node);
|
|
11162
|
+
if (n.type === "Identifier") return n.name === "location";
|
|
11163
|
+
return n.type === "MemberExpression" && !n.computed && n.property.type === "Identifier" && n.property.name === "location" && n.object.type === "Identifier" && LOCATION_HOLDERS.has(n.object.name);
|
|
11164
|
+
};
|
|
11165
|
+
let found = null;
|
|
11166
|
+
const at2 = (node) => {
|
|
11167
|
+
found = { start: node.start - PREFIX.length, end: node.end - PREFIX.length, text: (PREFIX + body).slice(node.start, node.end) };
|
|
11168
|
+
};
|
|
11169
|
+
const walk = (node) => {
|
|
11170
|
+
if (found !== null) return;
|
|
11171
|
+
if (node.type === "MemberExpression" && isLocation(node.object)) {
|
|
11172
|
+
const part = !node.computed && node.property.type === "Identifier" ? node.property.name : null;
|
|
11173
|
+
if (part === null || LOCATION_VARYING.has(part)) at2(node);
|
|
11174
|
+
return;
|
|
11175
|
+
}
|
|
11176
|
+
if (isLocation(node)) {
|
|
11177
|
+
at2(node);
|
|
11178
|
+
return;
|
|
11179
|
+
}
|
|
11180
|
+
if (node.type === "MemberExpression") {
|
|
11181
|
+
walk(node.object);
|
|
11182
|
+
if (node.computed) walk(node.property);
|
|
11183
|
+
return;
|
|
11184
|
+
}
|
|
11185
|
+
if (node.type === "Property") {
|
|
11186
|
+
if (node.computed) walk(node.key);
|
|
11187
|
+
walk(node.value);
|
|
11188
|
+
return;
|
|
11189
|
+
}
|
|
11190
|
+
forEachChild(node, walk);
|
|
11191
|
+
};
|
|
11192
|
+
walk(wrapper.body);
|
|
11193
|
+
return found;
|
|
11194
|
+
}
|
|
10946
11195
|
|
|
10947
11196
|
// src/core/messages.ts
|
|
10948
11197
|
function resolveLocale(locale2) {
|
|
@@ -10983,6 +11232,8 @@ var ja = {
|
|
|
10983
11232
|
getterCycle: (cycle) => `\u30D1\u30B9 getter \u304C\u5FAA\u74B0\u53C2\u7167\u3057\u3066\u3044\u307E\u3059: ${cycle}`,
|
|
10984
11233
|
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
11234
|
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`,
|
|
11235
|
+
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`,
|
|
11236
|
+
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
11237
|
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
11238
|
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
11239
|
typeExpectation: (label, expected, resultType) => `"${label}" \u306B\u306F${JA_EXPECTED_LABEL[expected]}\u304C\u5FC5\u8981\u3067\u3059\uFF08\u73FE\u5728\u306E\u578B: ${resultType}\uFF09`,
|
|
@@ -11006,6 +11257,8 @@ var ja = {
|
|
|
11006
11257
|
typeAnnotationIncompatible: (vt, rt) => `\u578B "${vt}" \u306F @type {${rt}} \u3068\u4E92\u63DB\u6027\u304C\u3042\u308A\u307E\u305B\u3093`,
|
|
11007
11258
|
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
11259
|
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`,
|
|
11260
|
+
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`,
|
|
11261
|
+
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`,
|
|
11009
11262
|
tagMemberUnknown: (prop, tag) => `"${prop}" \u306F <${tag}> \u306E wcBindable \u30E1\u30F3\u30D0\u30FC\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF08\u672A\u77E5\u30E1\u30F3\u30D0\u30FC\u3078\u306E\u30D0\u30A4\u30F3\u30C9\u306F\u9ED9\u3063\u3066\u7121\u8996\u3055\u308C\u307E\u3059\uFF09`,
|
|
11010
11263
|
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
11264
|
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\u304F\u3060\u3055\u3044`,
|
|
@@ -11042,6 +11295,9 @@ var ja = {
|
|
|
11042
11295
|
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
11296
|
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
11297
|
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`,
|
|
11298
|
+
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`,
|
|
11299
|
+
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`,
|
|
11300
|
+
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
11301
|
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
11302
|
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
11303
|
mountPathInvalid: (problem, mountPath) => {
|
|
@@ -11175,6 +11431,8 @@ var en = {
|
|
|
11175
11431
|
getterCycle: (cycle) => `Path getters form a dependency cycle: ${cycle}`,
|
|
11176
11432
|
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
11433
|
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`,
|
|
11434
|
+
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`,
|
|
11435
|
+
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
11436
|
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
11437
|
handlerFilterNotAllowed: (prop) => `Filters cannot be applied to event handler "${prop}"`,
|
|
11180
11438
|
typeExpectation: (label, expected, resultType) => `"${label}" requires ${EN_EXPECTED_LABEL[expected]} (current type: ${resultType})`,
|
|
@@ -11198,6 +11456,8 @@ var en = {
|
|
|
11198
11456
|
typeAnnotationIncompatible: (vt, rt) => `Type "${vt}" is not compatible with @type {${rt}}`,
|
|
11199
11457
|
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
11458
|
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.`,
|
|
11459
|
+
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 })`,
|
|
11460
|
+
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}`,
|
|
11201
11461
|
tagMemberUnknown: (prop, tag) => `"${prop}" is not a wcBindable member of <${tag}> (bindings to unknown members are silently ignored)`,
|
|
11202
11462
|
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
11463
|
declarationAliasRead: (alias, canonical) => `"${alias}" is a declaration key 4.0 removed (the 3.x old name of "${canonical}"), so this["${alias}"] is undefined. Read "${canonical}" instead`,
|
|
@@ -11234,6 +11494,9 @@ var en = {
|
|
|
11234
11494
|
baseHrefMissing: () => `An SPA using @wcstack/router needs <base href="/"> in <head> (without it, deep links misderive the basename)`,
|
|
11235
11495
|
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
11496
|
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`,
|
|
11497
|
+
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)`,
|
|
11498
|
+
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>)`,
|
|
11499
|
+
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
11500
|
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
11501
|
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
11502
|
mountPathInvalid: (problem, mountPath) => {
|
|
@@ -11456,6 +11719,19 @@ var DELEGATED_EVENTS = /* @__PURE__ */ new Set([
|
|
|
11456
11719
|
var CUSTOM_ELEMENT_OWN_EVENTS = /* @__PURE__ */ new Set(["input", "change", "submit"]);
|
|
11457
11720
|
function collectCurrentTargetHandlers(elements, html, fileReader) {
|
|
11458
11721
|
const names = /* @__PURE__ */ new Set();
|
|
11722
|
+
forEachStateMethod(elements, html, fileReader, "currentTarget", (name, params, body) => {
|
|
11723
|
+
if (readsEventCurrentTarget(params, body)) names.add(name);
|
|
11724
|
+
});
|
|
11725
|
+
return names;
|
|
11726
|
+
}
|
|
11727
|
+
function collectPreventDefaultHandlers(elements, html, fileReader) {
|
|
11728
|
+
const handlers = /* @__PURE__ */ new Map();
|
|
11729
|
+
forEachStateMethod(elements, html, fileReader, null, (name, _params, body) => {
|
|
11730
|
+
handlers.set(name, /\bpreventDefault\b/.test(body));
|
|
11731
|
+
});
|
|
11732
|
+
return handlers;
|
|
11733
|
+
}
|
|
11734
|
+
function forEachStateMethod(elements, html, fileReader, spelling, fn) {
|
|
11459
11735
|
let insideTemplate = null;
|
|
11460
11736
|
for (const element2 of elements) {
|
|
11461
11737
|
if (element2.bindComponent) continue;
|
|
@@ -11465,20 +11741,19 @@ function collectCurrentTargetHandlers(elements, html, fileReader) {
|
|
|
11465
11741
|
const script = readStateScript(element2.srcAttr, fileReader);
|
|
11466
11742
|
if (script !== void 0) scripts = [script];
|
|
11467
11743
|
}
|
|
11468
|
-
scripts = scripts.filter((script) => script.includes(
|
|
11744
|
+
if (spelling !== null) scripts = scripts.filter((script) => script.includes(spelling));
|
|
11469
11745
|
if (scripts.length === 0) continue;
|
|
11470
11746
|
if ((insideTemplate ??= createTemplateTester(html))(element2.tagStart)) continue;
|
|
11471
11747
|
for (const script of scripts) {
|
|
11472
11748
|
for (const callable of analyzeCallableBodies(script)) {
|
|
11473
|
-
if (callable.kind !== "method" || !callable.body.includes(
|
|
11749
|
+
if (callable.kind !== "method" || spelling !== null && !callable.body.includes(spelling)) continue;
|
|
11474
11750
|
const head = script.slice(callable.end, callable.bodyStart - 1);
|
|
11475
11751
|
const params = /\(([^)]*)\)\s*$/.exec(head);
|
|
11476
11752
|
if (params === null) continue;
|
|
11477
|
-
|
|
11753
|
+
fn(volume === null ? callable.name : `${volume}.${callable.name}`, params[1], callable.body);
|
|
11478
11754
|
}
|
|
11479
11755
|
}
|
|
11480
11756
|
}
|
|
11481
|
-
return names;
|
|
11482
11757
|
}
|
|
11483
11758
|
function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, fileReader, applicationSchema) {
|
|
11484
11759
|
const diagnostics = [];
|
|
@@ -11498,6 +11773,11 @@ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, f
|
|
|
11498
11773
|
currentTargetHandlers ??= collectCurrentTargetHandlers(pathIndex.elements, html, fileReader);
|
|
11499
11774
|
return currentTargetHandlers;
|
|
11500
11775
|
};
|
|
11776
|
+
let preventDefaultHandlers = null;
|
|
11777
|
+
const getPreventDefaultHandlers = () => {
|
|
11778
|
+
preventDefaultHandlers ??= collectPreventDefaultHandlers(pathIndex.elements, html, fileReader);
|
|
11779
|
+
return preventDefaultHandlers;
|
|
11780
|
+
};
|
|
11501
11781
|
for (const attr of attrs) {
|
|
11502
11782
|
const bindings = splitBindingExpressions(attr.value);
|
|
11503
11783
|
const nonEmptyCount = bindings.filter((b) => b.trim().length > 0).length;
|
|
@@ -11559,6 +11839,15 @@ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, f
|
|
|
11559
11839
|
const eventName = propNoMod.slice(2);
|
|
11560
11840
|
const handler = parsed.path.trim();
|
|
11561
11841
|
const modifiers = modifiersOf(parsed.property);
|
|
11842
|
+
if (eventName === "submit" && attr.tagName === "form" && !modifiers.includes("prevent") && getPreventDefaultHandlers().get(handler) === false && !/\saction\s*=/i.test(openTagBefore(html, attr.valueStart))) {
|
|
11843
|
+
diagnostics.push({
|
|
11844
|
+
code: WcsDiagnosticCode.SubmitWithoutPrevent,
|
|
11845
|
+
start: bindingStart + leadingSpace,
|
|
11846
|
+
end: bindingStart + leadingSpace + propNoMod.length,
|
|
11847
|
+
message: msgs.submitWithoutPrevent(handler),
|
|
11848
|
+
severity: "warning"
|
|
11849
|
+
});
|
|
11850
|
+
}
|
|
11562
11851
|
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
11852
|
currentTargetCandidates.push({
|
|
11564
11853
|
offset: attr.valueStart,
|
|
@@ -11867,6 +12156,10 @@ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, f
|
|
|
11867
12156
|
}
|
|
11868
12157
|
return diagnostics;
|
|
11869
12158
|
}
|
|
12159
|
+
function openTagBefore(html, valueStart) {
|
|
12160
|
+
const lt2 = html.lastIndexOf("<", valueStart);
|
|
12161
|
+
return lt2 === -1 ? "" : html.slice(lt2, valueStart);
|
|
12162
|
+
}
|
|
11870
12163
|
function findAllBindAttributes(html, attrName) {
|
|
11871
12164
|
const attrs = [];
|
|
11872
12165
|
const escaped = attrName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -14459,9 +14752,63 @@ function validateDocumentEnv(html, locale2) {
|
|
|
14459
14752
|
severity: "error",
|
|
14460
14753
|
message: msgs.signalsDualEntry()
|
|
14461
14754
|
});
|
|
14755
|
+
} else {
|
|
14756
|
+
const both = findSignalsImportMapBoth(scanText);
|
|
14757
|
+
if (both) {
|
|
14758
|
+
diagnostics.push({
|
|
14759
|
+
code: WcsDiagnosticCode.SignalsDualEntry,
|
|
14760
|
+
start: both.start,
|
|
14761
|
+
end: both.end,
|
|
14762
|
+
severity: "warning",
|
|
14763
|
+
message: msgs.signalsImportMapBoth()
|
|
14764
|
+
});
|
|
14765
|
+
}
|
|
14766
|
+
}
|
|
14767
|
+
const structure = scanStructure(scanText);
|
|
14768
|
+
for (const at2 of structure.bareMustaches) {
|
|
14769
|
+
diagnostics.push({
|
|
14770
|
+
code: WcsDiagnosticCode.RouteBareMustache,
|
|
14771
|
+
start: at2.start,
|
|
14772
|
+
end: at2.end,
|
|
14773
|
+
severity: "warning",
|
|
14774
|
+
message: msgs.routeBareMustache(at2.inLayout)
|
|
14775
|
+
});
|
|
14776
|
+
}
|
|
14777
|
+
for (const layout of structure.layoutsWithoutDefaultSlot) {
|
|
14778
|
+
diagnostics.push({
|
|
14779
|
+
code: WcsDiagnosticCode.LayoutSlotMissing,
|
|
14780
|
+
start: layout.start,
|
|
14781
|
+
end: layout.end,
|
|
14782
|
+
severity: "warning",
|
|
14783
|
+
message: msgs.layoutSlotMissing(layout.id)
|
|
14784
|
+
});
|
|
14462
14785
|
}
|
|
14463
14786
|
return diagnostics;
|
|
14464
14787
|
}
|
|
14788
|
+
function findSignalsImportMapBoth(html) {
|
|
14789
|
+
const mapRegex = /<script\b((?:"[^"]*"|'[^']*'|[^>"'])*)>([\s\S]*?)<\/script\s*>/gi;
|
|
14790
|
+
let match;
|
|
14791
|
+
while ((match = mapRegex.exec(html)) !== null) {
|
|
14792
|
+
if (!/\btype\s*=\s*(["'])importmap\1/i.test(match[1])) continue;
|
|
14793
|
+
let imports;
|
|
14794
|
+
try {
|
|
14795
|
+
imports = JSON.parse(match[2]).imports;
|
|
14796
|
+
} catch {
|
|
14797
|
+
continue;
|
|
14798
|
+
}
|
|
14799
|
+
if (imports === null || typeof imports !== "object") continue;
|
|
14800
|
+
const core = imports["@wcstack/signals"];
|
|
14801
|
+
const dom = imports["@wcstack/signals/dom"] ?? imports["@wcstack/signals/"];
|
|
14802
|
+
if (typeof core !== "string" || typeof dom !== "string") continue;
|
|
14803
|
+
if (core.includes("/dist/") && dom.includes("/dist/")) continue;
|
|
14804
|
+
const key = '"@wcstack/signals"';
|
|
14805
|
+
const at2 = match[2].indexOf(key);
|
|
14806
|
+
const bodyStart = match.index + match[0].indexOf(">") + 1;
|
|
14807
|
+
const start = bodyStart + (at2 === -1 ? 0 : at2 + 1);
|
|
14808
|
+
return { start, end: start + key.length - 2 };
|
|
14809
|
+
}
|
|
14810
|
+
return null;
|
|
14811
|
+
}
|
|
14465
14812
|
var SCOPED_AUTO = /@wcstack\/([a-z0-9-]+)(?:@[^/"'\s]+)?\/(?:auto\b|dist\/(?:split\/)?auto(?:\.min)?\.js\b)/;
|
|
14466
14813
|
var BUNDLE_AUTO = /(?:^|\/)wcstack(?:@[^/"'\s]+)?\/(?:auto\b|dist\/auto\.min\.js\b)/;
|
|
14467
14814
|
var BUNDLE_PACKAGES = ["state", "router", "fetch", "storage", "autoloader"];
|
|
@@ -14540,6 +14887,88 @@ function blankHtmlComments(html) {
|
|
|
14540
14887
|
function blankJsComments(code) {
|
|
14541
14888
|
return code.replace(/\/\*[\s\S]*?\*\//g, (m) => " ".repeat(m.length)).replace(/(^|[^:])\/\/[^\n]*/g, (m, pre) => pre + " ".repeat(m.length - pre.length));
|
|
14542
14889
|
}
|
|
14890
|
+
var VOID_TAGS = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "source", "track", "wbr"]);
|
|
14891
|
+
var ROUTE_TAG = "wcs-route";
|
|
14892
|
+
var LAYOUT_TAG2 = "wcs-layout";
|
|
14893
|
+
function attrValue(attrs, name) {
|
|
14894
|
+
const m = new RegExp(`(?:^|\\s)${name}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s>]+))`, "i").exec(attrs);
|
|
14895
|
+
return m === null ? null : m[1] ?? m[2] ?? m[3] ?? "";
|
|
14896
|
+
}
|
|
14897
|
+
function scanStructure(html) {
|
|
14898
|
+
const scan = html.replace(
|
|
14899
|
+
/(<(script|style)\b[^>]*>)([\s\S]*?)(<\/\2\s*>)/gi,
|
|
14900
|
+
(_m, open, _name, body, close) => open + " ".repeat(body.length) + close
|
|
14901
|
+
);
|
|
14902
|
+
const tagRegex = /<(\/?)([a-zA-Z][\w-]*)((?:"[^"]*"|'[^']*'|[^>"'])*)>/g;
|
|
14903
|
+
const layoutIds = /* @__PURE__ */ new Set();
|
|
14904
|
+
for (const m of scan.matchAll(/<wcs-layout\b((?:"[^"]*"|'[^']*'|[^>"'])*)>/gi)) {
|
|
14905
|
+
const id = attrValue(m[1], "layout");
|
|
14906
|
+
if (id !== null && id !== "") layoutIds.add(id);
|
|
14907
|
+
}
|
|
14908
|
+
const bareMustaches = [];
|
|
14909
|
+
const layouts = [];
|
|
14910
|
+
const templateHasDefaultSlot = /* @__PURE__ */ new Map();
|
|
14911
|
+
const stack = [];
|
|
14912
|
+
let last = 0;
|
|
14913
|
+
let match;
|
|
14914
|
+
const text3 = (from, to) => {
|
|
14915
|
+
const top = stack[stack.length - 1];
|
|
14916
|
+
if (top === void 0 || to <= from) return;
|
|
14917
|
+
const chunk = scan.slice(from, to);
|
|
14918
|
+
if (top.name === LAYOUT_TAG2 && chunk.trim() !== "") top.unslotted = true;
|
|
14919
|
+
if (top.name !== ROUTE_TAG && !top.layoutTemplate) return;
|
|
14920
|
+
for (const m of chunk.matchAll(/\{\{[\s\S]*?\}\}/g)) {
|
|
14921
|
+
bareMustaches.push({ start: from + m.index, end: from + m.index + m[0].length, inLayout: top.layoutTemplate });
|
|
14922
|
+
}
|
|
14923
|
+
};
|
|
14924
|
+
while ((match = tagRegex.exec(scan)) !== null) {
|
|
14925
|
+
text3(last, match.index);
|
|
14926
|
+
last = match.index + match[0].length;
|
|
14927
|
+
const name = match[2].toLowerCase();
|
|
14928
|
+
const nameStart = match.index + 1 + match[1].length;
|
|
14929
|
+
if (match[1] === "/") {
|
|
14930
|
+
const at2 = stack.map((e) => e.name).lastIndexOf(name);
|
|
14931
|
+
if (at2 === -1) continue;
|
|
14932
|
+
for (const closed of stack.splice(at2)) {
|
|
14933
|
+
if (closed.name === LAYOUT_TAG2 && closed.unslotted && closed.layoutId !== void 0) {
|
|
14934
|
+
layouts.push({ start: closed.nameStart, end: closed.nameEnd, id: closed.layoutId });
|
|
14935
|
+
}
|
|
14936
|
+
}
|
|
14937
|
+
continue;
|
|
14938
|
+
}
|
|
14939
|
+
const attrs = match[3];
|
|
14940
|
+
const parent = stack[stack.length - 1];
|
|
14941
|
+
if (parent?.name === LAYOUT_TAG2 && !attrValue(attrs, "slot")) parent.unslotted = true;
|
|
14942
|
+
for (const open of stack) {
|
|
14943
|
+
if (open.layoutTemplate && name === "slot" && !attrValue(attrs, "name")) templateHasDefaultSlot.set(open.layoutId, true);
|
|
14944
|
+
}
|
|
14945
|
+
if (VOID_TAGS.has(name) || /\/\s*$/.test(attrs)) continue;
|
|
14946
|
+
const id = name === "template" ? attrValue(attrs, "id") : null;
|
|
14947
|
+
const element2 = {
|
|
14948
|
+
name,
|
|
14949
|
+
layoutTemplate: id !== null && layoutIds.has(id),
|
|
14950
|
+
nameStart,
|
|
14951
|
+
nameEnd: nameStart + match[2].length
|
|
14952
|
+
};
|
|
14953
|
+
if (element2.layoutTemplate) {
|
|
14954
|
+
element2.layoutId = id;
|
|
14955
|
+
if (!templateHasDefaultSlot.has(id)) templateHasDefaultSlot.set(id, false);
|
|
14956
|
+
}
|
|
14957
|
+
if (name === LAYOUT_TAG2 && attrValue(attrs, "src") === null) {
|
|
14958
|
+
const layoutId = attrValue(attrs, "layout");
|
|
14959
|
+
if (layoutId !== null && layoutId !== "") element2.layoutId = layoutId;
|
|
14960
|
+
}
|
|
14961
|
+
stack.push(element2);
|
|
14962
|
+
}
|
|
14963
|
+
text3(last, scan.length);
|
|
14964
|
+
for (const closed of stack) {
|
|
14965
|
+
if (closed.name === LAYOUT_TAG2 && closed.unslotted && closed.layoutId !== void 0) {
|
|
14966
|
+
layouts.push({ start: closed.nameStart, end: closed.nameEnd, id: closed.layoutId });
|
|
14967
|
+
}
|
|
14968
|
+
}
|
|
14969
|
+
const layoutsWithoutDefaultSlot = layouts.filter((l) => templateHasDefaultSlot.get(l.id) === false);
|
|
14970
|
+
return { bareMustaches, layoutsWithoutDefaultSlot };
|
|
14971
|
+
}
|
|
14543
14972
|
var ROUTER_TAG2 = "wcs-router";
|
|
14544
14973
|
var OUTLET_TAG = "wcs-outlet";
|
|
14545
14974
|
function findMisplacedOutlets(html) {
|
|
@@ -15969,6 +16398,54 @@ function validateGetterUntrackedReads(script, scriptStart, nestedWriteRoots, loc
|
|
|
15969
16398
|
}
|
|
15970
16399
|
return out;
|
|
15971
16400
|
}
|
|
16401
|
+
function validateGetterLocationReads(script, scriptStart, locale2) {
|
|
16402
|
+
if (!script.includes("location")) return [];
|
|
16403
|
+
const msgs = getMessages(locale2);
|
|
16404
|
+
const out = [];
|
|
16405
|
+
for (const getter of analyzeCallableBodies(script)) {
|
|
16406
|
+
if (getter.kind !== "getter" || getter.accessor !== "get" || !getter.body.includes("location")) continue;
|
|
16407
|
+
const read = findLocationRead(getter.body);
|
|
16408
|
+
if (read === null) continue;
|
|
16409
|
+
out.push({
|
|
16410
|
+
code: WcsDiagnosticCode.GetterUntrackedRead,
|
|
16411
|
+
start: scriptStart + getter.bodyStart + read.start,
|
|
16412
|
+
end: scriptStart + getter.bodyStart + read.end,
|
|
16413
|
+
message: msgs.getterReadsLocation(read.text),
|
|
16414
|
+
severity: "warning"
|
|
16415
|
+
});
|
|
16416
|
+
}
|
|
16417
|
+
return out;
|
|
16418
|
+
}
|
|
16419
|
+
function onHandlerStateParam(script, handler) {
|
|
16420
|
+
if (handler.kind === "body") {
|
|
16421
|
+
const head = script.slice(Math.max(0, handler.start - 400), handler.start);
|
|
16422
|
+
return /\(\s*([A-Za-z_$][\w$]*)[^()]*\)\s*\{\s*$/.exec(head)?.[1] ?? null;
|
|
16423
|
+
}
|
|
16424
|
+
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;
|
|
16425
|
+
}
|
|
16426
|
+
function validateInPlaceChanges(script, scriptStart, locale2) {
|
|
16427
|
+
const msgs = getMessages(locale2);
|
|
16428
|
+
const out = [];
|
|
16429
|
+
const push3 = (text3, kind, textStart, root) => {
|
|
16430
|
+
for (const change of findInPlaceChanges(text3, kind, root)) {
|
|
16431
|
+
out.push({
|
|
16432
|
+
code: change.form === "method" ? WcsDiagnosticCode.ArrayMutation : change.form === "index" ? WcsDiagnosticCode.ArrayIndexAssign : WcsDiagnosticCode.NestedAssign,
|
|
16433
|
+
start: scriptStart + textStart + change.start,
|
|
16434
|
+
end: scriptStart + textStart + change.end,
|
|
16435
|
+
severity: "error",
|
|
16436
|
+
message: change.alias !== null ? msgs.inPlaceAlias(change.alias, change.source, change.target) : msgs.inPlaceChange(change.source, change.target)
|
|
16437
|
+
});
|
|
16438
|
+
}
|
|
16439
|
+
};
|
|
16440
|
+
for (const callable of analyzeCallableBodies(script)) push3(callable.body, "body", callable.bodyStart, "this");
|
|
16441
|
+
for (const handler of analyzeWatchHandlerSources(script)) push3(handler.text, handler.kind, handler.start, "this");
|
|
16442
|
+
for (const handler of analyzeOnHandlerSources(script)) {
|
|
16443
|
+
const root = handler.kind === "body" ? onHandlerStateParam(script, handler) : null;
|
|
16444
|
+
if (handler.kind === "body" && root === null) continue;
|
|
16445
|
+
push3(handler.text, handler.kind, handler.start, root);
|
|
16446
|
+
}
|
|
16447
|
+
return out;
|
|
16448
|
+
}
|
|
15972
16449
|
var NESTED_WRITE_INPUTS = {
|
|
15973
16450
|
"wcs-storage": { inputs: ["value"], exemptWhenManual: true },
|
|
15974
16451
|
"wcs-fetch": { inputs: ["body"], exemptWhenManual: false, oneShot: true }
|
|
@@ -16080,6 +16557,26 @@ function collectNestedWriteRoots(html, stateTagName, bindAttrName, blocks) {
|
|
|
16080
16557
|
if (path !== null) addPrefixes(path, false);
|
|
16081
16558
|
}
|
|
16082
16559
|
}
|
|
16560
|
+
for (const handler of analyzeOnHandlerSources(block.content)) {
|
|
16561
|
+
const param = onHandlerStateParam(block.content, handler);
|
|
16562
|
+
if (param === null) continue;
|
|
16563
|
+
const name = param.replace(/\$/g, "\\$");
|
|
16564
|
+
const region = { start: handler.start, end: handler.start + handler.text.length };
|
|
16565
|
+
const bracket = `\\b${name}\\s*(?:\\?\\.)?\\s*\\[\\s*["']([^"']+)["']\\s*\\]`;
|
|
16566
|
+
const template = `\\b${name}\\s*(?:\\?\\.)?\\s*\\[\\s*\`([^\`]*)\`` + String.raw`\s*\]`;
|
|
16567
|
+
for (const [pattern, quote] of [[bracket, /["']/], [template, /`/]]) {
|
|
16568
|
+
for (const regex of [new RegExp(`${pattern}${ASSIGN_TAIL}`, "g"), new RegExp(`${PRE_INCDEC}${pattern}`, "g")]) {
|
|
16569
|
+
let match;
|
|
16570
|
+
const part = scan.slice(region.start, region.end);
|
|
16571
|
+
while ((match = regex.exec(part)) !== null) {
|
|
16572
|
+
const keyStart = region.start + match.index + match[0].search(quote) + 1;
|
|
16573
|
+
const raw = block.content.slice(keyStart, keyStart + match[1].length);
|
|
16574
|
+
const path = quote.source === "`" ? templateKeyPath(raw) : raw;
|
|
16575
|
+
if (path !== null) addPrefixes(path, false);
|
|
16576
|
+
}
|
|
16577
|
+
}
|
|
16578
|
+
}
|
|
16579
|
+
}
|
|
16083
16580
|
API_CALL.lastIndex = 0;
|
|
16084
16581
|
let call;
|
|
16085
16582
|
while ((call = API_CALL.exec(scan)) !== null) {
|
|
@@ -16210,7 +16707,9 @@ function validateSemantics(html, stateTagName = "wcs-state", locale2, bindAttrNa
|
|
|
16210
16707
|
out.push(...validateIndexParamReads(block.content, block.contentStart, locale2));
|
|
16211
16708
|
out.push(...validateGetterCycles(block.content, block.contentStart, locale2));
|
|
16212
16709
|
out.push(...validateGetterUntrackedReads(block.content, block.contentStart, getNestedWriteRoots, locale2));
|
|
16710
|
+
out.push(...validateGetterLocationReads(block.content, block.contentStart, locale2));
|
|
16213
16711
|
out.push(...validateOnHandlerThis(block.content, block.contentStart, locale2));
|
|
16712
|
+
out.push(...validateInPlaceChanges(block.content, block.contentStart, locale2));
|
|
16214
16713
|
}
|
|
16215
16714
|
out.push(...validateInputNestedWrites(html, stateTagName, bindAttrName, getNestedWriteRoots, locale2));
|
|
16216
16715
|
out.push(...validateUpdatedCallbackDemand(html, stateTagName, bindAttrName, locale2));
|
package/dist/tsc-core.cjs
CHANGED
|
@@ -255,11 +255,17 @@ function optionsRequired(fnName) {
|
|
|
255
255
|
function optionMustBeNumber(fnName) {
|
|
256
256
|
raise(27, [fnName]);
|
|
257
257
|
}
|
|
258
|
-
function
|
|
259
|
-
raise(
|
|
258
|
+
function styleInvalid(fnName, value) {
|
|
259
|
+
raise(52, [fnName, value]);
|
|
260
260
|
}
|
|
261
|
-
function
|
|
262
|
-
raise(
|
|
261
|
+
function currencyInvalid(value) {
|
|
262
|
+
raise(53, [value]);
|
|
263
|
+
}
|
|
264
|
+
function valueMustBeNumber(fnName, value) {
|
|
265
|
+
raise(28, [fnName, value]);
|
|
266
|
+
}
|
|
267
|
+
function valueMustBeDate(fnName, value) {
|
|
268
|
+
raise(29, [fnName, value]);
|
|
263
269
|
}
|
|
264
270
|
function valueMustBeArray(fnName) {
|
|
265
271
|
raise(30, [fnName]);
|
|
@@ -326,7 +332,7 @@ var numeric = (name, op) => ({
|
|
|
326
332
|
const opt = requiredNumberOption(options, 0, name);
|
|
327
333
|
return (value) => {
|
|
328
334
|
if (typeof value !== "number") {
|
|
329
|
-
valueMustBeNumber(name);
|
|
335
|
+
valueMustBeNumber(name, value);
|
|
330
336
|
}
|
|
331
337
|
return op(value, opt);
|
|
332
338
|
};
|
|
@@ -356,7 +362,7 @@ var toFixed = (options) => {
|
|
|
356
362
|
const opt = numberOption(options?.[0] ?? "0", "toFixed");
|
|
357
363
|
return (value) => {
|
|
358
364
|
if (typeof value !== "number") {
|
|
359
|
-
valueMustBeNumber("toFixed");
|
|
365
|
+
valueMustBeNumber("toFixed", value);
|
|
360
366
|
}
|
|
361
367
|
return value.toFixed(opt);
|
|
362
368
|
};
|
|
@@ -365,7 +371,7 @@ var round = (options) => {
|
|
|
365
371
|
const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "round"));
|
|
366
372
|
return (value) => {
|
|
367
373
|
if (typeof value !== "number") {
|
|
368
|
-
valueMustBeNumber("round");
|
|
374
|
+
valueMustBeNumber("round", value);
|
|
369
375
|
}
|
|
370
376
|
return Math.round(value * optValue) / optValue;
|
|
371
377
|
};
|
|
@@ -374,7 +380,7 @@ var floor = (options) => {
|
|
|
374
380
|
const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "floor"));
|
|
375
381
|
return (value) => {
|
|
376
382
|
if (typeof value !== "number") {
|
|
377
|
-
valueMustBeNumber("floor");
|
|
383
|
+
valueMustBeNumber("floor", value);
|
|
378
384
|
}
|
|
379
385
|
return Math.floor(value * optValue) / optValue;
|
|
380
386
|
};
|
|
@@ -383,7 +389,7 @@ var ceil = (options) => {
|
|
|
383
389
|
const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "ceil"));
|
|
384
390
|
return (value) => {
|
|
385
391
|
if (typeof value !== "number") {
|
|
386
|
-
valueMustBeNumber("ceil");
|
|
392
|
+
valueMustBeNumber("ceil", value);
|
|
387
393
|
}
|
|
388
394
|
return Math.ceil(value * optValue) / optValue;
|
|
389
395
|
};
|
|
@@ -392,7 +398,7 @@ var percent = (options) => {
|
|
|
392
398
|
const opt = numberOption(options?.[0] ?? "0", "percent");
|
|
393
399
|
return (value) => {
|
|
394
400
|
if (typeof value !== "number") {
|
|
395
|
-
valueMustBeNumber("percent");
|
|
401
|
+
valueMustBeNumber("percent", value);
|
|
396
402
|
}
|
|
397
403
|
return `${(value * 100).toFixed(opt)}%`;
|
|
398
404
|
};
|
|
@@ -419,11 +425,29 @@ var locale = (options) => {
|
|
|
419
425
|
const explicit = options?.[0];
|
|
420
426
|
return (value) => {
|
|
421
427
|
if (typeof value !== "number") {
|
|
422
|
-
valueMustBeNumber("locale");
|
|
428
|
+
valueMustBeNumber("locale", value);
|
|
423
429
|
}
|
|
424
430
|
return value.toLocaleString(explicit ?? defaultLocale());
|
|
425
431
|
};
|
|
426
432
|
};
|
|
433
|
+
var currency = (options) => {
|
|
434
|
+
const code = options?.[0] ?? optionsRequired("currency");
|
|
435
|
+
const explicit = options?.[1];
|
|
436
|
+
const format = { style: "currency", currency: code };
|
|
437
|
+
try {
|
|
438
|
+
new Intl.NumberFormat("en", format);
|
|
439
|
+
const known = Intl.supportedValuesOf?.("currency");
|
|
440
|
+
if (known && !known.includes(code.toUpperCase())) throw 0;
|
|
441
|
+
} catch {
|
|
442
|
+
currencyInvalid(code);
|
|
443
|
+
}
|
|
444
|
+
return (value) => {
|
|
445
|
+
if (typeof value !== "number") {
|
|
446
|
+
valueMustBeNumber("currency", value);
|
|
447
|
+
}
|
|
448
|
+
return value.toLocaleString(explicit ?? defaultLocale(), format);
|
|
449
|
+
};
|
|
450
|
+
};
|
|
427
451
|
var upper = () => (value) => String(value).toUpperCase();
|
|
428
452
|
var lower = () => (value) => String(value).toLowerCase();
|
|
429
453
|
var capitalize = () => (value) => {
|
|
@@ -480,38 +504,48 @@ var join = (options) => {
|
|
|
480
504
|
return value.join(opt);
|
|
481
505
|
};
|
|
482
506
|
};
|
|
507
|
+
var STYLES = ["full", "long", "medium", "short"];
|
|
508
|
+
function dateOptions(options, fn) {
|
|
509
|
+
let [loc, style] = options ?? [];
|
|
510
|
+
if (style === void 0 && loc !== void 0 && STYLES.includes(loc)) [loc, style] = [void 0, loc];
|
|
511
|
+
if (style !== void 0 && !STYLES.includes(style)) styleInvalid(fn, style);
|
|
512
|
+
return [loc, style];
|
|
513
|
+
}
|
|
483
514
|
var date = (options) => {
|
|
484
|
-
const explicit = options
|
|
515
|
+
const [explicit, style] = dateOptions(options, "date");
|
|
516
|
+
const format = style && { dateStyle: style };
|
|
485
517
|
return (value) => {
|
|
486
518
|
if (!(value instanceof Date)) {
|
|
487
|
-
valueMustBeDate("date");
|
|
519
|
+
valueMustBeDate("date", value);
|
|
488
520
|
}
|
|
489
|
-
return value.toLocaleDateString(explicit ?? defaultLocale());
|
|
521
|
+
return value.toLocaleDateString(explicit ?? defaultLocale(), format);
|
|
490
522
|
};
|
|
491
523
|
};
|
|
492
524
|
var time = (options) => {
|
|
493
|
-
const explicit = options
|
|
525
|
+
const [explicit, style] = dateOptions(options, "time");
|
|
526
|
+
const format = style && { timeStyle: style };
|
|
494
527
|
return (value) => {
|
|
495
528
|
if (!(value instanceof Date)) {
|
|
496
|
-
valueMustBeDate("time");
|
|
529
|
+
valueMustBeDate("time", value);
|
|
497
530
|
}
|
|
498
|
-
return value.toLocaleTimeString(explicit ?? defaultLocale());
|
|
531
|
+
return value.toLocaleTimeString(explicit ?? defaultLocale(), format);
|
|
499
532
|
};
|
|
500
533
|
};
|
|
501
534
|
var datetime = (options) => {
|
|
502
|
-
const explicit = options
|
|
535
|
+
const [explicit, style] = dateOptions(options, "datetime");
|
|
536
|
+
const format = style && { dateStyle: style, timeStyle: style };
|
|
503
537
|
return (value) => {
|
|
504
538
|
if (!(value instanceof Date)) {
|
|
505
|
-
valueMustBeDate("datetime");
|
|
539
|
+
valueMustBeDate("datetime", value);
|
|
506
540
|
}
|
|
507
|
-
return value.toLocaleString(explicit ?? defaultLocale());
|
|
541
|
+
return value.toLocaleString(explicit ?? defaultLocale(), format);
|
|
508
542
|
};
|
|
509
543
|
};
|
|
510
544
|
var ymd = (options) => {
|
|
511
545
|
const opt = options?.[0] ?? "-";
|
|
512
546
|
return (value) => {
|
|
513
547
|
if (!(value instanceof Date)) {
|
|
514
|
-
valueMustBeDate("ymd");
|
|
548
|
+
valueMustBeDate("ymd", value);
|
|
515
549
|
}
|
|
516
550
|
const year = value.getFullYear().toString();
|
|
517
551
|
const month = (value.getMonth() + 1).toString().padStart(2, "0");
|
|
@@ -523,7 +557,7 @@ var hms = (options) => {
|
|
|
523
557
|
const opt = options?.[0] ?? ":";
|
|
524
558
|
return (value) => {
|
|
525
559
|
if (!(value instanceof Date)) {
|
|
526
|
-
valueMustBeDate("hms");
|
|
560
|
+
valueMustBeDate("hms", value);
|
|
527
561
|
}
|
|
528
562
|
const hours = value.getHours().toString().padStart(2, "0");
|
|
529
563
|
const minutes = value.getMinutes().toString().padStart(2, "0");
|
|
@@ -533,7 +567,7 @@ var hms = (options) => {
|
|
|
533
567
|
};
|
|
534
568
|
var abs = () => (value) => {
|
|
535
569
|
if (typeof value !== "number") {
|
|
536
|
-
valueMustBeNumber("abs");
|
|
570
|
+
valueMustBeNumber("abs", value);
|
|
537
571
|
}
|
|
538
572
|
return Math.abs(value);
|
|
539
573
|
};
|
|
@@ -542,7 +576,7 @@ var clamp = (options) => {
|
|
|
542
576
|
const max = requiredNumberOption(options, 1, "clamp");
|
|
543
577
|
return (value) => {
|
|
544
578
|
if (typeof value !== "number") {
|
|
545
|
-
valueMustBeNumber("clamp");
|
|
579
|
+
valueMustBeNumber("clamp", value);
|
|
546
580
|
}
|
|
547
581
|
return Math.min(Math.max(value, min), max);
|
|
548
582
|
};
|
|
@@ -589,10 +623,10 @@ var registered = {
|
|
|
589
623
|
ceil: { factory: ceil, arity: [0, 1] },
|
|
590
624
|
percent: { factory: percent, arity: [0, 1] },
|
|
591
625
|
unit: { factory: nullishPassthrough(unit), arity: [1, 1] },
|
|
592
|
-
// The locale-dependent three take a locale like `locale` does (`date(ja-JP)`)
|
|
593
|
-
date: { factory: date, arity: [0,
|
|
594
|
-
time: { factory: time, arity: [0,
|
|
595
|
-
datetime: { factory: datetime, arity: [0,
|
|
626
|
+
// The locale-dependent three take a locale like `locale` does (`date(ja-JP)`), and a style (`date(ja-JP,long)`)
|
|
627
|
+
date: { factory: date, arity: [0, 2] },
|
|
628
|
+
time: { factory: time, arity: [0, 2] },
|
|
629
|
+
datetime: { factory: datetime, arity: [0, 2] },
|
|
596
630
|
ymd: { factory: ymd, arity: [0, 1] },
|
|
597
631
|
hms: { factory: hms, arity: [0, 1] },
|
|
598
632
|
// the core set of 4.0.0-rc.3 (the core's own: eq ne not lt le gt ge falsy truthy boolean)
|
|
@@ -619,7 +653,9 @@ var registered = {
|
|
|
619
653
|
boolean: boolean2,
|
|
620
654
|
number: { factory: number, arity: [0, 0] },
|
|
621
655
|
string: { factory: string, arity: [0, 0] },
|
|
622
|
-
nullIfEmpty: { factory: nullIfEmpty, arity: [0, 0] }
|
|
656
|
+
nullIfEmpty: { factory: nullIfEmpty, arity: [0, 0] },
|
|
657
|
+
// (added in 4.2: last, so the order of the others is unchanged)
|
|
658
|
+
currency: { factory: currency, arity: [1, 2] }
|
|
623
659
|
};
|
|
624
660
|
var formatFilters = /* @__PURE__ */ Object.fromEntries(
|
|
625
661
|
/* @__PURE__ */ Object.entries(registered).filter(([name]) => !(name in coreFilters))
|
|
@@ -690,10 +726,11 @@ var builtinFilterMeta = {
|
|
|
690
726
|
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"] },
|
|
691
727
|
// 日付・時刻
|
|
692
728
|
// `locale` と同じくロケールを 1 つ受ける(`date(ja-JP)`)。実装は最初からこれを読んでいたが、
|
|
693
|
-
// メタデータ側が maxArgs: 0 だったため lint
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
729
|
+
// メタデータ側が maxArgs: 0 だったため lint と補完が正しい書き方を誤りとして報告していた。
|
|
730
|
+
// 4.2: 2 つ目は書式(full / long / medium / short — Intl の dateStyle / timeStyle)。書式だけなら既定のロケール
|
|
731
|
+
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"] },
|
|
732
|
+
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"] },
|
|
733
|
+
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"] },
|
|
697
734
|
ymd: { description: "YYYY-MM-DD \u5F62\u5F0F ([separator]\u3002\u65E2\u5B9A\u306F -)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
698
735
|
hms: { description: "HH:MM:SS \u5F62\u5F0F ([separator]\u3002\u65E2\u5B9A\u306F :)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
699
736
|
// 真偽値・変換
|
|
@@ -704,7 +741,9 @@ var builtinFilterMeta = {
|
|
|
704
741
|
boolean: { description: "\u30D6\u30FC\u30EB\u5024\u306B\u5909\u63DB", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
705
742
|
number: { description: "\u6570\u5024\u306B\u5909\u63DB", hasArgs: false, resultType: "number", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
706
743
|
string: { description: "\u6587\u5B57\u5217\u306B\u5909\u63DB", hasArgs: false, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
707
|
-
nullIfEmpty: { description: "\u7A7A\u6587\u5B57\u5217\u3092null\u306B\u5909\u63DB", hasArgs: false, resultType: "passthrough", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 }
|
|
744
|
+
nullIfEmpty: { description: "\u7A7A\u6587\u5B57\u5217\u3092null\u306B\u5909\u63DB", hasArgs: false, resultType: "passthrough", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
745
|
+
// 4.2(formats の最後に登録)
|
|
746
|
+
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"] }
|
|
708
747
|
};
|
|
709
748
|
var WCS_MANIFEST_VERSION = 2;
|
|
710
749
|
var builtinFilterAliases = Object.freeze({});
|
package/dist/wcs-schema.mjs
CHANGED
package/dist/wcs-tsc.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wcstack/typescript",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "TypeScript tooling for wcstack apps: wcs-schema generates the sidecar stateSchema from a typed state file, so wcs-validate checks data-wcs paths against real types in CI and every editor.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.esm.js",
|