tutuca 0.9.69 → 0.9.71

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.
@@ -12324,18 +12324,13 @@ var UNKNOWN_DIRECTIVE = "UNKNOWN_DIRECTIVE";
12324
12324
  var UNKNOWN_X_OP = "UNKNOWN_X_OP";
12325
12325
  var UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR";
12326
12326
  var MAYBE_DROP_AT_PREFIX = "MAYBE_DROP_AT_PREFIX";
12327
+ var MAYBE_ADD_AT_PREFIX = "MAYBE_ADD_AT_PREFIX";
12327
12328
  var BAD_VALUE = "BAD_VALUE";
12328
12329
  var UNSUPPORTED_EXPR_SYNTAX = "UNSUPPORTED_EXPR_SYNTAX";
12329
12330
  var REDUNDANT_TEMPLATE_STRING = "REDUNDANT_TEMPLATE_STRING";
12330
12331
  var PLACEHOLDERLESS_TEMPLATE_STRING = "PLACEHOLDERLESS_TEMPLATE_STRING";
12331
12332
  var UNKNOWN_COMPONENT_SPEC_KEY = "UNKNOWN_COMPONENT_SPEC_KEY";
12332
12333
  var COMP_FIELD_BAD_SHAPE = "COMP_FIELD_BAD_SHAPE";
12333
- var PARSE_ISSUE_KIND_TO_LINT_ID = {
12334
- "unknown-directive": UNKNOWN_DIRECTIVE,
12335
- "unknown-x-op": UNKNOWN_X_OP,
12336
- "unknown-x-attr": UNKNOWN_X_ATTR,
12337
- "bad-value": BAD_VALUE
12338
- };
12339
12334
  var X_KNOWN_OP_NAMES = new Set([
12340
12335
  "slot",
12341
12336
  "text",
@@ -12346,17 +12341,19 @@ var X_KNOWN_OP_NAMES = new Set([
12346
12341
  "hide"
12347
12342
  ]);
12348
12343
  var X_KNOWN_ATTR_NAMES = new Set(["as", "when", "loop-with", "show", "hide"]);
12349
- var AT_PREFIX_HINT_KNOWN_BY_KIND = {
12350
- "unknown-x-op": X_KNOWN_OP_NAMES,
12351
- "unknown-x-attr": X_KNOWN_ATTR_NAMES
12352
- };
12344
+ var HOST_DIRECTIVE_ONLY_NAMES = new Set(["when", "enrich-with", "loop-with", "show", "hide"]);
12353
12345
  var LEVEL_WARN2 = "warn";
12354
12346
  var LEVEL_ERROR2 = "error";
12355
12347
  var LEVEL_HINT = "hint";
12356
- var PARSE_ISSUE_KIND_TO_KNOWN_NAMES = {
12357
- "unknown-directive": KNOWN_DIRECTIVE_NAMES,
12358
- "unknown-x-op": X_KNOWN_OP_NAMES,
12359
- "unknown-x-attr": X_KNOWN_ATTR_NAMES
12348
+ var PARSE_ISSUES = {
12349
+ "unknown-directive": { id: UNKNOWN_DIRECTIVE, candidates: KNOWN_DIRECTIVE_NAMES },
12350
+ "unknown-x-op": { id: UNKNOWN_X_OP, candidates: X_KNOWN_OP_NAMES, atPrefix: X_KNOWN_OP_NAMES },
12351
+ "unknown-x-attr": {
12352
+ id: UNKNOWN_X_ATTR,
12353
+ candidates: X_KNOWN_ATTR_NAMES,
12354
+ atPrefix: X_KNOWN_ATTR_NAMES
12355
+ },
12356
+ "bad-value": { id: BAD_VALUE }
12360
12357
  };
12361
12358
  function collectProtoMethodNames(proto) {
12362
12359
  const out = [];
@@ -12451,9 +12448,10 @@ function checkParseIssues(lx, view) {
12451
12448
  if (!issues)
12452
12449
  return;
12453
12450
  for (const { kind, info } of issues) {
12454
- const id = PARSE_ISSUE_KIND_TO_LINT_ID[kind];
12455
- if (!id)
12451
+ const rule = PARSE_ISSUES[kind];
12452
+ if (!rule)
12456
12453
  continue;
12454
+ const id = rule.id;
12457
12455
  if (kind === "bad-value") {
12458
12456
  const detected = classifyBadValue(info.value);
12459
12457
  if (detected) {
@@ -12461,15 +12459,13 @@ function checkParseIssues(lx, view) {
12461
12459
  continue;
12462
12460
  }
12463
12461
  }
12464
- const atPrefixKnown = AT_PREFIX_HINT_KNOWN_BY_KIND[kind];
12462
+ const atPrefixKnown = rule.atPrefix;
12465
12463
  const isAtPrefixedTypo = atPrefixKnown && info.name?.startsWith("@") && atPrefixKnown.has(info.name.slice(1));
12466
12464
  let suggestion = null;
12467
12465
  if (isAtPrefixedTypo) {
12468
12466
  suggestion = { kind: "drop-prefix", from: info.name, to: info.name.slice(1) };
12469
- } else {
12470
- const candidates = PARSE_ISSUE_KIND_TO_KNOWN_NAMES[kind];
12471
- if (candidates)
12472
- suggestion = replaceNameSuggestion(info.name, candidates);
12467
+ } else if (rule.candidates) {
12468
+ suggestion = replaceNameSuggestion(info.name, rule.candidates);
12473
12469
  }
12474
12470
  lx.error(id, info, suggestion);
12475
12471
  if (isAtPrefixedTypo) {
@@ -12639,70 +12635,83 @@ function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
12639
12635
  });
12640
12636
  }
12641
12637
  }
12642
- function checkConsistentAttrVal(lx, val, env, skipNameVal = false, errCtx = null) {
12643
- const { fields, proto, scope, alter } = env;
12644
- const valName = val?.constructor.name;
12645
- if (valName === "FieldVal") {
12638
+ var fixTo = (from, to) => ({ kind: "rewrite", from, to });
12639
+ function reportUnknownName(lx, code, name, candidates, info) {
12640
+ lx.error(code, { ...info, name }, replaceNameSuggestion(name, candidates));
12641
+ }
12642
+ var ATTR_VAL_CHECKERS = {
12643
+ FieldVal({ lx, val, env, errCtx }) {
12644
+ const { fields, proto } = env;
12646
12645
  const { name } = val;
12647
- if (fields[name] === undefined) {
12648
- if (proto[name] !== undefined) {
12649
- lx.error(FIELD_VAL_IS_METHOD, { ...errCtx, val, name }, { kind: "rewrite", from: `.${name}`, to: `$${name}` });
12650
- } else {
12651
- lx.error(FIELD_VAL_NOT_DEFINED, { ...errCtx, val, name }, replaceNameSuggestion(name, Object.keys(fields)));
12652
- }
12653
- }
12654
- } else if (valName === "MethodVal") {
12646
+ if (fields[name] !== undefined)
12647
+ return;
12648
+ if (proto[name] !== undefined)
12649
+ lx.error(FIELD_VAL_IS_METHOD, { ...errCtx, val, name }, fixTo(`.${name}`, `$${name}`));
12650
+ else
12651
+ reportUnknownName(lx, FIELD_VAL_NOT_DEFINED, name, Object.keys(fields), { ...errCtx, val });
12652
+ },
12653
+ MethodVal({ lx, val, env, errCtx }) {
12654
+ const { fields, proto } = env;
12655
12655
  const { name } = val;
12656
- if (proto[name] === undefined) {
12657
- if (fields[name] !== undefined) {
12658
- lx.error(METHOD_VAL_IS_FIELD, { ...errCtx, val, name }, { kind: "rewrite", from: `$${name}`, to: `.${name}` });
12659
- } else {
12660
- lx.error(METHOD_VAL_NOT_DEFINED, { ...errCtx, val, name }, replaceNameSuggestion(name, collectProtoMethodNames(proto)));
12661
- }
12662
- }
12663
- } else if (valName === "SeqAccessVal") {
12664
- checkConsistentAttrVal(lx, val.seqVal, env, skipNameVal, errCtx);
12665
- checkConsistentAttrVal(lx, val.keyVal, env, skipNameVal, errCtx);
12666
- } else if (valName === "RequestVal") {
12667
- if (scope.lookupRequest(val.name) === null) {
12668
- lx.error(UNKNOWN_REQUEST_NAME, { ...errCtx, name: val.name }, replaceNameSuggestion(val.name, scopeKeysAlong(scope, "reqsByName")));
12669
- }
12670
- } else if (valName === "TypeVal") {
12671
- if (scope.lookupComponent(val.name) === null) {
12672
- lx.error(UNKNOWN_COMPONENT_NAME, { ...errCtx, name: val.name }, replaceNameSuggestion(val.name, scopeKeysAlong(scope, "byName")));
12673
- }
12674
- } else if (valName === "NameVal") {
12675
- if (!skipNameVal && !isKnownHandlerName(val.name)) {
12676
- lx.error(UNKNOWN_HANDLER_ARG_NAME, { ...errCtx, name: val.name }, replaceNameSuggestion(val.name, KNOWN_HANDLER_NAMES));
12677
- }
12678
- } else if (valName === "StrTplVal") {
12656
+ if (proto[name] !== undefined)
12657
+ return;
12658
+ if (fields[name] !== undefined)
12659
+ lx.error(METHOD_VAL_IS_FIELD, { ...errCtx, val, name }, fixTo(`$${name}`, `.${name}`));
12660
+ else
12661
+ reportUnknownName(lx, METHOD_VAL_NOT_DEFINED, name, collectProtoMethodNames(proto), {
12662
+ ...errCtx,
12663
+ val
12664
+ });
12665
+ },
12666
+ SeqAccessVal({ val, recurse }) {
12667
+ recurse(val.seqVal);
12668
+ recurse(val.keyVal);
12669
+ },
12670
+ RequestVal({ lx, val, env, errCtx }) {
12671
+ if (env.scope.lookupRequest(val.name) === null)
12672
+ reportUnknownName(lx, UNKNOWN_REQUEST_NAME, val.name, scopeKeysAlong(env.scope, "reqsByName"), errCtx);
12673
+ },
12674
+ TypeVal({ lx, val, env, errCtx }) {
12675
+ if (env.scope.lookupComponent(val.name) === null)
12676
+ reportUnknownName(lx, UNKNOWN_COMPONENT_NAME, val.name, scopeKeysAlong(env.scope, "byName"), errCtx);
12677
+ },
12678
+ NameVal({ lx, val, errCtx, skipNameVal }) {
12679
+ if (!skipNameVal && !isKnownHandlerName(val.name))
12680
+ reportUnknownName(lx, UNKNOWN_HANDLER_ARG_NAME, val.name, KNOWN_HANDLER_NAMES, errCtx);
12681
+ },
12682
+ StrTplVal({ lx, val, errCtx, recurse }) {
12679
12683
  const vs = val.vals;
12680
12684
  const literal = val.toLiteralSource();
12681
12685
  if (literal !== null) {
12682
- lx.hint(PLACEHOLDERLESS_TEMPLATE_STRING, { ...errCtx, literal }, { kind: "rewrite", from: `$${literal}`, to: literal });
12686
+ lx.hint(PLACEHOLDERLESS_TEMPLATE_STRING, { ...errCtx, literal }, fixTo(`$${literal}`, literal));
12683
12687
  } else if (vs.length === 1) {
12684
12688
  const simpler = String(vs[0]);
12685
- lx.warn(REDUNDANT_TEMPLATE_STRING, { ...errCtx, simpler }, { kind: "rewrite", from: `$'{${simpler}}'`, to: simpler });
12686
- }
12687
- for (const subVal of vs) {
12688
- checkConsistentAttrVal(lx, subVal, env, skipNameVal, errCtx);
12689
+ lx.warn(REDUNDANT_TEMPLATE_STRING, { ...errCtx, simpler }, fixTo(`$'{${simpler}}'`, simpler));
12689
12690
  }
12690
- } else if (valName === "HandlerNameVal") {
12691
+ for (const subVal of vs)
12692
+ recurse(subVal);
12693
+ },
12694
+ HandlerNameVal({ lx, val, env, errCtx }) {
12691
12695
  env.referencedAlters?.add(val.name);
12692
- if (alter[val.name] === undefined) {
12693
- lx.error(ALT_HANDLER_NOT_DEFINED, { ...errCtx, name: val.name }, replaceNameSuggestion(val.name, Object.keys(alter)));
12694
- }
12695
- } else if (valName === "PredicateVal") {
12696
+ if (env.alter[val.name] === undefined)
12697
+ reportUnknownName(lx, ALT_HANDLER_NOT_DEFINED, val.name, Object.keys(env.alter), errCtx);
12698
+ },
12699
+ PredicateVal({ val, recurse }) {
12696
12700
  for (const arg of val.args)
12697
- checkConsistentAttrVal(lx, arg, env, skipNameVal, errCtx);
12698
- } else if (valName === "DynVal") {
12701
+ recurse(arg);
12702
+ },
12703
+ DynVal({ lx, val, env, errCtx }) {
12699
12704
  env.referencedDynamics?.add(val.name);
12700
- if (env.dynamicMap[val.name] === undefined) {
12701
- lx.error(DYN_VAL_NOT_DEFINED, { ...errCtx, name: val.name }, replaceNameSuggestion(val.name, Object.keys(env.dynamicMap)));
12702
- }
12703
- } else if (valName !== "ConstVal" && valName !== "BindVal") {
12704
- console.log(val);
12705
+ if (env.dynamicMap[val.name] === undefined)
12706
+ reportUnknownName(lx, DYN_VAL_NOT_DEFINED, val.name, Object.keys(env.dynamicMap), errCtx);
12705
12707
  }
12708
+ };
12709
+ function checkConsistentAttrVal(lx, val, env, skipNameVal = false, errCtx = null) {
12710
+ const check = ATTR_VAL_CHECKERS[val?.constructor.name];
12711
+ if (check === undefined)
12712
+ return;
12713
+ const recurse = (sub) => checkConsistentAttrVal(lx, sub, env, skipNameVal, errCtx);
12714
+ check({ lx, val, env, errCtx, skipNameVal, recurse });
12706
12715
  }
12707
12716
  var NODE_KIND_TO_CTX = {
12708
12717
  RenderTextNode: { originAttr: "<x text>" },
@@ -12734,6 +12743,23 @@ function attrOriginAttr(attr) {
12734
12743
  return "@dangerouslysetinnerhtml";
12735
12744
  return `:${attr.name}`;
12736
12745
  }
12746
+ function checkHostBareDirectives(lx, attrs, tag, isMacroCall) {
12747
+ if (isMacroCall || !attrs)
12748
+ return;
12749
+ const kind = attrs.constructor.name;
12750
+ let names;
12751
+ if (kind === "ConstAttrs")
12752
+ names = Object.keys(attrs.items);
12753
+ else if (kind === "DynAttrs")
12754
+ names = attrs.items.map((a) => a?.name);
12755
+ else
12756
+ return;
12757
+ for (const name of names) {
12758
+ if (HOST_DIRECTIVE_ONLY_NAMES.has(name)) {
12759
+ lx.hint(MAYBE_ADD_AT_PREFIX, { name, tag, suggestion: `@${name}` }, { kind: "add-prefix", from: name, to: `@${name}` });
12760
+ }
12761
+ }
12762
+ }
12737
12763
  function checkConsistentAttrs(lx, Comp, referencedAlters, referencedDynamics) {
12738
12764
  const { views } = Comp;
12739
12765
  const env = mkAttrValEnv(Comp, referencedAlters, referencedDynamics);
@@ -12742,6 +12768,7 @@ function checkConsistentAttrs(lx, Comp, referencedAlters, referencedDynamics) {
12742
12768
  const view = views[viewName];
12743
12769
  for (const entry of view.ctx.attrs) {
12744
12770
  const { attrs, wrapperAttrs, textChild, isMacroCall, tag } = entry;
12771
+ checkHostBareDirectives(lx, attrs, tag, isMacroCall);
12745
12772
  if (attrs?.constructor.name === "DynAttrs") {
12746
12773
  const sourcesByName = new Map;
12747
12774
  for (const attr of attrs.items) {
@@ -13500,6 +13527,8 @@ function lintIdToMessage(id, info) {
13500
13527
  const written = info.value !== undefined ? `${info.name}=${JSON.stringify(info.value)}` : info.name;
13501
13528
  return `'${written}' on <x> looks like a directive but is actually an x op/attr written with a leading '@'`;
13502
13529
  }
13530
+ case "MAYBE_ADD_AT_PREFIX":
13531
+ return `'${info.name}' on <${(info.tag ?? "").toLowerCase()}> is a plain attribute, but '@${info.name}' is a directive — add the leading '@'`;
13503
13532
  case "BAD_VALUE":
13504
13533
  return `${badValueMessage(info)}${fmtTagSuffix(info)}`;
13505
13534
  case "UNSUPPORTED_EXPR_SYNTAX":
@@ -13510,6 +13539,8 @@ function lintIdToMessage(id, info) {
13510
13539
  return `Template string has no dynamic parts — use the string literal ${info.literal} instead${fmtOriginSuffix(info)}`;
13511
13540
  case "UNKNOWN_COMPONENT_SPEC_KEY":
13512
13541
  return `Unknown component spec key '${info.key}' — value will be ignored at runtime`;
13542
+ case "COMP_FIELD_BAD_SHAPE":
13543
+ return info.kind === "args-not-object" ? `Field '${info.fieldName}': in { component, args }, 'args' must be a plain object, got ${info.got}` : `Field '${info.fieldName}': in { component, args }, 'component' must be the component name as a string, got ${info.gotName ? `the ${info.gotName} class` : info.got}`;
13513
13544
  case "HTML_TAG_NAME_HAS_UPPERCASE":
13514
13545
  return `Tag <${info.raw}> will be lowercased to <${info.lowercased}>${fmtLocationSuffix(info)}`;
13515
13546
  case "HTML_SVG_TAG_WILL_LOWERCASE":
@@ -15639,6 +15670,7 @@ export {
15639
15670
  METHOD_VAL_NOT_DEFINED,
15640
15671
  METHOD_VAL_IS_FIELD,
15641
15672
  MAYBE_DROP_AT_PREFIX,
15673
+ MAYBE_ADD_AT_PREFIX,
15642
15674
  List,
15643
15675
  LintReport,
15644
15676
  LintParseContext,