UNPKG

@lwc/errors

Version:

LWC Error Utilities

1,366 lines (1,357 loc) 54.7 kB
/** * Copyright (c) 2025 Salesforce, Inc. */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); /* * Copyright (c) 2024, Salesforce, Inc. * All rights reserved. * SPDX-License-Identifier: MIT * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ const templateRegex = /\{([0-9]+)\}/g; /** * Replaces {0} in the given string with the value from the given array * @param template Template string to fill * @param args Values to fill with * @returns Filled string */ function templateString(template, args) { return template.replace(templateRegex, (_, index) => { return args[index]; }); } /* * Copyright (c) 2018, salesforce.com, inc. * All rights reserved. * SPDX-License-Identifier: MIT * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ exports.DiagnosticLevel = void 0; (function (DiagnosticLevel) { /** Unexpected error, parsing error, bundling error */ DiagnosticLevel[DiagnosticLevel["Fatal"] = 0] = "Fatal"; /** Linting error with error level, invalid external reference, invalid import, invalid transform */ DiagnosticLevel[DiagnosticLevel["Error"] = 1] = "Error"; /** Linting error with warning level, usage of an API to be deprecated */ DiagnosticLevel[DiagnosticLevel["Warning"] = 2] = "Warning"; /** Logging messages */ DiagnosticLevel[DiagnosticLevel["Log"] = 3] = "Log"; })(exports.DiagnosticLevel || (exports.DiagnosticLevel = {})); /* * Copyright (c) 2024, Salesforce, Inc. * All rights reserved. * SPDX-License-Identifier: MIT * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ class CompilerError extends Error { constructor(code, message, filename, location) { super(message); this.level = exports.DiagnosticLevel.Error; this.code = code; this.filename = filename; this.location = location; } static from(diagnostic, origin) { const { code, message } = diagnostic; const filename = getFilename(origin, diagnostic); const location = getLocation(origin, diagnostic); const compilerError = new CompilerError(code, message, filename, location); // The stack here is misleading and doesn't point to the cause of the original error message // TODO [W-5712064]: Enhance diagnostics with useful stack trace and source code compilerError.stack = undefined; return compilerError; } toDiagnostic() { return { code: this.code, message: this.message, level: this.level, filename: this.filename, location: this.location, }; } } /** * Extracts an error code from the given error. * @param error The error to check. * @returns The error code, if found. */ function getCodeFromError(error) { if (error.lwcCode && typeof error.lwcCode === 'number') { return error.lwcCode; } else if (error.code && typeof error.code === 'number') { return error.code; } return undefined; } /** * Extracts the filename from the provided parameters, preferring to use the compiler diagnostic * origin, if provided. * @param origin Compiler diagnositic origin data * @param obj Any object that might have a filename associated * @returns The filename, if found. */ function getFilename(origin, obj) { // Give priority to explicit origin if (origin && origin.filename) { return origin.filename; } else if (obj) { return obj.filename || obj.fileName || obj.file; } return undefined; } /** * Extracts the location from the provided parameters, preferring to use the compiler diagnostic * origin, if provided. * @param origin Compiler diagnositic origin data * @param obj Any object that might have a location property * @returns The location, if found. */ function getLocation(origin, obj) { // Give priority to explicit origin if (origin && origin.location) { return origin.location; } return getLocationFromObject(obj); } function getLocationFromObject(obj) { if (obj) { if (obj.location) { return obj.location; } else if (obj.loc) { return obj.loc; } else if (Number.isInteger(obj.line) && Number.isInteger(obj.column)) { return { line: obj.line, column: obj.column, start: obj.start, length: obj.length }; } } return undefined; } /* * Copyright (c) 2024, Salesforce, Inc. * All rights reserved. * SPDX-License-Identifier: MIT * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ /* * For the next available error code, reference (and update!) the value in ./index.ts */ const GENERIC_COMPILER_ERROR = { code: 1001, message: 'Unexpected compilation error: {0}', level: exports.DiagnosticLevel.Error, url: '', }; const CompilerValidationErrors = { INVALID_COMPAT_PROPERTY: { code: 1013, message: 'Expected a boolean for outputConfig.compat, received "{0}".', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_ENV_ENTRY_VALUE: { code: 1014, message: 'Expected a string for outputConfig.env["{0}"], received "{1}".', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_ENV_PROPERTY: { code: 1015, message: 'Expected an object for outputConfig.env, received "{0}".', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_FILES_PROPERTY: { code: 1016, message: 'Expected an object with files to be compiled.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_NAME_PROPERTY: { code: 1018, message: 'Expected a string for name, received "{0}".', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_NAMESPACE_PROPERTY: { code: 1019, message: 'Expected a string for namespace, received "{0}".', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_SOURCEMAP_PROPERTY: { code: 1021, message: 'Expected a boolean value or \'inline\' for outputConfig.sourcemap, received "{0}".', level: exports.DiagnosticLevel.Error, url: '', }, MISSING_OPTIONS_OBJECT: { code: 1023, message: 'Expected options object, received "{0}".', level: exports.DiagnosticLevel.Error, url: '', }, UNEXPECTED_FILE_CONTENT: { code: 1024, message: 'Unexpected file content for "{0}". Expected a string, received "{1}".', level: exports.DiagnosticLevel.Error, url: '', }, UNKNOWN_ENV_ENTRY_KEY: { code: 1025, message: 'Unknown entry "{0}" in outputConfig.env.', level: exports.DiagnosticLevel.Error, url: '', }, }; const ModuleResolutionErrors = { MODULE_RESOLUTION_ERROR: { code: 1002, message: 'Error in module resolution: {0}', level: exports.DiagnosticLevel.Warning, url: '', }, IMPORTEE_RESOLUTION_FAILED: { code: 1010, message: 'Failed to resolve entry for module "{0}".', level: exports.DiagnosticLevel.Error, url: '', }, IMPORTEE_RESOLUTION_FROM_IMPORTER_FAILED: { code: 1011, message: 'Failed to resolve import "{0}" from "{1}". Please add "{2}" file to the component folder.', level: exports.DiagnosticLevel.Error, url: '', }, NONEXISTENT_FILE: { code: 1004, message: 'No such file {0}', level: exports.DiagnosticLevel.Error, url: '', }, FOLDER_NAME_STARTS_WITH_CAPITAL_LETTER: { code: 1116, message: 'Illegal folder name "{0}". The folder name must start with a lowercase character: "{1}".', level: exports.DiagnosticLevel.Error, url: '', }, FOLDER_AND_FILE_NAME_CASE_MISMATCH: { code: 1117, message: 'Failed to resolve "{0}". The file name must case match the component folder name "{1}".', level: exports.DiagnosticLevel.Error, url: '', }, IMPORT_AND_FILE_NAME_CASE_MISMATCH: { code: 1118, message: 'Failed to resolve "{0}" from "{1}". Did you mean "{2}"?', level: exports.DiagnosticLevel.Error, url: '', }, RELATIVE_DYNAMIC_IMPORT: { code: 1120, message: 'Illegal usage of the dynamic import syntax with a relative path.', level: exports.DiagnosticLevel.Error, url: '', }, }; const TransformerErrors = { CSS_TRANSFORMER_ERROR: { code: 1009, message: '{0}', level: exports.DiagnosticLevel.Error, url: '', }, CSS_IN_HTML_ERROR: { code: 1026, message: 'An error occurred parsing inline CSS. {0}', level: exports.DiagnosticLevel.Error, url: '', }, HTML_TRANSFORMER_ERROR: { code: 1008, message: '{0}', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_ID: { code: 1027, message: 'Expect a string for id. Received {0}', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_SOURCE: { code: 1006, message: 'Expect a string for source. Received {0}', level: exports.DiagnosticLevel.Error, url: '', }, JS_TRANSFORMER_ERROR: { code: 1007, message: '{0}', level: exports.DiagnosticLevel.Error, url: '', }, NO_AVAILABLE_TRANSFORMER: { code: 1005, message: 'No available transformer for "{0}"', level: exports.DiagnosticLevel.Error, url: '', }, JS_TRANSFORMER_DECORATOR_ERROR: { code: 1198, message: 'Decorators like @api, @track, and @wire are only supported in LightningElement classes. {0}', level: exports.DiagnosticLevel.Error, url: '', }, }; /* * Copyright (c) 2024, Salesforce, Inc. * All rights reserved. * SPDX-License-Identifier: MIT * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ /* * For the next available error code, reference (and update!) the value in ./index.ts */ const LWCClassErrors = { INVALID_DYNAMIC_IMPORT_SOURCE_STRICT: { code: 1121, message: 'Invalid import. The argument "{0}" must be a stringLiteral for dynamic imports when strict mode is enabled.', url: '', level: exports.DiagnosticLevel.Error, }, }; const DecoratorErrors = { ADAPTER_SHOULD_BE_FIRST_PARAMETER: { code: 1092, message: '@wire expects an adapter as first parameter. @wire(adapter: WireAdapter, config?: any).', level: exports.DiagnosticLevel.Error, url: '', }, API_AND_TRACK_DECORATOR_CONFLICT: { code: 1093, message: '@api method or property cannot be used with @track', level: exports.DiagnosticLevel.Error, url: '', }, CONFIG_OBJECT_SHOULD_BE_SECOND_PARAMETER: { code: 1094, message: '@wire expects a configuration object expression as second parameter.', level: exports.DiagnosticLevel.Error, url: '', }, CONFLICT_WITH_ANOTHER_DECORATOR: { code: 1095, message: '@wire method or property cannot be used with @{0}', level: exports.DiagnosticLevel.Error, url: '', }, DUPLICATE_API_PROPERTY: { code: 1096, message: 'Duplicate @api property "{0}".', level: exports.DiagnosticLevel.Error, url: '', }, FUNCTION_IDENTIFIER_SHOULD_BE_FIRST_PARAMETER: { code: 1097, message: '@wire expects a function identifier as first parameter.', level: exports.DiagnosticLevel.Error, url: '', }, IMPORTED_FUNCTION_IDENTIFIER_SHOULD_BE_FIRST_PARAMETER: { code: 1098, message: '@wire expects a function identifier to be imported as first parameter.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_BOOLEAN_PUBLIC_PROPERTY: { code: 1099, message: 'Boolean public property must default to false.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_DECORATOR: { code: 1100, message: 'Invalid decorator usage. Supported decorators ({0}) should be imported from "{1}"', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_DECORATOR_TYPE: { code: 1101, message: 'Invalid property of field type', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_DECORATOR_WITH_NAME: { code: 1102, message: 'Invalid \'{0}\' decorator usage. Supported decorators ({1}) should be imported from "{2}"', level: exports.DiagnosticLevel.Error, url: '', }, IS_NOT_CLASS_PROPERTY_OR_CLASS_METHOD: { code: 1103, message: '"@{0}" can only be applied on class properties', level: exports.DiagnosticLevel.Error, url: '', }, IS_NOT_DECORATOR: { code: 1104, message: '"{0}" can only be used as a class decorator', level: exports.DiagnosticLevel.Error, url: '', }, ONE_WIRE_DECORATOR_ALLOWED: { code: 1105, message: 'Method or property can only have 1 @wire decorator', level: exports.DiagnosticLevel.Error, url: '', }, PROPERTY_CANNOT_BE_COMPUTED: { code: 1106, message: '@api cannot be applied to a computed property, getter, setter or method.', level: exports.DiagnosticLevel.Error, url: '', }, PROPERTY_NAME_CANNOT_START_WITH_DATA: { code: 1107, message: 'Invalid property name "{0}". Properties starting with "data" are reserved attributes.', level: exports.DiagnosticLevel.Error, url: '', }, PROPERTY_NAME_CANNOT_START_WITH_ON: { code: 1108, message: 'Invalid property name "{0}". Properties starting with "on" are reserved for event handlers.', level: exports.DiagnosticLevel.Error, url: '', }, PROPERTY_NAME_IS_AMBIGUOUS: { code: 1109, message: 'Ambiguous attribute name "{0}". "{0}" will never be called from template because its corresponding property is camel cased. Consider renaming to "{1}".', level: exports.DiagnosticLevel.Error, url: '', }, PROPERTY_NAME_IS_RESERVED: { code: 1110, message: 'Invalid property name "{0}". "{0}" is a reserved attribute.', level: exports.DiagnosticLevel.Error, url: '', }, PROPERTY_NAME_PART_IS_RESERVED: { code: 1111, message: 'Invalid property name "{0}". "part" is a future reserved attribute for web components.', level: exports.DiagnosticLevel.Error, url: '', }, SINGLE_DECORATOR_ON_SETTER_GETTER_PAIR: { code: 1112, message: '@api get {0} and @api set {0} detected in class declaration. Only one of the two needs to be decorated with @api.', level: exports.DiagnosticLevel.Error, url: '', }, TRACK_ONLY_ALLOWED_ON_CLASS_PROPERTIES: { code: 1113, message: '@track decorator can only be applied to class properties.', level: exports.DiagnosticLevel.Error, url: '', }, WIRE_ADAPTER_SHOULD_BE_IMPORTED: { code: 1119, message: 'Failed to resolve @wire adapter "{0}". Ensure it is imported.', level: exports.DiagnosticLevel.Error, url: '', }, FUNCTION_IDENTIFIER_CANNOT_HAVE_COMPUTED_PROPS: { code: 1131, message: '@wire identifier cannot contain computed properties', level: exports.DiagnosticLevel.Error, url: '', }, FUNCTION_IDENTIFIER_CANNOT_HAVE_NESTED_MEMBER_EXRESSIONS: { code: 1132, message: '@wire identifier cannot contain nested member expressions', level: exports.DiagnosticLevel.Error, url: '', }, COMPUTED_PROPERTY_CANNOT_BE_TEMPLATE_LITERAL: { code: 1199, message: 'Cannot use a template literal as a computed property key. Instead, use a string or extract the value to a constant.', level: exports.DiagnosticLevel.Error, url: '', }, COMPUTED_PROPERTY_MUST_BE_CONSTANT_OR_LITERAL: { code: 1200, message: 'Computed property in @wire config must be a constant or primitive literal.', level: exports.DiagnosticLevel.Error, url: '', }, }; /* * Copyright (c) 2024, Salesforce, Inc. * All rights reserved. * SPDX-License-Identifier: MIT * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ /* * For the next available error code, reference (and update!) the value in ./index.ts */ const TemplateErrors = { INVALID_TEMPLATE: { code: 1003, message: 'Invalid template', level: exports.DiagnosticLevel.Error, url: '', }, OPTIONS_MUST_BE_OBJECT: { code: 1028, message: 'Compiler options must be an object', level: exports.DiagnosticLevel.Error, url: '', }, UNKNOWN_IF_MODIFIER: { code: 1029, message: 'Unknown if modifier {0}', level: exports.DiagnosticLevel.Error, url: '', }, UNKNOWN_OPTION_PROPERTY: { code: 1030, message: 'Unknown option property {0}', level: exports.DiagnosticLevel.Error, url: '', }, DUPLICATE_ELEMENT_ENTRY: { code: 1150, message: 'customRendererConfig contains duplicate entry for {0} element tag', level: exports.DiagnosticLevel.Error, url: '', }, CUSTOM_ELEMENT_TAG_DISALLOWED: { code: 1151, message: 'customRendererConfig should not contain a custom element tag, but found {0}', level: exports.DiagnosticLevel.Error, url: '', }, }; const ParserDiagnostics = { AMBIGUOUS_ATTRIBUTE_VALUE: { code: 1034, message: 'Ambiguous attribute value {0}. ' + 'If you want to make it a valid identifier you should remove the surrounding quotes {1}. ' + 'If you want to make it a string you should escape it {2}.', level: exports.DiagnosticLevel.Error, url: '', }, AMBIGUOUS_ATTRIBUTE_VALUE_STRING: { code: 1035, message: 'Ambiguous attribute value {0}. If you want to make it a string you should escape it {1}', level: exports.DiagnosticLevel.Error, url: '', }, BOOLEAN_ATTRIBUTE_FALSE: { code: 1036, message: 'To not set a boolean attribute, try <{0}> instead of <{0} {1}="{2}">. ' + 'To represent a false value, the attribute has to be omitted altogether.', level: exports.DiagnosticLevel.Error, url: '', }, BOOLEAN_ATTRIBUTE_TRUE: { code: 1037, message: 'To set a boolean attributes, try <{0} {1}> instead of <{0} {1}="{2}">. ' + 'If the attribute is present, its value must either be the empty string ' + "or a value that is an ASCII case -insensitive match for the attribute's canonical name " + 'with no leading or trailing whitespace.', level: exports.DiagnosticLevel.Error, url: '', }, COMPUTED_PROPERTY_ACCESS_NOT_ALLOWED: { code: 1038, message: "Template expression doesn't allow computed property access", level: exports.DiagnosticLevel.Error, url: '', }, DIRECTIVE_SHOULD_BE_EXPRESSION: { code: 1039, message: '{0} directive is expected to be an expression', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_ID_ATTRIBUTE: { code: 1040, message: 'Invalid id value "{0}". Id values must not contain any whitespace.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_STATIC_ID_IN_ITERATION: { code: 1041, message: 'Static id values are not allowed in iterators. Id values must be unique within a template and must therefore be computed with an expression.', level: exports.DiagnosticLevel.Warning, url: '', }, DUPLICATE_ID_FOUND: { code: 1042, message: 'Duplicate id value "{0}" detected. Id values must be unique within a template.', level: exports.DiagnosticLevel.Error, url: '', }, EVENT_HANDLER_SHOULD_BE_EXPRESSION: { code: 1043, message: 'Event handler should be an expression', level: exports.DiagnosticLevel.Error, url: '', }, FOR_EACH_AND_FOR_ITEM_DIRECTIVES_SHOULD_BE_TOGETHER: { code: 1044, message: 'for:each and for:item directives should be associated together.', level: exports.DiagnosticLevel.Error, url: '', }, FOR_EACH_DIRECTIVE_SHOULD_BE_EXPRESSION: { code: 1045, message: 'for:each directive is expected to be a expression.', level: exports.DiagnosticLevel.Error, url: '', }, FOR_INDEX_DIRECTIVE_SHOULD_BE_STRING: { code: 1046, message: 'for:index directive is expected to be a string.', level: exports.DiagnosticLevel.Error, url: '', }, FOR_ITEM_DIRECTIVE_SHOULD_BE_STRING: { code: 1047, message: 'for:item directive is expected to be a string.', level: exports.DiagnosticLevel.Error, url: '', }, FORBIDDEN_IFRAME_SRCDOC_ATTRIBUTE: { code: 1048, message: 'srcdoc attribute is disallowed on <iframe> for security reasons', level: exports.DiagnosticLevel.Error, url: '', }, FORBIDDEN_SVG_NAMESPACE_IN_TEMPLATE: { code: 1049, message: "Forbidden svg namespace tag found in template: '<{0}>' tag is not allowed within <svg>", level: exports.DiagnosticLevel.Error, url: '', }, FORBIDDEN_MATHML_NAMESPACE_IN_TEMPLATE: { code: 1050, message: "Forbidden MathML namespace tag found in template: '<{0}>' tag is not allowed within <math>", level: exports.DiagnosticLevel.Error, url: '', }, FORBIDDEN_TAG_ON_TEMPLATE: { code: 1051, message: "Forbidden tag found in template: '<{0}>' tag is not allowed.", level: exports.DiagnosticLevel.Error, url: '', }, GENERIC_PARSING_ERROR: { code: 1052, message: 'Error parsing attribute: {0}', level: exports.DiagnosticLevel.Error, url: '', }, IDENTIFIER_PARSING_ERROR: { code: 1053, message: 'Error parsing identifier: {0}', level: exports.DiagnosticLevel.Error, url: '', }, IF_DIRECTIVE_SHOULD_BE_EXPRESSION: { code: 1054, message: 'If directive should be an expression', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_ATTRIBUTE_CASE: { code: 1055, message: '{0} is not valid attribute for {1}. All attributes name should be all lowercase.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_EVENT_NAME: { code: 1056, message: 'Invalid event type "{0}". Event type must begin with a lower-case alphabetic character and contain only lower-case alphabetic characters, underscores, and numeric characters', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_HTML_ATTRIBUTE: { code: 1057, message: '{0} is not valid attribute for {1}. For more information refer to https://developer.mozilla.org/en-US/docs/Web/HTML/Element/{1}', level: exports.DiagnosticLevel.Warning, url: '', }, INVALID_HTML_SYNTAX: { code: 1058, message: 'Invalid HTML syntax: {0}. For more information, ' + 'please visit https://html.spec.whatwg.org/multipage/parsing.html#parse-error-{0}', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_IDENTIFIER: { code: 1059, message: '{0} is not a valid identifier', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_NODE: { code: 1060, message: "Template expression doesn't allow {0}", level: exports.DiagnosticLevel.Error, url: '', }, INVALID_TABINDEX_ATTRIBUTE: { code: 1061, message: 'The attribute "tabindex" can only be set to "0" or "-1".', level: exports.DiagnosticLevel.Error, url: '', }, DEPRECATED_IS_ATTRIBUTE_CANNOT_BE_EXPRESSION: { code: 1062, message: '"is" attribute value can\'t be an expression', level: exports.DiagnosticLevel.Error, url: '', }, IS_ATTRIBUTE_NOT_SUPPORTED: { code: 1063, message: '"is" attribute is disallowed', level: exports.DiagnosticLevel.Error, url: '', }, KEY_ATTRIBUTE_SHOULD_BE_EXPRESSION: { code: 1064, message: 'Key attribute value should be an expression', level: exports.DiagnosticLevel.Error, url: '', }, KEY_SHOULDNT_REFERENCE_FOR_EACH_INDEX: { code: 1065, message: 'Invalid key value for element <{0}>. Key cannot reference for:each index {1}', level: exports.DiagnosticLevel.Error, url: '', }, KEY_SHOULDNT_REFERENCE_ITERATOR_INDEX: { code: 1066, message: 'Invalid key value for element <{0}>. Key cannot reference iterator index', level: exports.DiagnosticLevel.Error, url: '', }, MISSING_KEY_IN_ITERATOR: { code: 1071, message: 'Missing key for element <{0}> inside of iterator. Elements within iterators must have a unique, computed key value.', level: exports.DiagnosticLevel.Error, url: '', }, MISSING_ROOT_TEMPLATE_TAG: { code: 1072, message: 'Missing root template tag', level: exports.DiagnosticLevel.Error, url: '', }, MODIFYING_ITERATORS_NOT_ALLOWED: { code: 1073, message: "Template expression doesn't allow to modify iterators", level: exports.DiagnosticLevel.Error, url: '', }, MULTIPLE_EXPRESSIONS: { code: 1074, message: 'Multiple expressions found', level: exports.DiagnosticLevel.Error, url: '', }, MULTIPLE_ROOTS_FOUND: { code: 1075, message: 'Multiple roots found', level: exports.DiagnosticLevel.Error, url: '', }, NAME_ON_SLOT_CANNOT_BE_EXPRESSION: { code: 1076, message: "Name attribute on slot tag can't be an expression.", level: exports.DiagnosticLevel.Error, url: '', }, NO_DIRECTIVE_FOUND_ON_TEMPLATE: { code: 1077, message: 'Invalid template tag. A directive is expected to be associated with the template tag.', level: exports.DiagnosticLevel.Error, url: '', }, NO_MATCHING_CLOSING_TAGS: { code: 1078, message: '<{0}> has no matching closing tag.', level: exports.DiagnosticLevel.Error, url: '', }, ROOT_TAG_SHOULD_BE_TEMPLATE: { code: 1079, message: 'Expected root tag to be template, found {0}', level: exports.DiagnosticLevel.Error, url: '', }, ROOT_TEMPLATE_HAS_UNKNOWN_ATTRIBUTES: { code: 1080, message: 'Root template has unknown or disallowed attributes: {0}', level: exports.DiagnosticLevel.Error, url: '', }, // TODO [#3100]: Update message to point to external documentation once available. SLOT_TAG_CANNOT_HAVE_DIRECTIVES: { code: 1082, message: "<slot> tag can't be associated with {0} template directives.", level: exports.DiagnosticLevel.Error, url: '', }, TEMPLATE_EXPRESSION_PARSING_ERROR: { code: 1083, message: 'Error parsing template expression: {0}', level: exports.DiagnosticLevel.Error, url: '', }, UNEXPECTED_IF_MODIFIER: { code: 1084, message: 'Unexpected if modifier {0}', level: exports.DiagnosticLevel.Error, url: '', }, LWC_DOM_INVALID_VALUE: { code: 1085, message: 'Invalid value for "lwc:dom". \'lwc:dom\' can only be set to {0}', level: exports.DiagnosticLevel.Error, url: '', }, LWC_DOM_INVALID_CONTENTS: { code: 1086, message: 'Invalid contents for element with "lwc:dom". Element must be empty', level: exports.DiagnosticLevel.Error, url: '', }, LWC_DOM_INVALID_CUSTOM_ELEMENT: { code: 1087, message: 'Invalid directive "lwc:dom" on element {0}. "lwc:dom" cannot be added to a custom element', level: exports.DiagnosticLevel.Error, url: '', }, LWC_DOM_INVALID_SLOT_ELEMENT: { code: 1088, message: 'Invalid directive "lwc:dom" on <slot>.. "lwc:dom" cannot be added to a <slot>', level: exports.DiagnosticLevel.Error, url: '', }, STYLE_TAG_NOT_ALLOWED_IN_TEMPLATE: { code: 1122, message: "The <style> element is disallowed inside the template. Please add css rules into '.css' file of your component bundle.", level: exports.DiagnosticLevel.Error, url: '', }, UNKNOWN_HTML_TAG_IN_TEMPLATE: { code: 1123, message: "Unknown html tag '<{0}>'. For more information refer to https://developer.mozilla.org/en-US/docs/Web/HTML/Element and https://developer.mozilla.org/en-US/docs/Web/SVG/Element", level: exports.DiagnosticLevel.Warning, url: '', }, ATTRIBUTE_NAME_STARTS_WITH_INVALID_CHARACTER: { code: 1124, message: '{0} is not valid attribute for {1}. Attribute name must start with an underscore, dollar sign, or an optional hyphen character followed by an alphabetic character.', level: exports.DiagnosticLevel.Error, url: '', }, ATTRIBUTE_NAME_MUST_END_WITH_ALPHA_NUMERIC_CHARACTER: { code: 1125, message: '{0} is not valid attribute for {1}. Attribute name must end with alpha-numeric character.', level: exports.DiagnosticLevel.Error, url: '', }, UNKNOWN_LWC_DIRECTIVE: { code: 1127, message: 'Invalid directive "{0}" on element {1}.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_OPTS_LWC_DYNAMIC: { code: 1128, message: 'Invalid lwc:dynamic usage. The LWC dynamic directive must be enabled in order to use this feature.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_LWC_DYNAMIC_ON_NATIVE_ELEMENT: { code: 1129, message: 'Invalid lwc:dynamic usage on element "{0}". This directive can only be used in a custom element.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_LWC_DYNAMIC_LITERAL_PROP: { code: 1130, message: 'Invalid lwc:dynamic usage on element "{0}". The directive binding must be an expression.', level: exports.DiagnosticLevel.Error, url: '', }, LWC_RENDER_MODE_INVALID_VALUE: { code: 1133, message: 'Invalid value for "lwc:render-mode". \'lwc:render-mode\' can only be set to "shadow", or "light"', level: exports.DiagnosticLevel.Error, url: '', }, LWC_LIGHT_SLOT_INVALID_ATTRIBUTES: { code: 1134, message: "Invalid attribute(s) '{0}' on slot. Slots in Light DOM templates (which have 'lwc:render-mode' directive) can only have [{1}] attributes", level: exports.DiagnosticLevel.Error, url: '', }, LWC_DOM_INVALID_IN_LIGHT_DOM: { code: 1135, message: "Invalid directive 'lwc:dom' on element {0}. 'lwc:dom' is not necessary in Light DOM components.", level: exports.DiagnosticLevel.Error, url: '', }, INVALID_FOR_EACH_WITH_ITERATOR: { code: 1136, message: "Invalid usage for 'for:each' and '{0}' directives on the same element.", level: exports.DiagnosticLevel.Error, url: '', }, NO_DUPLICATE_SLOTS: { code: 1137, message: 'Invalid duplicate slot ({0}).', level: exports.DiagnosticLevel.Warning, url: '', }, NO_SLOTS_IN_ITERATOR: { code: 1138, message: 'Invalid slot ({0}). A slot cannot appear inside of an iterator.', level: exports.DiagnosticLevel.Warning, url: '', }, LWC_LIGHT_SLOT_INVALID_EVENT_LISTENER: { code: 1139, message: "Invalid event listener '{0}' on slot. Slots in Light DOM templates cannot have event listeners.", level: exports.DiagnosticLevel.Error, url: '', }, LWC_INNER_HTML_INVALID_CUSTOM_ELEMENT: { code: 1140, message: 'Invalid lwc:inner-html usage on element "{0}". The directive can\'t be used on a custom element or special LWC managed elements denoted with lwc:*.', level: exports.DiagnosticLevel.Error, url: '', }, LWC_INNER_HTML_INVALID_ELEMENT: { code: 1141, message: 'Invalid lwc:inner-html usage on element "{0}". The directive can\'t be used on a slot or a template element.', level: exports.DiagnosticLevel.Error, url: '', }, LWC_INNER_HTML_INVALID_CONTENTS: { code: 1142, message: 'Invalid lwc:inner-html usage on element "{0}". The directive can\'t be used on an element with content.', level: exports.DiagnosticLevel.Error, url: '', }, LWC_INNER_HTML_INVALID_VALUE: { code: 1143, message: 'Invalid lwc:inner-html usage on element "{0}". The directive binding can only be an expression or a string.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_HTML_RECOVERY: { code: 1144, message: 'Invalid HTML detected, "<{0}>" was automatically inserted within "<{1}>"; the compiled template may not match the template source.', level: exports.DiagnosticLevel.Warning, url: '', }, INVALID_TEMPLATE_ATTRIBUTE: { code: 1145, message: 'Invalid attributes detected on template. The following attributes are not supported on template tags in LWC: {0}. For more information, ' + 'please visit https://sfdc.co/template-directives', level: exports.DiagnosticLevel.Warning, url: '', }, PRESERVE_COMMENTS_MUST_BE_BOOLEAN: { code: 1146, message: 'lwc:preserve-comments must be a boolean attribute.', level: exports.DiagnosticLevel.Error, url: '', }, DUPLICATE_ATTR_PROP_TRANSFORM: { code: 1147, message: 'Found multiple HTML attributes mapping to the same JavaScript property. "{0}" and "{1}" both map to "{2}".', level: exports.DiagnosticLevel.Warning, url: '', }, INVALID_HTML_SYNTAX_WARNING: { code: 1148, message: 'Invalid HTML syntax: {0}. This will not be supported in future versions of LWC. For more information, ' + 'please visit https://html.spec.whatwg.org/multipage/parsing.html#parse-error-{0}', level: exports.DiagnosticLevel.Warning, url: '', }, KEY_SHOULD_BE_IN_ITERATION: { code: 1149, message: 'Invalid key attribute on element <{0}>. The key attribute should be applied to an element with for:each or iterator:*, or to a direct child of a <template> element with for:each or iterator:*. This key will be ignored, and may throw an error in future versions of LWC.', level: exports.DiagnosticLevel.Warning, url: '', }, INVALID_TEMPLATE_WARNING: { code: 1153, message: 'Non-root template elements must contain valid LWC template directive attributes. Otherwise, the template and its children will be ignored. ' + 'For more information please visit https://sfdc.co/template-directives', level: exports.DiagnosticLevel.Warning, url: '', }, INVALID_LWC_SPREAD_LITERAL_PROP: { code: 1155, message: 'Invalid lwc:spread usage on element "{0}". The directive binding must be an expression.', level: exports.DiagnosticLevel.Error, url: '', }, LWC_REF_INVALID_ELEMENT: { code: 1156, message: 'Invalid lwc:ref usage on element "{0}". The directive can\'t be used on a slot or a template element.', level: exports.DiagnosticLevel.Error, url: '', }, LWC_REF_INVALID_VALUE: { code: 1157, message: 'Invalid lwc:ref usage on element "{0}". The directive binding must be a non-empty string.', level: exports.DiagnosticLevel.Error, url: '', }, LWC_REF_INVALID_LOCATION_INSIDE_ITERATION: { code: 1158, message: 'Invalid lwc:ref usage on element "{0}". lwc:ref cannot be used inside for:each or an iterator.', level: exports.DiagnosticLevel.Error, url: '', }, IF_BLOCK_DIRECTIVE_SHOULD_BE_EXPRESSION: { code: 1159, message: 'lwc:if directive value should be an expression', level: exports.DiagnosticLevel.Error, url: '', }, ELSEIF_BLOCK_DIRECTIVE_SHOULD_BE_EXPRESSION: { code: 1160, message: 'lwc:elseif directive value should be an expression', level: exports.DiagnosticLevel.Error, url: '', }, ELSE_BLOCK_DIRECTIVE_CANNOT_HAVE_VALUE: { code: 1161, message: 'lwc:else directive cannot have a value', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_IF_BLOCK_DIRECTIVE_WITH_CONDITIONAL: { code: 1162, message: "Invalid usage of 'lwc:if' and '{0}' directives on the same element.", level: exports.DiagnosticLevel.Error, url: '', }, INVALID_ELSEIF_BLOCK_DIRECTIVE_WITH_CONDITIONAL: { code: 1163, message: "Invalid usage of 'lwc:elseif' and '{0}' directives on the same element.", level: exports.DiagnosticLevel.Error, url: '', }, INVALID_ELSE_BLOCK_DIRECTIVE_WITH_CONDITIONAL: { code: 1164, message: "Invalid usage of 'lwc:else' and '{0}' directives on the same element.", level: exports.DiagnosticLevel.Error, url: '', }, LWC_IF_SCOPE_NOT_FOUND: { code: 1165, message: "'{0}' directive must be used immediately after an element with 'lwc:if' or 'lwc:elseif'. No such element found.", level: exports.DiagnosticLevel.Error, url: '', }, LWC_IF_CANNOT_BE_USED_WITH_IF_DIRECTIVE: { code: 1166, message: "'{0}' directive cannot be used with 'lwc:if', 'lwc:elseif', or 'lwc:else directives on the same element.", level: exports.DiagnosticLevel.Error, url: '', }, SCOPED_SLOT_BIND_IN_LIGHT_DOM_ONLY: { code: 1169, message: 'Invalid lwc:slot-bind usage on <slot> element. Scoped slots usage is allowed in Light DOM templates only.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_LWC_SLOT_BIND_LITERAL_PROP: { code: 1170, message: 'Invalid lwc:slot-bind usage on element {0}. The directive binding must be an expression.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_LWC_SLOT_BIND_NON_SLOT_ELEMENT: { code: 1171, message: 'Invalid lwc:slot-bind usage on element {0}. The directive can be used on a <slot> element only.', level: exports.DiagnosticLevel.Error, url: '', }, NO_DUPLICATE_SCOPED_SLOT: { code: 1172, message: 'Invalid duplicate scoped slots ({0})', level: exports.DiagnosticLevel.Error, url: '', }, NO_MIXED_SLOT_TYPES: { code: 1173, message: 'Mixing slot types disallowed for same ({0}) slot.', level: exports.DiagnosticLevel.Error, url: '', }, SLOT_DATA_VALUE_SHOULD_BE_STRING: { code: 1174, message: 'lwc:slot-data attribute value is expected to be a string.', level: exports.DiagnosticLevel.Error, url: '', }, SCOPED_SLOT_DATA_ON_TEMPLATE_ONLY: { code: 1176, message: 'lwc:slot-data directive can be used on <template> elements only.', level: exports.DiagnosticLevel.Error, url: '', }, NON_ELEMENT_SCOPED_SLOT_CONTENT: { code: 1177, message: '<template> tag with lwc:slot-data directive cannot contain a comment or text node as a direct child.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_PARENT_OF_LWC_SLOT_DATA: { code: 1178, message: '<template> tag with lwc:slot-data directive must be the direct child of a custom element.', level: exports.DiagnosticLevel.Error, url: '', }, SCOPED_SLOTDATA_CANNOT_BE_COMBINED_WITH_OTHER_DIRECTIVE: { code: 1179, message: 'lwc:slot-data directive cannot be combined with other directives on the same <template> tag.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_LWC_EXTERNAL_ON_NON_CUSTOM_ELEMENT: { code: 1180, message: 'Invalid lwc:external directive usage: {0}. This directive can only be used on custom elements.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_LWC_EXTERNAL_VALUE: { code: 1181, message: 'Invalid lwc:external directive usage: {0}. This directive is a boolean attribute and should not have a value.', level: exports.DiagnosticLevel.Error, url: '', }, SINGLE_IF_DIRECTIVE_ALLOWED: { code: 1182, message: `Multiple if: directives found on '{0}'. Only one if: directive is allowed; the rest are ignored.`, level: exports.DiagnosticLevel.Warning, url: '', }, LWC_COMPONENT_TAG_WITHOUT_IS_DIRECTIVE: { code: 1183, message: `<lwc:component> must have an 'lwc:is' attribute.`, level: exports.DiagnosticLevel.Error, url: '', }, UNSUPPORTED_LWC_TAG_NAME: { code: 1184, message: '{0} is not a special LWC tag name and will be treated as an HTML element.', level: exports.DiagnosticLevel.Warning, url: '', }, INVALID_LWC_IS_DIRECTIVE_VALUE: { code: 1185, message: 'Invalid lwc:is usage for value {0}. The value assigned to lwc:is must be an expression.', level: exports.DiagnosticLevel.Error, url: '', }, LWC_IS_INVALID_ELEMENT: { code: 1186, message: 'Invalid lwc:is usage for element {0}. The directive can only be used with <lwc:component>', level: exports.DiagnosticLevel.Error, url: '', }, DEPRECATED_LWC_DYNAMIC_ATTRIBUTE: { code: 1187, message: `The lwc:dynamic directive is deprecated and will be removed in a future release. Please use lwc:is instead.`, level: exports.DiagnosticLevel.Warning, url: '', }, INVALID_OPTS_LWC_ENABLE_DYNAMIC_COMPONENTS: { code: 1188, message: 'Invalid dynamic components usage, lwc:component and lwc:is can only be used when dynamic components have been enabled.', level: exports.DiagnosticLevel.Error, url: '', }, // TODO [#3370]: remove this error if template expressions is removed INVALID_EXPR_ARROW_FN_PARAM: { code: 1189, message: "Template expression doesn't allow {0} in arrow function params.", level: exports.DiagnosticLevel.Error, url: '', }, // TODO [#3370]: remove this error if template expressions is removed INVALID_EXPR_STATEMENTS_PROHIBITED: { code: 1190, message: 'Statements are disallowed in template expressions.', level: exports.DiagnosticLevel.Error, url: '', }, // TODO [#3370]: remove this error if template expressions is removed INVALID_EXPR_MUTATION_OUTSIDE_ARROW: { code: 1191, message: 'Field mutations are only permitted within arrow functions.', level: exports.DiagnosticLevel.Error, url: '', }, // TODO [#3370]: remove this error if template expressions is removed INVALID_EXPR_DELETE_OP: { code: 1192, message: 'Use of the delete operator is prohibited within template expressions.', level: exports.DiagnosticLevel.Error, url: '', }, // TODO [#3370]: remove this error if template expressions is removed INVALID_EXPR_ARROW_FN_BODY: { code: 1193, message: 'The body of arrow functions in template expressions must be an expression.', level: exports.DiagnosticLevel.Error, url: '', }, // TODO [#3370]: remove this error if template expressions is removed INVALID_EXPR_ARROW_FN_KIND: { code: 1194, message: 'Arrow functions in template expressions cannot be {0}.', level: exports.DiagnosticLevel.Error, url: '', }, // TODO [#3370]: remove this error if template expressions is removed INVALID_EXPR_EARLY_STAGE_FEATURE: { code: 1195, message: 'Early-stage JS features are disallowed in template expressions.', level: exports.DiagnosticLevel.Error, url: '', }, // TODO [#3370]: remove this error if template expressions is removed INVALID_EXPR_PROHIBITED_NODE_TYPE: { code: 1196, message: 'Use of {0} is disallowed within template expressions.', level: exports.DiagnosticLevel.Error, url: '', }, // TODO [#3370]: remove this error if template expressions is removed INVALID_EXPR_COMMENTS_DISALLOWED: { code: 1197, message: 'Use of comments is disallowed within template expressions.', level: exports.DiagnosticLevel.Error, url: '', }, IGNORED_SLOT_ATTRIBUTE_IN_CHILD: { code: 1201, message: 'The slot attribute in {0} will be ignored due to its ancestor {1}. It must be a direct child of the containing component.', level: exports.DiagnosticLevel.Warning, url: '', }, INVALID_LWC_ON_ELEMENT: { code: 1203, message: 'Invalid lwc:on usage on element "{0}". The directive can\'t be used on a template element.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_LWC_ON_LITERAL_PROP: { code: 1204, message: 'Invalid lwc:on usage on element "{0}". The directive binding must be an expression.', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_LWC_ON_WITH_DECLARATIVE_LISTENERS: { code: 1205, message: 'Invalid lwc:on usage on element "{0}". It is not permitted to use declarative event listeners alongside lwc:on', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_LWC_ON_OPTS: { code: 1206, message: 'Invalid lwc:on usage. The `lwc:on` directive must be enabled in order to use this feature.', level: exports.DiagnosticLevel.Error, url: '', }, COMPUTED_PROPERTY_ACCESS_NOT_ALLOWED_COMPLEX: { code: 1207, message: 'Template expression doesn\'t allow computed property access unless the expression is surrounded by quotes: "{0}"', level: exports.DiagnosticLevel.Error, url: '', }, INVALID_NODE_COMPLEX: { code: 1208, message: 'Template expression doesn\'t allow {0} unless the expression is surrounded by quotes: "{1}"', level: exports.DiagnosticLevel.Error, url: '', }, }; /* * Copyright (c) 2025, Salesforce, Inc. * All rights reserved. * SPDX-License-Identifier: MIT * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ /* * For the next available error code, reference (and update!) the value in ./index.ts */ const SsrCompilerErrors = { RESERVED_IDENTIFIER_PREFIX: { code: 1202, message: 'Identifier name cannot start with "__lwc".', level: exports.DiagnosticLevel.Error, url: '', }, }; /* * Copyright (c) 2024, Salesforce, Inc. * All rights reserved. * SPDX-License-Identifier: MIT * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ /** * Generates a friendly error message for the given error type, using the provided template values. * @param errorInfo The object holding the error metadata. * @param args Values used to fill the error message template. * @returns The generated error message. */ function generateErrorMessage(errorInfo, args) { const message = Array.isArray(args) ? templateString(errorInfo.message, args) : errorInfo.message; if (errorInfo.url && errorInfo.url !== '') ; return `LWC${errorInfo.code}: ${message}`; } /** * Generates a compiler diagnostic. This function is used to look up the specified errorInfo * and generate a friendly and consistent diagnostic object. Diagnostic contains * info about the error's code and its origin (filename, line, column) when applicable. * @param errorInfo The object holding the error metadata. * @param config A config object providing any message arguments and origin info needed to create the error. * @returns The generated compiler diagnostic object. */ function generateCompilerDiagnostic(errorInfo, config) { const message = generateErrorMessage(errorInfo, config && config.messageArgs); const diagnostic = { code: errorInfo.code, message, level: errorInfo.level, }; if (config && config.origin) { diagnostic.filename = getFilename(config.origin); diagnostic.location = getLocation(config.origin); } return diagnostic; } /** * Generates a