@wcstack/typescript 4.6.2 → 4.7.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 CHANGED
@@ -641,7 +641,7 @@ function loadSchemaCore() {
641
641
  return cached;
642
642
  }
643
643
 
644
- var version = "4.6.2";
644
+ var version = "4.7.0";
645
645
  var pkg = {
646
646
  version: version};
647
647
 
@@ -60,6 +60,9 @@ var WcsDiagnosticCode = {
60
60
  // lint の限界の告知(作者の誤りではない): `export default { … }` のトップレベルの spread が持ち込むキーは読めないので、
61
61
  // stateSchema の無い state のパスは検査しない — それを spread の上で 1 回だけ言う。info。
62
62
  PathDynamicUnknown: "wcs/path-dynamic-unknown",
63
+ // lint の限界の告知(作者の誤りではない): 読めない `<wcs-state src>`(/ から始まるパス・URL・無いファイル)の state は
64
+ // パスもスクリプトの規則も検査しない — それを src の上で 1 回だけ言う。info(docs/seam-apps.md、prod-booking)。
65
+ StateSrcUnread: "wcs/state-src-unread",
63
66
  // --- existing binding-expression validators (retrofitted) ---
64
67
  FilterUnknown: "wcs/filter-unknown",
65
68
  FilterArity: "wcs/filter-arity",
@@ -2606,11 +2609,11 @@ var registered = {
2606
2609
  percent: { factory: percent, arity: [0, 1] },
2607
2610
  unit: { factory: nullishPassthrough(unit), arity: [1, 1] },
2608
2611
  // The locale-dependent three take a locale like `locale` does (`date(ja-JP)`), and a style (`date(ja-JP,long)`)
2609
- date: { factory: date, arity: [0, 2] },
2610
- time: { factory: time, arity: [0, 2] },
2611
- datetime: { factory: datetime, arity: [0, 2] },
2612
- ymd: { factory: ymd, arity: [0, 1] },
2613
- hms: { factory: hms, arity: [0, 1] },
2612
+ date: { factory: nullishPassthrough(date), arity: [0, 2] },
2613
+ time: { factory: nullishPassthrough(time), arity: [0, 2] },
2614
+ datetime: { factory: nullishPassthrough(datetime), arity: [0, 2] },
2615
+ ymd: { factory: nullishPassthrough(ymd), arity: [0, 1] },
2616
+ hms: { factory: nullishPassthrough(hms), arity: [0, 1] },
2614
2617
  // the core set of 4.0.0-rc.3 (the core's own: eq ne not lt le gt ge falsy truthy boolean)
2615
2618
  eq: eq2,
2616
2619
  ne: ne2,
@@ -3835,11 +3838,21 @@ function expressionShape(text3, paths, aliases) {
3835
3838
  if (scan.startsWith("[")) {
3836
3839
  const inner = extractDelimitedContent(expr, scan, 0, "[", "]");
3837
3840
  rest = inner.length + 2;
3838
- const spread = /^\s*\.\.\.([\s\S]+)$/.exec(inner);
3839
- if (spread === null || splitTopLevelElements(inner).length !== 1) return null;
3840
- const source = expressionShape(spread[1], paths, aliases);
3841
- if (source === null || !source.isList) return null;
3842
- shape = source;
3841
+ if (inner.trim() === "") {
3842
+ shape = EMPTY_LIST;
3843
+ } else {
3844
+ const spread = /^\s*\.\.\.([\s\S]+)$/.exec(inner);
3845
+ if (spread === null || splitTopLevelElements(inner).length !== 1) return null;
3846
+ const source = expressionShape(spread[1], paths, aliases);
3847
+ if (source === null || !source.isList) return null;
3848
+ shape = source;
3849
+ }
3850
+ } else if (scan.startsWith("(")) {
3851
+ const inner = extractDelimitedContent(expr, scan, 0, "(", ")");
3852
+ const base = expressionShape(inner, paths, aliases);
3853
+ if (base === null) return null;
3854
+ shape = base;
3855
+ rest = inner.length + 2;
3843
3856
  } else {
3844
3857
  const base = readBase(expr, scan, aliases, paths);
3845
3858
  if (base === null) return null;
@@ -3913,8 +3926,7 @@ function applyChain(expr, scan, start, initial) {
3913
3926
  if (!shape.isList) return null;
3914
3927
  shape = pickRow(shape);
3915
3928
  } else if (method === "map") {
3916
- if (!shape.isList) return null;
3917
- const mapped = mapRows(args, shape);
3929
+ const mapped = mapRows(args, shape.isList ? shape : OPAQUE);
3918
3930
  if (mapped === null) return null;
3919
3931
  shape = mapped;
3920
3932
  } else {
@@ -3924,6 +3936,7 @@ function applyChain(expr, scan, start, initial) {
3924
3936
  return shape.opaque ? null : shape;
3925
3937
  }
3926
3938
  var OPAQUE = { isList: true, mirrors: [], fields: [], opaque: true };
3939
+ var EMPTY_LIST = { isList: true, mirrors: [], fields: [] };
3927
3940
  function pickRow(shape) {
3928
3941
  return {
3929
3942
  isList: false,
@@ -11371,6 +11384,7 @@ var ja = {
11371
11384
  commandTokenUnbound: (t) => `\u30B3\u30DE\u30F3\u30C9\u30C8\u30FC\u30AF\u30F3 "${t}" \u3092 emit \u3057\u3066\u3044\u307E\u3059\u304C\u3001\u3053\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306B\u305D\u308C\u3092\u53D7\u3051\u308B command.<\u30E1\u30BD\u30C3\u30C9>: ${t} \u306E\u675F\u7E1B\u304C\u3042\u308A\u307E\u305B\u3093\u3002emit \u306F\u8AB0\u306B\u3082\u5C4A\u304D\u307E\u305B\u3093\u3002\u30E1\u30BD\u30C3\u30C9\u3092\u547C\u3076\u8981\u7D20\u306B\u675F\u306D\u3066\u304F\u3060\u3055\u3044\uFF08command.focus: ${t}\uFF09`,
11372
11385
  writePathMissing: (k) => `"${k}" \u306F state \u304C\u5BA3\u8A00\u3057\u3066\u3044\u306A\u3044\u30AD\u30FC\u3067\u3059\u3002\u66F8\u304D\u8FBC\u307F\u306F\u65B0\u3057\u3044\u30AD\u30FC\u3092\u4F5C\u308B\u3060\u3051\u3067\u3001\u5BA3\u8A00\u3057\u305F\u30AD\u30FC\u306E\u675F\u7E1B\u306B\u306F\u5C4A\u304D\u307E\u305B\u3093`,
11373
11386
  readPathMissing: (p, top) => top ? `"${p}" \u306F state \u304C\u5BA3\u8A00\u3057\u3066\u3044\u306A\u3044\u30AD\u30FC\u3067\u3059\u3002\u8AAD\u3093\u3060\u6642\u70B9\u3067\u4F8B\u5916\u306B\u306A\u308A\u307E\u3059\uFF08#301\uFF09` : `\u30D1\u30B9 "${p}" \u306F\u72B6\u614B\u5B9A\u7FA9\u306B\u5B58\u5728\u3057\u307E\u305B\u3093\u3002\u8AAD\u307F\u306F undefined \u306B\u306A\u308A\u3001\u305D\u3053\u304B\u3089\u8A08\u7B97\u3057\u305F\u5024\u306F\u9ED9\u3063\u3066\u9055\u3044\u307E\u3059`,
11387
+ stateSrcUnread: (src) => `"${src}" \u3092\u8AAD\u3081\u306A\u3044\u306E\u3067\u3001\u3053\u306E state \u306E\u30D1\u30B9\u3082\u30B9\u30AF\u30EA\u30D7\u30C8\u306E\u898F\u5247\u3082\u691C\u67FB\u3057\u3066\u3044\u307E\u305B\u3093\u3002src \u306F\u3053\u306E\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u306E\u76F8\u5BFE\u30D1\u30B9\u3067\u8AAD\u307F\u307E\u3059\uFF08/ \u304B\u3089\u59CB\u307E\u308B\u30D1\u30B9\u3068 URL \u306F\u8AAD\u307F\u307E\u305B\u3093\uFF09\u3002\u30B5\u30FC\u30D0\u30FC\u3068\u540C\u3058\u4E26\u3073\u306B\u7F6E\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u3092\u3001\u3053\u306E\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u306E\u76F8\u5BFE\u30D1\u30B9\u3067\u6307\u3057\u3066\u304F\u3060\u3055\u3044`,
11374
11388
  pathDynamicUnknownSpread: (sp) => `${sp} \u304C\u6301\u3061\u8FBC\u3080\u30AD\u30FC\u306F\u9759\u7684\u306B\u8AAD\u3081\u306A\u3044\u306E\u3067\u3001\u3053\u306E state \u306E\u30D1\u30B9\u306F\u691C\u67FB\u3057\u3066\u3044\u307E\u305B\u3093\uFF08\u675F\u7E1B\u30FBgetter \u306E\u4E2D\u306E\u8AAD\u307F\u30FB$watch \u306E\u30AD\u30FC\uFF09\u3002\u30AD\u30FC\u3092 wcstack.manifest.json \u306E stateSchema \u306B\u5BA3\u8A00\u3059\u308B\u3068\u691C\u67FB\u3055\u308C\u307E\u3059\u3002npx wcs-schema\uFF08@wcstack/typescript\uFF09\u304C state \u306E\u578B\uFF08JSDoc\u30FBTypeScript\uFF09\u304B\u3089\u4F5C\u308C\u307E\u3059`,
11375
11389
  pathReadonlyTwoWay: (p, prop) => `"${p}" \u306F setter \u306E\u7121\u3044 getter \u3067\u3059\u304C\u3001${prop}: \u306F\u8AAD\u8005\u306E\u5165\u529B\u3092\u66F8\u304D\u623B\u3059\u306E\u3067\u3001\u5165\u529B\u306E\u305F\u3073\u306B\u66F8\u304D\u8FBC\u307F\u304C\u5931\u6557\u3057\u307E\u3059\uFF08"${p}" is a getter without a setter\uFF09\u3002setter \u3092\u8DB3\u3059\uFF08set "${p}"(v) { \u2026 }\uFF09\u304B\u3001#ro \u3067\u4E00\u65B9\u5411\u306B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08${prop}#ro: ${p}\uFF09`,
11376
11390
  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`,
@@ -11580,6 +11594,7 @@ var en = {
11580
11594
  commandTokenUnbound: (t) => `The command token "${t}" is emitted, but no command.<method>: ${t} binding in this document receives it, so the emit reaches nothing. Bind it on the element whose method it should call (command.focus: ${t})`,
11581
11595
  writePathMissing: (k) => `"${k}" is not a key the state declares. The write creates a new key and reaches no binding of a declared one`,
11582
11596
  readPathMissing: (p, top) => top ? `"${p}" is not a key the state declares. Reading it throws (#301)` : `Path "${p}" does not exist in the state definition. The read gives undefined, and what is computed from it is wrong without a word`,
11597
+ stateSrcUnread: (src) => `"${src}" cannot be read, so this state's paths and script rules are not checked. A src is read relative to this file (a path from / or a URL is not read): point it at the file laid out as on the server, relative to this file`,
11583
11598
  pathDynamicUnknownSpread: (sp) => `The keys ${sp} brings in cannot be read statically, so this state's paths are not checked (bindings, reads in getters, $watch keys). Declare the keys in the stateSchema of wcstack.manifest.json to have them checked; npx wcs-schema (@wcstack/typescript) derives it from the state's types (JSDoc or TypeScript)`,
11584
11599
  pathReadonlyTwoWay: (p, prop) => `"${p}" is a getter without a setter, and ${prop}: writes back what the reader enters, so every edit fails ("${p}" is a getter without a setter). Add a setter (set "${p}"(v) { \u2026 }), or bind it one way with #ro (${prop}#ro: ${p})`,
11585
11600
  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`,
@@ -17216,6 +17231,27 @@ function nearName(path, tree) {
17216
17231
  return null;
17217
17232
  }
17218
17233
 
17234
+ // src/service/stateSourceValidator.ts
17235
+ function validateStateSources(html, stateTagName = "wcs-state", locale2, fileReader) {
17236
+ if (fileReader === void 0) return [];
17237
+ const out = [];
17238
+ for (const element2 of parseWcsStateElements(html, stateTagName)) {
17239
+ const src = element2.srcAttr;
17240
+ const span = element2.srcSpan;
17241
+ if (src === void 0 || span === void 0 || element2.stateAttr !== void 0 || element2.bindComponent) continue;
17242
+ const readable = src.endsWith(".json") ? Boolean(fileReader(src)) : readStateScriptFile(src, fileReader) !== void 0;
17243
+ if (readable) continue;
17244
+ out.push({
17245
+ code: WcsDiagnosticCode.StateSrcUnread,
17246
+ start: span.start,
17247
+ end: span.end,
17248
+ message: getMessages(locale2).stateSrcUnread(src),
17249
+ severity: "info"
17250
+ });
17251
+ }
17252
+ return out;
17253
+ }
17254
+
17219
17255
  // src/core/sidecar/discover.ts
17220
17256
  var APPLICATION_MANIFEST_FILENAME = "wcstack.manifest.json";
17221
17257
  var MAX_ASCEND = 16;
@@ -17323,9 +17359,9 @@ function validateDocument(text3, options = {}) {
17323
17359
  const stateTagName = options.stateTagName ?? "wcs-state";
17324
17360
  const fileReader = options.fileReader;
17325
17361
  const applicationSchema = options.applicationSchema ?? (fileReader !== void 0 ? discoverApplicationManifest(fileReader)?.schema : void 0);
17326
- const found = validateText(text3, options, applicationSchema);
17362
+ const found = [...validateText(text3, options, applicationSchema), ...validateStateSources(text3, stateTagName, options.locale, fileReader)];
17327
17363
  const page = fileReader === void 0 ? null : inlineExternalStates(text3, stateTagName, fileReader);
17328
- if (page === null) return found;
17364
+ if (page === null) return sortDiagnostics(found);
17329
17365
  const key = (d) => [d.code, d.start, d.end, d.message, d.origin?.path, d.origin?.start].join("\0");
17330
17366
  const seen2 = new Set(found.map(key));
17331
17367
  const out = [...found];
package/dist/tsc-core.cjs CHANGED
@@ -6403,11 +6403,11 @@ var registered = {
6403
6403
  percent: { factory: percent, arity: [0, 1] },
6404
6404
  unit: { factory: nullishPassthrough(unit), arity: [1, 1] },
6405
6405
  // The locale-dependent three take a locale like `locale` does (`date(ja-JP)`), and a style (`date(ja-JP,long)`)
6406
- date: { factory: date, arity: [0, 2] },
6407
- time: { factory: time, arity: [0, 2] },
6408
- datetime: { factory: datetime, arity: [0, 2] },
6409
- ymd: { factory: ymd, arity: [0, 1] },
6410
- hms: { factory: hms, arity: [0, 1] },
6406
+ date: { factory: nullishPassthrough(date), arity: [0, 2] },
6407
+ time: { factory: nullishPassthrough(time), arity: [0, 2] },
6408
+ datetime: { factory: nullishPassthrough(datetime), arity: [0, 2] },
6409
+ ymd: { factory: nullishPassthrough(ymd), arity: [0, 1] },
6410
+ hms: { factory: nullishPassthrough(hms), arity: [0, 1] },
6411
6411
  // the core set of 4.0.0-rc.3 (the core's own: eq ne not lt le gt ge falsy truthy boolean)
6412
6412
  eq: eq2,
6413
6413
  ne: ne2,
@@ -643,7 +643,7 @@ function loadSchemaCore() {
643
643
  return cached;
644
644
  }
645
645
 
646
- var version = "4.6.2";
646
+ var version = "4.7.0";
647
647
  var pkg = {
648
648
  version: version};
649
649
 
package/dist/wcs-tsc.mjs CHANGED
@@ -25,7 +25,7 @@ function unsupportedTypeScriptMessage(version) {
25
25
  return `@wcstack/typescript runs on TypeScript 5 or 6, and the project has TypeScript ${version}, which has no JavaScript compiler API: npm i -D typescript@6`;
26
26
  }
27
27
 
28
- var version = "4.6.2";
28
+ var version = "4.7.0";
29
29
  var pkg = {
30
30
  version: version};
31
31
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wcstack/typescript",
3
- "version": "4.6.2",
3
+ "version": "4.7.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",