@wcstack/typescript 3.1.0 → 3.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 +141 -52
- package/dist/tsc-core.cjs +5 -0
- 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
|
@@ -150,6 +150,9 @@ var WcsDiagnosticCode = {
|
|
|
150
150
|
// タグのメンバー名が "on" で始まる(`once` 等)のに先頭ドット無しで束縛した: ランタイムはイベント束縛にして
|
|
151
151
|
// "ce" イベントを待ち、値は届かない。明示のプロパティ形 `.once:` を提案する(@wcstack/state 3.1・要件 B5 / 3.x 計画 D36)
|
|
152
152
|
OnPrefixedMember: "wcs/on-prefixed-member",
|
|
153
|
+
// 3.x の間だけ残る旧名(フィルタ `uc` → `upper`、`$trackDependency` → `$dependOn` …)を書いた(info)。
|
|
154
|
+
// 動くが 4.0 で外れるので正式名を提案する(@wcstack/state 3.2・要件 B12 / 3.x 計画 D39)
|
|
155
|
+
NameAlias: "wcs/name-alias",
|
|
153
156
|
// wcBindable 無宣言タグ(wcs-fetch-header 等のヘルパー)への spread。
|
|
154
157
|
// ランタイム(expandSpread)は raiseError で落とす。
|
|
155
158
|
SpreadNoBindable: "wcs/spread-no-bindable",
|
|
@@ -694,6 +697,18 @@ function valueMustBeDate(fnName) {
|
|
|
694
697
|
function valueMustBeArray(fnName) {
|
|
695
698
|
raiseError(`filter ${fnName} requires an array value`);
|
|
696
699
|
}
|
|
700
|
+
var builtinFilterAliases = {
|
|
701
|
+
inc: "add",
|
|
702
|
+
dec: "sub",
|
|
703
|
+
fix: "toFixed",
|
|
704
|
+
uc: "upper",
|
|
705
|
+
lc: "lower",
|
|
706
|
+
cap: "capitalize",
|
|
707
|
+
rep: "repeat",
|
|
708
|
+
rev: "reverse",
|
|
709
|
+
pad: "padStart",
|
|
710
|
+
null: "nullIfEmpty"
|
|
711
|
+
};
|
|
697
712
|
function validateNumberString(value) {
|
|
698
713
|
if (!value || isNaN(Number(value))) {
|
|
699
714
|
return false;
|
|
@@ -789,25 +804,25 @@ var ge = (options) => {
|
|
|
789
804
|
};
|
|
790
805
|
};
|
|
791
806
|
var inc = (options) => {
|
|
792
|
-
const opt = options?.[0] ?? optionsRequired("
|
|
807
|
+
const opt = options?.[0] ?? optionsRequired("add");
|
|
793
808
|
if (!validateNumberString(opt)) {
|
|
794
|
-
optionMustBeNumber("
|
|
809
|
+
optionMustBeNumber("add");
|
|
795
810
|
}
|
|
796
811
|
return (value) => {
|
|
797
812
|
if (typeof value !== "number") {
|
|
798
|
-
valueMustBeNumber("
|
|
813
|
+
valueMustBeNumber("add");
|
|
799
814
|
}
|
|
800
815
|
return value + Number(opt);
|
|
801
816
|
};
|
|
802
817
|
};
|
|
803
818
|
var dec = (options) => {
|
|
804
|
-
const opt = options?.[0] ?? optionsRequired("
|
|
819
|
+
const opt = options?.[0] ?? optionsRequired("sub");
|
|
805
820
|
if (!validateNumberString(opt)) {
|
|
806
|
-
optionMustBeNumber("
|
|
821
|
+
optionMustBeNumber("sub");
|
|
807
822
|
}
|
|
808
823
|
return (value) => {
|
|
809
824
|
if (typeof value !== "number") {
|
|
810
|
-
valueMustBeNumber("
|
|
825
|
+
valueMustBeNumber("sub");
|
|
811
826
|
}
|
|
812
827
|
return value - Number(opt);
|
|
813
828
|
};
|
|
@@ -877,11 +892,11 @@ var clamp = (options) => {
|
|
|
877
892
|
var fix = (options) => {
|
|
878
893
|
const opt = options?.[0] ?? "0";
|
|
879
894
|
if (!validateNumberString(opt)) {
|
|
880
|
-
optionMustBeNumber("
|
|
895
|
+
optionMustBeNumber("toFixed");
|
|
881
896
|
}
|
|
882
897
|
return (value) => {
|
|
883
898
|
if (typeof value !== "number") {
|
|
884
|
-
valueMustBeNumber("
|
|
899
|
+
valueMustBeNumber("toFixed");
|
|
885
900
|
}
|
|
886
901
|
return value.toFixed(Number(opt));
|
|
887
902
|
};
|
|
@@ -954,19 +969,29 @@ var substr = (options) => {
|
|
|
954
969
|
};
|
|
955
970
|
};
|
|
956
971
|
var pad = (options) => {
|
|
957
|
-
const opt1 = options?.[0] ?? optionsRequired("
|
|
972
|
+
const opt1 = options?.[0] ?? optionsRequired("padStart");
|
|
958
973
|
if (!validateNumberString(opt1)) {
|
|
959
|
-
optionMustBeNumber("
|
|
974
|
+
optionMustBeNumber("padStart");
|
|
960
975
|
}
|
|
961
976
|
const opt2 = options?.[1] ?? "0";
|
|
962
977
|
return (value) => {
|
|
963
978
|
return String(value).padStart(Number(opt1), opt2);
|
|
964
979
|
};
|
|
965
980
|
};
|
|
981
|
+
var padEnd = (options) => {
|
|
982
|
+
const opt1 = options?.[0] ?? optionsRequired("padEnd");
|
|
983
|
+
if (!validateNumberString(opt1)) {
|
|
984
|
+
optionMustBeNumber("padEnd");
|
|
985
|
+
}
|
|
986
|
+
const opt2 = options?.[1] ?? " ";
|
|
987
|
+
return (value) => {
|
|
988
|
+
return String(value).padEnd(Number(opt1), opt2);
|
|
989
|
+
};
|
|
990
|
+
};
|
|
966
991
|
var rep = (options) => {
|
|
967
|
-
const opt = options?.[0] ?? optionsRequired("
|
|
992
|
+
const opt = options?.[0] ?? optionsRequired("repeat");
|
|
968
993
|
if (!validateNumberString(opt)) {
|
|
969
|
-
optionMustBeNumber("
|
|
994
|
+
optionMustBeNumber("repeat");
|
|
970
995
|
}
|
|
971
996
|
return (value) => {
|
|
972
997
|
return String(value).repeat(Number(opt));
|
|
@@ -1138,6 +1163,11 @@ var defaults = (options, literals) => {
|
|
|
1138
1163
|
return value;
|
|
1139
1164
|
};
|
|
1140
1165
|
};
|
|
1166
|
+
var coalesce = (options, literals) => {
|
|
1167
|
+
const opt = options?.[0] ?? optionsRequired("coalesce");
|
|
1168
|
+
const fallback = literals !== void 0 && literals.length > 0 ? literals[0] : opt;
|
|
1169
|
+
return (value) => value ?? fallback;
|
|
1170
|
+
};
|
|
1141
1171
|
var boolean = (_options) => {
|
|
1142
1172
|
return (value) => {
|
|
1143
1173
|
return Boolean(value);
|
|
@@ -1166,24 +1196,25 @@ var builtinFilters = {
|
|
|
1166
1196
|
"le": le,
|
|
1167
1197
|
"gt": gt,
|
|
1168
1198
|
"ge": ge,
|
|
1169
|
-
"
|
|
1170
|
-
"
|
|
1199
|
+
"add": inc,
|
|
1200
|
+
"sub": dec,
|
|
1171
1201
|
"mul": mul,
|
|
1172
1202
|
"div": div,
|
|
1173
1203
|
"mod": mod,
|
|
1174
1204
|
"abs": abs,
|
|
1175
1205
|
"clamp": clamp,
|
|
1176
|
-
"
|
|
1206
|
+
"toFixed": fix,
|
|
1177
1207
|
"locale": locale,
|
|
1178
|
-
"
|
|
1179
|
-
"
|
|
1180
|
-
"
|
|
1208
|
+
"upper": uc,
|
|
1209
|
+
"lower": lc,
|
|
1210
|
+
"capitalize": cap,
|
|
1181
1211
|
"trim": trim,
|
|
1182
1212
|
"slice": slice,
|
|
1183
1213
|
"substr": substr,
|
|
1184
|
-
"
|
|
1185
|
-
"
|
|
1186
|
-
"
|
|
1214
|
+
"padStart": pad,
|
|
1215
|
+
"padEnd": padEnd,
|
|
1216
|
+
"repeat": rep,
|
|
1217
|
+
"reverse": rev,
|
|
1187
1218
|
"truncate": truncate,
|
|
1188
1219
|
"join": join,
|
|
1189
1220
|
"int": int,
|
|
@@ -1201,10 +1232,11 @@ var builtinFilters = {
|
|
|
1201
1232
|
"falsy": falsy,
|
|
1202
1233
|
"truthy": truthy,
|
|
1203
1234
|
"defaults": defaults,
|
|
1235
|
+
"coalesce": coalesce,
|
|
1204
1236
|
"boolean": boolean,
|
|
1205
1237
|
"number": number,
|
|
1206
1238
|
"string": string,
|
|
1207
|
-
"
|
|
1239
|
+
"nullIfEmpty": _null
|
|
1208
1240
|
};
|
|
1209
1241
|
var outputBuiltinFilters = builtinFilters;
|
|
1210
1242
|
var builtinFilterMeta = {
|
|
@@ -1217,26 +1249,27 @@ var builtinFilterMeta = {
|
|
|
1217
1249
|
gt: { description: "\u3088\u308A\u5927\u304D\u3044\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number", "string"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
1218
1250
|
ge: { description: "\u4EE5\u4E0A\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number", "string"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
1219
1251
|
// 算術
|
|
1220
|
-
|
|
1221
|
-
|
|
1252
|
+
add: { description: "\u52A0\u7B97", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
1253
|
+
sub: { description: "\u6E1B\u7B97", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
1222
1254
|
mul: { description: "\u4E57\u7B97", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
1223
1255
|
div: { description: "\u9664\u7B97", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
1224
1256
|
mod: { description: "\u5270\u4F59", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
1225
1257
|
abs: { description: "\u7D76\u5BFE\u5024", hasArgs: false, resultType: "number", acceptTypes: ["number"], minArgs: 0, maxArgs: 0 },
|
|
1226
1258
|
clamp: { description: "\u7BC4\u56F2\u5185\u306B\u4E38\u3081\u308B (min,max)", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 2, maxArgs: 2, argTypes: ["number", "number"] },
|
|
1227
1259
|
// 数値フォーマット
|
|
1228
|
-
|
|
1260
|
+
toFixed: { description: "\u56FA\u5B9A\u5C0F\u6570\u70B9\u8868\u8A18", hasArgs: true, resultType: "string", acceptTypes: ["number"], minArgs: 0, maxArgs: 1, argTypes: ["number"] },
|
|
1229
1261
|
locale: { description: "\u30ED\u30B1\u30FC\u30EB\u5F62\u5F0F\u3067\u6570\u5024\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8", hasArgs: true, resultType: "string", acceptTypes: ["number"], minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
1230
1262
|
// 文字列
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1263
|
+
upper: { description: "\u5927\u6587\u5B57\u306B\u5909\u63DB", hasArgs: false, resultType: "string", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
1264
|
+
lower: { description: "\u5C0F\u6587\u5B57\u306B\u5909\u63DB", hasArgs: false, resultType: "string", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
1265
|
+
capitalize: { description: "\u5148\u982D\u6587\u5B57\u3092\u5927\u6587\u5B57\u306B", hasArgs: false, resultType: "string", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
1234
1266
|
trim: { description: "\u524D\u5F8C\u306E\u7A7A\u767D\u3092\u524A\u9664", hasArgs: false, resultType: "string", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
1235
1267
|
slice: { description: "\u90E8\u5206\u6587\u5B57\u5217 (start[,end])", hasArgs: true, resultType: "string", acceptTypes: ["string"], minArgs: 1, maxArgs: 2, argTypes: ["number", "number"] },
|
|
1236
1268
|
substr: { description: "\u90E8\u5206\u6587\u5B57\u5217 (pos,len)", hasArgs: true, resultType: "string", acceptTypes: ["string"], minArgs: 1, maxArgs: 2, argTypes: ["number", "number"] },
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1269
|
+
padStart: { description: "\u5148\u982D\u3092\u57CB\u3081\u308B (length[,char])", hasArgs: true, resultType: "string", acceptTypes: ["string"], minArgs: 1, maxArgs: 2, argTypes: ["number", "string"] },
|
|
1270
|
+
padEnd: { description: "\u672B\u5C3E\u3092\u57CB\u3081\u308B (length[,char])", hasArgs: true, resultType: "string", acceptTypes: ["string"], minArgs: 1, maxArgs: 2, argTypes: ["number", "string"] },
|
|
1271
|
+
repeat: { description: "\u7E70\u308A\u8FD4\u3057 (count)", hasArgs: true, resultType: "string", acceptTypes: ["string"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
1272
|
+
reverse: { description: "\u6587\u5B57\u9806\u3092\u53CD\u8EE2", hasArgs: false, resultType: "string", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
1240
1273
|
truncate: { description: "\u5207\u308A\u8A70\u3081\u3066\u7701\u7565\u8A18\u53F7 (length[,suffix])", hasArgs: true, resultType: "string", acceptTypes: ["string"], minArgs: 1, maxArgs: 2, argTypes: ["number", "string"] },
|
|
1241
1274
|
join: { description: "\u914D\u5217\u3092\u9023\u7D50 ([separator])", hasArgs: true, resultType: "string", acceptTypes: ["array"], minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
1242
1275
|
// 数値パース・丸め
|
|
@@ -1259,10 +1292,11 @@ var builtinFilterMeta = {
|
|
|
1259
1292
|
falsy: { description: "\u507D\u5024\u304B\u5224\u5B9A", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
1260
1293
|
truthy: { description: "\u771F\u5024\u304B\u5224\u5B9A", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
1261
1294
|
defaults: { description: "\u507D\u5024\u306E\u5834\u5408\u30C7\u30D5\u30A9\u30EB\u30C8\u5024", hasArgs: true, resultType: "passthrough", acceptTypes: "any", minArgs: 1, maxArgs: 1, argTypes: ["any"] },
|
|
1295
|
+
coalesce: { description: "null / undefined \u306E\u5834\u5408\u30C7\u30D5\u30A9\u30EB\u30C8\u5024", hasArgs: true, resultType: "passthrough", acceptTypes: "any", minArgs: 1, maxArgs: 1, argTypes: ["any"] },
|
|
1262
1296
|
boolean: { description: "\u30D6\u30FC\u30EB\u5024\u306B\u5909\u63DB", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
1263
1297
|
number: { description: "\u6570\u5024\u306B\u5909\u63DB", hasArgs: false, resultType: "number", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
1264
1298
|
string: { description: "\u6587\u5B57\u5217\u306B\u5909\u63DB", hasArgs: false, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
1265
|
-
|
|
1299
|
+
nullIfEmpty: { description: "\u7A7A\u6587\u5B57\u5217\u3092null\u306B\u5909\u63DB", hasArgs: false, resultType: "passthrough", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 }
|
|
1266
1300
|
};
|
|
1267
1301
|
var STRUCTURAL_BINDING_TYPE_SET = /* @__PURE__ */ new Set([
|
|
1268
1302
|
"if",
|
|
@@ -1307,7 +1341,7 @@ for (let i = 0; i < MAX_WILDCARD_DEPTH; i++) {
|
|
|
1307
1341
|
Object.freeze(tmpIndexByIndexName);
|
|
1308
1342
|
var STATE_CONNECTED_CALLBACK_NAME = "$connectedCallback";
|
|
1309
1343
|
var STATE_DISCONNECTED_CALLBACK_NAME = "$disconnectedCallback";
|
|
1310
|
-
var STATE_UPDATED_CALLBACK_NAME = "$
|
|
1344
|
+
var STATE_UPDATED_CALLBACK_NAME = "$renderedCallback";
|
|
1311
1345
|
var STATE_ERROR_CALLBACK_NAME = "$errorCallback";
|
|
1312
1346
|
var WEBCOMPONENT_STATE_READY_CALLBACK_NAME = "$stateReadyCallback";
|
|
1313
1347
|
var STATE_BINDABLES_NAME = "$bindables";
|
|
@@ -1316,7 +1350,7 @@ var STATE_COMMAND_TOKENS_NAME = "$commandTokens";
|
|
|
1316
1350
|
var STATE_COMMAND_NAMESPACE_NAME = "$command";
|
|
1317
1351
|
var STATE_EVENT_TOKENS_NAME = "$eventTokens";
|
|
1318
1352
|
var STATE_ON_NAME = "$on";
|
|
1319
|
-
var STATE_STREAMS_NAME = "$
|
|
1353
|
+
var STATE_STREAMS_NAME = "$stream";
|
|
1320
1354
|
var STATE_WATCH_NAME = "$watch";
|
|
1321
1355
|
var STATE_SCAN_NAME = "$scan";
|
|
1322
1356
|
var STATE_RECURSION_NAME = "$recursion";
|
|
@@ -1366,6 +1400,7 @@ function getWcsManifest() {
|
|
|
1366
1400
|
// 実装(Record のキー)から自動導出。手リストを持たない=ドリフトの構造的排除。
|
|
1367
1401
|
filters: Object.keys(outputBuiltinFilters),
|
|
1368
1402
|
filterMeta: builtinFilterMeta,
|
|
1403
|
+
filterAliases: builtinFilterAliases,
|
|
1369
1404
|
reservedLifecycle: [
|
|
1370
1405
|
STATE_CONNECTED_CALLBACK_NAME,
|
|
1371
1406
|
STATE_DISCONNECTED_CALLBACK_NAME,
|
|
@@ -1392,6 +1427,9 @@ function getWcsManifest() {
|
|
|
1392
1427
|
}
|
|
1393
1428
|
|
|
1394
1429
|
// src/service/completionData.ts
|
|
1430
|
+
function canonicalFilterName(name) {
|
|
1431
|
+
return Object.prototype.hasOwnProperty.call(builtinFilterAliases, name) ? builtinFilterAliases[name] : name;
|
|
1432
|
+
}
|
|
1395
1433
|
var BUILTIN_FILTERS = Object.entries(builtinFilterMeta).map(
|
|
1396
1434
|
([name, meta]) => ({ name, ...meta })
|
|
1397
1435
|
);
|
|
@@ -1567,7 +1605,7 @@ function coversSuffix(spec, familySuffix, suffix) {
|
|
|
1567
1605
|
}
|
|
1568
1606
|
|
|
1569
1607
|
// src/service/stateAnalyzer.ts
|
|
1570
|
-
var
|
|
1608
|
+
var RESERVED_STREAMS_KEYS = /* @__PURE__ */ new Set(["$stream", "$streams"]);
|
|
1571
1609
|
var RESERVED_COMMAND_TOKENS_KEY = "$commandTokens";
|
|
1572
1610
|
var RESERVED_EVENT_TOKENS_KEY = "$eventTokens";
|
|
1573
1611
|
var RESERVED_LIST_KEYS_KEY = "$listKeys";
|
|
@@ -1939,7 +1977,7 @@ function findNonObjectDeclaration(scriptContent, key, rejectArray = false) {
|
|
|
1939
1977
|
return span;
|
|
1940
1978
|
}
|
|
1941
1979
|
function collectReservedKeyPaths(prop, paths, pendingStreamValues, pendingListKeys) {
|
|
1942
|
-
if (prop.name
|
|
1980
|
+
if (RESERVED_STREAMS_KEYS.has(prop.name) && prop.kind === "data" && prop.value && isObjectLiteral(prop.value)) {
|
|
1943
1981
|
const entries = parseTopLevelProperties(extractObjectContent(prop.value));
|
|
1944
1982
|
for (const entry of entries) {
|
|
1945
1983
|
if (entry.kind !== "data" || entry.name.startsWith("$")) continue;
|
|
@@ -3068,6 +3106,7 @@ var ja = {
|
|
|
3068
3106
|
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`,
|
|
3069
3107
|
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`,
|
|
3070
3108
|
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`,
|
|
3109
|
+
nameAlias: (written, canonical) => `"${written}" \u306F "${canonical}" \u306E\u65E7\u540D\u3067\u3059\u30023.x \u306E\u9593\u306F\u52D5\u304D\u307E\u3059\u304C 4.0 \u3067\u5916\u308C\u308B\u306E\u3067\u3001"${canonical}" \u3068\u66F8\u3044\u3066\u304F\u3060\u3055\u3044\uFF08@wcstack/state 3.2\uFF09`,
|
|
3071
3110
|
onPrefixedMember: (member, tag) => `"${member}" \u306F <${tag}> \u306E\u30E1\u30F3\u30D0\u30FC\u3067\u3059\u304C\u3001"on" \u3067\u59CB\u307E\u308B\u540D\u524D\u306F\u30A4\u30D9\u30F3\u30C8\u675F\u7E1B\u306B\u306A\u308A\uFF08"${member.slice(2)}" \u30A4\u30D9\u30F3\u30C8\u3092\u5F85\u3064\uFF09\u3001\u5024\u306F\u5C4A\u304D\u307E\u305B\u3093\u3002\u30D7\u30ED\u30D1\u30C6\u30A3\u3068\u3057\u3066\u675F\u7E1B\u3059\u308B\u306B\u306F ".${member}:" \u3068\u66F8\u3044\u3066\u304F\u3060\u3055\u3044\uFF08@wcstack/state 3.1\uFF09`,
|
|
3072
3111
|
tagCommandUnknown: (name, tag, declared) => `"${name}" \u306F <${tag}> \u306E command \u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF08\u5BA3\u8A00\u6E08\u307F: ${declared}\uFF09`,
|
|
3073
3112
|
spreadNoBindable: (tag) => `'...'\uFF08spread\uFF09\u306F <${tag}> \u306B\u6709\u52B9\u306A wcBindable \u5BA3\u8A00\u304C\u5FC5\u8981\u3067\u3059 \u2014 \u3053\u306E\u30BF\u30B0\u306F\u5BA3\u8A00\u3092\u6301\u305F\u306A\u3044\u305F\u3081\u3001\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u30A8\u30E9\u30FC\u3092\u9001\u51FA\u3057\u307E\u3059`,
|
|
@@ -3258,6 +3297,7 @@ var en = {
|
|
|
3258
3297
|
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}).`,
|
|
3259
3298
|
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.`,
|
|
3260
3299
|
tagMemberUnknown: (prop, tag) => `"${prop}" is not a wcBindable member of <${tag}> (bindings to unknown members are silently ignored)`,
|
|
3300
|
+
nameAlias: (written, canonical) => `"${written}" is the old name of "${canonical}". It works through 3.x and goes in 4.0 \u2014 write "${canonical}" (@wcstack/state 3.2)`,
|
|
3261
3301
|
onPrefixedMember: (member, tag) => `"${member}" is a member of <${tag}>, but a name starting with "on" makes an event binding (it listens for a "${member.slice(2)}" event) and the value never arrives. Write ".${member}:" to bind the property (@wcstack/state 3.1)`,
|
|
3262
3302
|
tagCommandUnknown: (name, tag, declared) => `"${name}" is not a command of <${tag}> (declared: ${declared})`,
|
|
3263
3303
|
spreadNoBindable: (tag) => `'...' (spread) requires <${tag}> to expose a valid wcBindable declaration \u2014 this tag declares none, so the runtime raises an error`,
|
|
@@ -3391,7 +3431,6 @@ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, f
|
|
|
3391
3431
|
structuralTemplates ??= collectStructuralTemplates(html, attrName);
|
|
3392
3432
|
return structuralTemplates;
|
|
3393
3433
|
};
|
|
3394
|
-
const filterNameSet = new Set(BUILTIN_FILTERS.map((f) => f.name));
|
|
3395
3434
|
for (const attr of attrs) {
|
|
3396
3435
|
const bindings = splitBindingExpressions(attr.value);
|
|
3397
3436
|
const nonEmptyCount = bindings.filter((b) => b.trim().length > 0).length;
|
|
@@ -3725,7 +3764,17 @@ function parseFilterSegments(expr, segments, searchStart) {
|
|
|
3725
3764
|
}
|
|
3726
3765
|
function validateFilterUsage(filter, bindingStart, msgs) {
|
|
3727
3766
|
const diagnostics = [];
|
|
3728
|
-
const
|
|
3767
|
+
const canonical = canonicalFilterName(filter.name);
|
|
3768
|
+
const info = filterMap.get(canonical);
|
|
3769
|
+
if (info && canonical !== filter.name) {
|
|
3770
|
+
diagnostics.push({
|
|
3771
|
+
code: WcsDiagnosticCode.NameAlias,
|
|
3772
|
+
start: bindingStart + filter.offset,
|
|
3773
|
+
end: bindingStart + filter.offset + filter.name.length,
|
|
3774
|
+
message: msgs.nameAlias(filter.name, canonical),
|
|
3775
|
+
severity: "info"
|
|
3776
|
+
});
|
|
3777
|
+
}
|
|
3729
3778
|
if (!info) {
|
|
3730
3779
|
diagnostics.push({
|
|
3731
3780
|
code: WcsDiagnosticCode.FilterUnknown,
|
|
@@ -4355,8 +4404,17 @@ function validateTemplateSyntax(html, stateTagName, bindAttrName = "data-wcs", l
|
|
|
4355
4404
|
}
|
|
4356
4405
|
for (let i = 1; i < parts.length; i++) {
|
|
4357
4406
|
const filterName = parts[i].trim().replace(/\(.*$/, "");
|
|
4358
|
-
|
|
4359
|
-
|
|
4407
|
+
const filterOffset = item.expression.indexOf(parts[i]) + (parts[i].length - parts[i].trimStart().length);
|
|
4408
|
+
const canonical = canonicalFilterName(filterName);
|
|
4409
|
+
if (filterName && canonical !== filterName && filterNameSet.has(canonical)) {
|
|
4410
|
+
diagnostics.push({
|
|
4411
|
+
code: WcsDiagnosticCode.NameAlias,
|
|
4412
|
+
start: item.exprStart + filterOffset,
|
|
4413
|
+
end: item.exprStart + filterOffset + filterName.length,
|
|
4414
|
+
message: msgs.nameAlias(filterName, canonical),
|
|
4415
|
+
severity: "info"
|
|
4416
|
+
});
|
|
4417
|
+
} else if (filterName && !filterNameSet.has(filterName)) {
|
|
4360
4418
|
diagnostics.push({
|
|
4361
4419
|
code: WcsDiagnosticCode.FilterUnknown,
|
|
4362
4420
|
start: item.exprStart + filterOffset,
|
|
@@ -7114,7 +7172,8 @@ var RECURSION_APIS = ["getAll", "setAll", "resolve", "postUpdate", "trackDepende
|
|
|
7114
7172
|
var UNSUPPORTED_API_SITE = {
|
|
7115
7173
|
$resolve: "resolve",
|
|
7116
7174
|
$postUpdate: "postUpdate",
|
|
7117
|
-
$trackDependency: "trackDependency"
|
|
7175
|
+
$trackDependency: "trackDependency",
|
|
7176
|
+
$dependOn: "trackDependency"
|
|
7118
7177
|
};
|
|
7119
7178
|
var BRACKET_ASSIGNMENT = new RegExp(`${ROOT_BRACKET}${ASSIGN_TAIL}`, "g");
|
|
7120
7179
|
var PRE_BRACKET_INCDEC = new RegExp(`${PRE_INCDEC}${ROOT_BRACKET}`, "g");
|
|
@@ -10074,16 +10133,16 @@ pp$5.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit)
|
|
|
10074
10133
|
if (prec != null && (!forInit || this.type !== types$1._in)) {
|
|
10075
10134
|
if (prec > minPrec) {
|
|
10076
10135
|
var logical = this.type === types$1.logicalOR || this.type === types$1.logicalAND;
|
|
10077
|
-
var
|
|
10078
|
-
if (
|
|
10136
|
+
var coalesce2 = this.type === types$1.coalesce;
|
|
10137
|
+
if (coalesce2) {
|
|
10079
10138
|
prec = types$1.logicalAND.binop;
|
|
10080
10139
|
}
|
|
10081
10140
|
var op = this.value;
|
|
10082
10141
|
this.next();
|
|
10083
10142
|
var startPos = this.start, startLoc = this.startLoc;
|
|
10084
10143
|
var right = this.parseExprOp(this.parseMaybeUnary(null, false, false, forInit), startPos, startLoc, prec, forInit);
|
|
10085
|
-
var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical ||
|
|
10086
|
-
if (logical && this.type === types$1.coalesce ||
|
|
10144
|
+
var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce2);
|
|
10145
|
+
if (logical && this.type === types$1.coalesce || coalesce2 && (this.type === types$1.logicalOR || this.type === types$1.logicalAND)) {
|
|
10087
10146
|
this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses");
|
|
10088
10147
|
}
|
|
10089
10148
|
return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit);
|
|
@@ -13334,8 +13393,9 @@ function parse3(input, options) {
|
|
|
13334
13393
|
// src/service/scriptAst.ts
|
|
13335
13394
|
var PREFIX = "(async function* () {\n";
|
|
13336
13395
|
var SUFFIX = "\n})";
|
|
13337
|
-
var PATH_ARG_APIS = /* @__PURE__ */ new Set(["$getAll", "$resolve", "$trackDependency"]);
|
|
13338
|
-
var
|
|
13396
|
+
var PATH_ARG_APIS = /* @__PURE__ */ new Set(["$getAll", "$resolve", "$dependOn", "$trackDependency"]);
|
|
13397
|
+
var TRACK_APIS = /* @__PURE__ */ new Set(["$dependOn", "$trackDependency"]);
|
|
13398
|
+
var UNTRACK_APIS = /* @__PURE__ */ new Set(["$untracked", "$untrackDependency"]);
|
|
13339
13399
|
function collectGetterReads(body) {
|
|
13340
13400
|
let program;
|
|
13341
13401
|
try {
|
|
@@ -13560,7 +13620,7 @@ function visitCall(node, scope, out) {
|
|
|
13560
13620
|
const { segments, base } = resolveChain(callee);
|
|
13561
13621
|
if (isThisRoot(base, scope) && segments.length === 1 && segments[0].text !== null) {
|
|
13562
13622
|
const api = segments[0].text;
|
|
13563
|
-
if (api
|
|
13623
|
+
if (UNTRACK_APIS.has(api)) return;
|
|
13564
13624
|
if (PATH_ARG_APIS.has(api)) {
|
|
13565
13625
|
const first = node.arguments[0];
|
|
13566
13626
|
const path = first !== void 0 && first.type !== "SpreadElement" ? literalString2(first) : null;
|
|
@@ -13568,7 +13628,7 @@ function visitCall(node, scope, out) {
|
|
|
13568
13628
|
out.push({
|
|
13569
13629
|
path,
|
|
13570
13630
|
chain: null,
|
|
13571
|
-
form: api
|
|
13631
|
+
form: TRACK_APIS.has(api) ? "track" : "api",
|
|
13572
13632
|
callee: false,
|
|
13573
13633
|
written: false,
|
|
13574
13634
|
start: node.start - PREFIX.length,
|
|
@@ -13751,7 +13811,35 @@ function buildReferenceIndex(html, options = {}) {
|
|
|
13751
13811
|
}
|
|
13752
13812
|
|
|
13753
13813
|
// src/service/semanticValidator.ts
|
|
13754
|
-
var
|
|
13814
|
+
var STATE_UPDATED_CALLBACKS = /* @__PURE__ */ new Set(["$renderedCallback", "$updatedCallback"]);
|
|
13815
|
+
var OLD_API_NAMES = { $trackDependency: "$dependOn", $untrackDependency: "$untracked" };
|
|
13816
|
+
var OLD_DECLARATION_KEYS = { $streams: "$stream", $updatedCallback: "$renderedCallback" };
|
|
13817
|
+
var OLD_API_CALL = /\.\s*(\$trackDependency|\$untrackDependency)\b/g;
|
|
13818
|
+
var OLD_DECLARATION_KEY = /(^|[{,\s])(\$streams|\$updatedCallback)(?=\s*[:(])/g;
|
|
13819
|
+
function validateNameAliases(script, scriptStart, locale2) {
|
|
13820
|
+
const msgs = getMessages(locale2);
|
|
13821
|
+
const scan = blankComments(script);
|
|
13822
|
+
const out = [];
|
|
13823
|
+
const push2 = (name, canonical, offset2) => {
|
|
13824
|
+
out.push({
|
|
13825
|
+
code: WcsDiagnosticCode.NameAlias,
|
|
13826
|
+
start: scriptStart + offset2,
|
|
13827
|
+
end: scriptStart + offset2 + name.length,
|
|
13828
|
+
message: msgs.nameAlias(name, canonical),
|
|
13829
|
+
severity: "info"
|
|
13830
|
+
});
|
|
13831
|
+
};
|
|
13832
|
+
OLD_API_CALL.lastIndex = 0;
|
|
13833
|
+
let match;
|
|
13834
|
+
while ((match = OLD_API_CALL.exec(scan)) !== null) {
|
|
13835
|
+
push2(match[1], OLD_API_NAMES[match[1]], match.index + match[0].length - match[1].length);
|
|
13836
|
+
}
|
|
13837
|
+
OLD_DECLARATION_KEY.lastIndex = 0;
|
|
13838
|
+
while ((match = OLD_DECLARATION_KEY.exec(scan)) !== null) {
|
|
13839
|
+
push2(match[2], OLD_DECLARATION_KEYS[match[2]], match.index + match[1].length);
|
|
13840
|
+
}
|
|
13841
|
+
return out;
|
|
13842
|
+
}
|
|
13755
13843
|
var API_CALL = /\.\s*\$(getAll|setAll|resolve)\s*\(/g;
|
|
13756
13844
|
function validateIndexArity(script, scriptStart, locale2) {
|
|
13757
13845
|
const msgs = getMessages(locale2);
|
|
@@ -13933,13 +14021,13 @@ var PATH_TEST_LITERAL = /(?:\.\s*(?:includes|indexOf)\s*\(\s*|[!=]==\s*)(["'])((
|
|
|
13933
14021
|
function validateUpdatedCallbackDemand(html, stateTagName, bindAttrName, locale2) {
|
|
13934
14022
|
const blocks = parseWcsScriptBlocks(html, stateTagName);
|
|
13935
14023
|
if (blocks.length === 0) return [];
|
|
13936
|
-
const hasCallback = blocks.some((block) => block.content.includes(
|
|
14024
|
+
const hasCallback = blocks.some((block) => [...STATE_UPDATED_CALLBACKS].some((name) => block.content.includes(name)));
|
|
13937
14025
|
if (!hasCallback) return [];
|
|
13938
14026
|
const msgs = getMessages(locale2);
|
|
13939
14027
|
const boundPaths = collectBoundPaths(html, stateTagName, bindAttrName);
|
|
13940
14028
|
const out = [];
|
|
13941
14029
|
for (const block of blocks) {
|
|
13942
|
-
const callback = analyzeCallableBodies(block.content).find((entry) => entry.name
|
|
14030
|
+
const callback = analyzeCallableBodies(block.content).find((entry) => STATE_UPDATED_CALLBACKS.has(entry.name) && entry.kind === "method");
|
|
13943
14031
|
if (callback === void 0) continue;
|
|
13944
14032
|
if (block.mountPath !== null) continue;
|
|
13945
14033
|
const declared = new Set(analyzeStatePaths(block.content).map((p) => p.path));
|
|
@@ -13986,6 +14074,7 @@ function validateSemantics(html, stateTagName = "wcs-state", locale2, bindAttrNa
|
|
|
13986
14074
|
const getNestedWriteRoots = () => nestedWriteRoots ??= collectNestedWriteRoots(html, stateTagName, bindAttrName, blocks);
|
|
13987
14075
|
for (const block of blocks) {
|
|
13988
14076
|
out.push(...validateIndexArity(block.content, block.contentStart, locale2));
|
|
14077
|
+
out.push(...validateNameAliases(block.content, block.contentStart, locale2));
|
|
13989
14078
|
out.push(...validateGetterCycles(block.content, block.contentStart, locale2));
|
|
13990
14079
|
out.push(...validateGetterUntrackedReads(block.content, block.contentStart, getNestedWriteRoots, locale2));
|
|
13991
14080
|
}
|
package/dist/tsc-core.cjs
CHANGED
|
@@ -204,7 +204,11 @@ interface WcsStateApi {
|
|
|
204
204
|
$setAll<V = any>(path: string, indexes: number[], values: readonly V[], options: { spread: true }): number;
|
|
205
205
|
$postUpdate(path: string): void;
|
|
206
206
|
$resolve(path: string, indexes: number[], value?: any): any;
|
|
207
|
+
$dependOn(path: string): void;
|
|
208
|
+
$untracked<T>(fn: () => T): T;
|
|
209
|
+
/** @deprecated $dependOn \u306E\u65E7\u540D\uFF08@wcstack/state 3.2 \u2014 4.0 \u3067\u5916\u308C\u308B\uFF09 */
|
|
207
210
|
$trackDependency(path: string): void;
|
|
211
|
+
/** @deprecated $untracked \u306E\u65E7\u540D\uFF08@wcstack/state 3.2 \u2014 4.0 \u3067\u5916\u308C\u308B\uFF09 */
|
|
208
212
|
$untrackDependency<T>(fn: () => T): T;
|
|
209
213
|
$eq(path: string, key: unknown): boolean;
|
|
210
214
|
$eqPath(path: string, keyPath: string): boolean;
|
|
@@ -233,6 +237,7 @@ interface WcsStateApi {
|
|
|
233
237
|
// T \u306B\u540C\u540D\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u660E\u793A\u7684\u306B\u4E8B\u524D\u5BA3\u8A00\u3057\u3066\u3044\u308C\u3070\u5199\u3055\u306A\u3044\uFF08\u4EA4\u5DEE\u3067\u305D\u306E\u578B\u307E\u3067 any \u306B\u6F70\u3055\u306A\u3044\u305F\u3081\uFF09\u3002
|
|
234
238
|
type _WcsDeclaredValues<T> =
|
|
235
239
|
(T extends { $scan: infer S } ? { [K in Exclude<keyof S & string, keyof T>]: any } : {}) &
|
|
240
|
+
(T extends { $stream: infer S } ? { [K in Exclude<keyof S & string, keyof T>]: any } : {}) &
|
|
236
241
|
(T extends { $streams: infer S } ? { [K in Exclude<keyof S & string, keyof T>]: any } : {});
|
|
237
242
|
type _WcsThis<T> = T & WcsStateApi & _WcsPathAccessor<T> & _WcsDeclaredValues<T>;
|
|
238
243
|
// $listKeys: { "<listPath>": "<field>" | (row) => key }\uFF08list/listKeys.ts\uFF09\u3002
|
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": "3.
|
|
3
|
+
"version": "3.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",
|