/*
 * Copyright (c) 2018, 2026, Oracle and/or its affiliates.
 * Licensed under The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 */
const path=require("path");const Utils=require("../jetwc-lib/jetwcutils-componentAuditUtils");const ruleDef=function(){};ruleDef.prototype.getName=function(){return"jetwc-loader-file"};ruleDef.prototype.getShortDescription=function(){return"Checks for the existence of the loader.js / ts"};ruleDef.prototype.getDescription=function(){return"This rule ensures that standard loader entry point is available for composites. This looks for a file called loader.js or loader.ts in the same folder as the components component.json file and then checks that the information matches, e.g. the loader registers the correct tag name for the component."};ruleDef.prototype.register=function(context){return{compjson:this._doAuditPhysical,CallExpression:this._doAuditMapping}};ruleDef.prototype._doAuditPhysical=function(context){const componentMetadata=context.suppData.obj;if(componentMetadata){let issue;const fullName=Utils.getComponentFullName(componentMetadata);const componentType=Utils.getComponentType(componentMetadata);if(componentType==="composite"){const testLoader=Utils.toJAFPath(path.join(path.dirname(context.filepath),"loader."));if(!context.utils.fsUtils.fileExistsSync(testLoader+"js")&&!context.utils.fsUtils.fileExistsSync(testLoader+"ts")){issue=new context.Issue(`Required loader script for ${fullName} is not present`);issue.setMsgKey(context.ruleName+"_1");context.reporter.addIssue(issue,context)}}}};ruleDef.prototype._doAuditMapping=function(context,node){if(this._isCompositeLoader(context)){const candidateTag=this._getLoaderTag(context,node);if(candidateTag){if(candidateTag==="?"){issue=new context.Issue(`Web Component tag registration does not pass a literal for the tag name and so cannot be verified`);issue.setMsgKey(context.ruleName+"_2");context.reporter.addIssue(issue,context,"info")}else{const checkFormat=/^[a-zA_Z]\w*-.*$/;if(!candidateTag.match(checkFormat)){issue=new context.Issue(`Tag ${candidateTag} used in Web Component registration does not conform to HTML custom element syntax rules. It must begin with a letter and have at least one hyphen`);issue.setMsgKey(context.ruleName+"_3");context.reporter.addIssue(issue,context)}else{const componentDefFile=Utils.toJAFPath(path.join(path.dirname(context.filepath),"component.json"));if(context.utils.fsUtils.fileExistsSync(componentDefFile)){const componentDef=context.utils.fsUtils.readJsonSync(componentDefFile);const expectedTag=componentDef.pack?`${componentDef.pack}-${componentDef.name}`:componentDef.name;if(expectedTag!==candidateTag){issue=new context.Issue(`Tag '${candidateTag}' does not match the full name of the associated component '${expectedTag}'`);issue.setMsgKey(context.ruleName+"_4");context.reporter.addIssue(issue,context)}}}}}}};ruleDef.prototype._getLoaderTag=function(context,node){let tagName;const registerInfo=Utils.getLoaderRegisterInfo(context,node);if(registerInfo){tagName=registerInfo.tag}return tagName};ruleDef.prototype._isCompositeLoader=function(context){let loaderFound=false;if(context.rulePack.getExtension()&&context.rulePack.getExtension().hasOwnProperty("allComponents")){const fileName=context.filepath;const withinComponent=Utils.matchComponentPath(context,path.dirname(fileName));const componentInfo=context.rulePack.getExtension().allComponents.get(withinComponent);if(withinComponent&&componentInfo&&componentInfo.type==="composite"){const targetLoaderExt=componentInfo.language==="tsx"?".ts":`.${componentInfo.language}`;if(path.basename(fileName,targetLoaderExt)==="loader"){loaderFound=true}}}else{Utils.reportMissingBootstrapInfo(context,"allComponents")}return loaderFound};module.exports=ruleDef;