tutuca 0.9.70 → 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.
- package/dist/tutuca-cli.js +30 -1
- package/dist/tutuca-dev.ext.js +27 -0
- package/dist/tutuca-dev.js +25 -0
- package/dist/tutuca-dev.min.js +2 -2
- package/package.json +1 -1
- package/skill/tutuca/cli.md +6 -4
- package/skill/tutuca/core.md +21 -3
package/dist/tutuca-cli.js
CHANGED
|
@@ -8960,6 +8960,23 @@ function attrOriginAttr(attr) {
|
|
|
8960
8960
|
return "@dangerouslysetinnerhtml";
|
|
8961
8961
|
return `:${attr.name}`;
|
|
8962
8962
|
}
|
|
8963
|
+
function checkHostBareDirectives(lx, attrs, tag, isMacroCall) {
|
|
8964
|
+
if (isMacroCall || !attrs)
|
|
8965
|
+
return;
|
|
8966
|
+
const kind = attrs.constructor.name;
|
|
8967
|
+
let names;
|
|
8968
|
+
if (kind === "ConstAttrs")
|
|
8969
|
+
names = Object.keys(attrs.items);
|
|
8970
|
+
else if (kind === "DynAttrs")
|
|
8971
|
+
names = attrs.items.map((a) => a?.name);
|
|
8972
|
+
else
|
|
8973
|
+
return;
|
|
8974
|
+
for (const name of names) {
|
|
8975
|
+
if (HOST_DIRECTIVE_ONLY_NAMES.has(name)) {
|
|
8976
|
+
lx.hint(MAYBE_ADD_AT_PREFIX, { name, tag, suggestion: `@${name}` }, { kind: "add-prefix", from: name, to: `@${name}` });
|
|
8977
|
+
}
|
|
8978
|
+
}
|
|
8979
|
+
}
|
|
8963
8980
|
function checkConsistentAttrs(lx, Comp, referencedAlters, referencedDynamics) {
|
|
8964
8981
|
const { views } = Comp;
|
|
8965
8982
|
const env = mkAttrValEnv(Comp, referencedAlters, referencedDynamics);
|
|
@@ -8968,6 +8985,7 @@ function checkConsistentAttrs(lx, Comp, referencedAlters, referencedDynamics) {
|
|
|
8968
8985
|
const view = views[viewName];
|
|
8969
8986
|
for (const entry of view.ctx.attrs) {
|
|
8970
8987
|
const { attrs, wrapperAttrs, textChild, isMacroCall, tag } = entry;
|
|
8988
|
+
checkHostBareDirectives(lx, attrs, tag, isMacroCall);
|
|
8971
8989
|
if (attrs?.constructor.name === "DynAttrs") {
|
|
8972
8990
|
const sourcesByName = new Map;
|
|
8973
8991
|
for (const attr of attrs.items) {
|
|
@@ -9144,7 +9162,7 @@ class LintContext {
|
|
|
9144
9162
|
this.reports.push({ id, info, level, context: { ...this.frame }, suggestion });
|
|
9145
9163
|
}
|
|
9146
9164
|
}
|
|
9147
|
-
var KNOWN_COMPONENT_SPEC_KEYS, EMPTY_SET2, KNOWN_DIRECTIVE_NAMES, ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED", ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED", DYN_VAL_NOT_DEFINED = "DYN_VAL_NOT_DEFINED", DYN_ALIAS_NOT_REFERENCED = "DYN_ALIAS_NOT_REFERENCED", RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP", UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER", UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME", INPUT_HANDLER_NOT_IMPLEMENTED = "INPUT_HANDLER_NOT_IMPLEMENTED", INPUT_HANDLER_NOT_REFERENCED = "INPUT_HANDLER_NOT_REFERENCED", INPUT_HANDLER_METHOD_NOT_IMPLEMENTED = "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED", INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD = "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD", INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER", FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED", FIELD_VAL_IS_METHOD = "FIELD_VAL_IS_METHOD", METHOD_VAL_NOT_DEFINED = "METHOD_VAL_NOT_DEFINED", METHOD_VAL_IS_FIELD = "METHOD_VAL_IS_FIELD", DUPLICATE_ATTR_DEFINITION = "DUPLICATE_ATTR_DEFINITION", IF_NO_BRANCH_SET = "IF_NO_BRANCH_SET", UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME", UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME", UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG", UNKNOWN_DIRECTIVE = "UNKNOWN_DIRECTIVE", UNKNOWN_X_OP = "UNKNOWN_X_OP", UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR", MAYBE_DROP_AT_PREFIX = "MAYBE_DROP_AT_PREFIX", BAD_VALUE = "BAD_VALUE", UNSUPPORTED_EXPR_SYNTAX = "UNSUPPORTED_EXPR_SYNTAX", REDUNDANT_TEMPLATE_STRING = "REDUNDANT_TEMPLATE_STRING", PLACEHOLDERLESS_TEMPLATE_STRING = "PLACEHOLDERLESS_TEMPLATE_STRING", UNKNOWN_COMPONENT_SPEC_KEY = "UNKNOWN_COMPONENT_SPEC_KEY", COMP_FIELD_BAD_SHAPE = "COMP_FIELD_BAD_SHAPE", X_KNOWN_OP_NAMES, X_KNOWN_ATTR_NAMES, LEVEL_WARN2 = "warn", LEVEL_ERROR2 = "error", LEVEL_HINT = "hint", PARSE_ISSUES, UNSUPPORTED_EXPR_GUIDANCE, HTML_LINT_OPTS, NO_WRAPPERS, KNOWN_HANDLER_NAMES, fixTo = (from, to) => ({ kind: "rewrite", from, to }), ATTR_VAL_CHECKERS, NODE_KIND_TO_CTX, LintParseContext;
|
|
9165
|
+
var KNOWN_COMPONENT_SPEC_KEYS, EMPTY_SET2, KNOWN_DIRECTIVE_NAMES, ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED", ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED", DYN_VAL_NOT_DEFINED = "DYN_VAL_NOT_DEFINED", DYN_ALIAS_NOT_REFERENCED = "DYN_ALIAS_NOT_REFERENCED", RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP", UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER", UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME", INPUT_HANDLER_NOT_IMPLEMENTED = "INPUT_HANDLER_NOT_IMPLEMENTED", INPUT_HANDLER_NOT_REFERENCED = "INPUT_HANDLER_NOT_REFERENCED", INPUT_HANDLER_METHOD_NOT_IMPLEMENTED = "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED", INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD = "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD", INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER", FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED", FIELD_VAL_IS_METHOD = "FIELD_VAL_IS_METHOD", METHOD_VAL_NOT_DEFINED = "METHOD_VAL_NOT_DEFINED", METHOD_VAL_IS_FIELD = "METHOD_VAL_IS_FIELD", DUPLICATE_ATTR_DEFINITION = "DUPLICATE_ATTR_DEFINITION", IF_NO_BRANCH_SET = "IF_NO_BRANCH_SET", UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME", UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME", UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG", UNKNOWN_DIRECTIVE = "UNKNOWN_DIRECTIVE", UNKNOWN_X_OP = "UNKNOWN_X_OP", UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR", MAYBE_DROP_AT_PREFIX = "MAYBE_DROP_AT_PREFIX", MAYBE_ADD_AT_PREFIX = "MAYBE_ADD_AT_PREFIX", BAD_VALUE = "BAD_VALUE", UNSUPPORTED_EXPR_SYNTAX = "UNSUPPORTED_EXPR_SYNTAX", REDUNDANT_TEMPLATE_STRING = "REDUNDANT_TEMPLATE_STRING", PLACEHOLDERLESS_TEMPLATE_STRING = "PLACEHOLDERLESS_TEMPLATE_STRING", UNKNOWN_COMPONENT_SPEC_KEY = "UNKNOWN_COMPONENT_SPEC_KEY", COMP_FIELD_BAD_SHAPE = "COMP_FIELD_BAD_SHAPE", X_KNOWN_OP_NAMES, X_KNOWN_ATTR_NAMES, HOST_DIRECTIVE_ONLY_NAMES, LEVEL_WARN2 = "warn", LEVEL_ERROR2 = "error", LEVEL_HINT = "hint", PARSE_ISSUES, UNSUPPORTED_EXPR_GUIDANCE, HTML_LINT_OPTS, NO_WRAPPERS, KNOWN_HANDLER_NAMES, fixTo = (from, to) => ({ kind: "rewrite", from, to }), ATTR_VAL_CHECKERS, NODE_KIND_TO_CTX, LintParseContext;
|
|
9148
9166
|
var init_lint_check = __esm(() => {
|
|
9149
9167
|
init_anode();
|
|
9150
9168
|
init_htmllinter();
|
|
@@ -9174,6 +9192,7 @@ var init_lint_check = __esm(() => {
|
|
|
9174
9192
|
"hide"
|
|
9175
9193
|
]);
|
|
9176
9194
|
X_KNOWN_ATTR_NAMES = new Set(["as", "when", "loop-with", "show", "hide"]);
|
|
9195
|
+
HOST_DIRECTIVE_ONLY_NAMES = new Set(["when", "enrich-with", "loop-with", "show", "hide"]);
|
|
9177
9196
|
PARSE_ISSUES = {
|
|
9178
9197
|
"unknown-directive": { id: UNKNOWN_DIRECTIVE, candidates: KNOWN_DIRECTIVE_NAMES },
|
|
9179
9198
|
"unknown-x-op": { id: UNKNOWN_X_OP, candidates: X_KNOWN_OP_NAMES, atPrefix: X_KNOWN_OP_NAMES },
|
|
@@ -9459,6 +9478,12 @@ var init_lint_rules = __esm(() => {
|
|
|
9459
9478
|
group: "Templates / events",
|
|
9460
9479
|
summary: "An `<x>` op/attr was written with a leading `@` like a directive."
|
|
9461
9480
|
},
|
|
9481
|
+
{
|
|
9482
|
+
code: MAYBE_ADD_AT_PREFIX,
|
|
9483
|
+
level: "hint",
|
|
9484
|
+
group: "Templates / events",
|
|
9485
|
+
summary: "A directive name (`when`/`enrich-with`/`loop-with`/`show`/`hide`) was written as a plain attribute on a host element — add the `@` prefix."
|
|
9486
|
+
},
|
|
9462
9487
|
{
|
|
9463
9488
|
code: BAD_VALUE,
|
|
9464
9489
|
level: "error",
|
|
@@ -14925,6 +14950,8 @@ function lintIdToMessage(id, info) {
|
|
|
14925
14950
|
const written = info.value !== undefined ? `${info.name}=${JSON.stringify(info.value)}` : info.name;
|
|
14926
14951
|
return `'${written}' on <x> looks like a directive but is actually an x op/attr written with a leading '@'`;
|
|
14927
14952
|
}
|
|
14953
|
+
case "MAYBE_ADD_AT_PREFIX":
|
|
14954
|
+
return `'${info.name}' on <${(info.tag ?? "").toLowerCase()}> is a plain attribute, but '@${info.name}' is a directive — add the leading '@'`;
|
|
14928
14955
|
case "BAD_VALUE":
|
|
14929
14956
|
return `${badValueMessage(info)}${fmtTagSuffix(info)}`;
|
|
14930
14957
|
case "UNSUPPORTED_EXPR_SYNTAX":
|
|
@@ -14935,6 +14962,8 @@ function lintIdToMessage(id, info) {
|
|
|
14935
14962
|
return `Template string has no dynamic parts — use the string literal ${info.literal} instead${fmtOriginSuffix(info)}`;
|
|
14936
14963
|
case "UNKNOWN_COMPONENT_SPEC_KEY":
|
|
14937
14964
|
return `Unknown component spec key '${info.key}' — value will be ignored at runtime`;
|
|
14965
|
+
case "COMP_FIELD_BAD_SHAPE":
|
|
14966
|
+
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}`;
|
|
14938
14967
|
case "HTML_TAG_NAME_HAS_UPPERCASE":
|
|
14939
14968
|
return `Tag <${info.raw}> will be lowercased to <${info.lowercased}>${fmtLocationSuffix(info)}`;
|
|
14940
14969
|
case "HTML_SVG_TAG_WILL_LOWERCASE":
|
package/dist/tutuca-dev.ext.js
CHANGED
|
@@ -89,6 +89,7 @@ __export(exports_dev, {
|
|
|
89
89
|
METHOD_VAL_NOT_DEFINED: () => METHOD_VAL_NOT_DEFINED,
|
|
90
90
|
METHOD_VAL_IS_FIELD: () => METHOD_VAL_IS_FIELD,
|
|
91
91
|
MAYBE_DROP_AT_PREFIX: () => MAYBE_DROP_AT_PREFIX,
|
|
92
|
+
MAYBE_ADD_AT_PREFIX: () => MAYBE_ADD_AT_PREFIX,
|
|
92
93
|
LintReport: () => LintReport,
|
|
93
94
|
LintParseContext: () => LintParseContext,
|
|
94
95
|
LintFinding: () => LintFinding,
|
|
@@ -5854,6 +5855,7 @@ __export(exports_lint_check, {
|
|
|
5854
5855
|
METHOD_VAL_NOT_DEFINED: () => METHOD_VAL_NOT_DEFINED,
|
|
5855
5856
|
METHOD_VAL_IS_FIELD: () => METHOD_VAL_IS_FIELD,
|
|
5856
5857
|
MAYBE_DROP_AT_PREFIX: () => MAYBE_DROP_AT_PREFIX,
|
|
5858
|
+
MAYBE_ADD_AT_PREFIX: () => MAYBE_ADD_AT_PREFIX,
|
|
5857
5859
|
LintParseContext: () => LintParseContext,
|
|
5858
5860
|
LintContext: () => LintContext,
|
|
5859
5861
|
INPUT_HANDLER_NOT_REFERENCED: () => INPUT_HANDLER_NOT_REFERENCED,
|
|
@@ -8174,6 +8176,7 @@ var UNKNOWN_DIRECTIVE = "UNKNOWN_DIRECTIVE";
|
|
|
8174
8176
|
var UNKNOWN_X_OP = "UNKNOWN_X_OP";
|
|
8175
8177
|
var UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR";
|
|
8176
8178
|
var MAYBE_DROP_AT_PREFIX = "MAYBE_DROP_AT_PREFIX";
|
|
8179
|
+
var MAYBE_ADD_AT_PREFIX = "MAYBE_ADD_AT_PREFIX";
|
|
8177
8180
|
var BAD_VALUE = "BAD_VALUE";
|
|
8178
8181
|
var UNSUPPORTED_EXPR_SYNTAX = "UNSUPPORTED_EXPR_SYNTAX";
|
|
8179
8182
|
var REDUNDANT_TEMPLATE_STRING = "REDUNDANT_TEMPLATE_STRING";
|
|
@@ -8190,6 +8193,7 @@ var X_KNOWN_OP_NAMES = new Set([
|
|
|
8190
8193
|
"hide"
|
|
8191
8194
|
]);
|
|
8192
8195
|
var X_KNOWN_ATTR_NAMES = new Set(["as", "when", "loop-with", "show", "hide"]);
|
|
8196
|
+
var HOST_DIRECTIVE_ONLY_NAMES = new Set(["when", "enrich-with", "loop-with", "show", "hide"]);
|
|
8193
8197
|
var LEVEL_WARN2 = "warn";
|
|
8194
8198
|
var LEVEL_ERROR2 = "error";
|
|
8195
8199
|
var LEVEL_HINT = "hint";
|
|
@@ -8591,6 +8595,23 @@ function attrOriginAttr(attr) {
|
|
|
8591
8595
|
return "@dangerouslysetinnerhtml";
|
|
8592
8596
|
return `:${attr.name}`;
|
|
8593
8597
|
}
|
|
8598
|
+
function checkHostBareDirectives(lx, attrs, tag, isMacroCall) {
|
|
8599
|
+
if (isMacroCall || !attrs)
|
|
8600
|
+
return;
|
|
8601
|
+
const kind = attrs.constructor.name;
|
|
8602
|
+
let names;
|
|
8603
|
+
if (kind === "ConstAttrs")
|
|
8604
|
+
names = Object.keys(attrs.items);
|
|
8605
|
+
else if (kind === "DynAttrs")
|
|
8606
|
+
names = attrs.items.map((a) => a?.name);
|
|
8607
|
+
else
|
|
8608
|
+
return;
|
|
8609
|
+
for (const name of names) {
|
|
8610
|
+
if (HOST_DIRECTIVE_ONLY_NAMES.has(name)) {
|
|
8611
|
+
lx.hint(MAYBE_ADD_AT_PREFIX, { name, tag, suggestion: `@${name}` }, { kind: "add-prefix", from: name, to: `@${name}` });
|
|
8612
|
+
}
|
|
8613
|
+
}
|
|
8614
|
+
}
|
|
8594
8615
|
function checkConsistentAttrs(lx, Comp, referencedAlters, referencedDynamics) {
|
|
8595
8616
|
const { views } = Comp;
|
|
8596
8617
|
const env = mkAttrValEnv(Comp, referencedAlters, referencedDynamics);
|
|
@@ -8599,6 +8620,7 @@ function checkConsistentAttrs(lx, Comp, referencedAlters, referencedDynamics) {
|
|
|
8599
8620
|
const view = views[viewName];
|
|
8600
8621
|
for (const entry of view.ctx.attrs) {
|
|
8601
8622
|
const { attrs, wrapperAttrs, textChild, isMacroCall, tag } = entry;
|
|
8623
|
+
checkHostBareDirectives(lx, attrs, tag, isMacroCall);
|
|
8602
8624
|
if (attrs?.constructor.name === "DynAttrs") {
|
|
8603
8625
|
const sourcesByName = new Map;
|
|
8604
8626
|
for (const attr of attrs.items) {
|
|
@@ -9400,6 +9422,8 @@ function lintIdToMessage(id, info) {
|
|
|
9400
9422
|
const written = info.value !== undefined ? `${info.name}=${JSON.stringify(info.value)}` : info.name;
|
|
9401
9423
|
return `'${written}' on <x> looks like a directive but is actually an x op/attr written with a leading '@'`;
|
|
9402
9424
|
}
|
|
9425
|
+
case "MAYBE_ADD_AT_PREFIX":
|
|
9426
|
+
return `'${info.name}' on <${(info.tag ?? "").toLowerCase()}> is a plain attribute, but '@${info.name}' is a directive — add the leading '@'`;
|
|
9403
9427
|
case "BAD_VALUE":
|
|
9404
9428
|
return `${badValueMessage(info)}${fmtTagSuffix(info)}`;
|
|
9405
9429
|
case "UNSUPPORTED_EXPR_SYNTAX":
|
|
@@ -9410,6 +9434,8 @@ function lintIdToMessage(id, info) {
|
|
|
9410
9434
|
return `Template string has no dynamic parts — use the string literal ${info.literal} instead${fmtOriginSuffix(info)}`;
|
|
9411
9435
|
case "UNKNOWN_COMPONENT_SPEC_KEY":
|
|
9412
9436
|
return `Unknown component spec key '${info.key}' — value will be ignored at runtime`;
|
|
9437
|
+
case "COMP_FIELD_BAD_SHAPE":
|
|
9438
|
+
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}`;
|
|
9413
9439
|
case "HTML_TAG_NAME_HAS_UPPERCASE":
|
|
9414
9440
|
return `Tag <${info.raw}> will be lowercased to <${info.lowercased}>${fmtLocationSuffix(info)}`;
|
|
9415
9441
|
case "HTML_SVG_TAG_WILL_LOWERCASE":
|
|
@@ -11629,6 +11655,7 @@ export {
|
|
|
11629
11655
|
METHOD_VAL_NOT_DEFINED,
|
|
11630
11656
|
METHOD_VAL_IS_FIELD,
|
|
11631
11657
|
MAYBE_DROP_AT_PREFIX,
|
|
11658
|
+
MAYBE_ADD_AT_PREFIX,
|
|
11632
11659
|
LintReport,
|
|
11633
11660
|
LintParseContext,
|
|
11634
11661
|
LintFinding,
|
package/dist/tutuca-dev.js
CHANGED
|
@@ -12324,6 +12324,7 @@ 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";
|
|
@@ -12340,6 +12341,7 @@ var X_KNOWN_OP_NAMES = new Set([
|
|
|
12340
12341
|
"hide"
|
|
12341
12342
|
]);
|
|
12342
12343
|
var X_KNOWN_ATTR_NAMES = new Set(["as", "when", "loop-with", "show", "hide"]);
|
|
12344
|
+
var HOST_DIRECTIVE_ONLY_NAMES = new Set(["when", "enrich-with", "loop-with", "show", "hide"]);
|
|
12343
12345
|
var LEVEL_WARN2 = "warn";
|
|
12344
12346
|
var LEVEL_ERROR2 = "error";
|
|
12345
12347
|
var LEVEL_HINT = "hint";
|
|
@@ -12741,6 +12743,23 @@ function attrOriginAttr(attr) {
|
|
|
12741
12743
|
return "@dangerouslysetinnerhtml";
|
|
12742
12744
|
return `:${attr.name}`;
|
|
12743
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
|
+
}
|
|
12744
12763
|
function checkConsistentAttrs(lx, Comp, referencedAlters, referencedDynamics) {
|
|
12745
12764
|
const { views } = Comp;
|
|
12746
12765
|
const env = mkAttrValEnv(Comp, referencedAlters, referencedDynamics);
|
|
@@ -12749,6 +12768,7 @@ function checkConsistentAttrs(lx, Comp, referencedAlters, referencedDynamics) {
|
|
|
12749
12768
|
const view = views[viewName];
|
|
12750
12769
|
for (const entry of view.ctx.attrs) {
|
|
12751
12770
|
const { attrs, wrapperAttrs, textChild, isMacroCall, tag } = entry;
|
|
12771
|
+
checkHostBareDirectives(lx, attrs, tag, isMacroCall);
|
|
12752
12772
|
if (attrs?.constructor.name === "DynAttrs") {
|
|
12753
12773
|
const sourcesByName = new Map;
|
|
12754
12774
|
for (const attr of attrs.items) {
|
|
@@ -13507,6 +13527,8 @@ function lintIdToMessage(id, info) {
|
|
|
13507
13527
|
const written = info.value !== undefined ? `${info.name}=${JSON.stringify(info.value)}` : info.name;
|
|
13508
13528
|
return `'${written}' on <x> looks like a directive but is actually an x op/attr written with a leading '@'`;
|
|
13509
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 '@'`;
|
|
13510
13532
|
case "BAD_VALUE":
|
|
13511
13533
|
return `${badValueMessage(info)}${fmtTagSuffix(info)}`;
|
|
13512
13534
|
case "UNSUPPORTED_EXPR_SYNTAX":
|
|
@@ -13517,6 +13539,8 @@ function lintIdToMessage(id, info) {
|
|
|
13517
13539
|
return `Template string has no dynamic parts — use the string literal ${info.literal} instead${fmtOriginSuffix(info)}`;
|
|
13518
13540
|
case "UNKNOWN_COMPONENT_SPEC_KEY":
|
|
13519
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}`;
|
|
13520
13544
|
case "HTML_TAG_NAME_HAS_UPPERCASE":
|
|
13521
13545
|
return `Tag <${info.raw}> will be lowercased to <${info.lowercased}>${fmtLocationSuffix(info)}`;
|
|
13522
13546
|
case "HTML_SVG_TAG_WILL_LOWERCASE":
|
|
@@ -15646,6 +15670,7 @@ export {
|
|
|
15646
15670
|
METHOD_VAL_NOT_DEFINED,
|
|
15647
15671
|
METHOD_VAL_IS_FIELD,
|
|
15648
15672
|
MAYBE_DROP_AT_PREFIX,
|
|
15673
|
+
MAYBE_ADD_AT_PREFIX,
|
|
15649
15674
|
List,
|
|
15650
15675
|
LintReport,
|
|
15651
15676
|
LintParseContext,
|