@ngcompass/config
Advanced tools
+7
-12
@@ -1,2 +0,4 @@ | ||
| 'use strict';var zod=require('zod'),Ae=require('os'),lilconfig=require('lilconfig'),jiti=require('jiti'),D=require('fs'),be=require('crypto'),C=require('path'),url=require('url'),common=require('@ngcompass/common'),defu=require('defu'),Ue=require('process'),module$1=require('module'),minimatch=require('minimatch'),ot=require('fs/promises');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var Ae__default=/*#__PURE__*/_interopDefault(Ae);var D__namespace=/*#__PURE__*/_interopNamespace(D);var be__default=/*#__PURE__*/_interopDefault(be);var C__namespace=/*#__PURE__*/_interopNamespace(C);var Ue__default=/*#__PURE__*/_interopDefault(Ue);var ot__default=/*#__PURE__*/_interopDefault(ot);var z=()=>Math.max(1,Math.min(4,Ae__default.default.cpus().length-1)),P={enabled:true,location:"node_modules/.cache/ngcompass",strategy:"local",ttl:864e5},S={outputFormat:"text",failOnSeverity:"error",maxWarnings:10,include:["src/**/*.ts"],exclude:["node_modules/**","dist/**","**/*.spec.ts","**/*.test.ts"]};var M=zod.z.enum(["warn","error"]),Se=zod.z.enum(["json","text","sarif","html"]),K=zod.z.union([M,zod.z.literal("off"),zod.z.object({severity:zod.z.union([M,zod.z.literal("off")]),options:zod.z.record(zod.z.string(),zod.z.unknown()).optional()})]),Ce=zod.z.object({enabled:zod.z.boolean().optional(),location:zod.z.string().optional(),strategy:zod.z.enum(["memory","local"]).optional(),ttl:zod.z.number().optional()}),Oe=zod.z.object({project:zod.z.string().optional(),tsconfigRootDir:zod.z.string().optional(),sourceType:zod.z.enum(["module","commonjs"]).optional(),ecmaVersion:zod.z.number().optional()}),J=zod.z.object({extends:zod.z.union([zod.z.string(),zod.z.array(zod.z.string())]).optional(),include:zod.z.array(zod.z.string()).default([...S.include]),exclude:zod.z.array(zod.z.string()).default([...S.exclude]),maxWorkers:zod.z.number().optional(),concurrency:zod.z.number().optional(),cache:zod.z.union([zod.z.boolean(),Ce]).optional(),cacheLocation:zod.z.string().optional(),outputFormat:Se.default(S.outputFormat),outputPath:zod.z.string().optional(),failOnSeverity:M.default(S.failOnSeverity),maxWarnings:zod.z.number().default(S.maxWarnings),ignorePatterns:zod.z.array(zod.z.string()).optional(),rules:zod.z.record(zod.z.string(),K).optional(),overrides:zod.z.array(zod.z.object({files:zod.z.union([zod.z.string(),zod.z.array(zod.z.string())]),rules:zod.z.record(zod.z.string(),K).optional()})).optional(),parserOptions:Oe.optional()}),Ne=zod.z.lazy(()=>J.partial()),Z=J.extend({profiles:zod.z.record(zod.z.string(),Ne).optional()}).transform(e=>{let t,r=e.maxWorkers??e.concurrency??z();if(e.cache===false)t={...P,enabled:false};else if(e.cache===true||e.cache===void 0){let s=e.cacheLocation??P.location;t={...P,location:s};}else t={...P,...e.cache};return {...e,maxWorkers:r,cache:t,rules:e.rules??{},overrides:e.overrides??[],ignorePatterns:e.ignorePatterns??[]}});var T="ngcompass",$e=[`${T}.config.ts`,`${T}.config.js`,`${T}.config.mjs`,`${T}.config.cjs`,`${T}.config.json`,`.${T}rc`,`.${T}rc.json`,"package.json"],w=e=>{let t=url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));return jiti.createJiti(e,{alias:{"@ngcompass/config":C__namespace.default.basename(t).startsWith("index.")?t:url.fileURLToPath(new URL("../index.ts",(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))))}}).import(e).then(r=>r&&typeof r=="object"&&"default"in r?r.default??r:r)},te=(e,t)=>JSON.parse(t.replace(/^\uFEFF/,"")),U=async(e=process.cwd())=>{common.time("config-discovery"),common.debug("discovery",`Searching for config in: ${e}`);let t=lilconfig.lilconfig(T,{searchPlaces:$e,loaders:{".ts":w,".js":w,".mjs":w,".cjs":w,".json":te,noExt:te}}),r=await t.search(e);if(!r)return common.debug("discovery","No config file found"),common.timeEnd("config-discovery"),null;common.debug("discovery",`Found config: ${r.filepath}`);let s="",i="";common.time("content-hash");try{s=D__namespace.default.readFileSync(r.filepath,"utf-8"),i=be__default.default.createHash("sha1").update(s).digest("hex");let n=common.timeEnd("content-hash");common.debug("discovery",`Content hash: ${i.substring(0,8)}... (${n.toFixed(1)}ms)`);}catch{}let o=common.timeEnd("config-discovery");return common.debug("discovery",`Discovery complete: ${o.toFixed(1)}ms`),{config:r.config,filepath:r.filepath,content:s,contentHash:i,isEmpty:r.isEmpty}};function k(e){return {cwd:Ue__default.default.cwd(),fs:{existsSync:D__namespace.existsSync,accessSync:(t,r)=>D__namespace.accessSync(t,r)},os:{cpus:Ae.cpus},path:{dirname:C__namespace.dirname,resolve:C__namespace.resolve,isAbsolute:C__namespace.isAbsolute},...e}}var u={NEGATIVE_MAX_WARNINGS:e=>({code:"negative-max-warnings",message:`Value for 'maxWarnings' must be non-negative. Received: ${e}.`,suggestion:"Set 'maxWarnings' to 0 or higher, or remove it to use default (10).",severity:"error"}),WORKERS_BELOW_MINIMUM:()=>({code:"workers-below-minimum",message:"Value for 'maxWorkers' must be at least 1.",suggestion:"Set to 1 or higher, or remove to use default (CPU count - 1).",severity:"error"}),NEGATIVE_CACHE_TTL:e=>({code:"negative-cache-ttl",message:`Cache TTL must be non-negative. Received: ${e}ms.`,suggestion:"Set to 0 (default TTL) or higher. Example: 86400000 for 24 hours.",severity:"error"}),WORKERS_EXCESSIVE:(e,t)=>({code:"warn-workers-excessive",message:`Worker count (${e}) exceeds CPU count (${t}). May cause context switching overhead.`,suggestion:`Reduce to ${t} or lower for optimal performance.`,severity:"warning"}),CACHE_TTL_ZERO:()=>({code:"warn-cache-ttl-zero",message:"Cache TTL is set to 0. Using driver default TTL (typically 24 hours).",suggestion:"Set explicit TTL if you need different cache expiration behavior.",severity:"warning"}),INVALID_GLOB_PATTERN:(e,t)=>({code:"invalid-glob-pattern",message:`Glob pattern "${e}" is invalid. Error: ${t}.`,suggestion:"Check pattern syntax. Valid examples: 'src/**/*.ts', '**/*.{ts,html}'.",severity:"error"}),EMPTY_INCLUDE:()=>({code:"empty-include",message:"No include patterns defined. Analysis will skip all files.",suggestion:"Add patterns like ['src/**/*.ts', 'src/**/*.html'] to enable analysis.",severity:"error"}),EMPTY_EXCLUDE:()=>({code:"warn-empty-exclude",message:"No exclude patterns defined. Performance may degrade.",suggestion:"Add common exclusions: ['node_modules/**', 'dist/**', '**/*.spec.ts'].",severity:"warning"}),DUPLICATE_PATTERNS:(e,t)=>({code:"warn-duplicate-patterns",message:`Duplicate patterns found in "${e}": ${t.map(r=>`"${r}"`).join(", ")}.`,suggestion:"Remove duplicate entries to simplify configuration.",severity:"warning"}),EMPTY_GLOB_PATTERN:e=>({code:"empty-glob-pattern",message:`Empty string detected in "${e}" patterns.`,suggestion:"Remove empty strings from the pattern array.",severity:"error"}),TSCONFIG_ROOT_NOT_FOUND:e=>({code:"tsconfig-root-not-found",message:`TSConfig root directory not found: "${e}".`,suggestion:"Verify the directory exists and the path is correct relative to the config file.",severity:"error"}),TSCONFIG_PROJECT_NOT_FOUND:e=>({code:"tsconfig-project-not-found",message:`TSConfig file not found: "${e}".`,suggestion:"Verify the file exists and the path is relative to 'tsconfigRootDir' or config location.",severity:"error"}),OUTPUT_PATH_TRAVERSAL:e=>({code:"output-path-traversal",message:`Output path contains unsafe traversal (..): "${e}".`,suggestion:"Use absolute paths or paths without '..' to prevent security issues.",severity:"error"}),OUTPUT_PATH_SYSTEM_DIR:e=>({code:"output-path-system-dir",message:`Output path points to a system directory: "${e}".`,suggestion:"Choose a safe output location within your project directory.",severity:"error"}),OUTPUT_PATH_NOT_FOUND:e=>({code:"output-path-not-found",message:`Output directory does not exist: "${e}".`,suggestion:"Create the directory or update 'outputPath' to an existing location.",severity:"error"}),OUTPUT_PATH_NOT_WRITABLE:e=>({code:"output-path-not-writable",message:`Output directory is not writable: "${e}".`,suggestion:"Check directory permissions or choose a different output location.",severity:"error"}),CACHE_IN_NODE_MODULES:e=>({code:"cache-in-node-modules",message:`Cache location inside 'node_modules' is unsafe: "${e}". node_modules can be deleted, causing cache loss.`,suggestion:"Use a different directory like '.cache' or 'node_modules/.cache/ngcompass'.",severity:"error"}),CACHE_PARENT_NOT_FOUND:e=>({code:"warn-cache-parent-not-found",message:`Cache parent directory missing: "${e}". It will be created automatically.`,suggestion:"No action needed. Directory will be created on first cache write.",severity:"warning"}),INVALID_RULE_SEVERITY:(e,t)=>({code:"invalid-rule-severity",message:`Rule "${e}" has invalid severity: "${t}".`,suggestion:"Use valid severities: 'off', 'info', 'low', 'moderate', 'high', or 'critical'.",severity:"error"}),NO_RULES_CONFIGURED:()=>({code:"warn-no-rules-configured",message:"No rules configured. Analysis effectively skips checks.",suggestion:"Add rules to enable analysis, or extend from a preset like 'recommended'.",severity:"warning"}),EMPTY_RULE_NAME:()=>({code:"empty-rule-name",message:"Empty rule name detected. Rule keys must be non-empty strings.",suggestion:"Remove empty keys from 'rules' configuration.",severity:"error"}),PROFILE_CIRCULAR_INHERITANCE:e=>({code:"profile-circular-inheritance",message:`Circular profile inheritance detected: ${e.join(" \u2192 ")}.`,suggestion:"Break the circular dependency by removing one 'extends' reference.",severity:"error"}),PROFILE_EMPTY:()=>({code:"warn-profile-empty",message:"Profiles section is defined but empty. Consider removing it.",suggestion:"Remove 'profiles: {}' or add at least one profile like 'dev' or 'ci'.",severity:"warning"}),EXTENDS_NOT_FOUND:e=>({code:"extends-not-found",message:`Cannot resolve preset "${e}". Make sure the package is installed.`,suggestion:`Run: npm install --save-dev ${e}`,severity:"error"}),DEPRECATED_CACHE_LOCATION:()=>({code:"warn-deprecated-cache-location",message:"'cacheLocation' is deprecated. Use 'cache.location' instead.",suggestion:`Replace 'cacheLocation: "..."' with 'cache: { location: "..." }'.`,severity:"warning"}),DEPRECATED_CONCURRENCY:()=>({code:"warn-deprecated-concurrency",message:"'concurrency' is deprecated. Use 'maxWorkers' instead.",suggestion:"Replace 'concurrency: N' with 'maxWorkers: N'.",severity:"warning"})};function W(e,t,r=[]){let s=[];if(e.maxWorkers!==void 0){let i=2*t.os.cpus().length;e.maxWorkers<1?s.push({...u.WORKERS_BELOW_MINIMUM(),path:[...r,"maxWorkers"]}):e.maxWorkers>i&&s.push({...u.WORKERS_EXCESSIVE(e.maxWorkers,i),path:[...r,"maxWorkers"]});}if(e.cache&&typeof e.cache=="object"&&e.cache.ttl!==void 0){let{ttl:i}=e.cache,o=[...r,"cache","ttl"];i<0&&s.push({...u.NEGATIVE_CACHE_TTL(i),path:o});}return {issues:s}}function re(e,t,r=[]){let s=[];if(e.maxWarnings!==void 0){let{maxWarnings:o}=e;o<0&&s.push({...u.NEGATIVE_MAX_WARNINGS(o),path:[...r,"maxWarnings"]});}let{issues:i}=W(e,t,r);return s.push(...i),{issues:s}}function se(e,t=[],r=Ue__default.default.cwd()){let s=[];if(!e.extends)return {issues:s};let i=Array.isArray(e.extends)?e.extends:[e.extends],o=Array.isArray(e.extends);for(let n=0;n<i.length;n++){let c=i[n];if(!(typeof c!="string"||c.trim()===""||(function(l){let d=l.startsWith("."),y=C__namespace.default.isAbsolute(l),E=l.includes(":");return d||y||E})(c))&&(function(l,d){try{let y=C__namespace.default.join(d,"__resolve_anchor__.cjs");return module$1.createRequire(y).resolve(l)}catch{return null}})(c,r)===null){let l=[...t,"extends"];o&&l.push(n),s.push({...u.EXTENDS_NOT_FOUND(c),path:l});}}return {issues:s}}var je=/\/\/\//,Me=/\{/g,Ve=/\}/g;function ne(e,t=[]){let r=[];for(let s of ["include","exclude","ignorePatterns"]){let i=e[s];if(!Array.isArray(i))continue;i.forEach((n,c)=>{r.push(...(function(l,d,y,E){let f=[],p=[...E,l,y];if(!d||d.trim()==="")return f.push({...u.EMPTY_GLOB_PATTERN(l),path:p}),f;if(d.includes("[")&&!d.includes("]"))return f.push({...u.INVALID_GLOB_PATTERN(d,"unclosed bracket"),path:p}),f;if(je.test(d)||d.startsWith("///"))return f.push({...u.INVALID_GLOB_PATTERN(d,"invalid path pattern with multiple slashes"),path:p}),f;(d.endsWith("\\")||d.endsWith("/"))&&f.push({...u.INVALID_GLOB_PATTERN(d,"trailing slash not allowed"),path:p}),(d.match(Me)||[]).length!==(d.match(Ve)||[]).length&&f.push({...u.INVALID_GLOB_PATTERN(d,"unmatched braces"),path:p});try{minimatch.minimatch("sample.ts",d);}catch(g){f.push({...u.INVALID_GLOB_PATTERN(d,g.message),path:p});}return f})(s,n,c,t));});let o=i.filter((n,c)=>i.indexOf(n)!==c);o.length>0&&r.push({...u.DUPLICATE_PATTERNS(s,[...new Set(o)]),path:[...t,s]});}return e.include&&e.include.length!==0||r.push({...u.EMPTY_INCLUDE(),path:[...t,"include"]}),e.exclude&&e.exclude.length!==0||r.push({...u.EMPTY_EXCLUDE(),path:[...t,"exclude"]}),{issues:r}}var We=["/etc/","\\etc\\","/var/","\\var\\"],ie="node_modules";function ce(e,t,r=[]){let s=[],i=o=>t.path.isAbsolute(o)?o:t.path.resolve(t.cwd??process.cwd(),o);if(e.outputPath){let{outputPath:o}=e,n=[...r,"outputPath"];o.includes("..")&&s.push({...u.OUTPUT_PATH_TRAVERSAL(o),path:n}),We.some(l=>o.includes(l))&&s.push({...u.OUTPUT_PATH_SYSTEM_DIR(o),path:n});let c=t.path.dirname(i(o));if(t.fs.existsSync(c))try{t.fs.accessSync(c,D__namespace.constants.W_OK);}catch{s.push({...u.OUTPUT_PATH_NOT_WRITABLE(c),path:n});}else s.push({...u.OUTPUT_PATH_NOT_FOUND(c),path:n});}if(e.cache&&typeof e.cache=="object"&&e.cache.enabled){let{location:o}=e.cache;if(o){let n=[...r,"cache","location"],c=o.includes(ie),l=o.includes(`${ie}/.cache`);c&&!l&&s.push({...u.CACHE_IN_NODE_MODULES(o),path:n});let d=t.path.dirname(i(o));t.fs.existsSync(d)||s.push({...u.CACHE_PARENT_NOT_FOUND(d),path:n});}}if(e.parserOptions){let{project:o,tsconfigRootDir:n}=e.parserOptions,c=o?i(o):void 0,l=n?i(n):void 0;c&&!t.fs.existsSync(c)&&s.push({...u.TSCONFIG_PROJECT_NOT_FOUND(o),path:[...r,"parserOptions","project"]}),l&&!t.fs.existsSync(l)&&s.push({...u.TSCONFIG_ROOT_NOT_FOUND(n),path:[...r,"parserOptions","tsconfigRootDir"]});}return {issues:s}}var Ge={info:0,low:1,warning:2,warn:2,moderate:2,high:3,error:4,critical:4},He=Object.keys(Ge),le=[...He,"off"];function ue(e,t=[]){let r=[],s=(Array.isArray(e.extends)||!!e.extends)&&e.extends.length>0,i=Object.entries(e.rules||{});for(let[o,n]of(i.length>0||s||r.push({...u.NO_RULES_CONFIGURED(),path:[...t,"rules"]}),i)){if(!o||o.trim()===""){r.push({...u.EMPTY_RULE_NAME(),path:[...t,"rules"]});continue}if(typeof n=="object"&&n!==null){let{severity:c}=n;c&&!le.includes(c)&&r.push({...u.INVALID_RULE_SEVERITY(o,c),path:[...t,"rules",o,"severity"]});}}return {issues:r}}function de(e,t=[]){let r=[];return e&&typeof e=="object"&&("cacheLocation"in e&&e.cacheLocation!==void 0&&r.push({...u.DEPRECATED_CACHE_LOCATION(),path:[...t,"cacheLocation"]}),"concurrency"in e&&e.concurrency!==void 0&&r.push({...u.DEPRECATED_CONCURRENCY(),path:[...t,"concurrency"]})),{issues:r}}function fe(e,t){let r=common.ASTUtils.parse(e,t);return common.ASTUtils.generateLocationMap(r)}async function qe(e,t,r,s){if(!r)return fe(e,t);let i=`v${common.CACHE_VERSION}:${s}`,o=await r.get(i);if(o)return o.ast;let n=fe(e,t);return await r.set(i,{filePath:t,ast:n}),n}async function me(e,t,r,s,i){if(e.length===0)return;let o=i??be__default.default.createHash("sha1").update(t).digest("hex"),n=await qe(t,r,s,o);for(let c of e){if(c.file||(c.file=r),!((!c.line||c.line===1)&&c.path))continue;let l=n[c.path.join(".")];l&&(c.line=l.line,c.column=l.column);}}var ze=new Set(["recommended","strict","performance","reactivity","all"]);async function Ke(e,t,r,s,i){if(r)return void await me(e,r,t,s,i);for(let o of e)o.file||(o.file=t);}function ge(e,t){let r,s=[...(r=new Set,e.filter(o=>{let n=`${o.code}:${o.message}:${JSON.stringify(o.path)}`;return !r.has(n)&&(r.add(n),true)}))].sort((o,n)=>o.severity===n.severity?0:o.severity==="error"?-1:1),i=!s.some(o=>o.severity==="error");return {config:i?t:void 0,report:{valid:i,issues:s}}}async function he(e){let t,{config:r,context:s,basePath:i=[],filePath:o,fileContent:n,astCache:c,contentHash:l}=e,{issues:d,validated:y,success:E}=(t=Z.safeParse(r)).success?{issues:[],validated:t.data,success:true}:{issues:t.error.issues.map(p=>({code:p.code.replace(/_/g,"-"),message:p.message,path:[...i,...p.path],severity:"error",file:o})),validated:r,success:false},f=[...d,...(function(p,g,m,h,b){let v=[];for(let O of [{name:"cross-fields",run:()=>re(p,m,h).issues},{name:"glob-patterns",run:()=>ne(p,h).issues},{name:"paths",run:()=>ce(p,m,h).issues},{name:"rules",run:()=>ue(p,h).issues},{name:"extends-chain",run:()=>se(p,h,m.cwd).issues},{name:"deprecated",run:()=>de(g,h).issues}])try{v.push(...O.run());}catch(j){v.push({code:"check-failed",message:`Check "${O.name}" encountered an unexpected error: ${j.message}`,path:h,severity:"error",file:b});}return v})(y,r,s,i,o)];return o&&await Ke(f,o,n,c,l),{issues:f,validated:E?y:void 0}}async function ye(e,t=k(),r,s,i,o){var n;let c={context:t,filePath:r,fileContent:s,astCache:i,contentHash:o},l=e===null||typeof e!="object"?{}:e.profiles??{};if(t.profile){let E=l[t.profile];if(!E){let m,h;return n=t.profile,m=Object.keys(l).join(", "),h=ze.has(n.replace(/^ngcompass:/,""))?` "${n}" is a built-in preset, not a config profile. Use 'extends: "ngcompass:${n.replace(/^ngcompass:/,"")}"' in your config instead.`:"",{config:void 0,report:{valid:false,issues:[{code:"error-profile-not-found",message:`Profile "${n}" not found. Available: [${m}]${h}`,path:["profiles",n],severity:"error",file:r}]}}}let f=defu.defu(E,e),{issues:p,validated:g}=await he({...c,config:f,basePath:["profiles",t.profile]});return ge(p,g)}let{issues:d,validated:y}=await he({...c,config:e});return ge(d,y)}var ve=async e=>{common.time("config-resolution");let{cwd:t=Ue__default.default.cwd(),profile:r,cache:s}=e;common.debug("loader",`Starting config resolution (cwd: ${t}, profile: ${r||"none"})`);let i=await U(t),{hash:o,cachedResult:n}=await tt(i,r,s);if(n){let d=common.timeEnd("config-resolution");return common.debug("loader",`Cache HIT - returning cached result (${d.toFixed(1)}ms)`),n}common.debug("loader","Cache MISS - running validation");let c=await rt(i,r,s);common.debug("loader",`Validation complete: ${c.report.valid?"valid":`invalid (${c.report.issues.length} issues)`}`),s&&o&&(await s.configs.set(o,c),common.debug("loader",`Cached validation result: key=${o.substring(0,8)}...`));let l=common.timeEnd("config-resolution");return common.debug("loader",`Config resolution complete: ${l.toFixed(1)}ms`),c};async function tt(e,t,r){if(!r)return {};let s=[e?.contentHash??"",t??"",common.PACKAGE_VERSION,common.CACHE_VERSION].join("::"),i=r.computeHash(s);common.debug("loader",`Cache lookup: key=${i.substring(0,8)}...`);let o=await r.configs.get(i);return {hash:i,cachedResult:o}}async function rt(e,t,r){return ye(e?.config??{},k({profile:t}),e?.filepath,e?.content,r?.asts,e?.contentHash)}var Te=class extends Error{constructor(t){super(`Configuration file already exists at: ${t}`),this.name="ConfigExistsError";}},nt=`import { defineConfig } from '@ngcompass/config'; | ||
| 'use strict';var common=require('@ngcompass/common'),$=require('fs'),O=require('path'),Ie=require('os'),Pe=require('process'),defu=require('defu'),zod=require('zod'),module$1=require('module'),minimatch=require('minimatch'),He=require('crypto'),url=require('url'),jiti=require('jiti'),lilconfig=require('lilconfig'),B=require('fs/promises');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var $__namespace=/*#__PURE__*/_interopNamespace($);var O__namespace=/*#__PURE__*/_interopNamespace(O);var Ie__default=/*#__PURE__*/_interopDefault(Ie);var Pe__default=/*#__PURE__*/_interopDefault(Pe);var He__default=/*#__PURE__*/_interopDefault(He);var B__default=/*#__PURE__*/_interopDefault(B);function w(e={}){return {cwd:Pe__default.default.cwd(),fs:{existsSync:$__namespace.existsSync,accessSync:(t,r)=>$__namespace.accessSync(t,r)},os:{cpus:Ie.cpus},path:{dirname:O__namespace.dirname,resolve:O__namespace.resolve,isAbsolute:O__namespace.isAbsolute},...e}}var J=()=>Math.max(1,Math.min(4,Ie__default.default.cpus().length-1)),b={enabled:true,location:"node_modules/.cache/ngcompass",strategy:"local",ttl:864e5},v={outputFormat:"text",failOnSeverity:"error",maxWarnings:10,include:common.DEFAULT_INCLUDE_PATTERNS,exclude:["**/node_modules/**","**/dist/**","**/build/**","**/*.spec.ts","**/*.test.ts"]};var V=zod.z.enum(["warn","error"]),Le=zod.z.enum(["json","text","sarif","html"]),Z=zod.z.union([V,zod.z.literal("off"),zod.z.object({severity:zod.z.union([V,zod.z.literal("off")]),options:zod.z.record(zod.z.string(),zod.z.unknown()).optional()})]),$e=zod.z.object({enabled:zod.z.boolean().optional(),location:zod.z.string().optional(),strategy:zod.z.enum(["memory","local"]).optional(),ttl:zod.z.number().optional()}),we=zod.z.object({project:zod.z.string().optional(),tsconfigRootDir:zod.z.string().optional(),sourceType:zod.z.enum(["module","commonjs"]).optional(),ecmaVersion:zod.z.number().optional()}),Q=zod.z.object({extends:zod.z.union([zod.z.string(),zod.z.array(zod.z.string())]).optional(),include:zod.z.array(zod.z.string()).default(()=>[...v.include]),exclude:zod.z.array(zod.z.string()).default(()=>[...v.exclude]),maxWorkers:zod.z.number().optional(),concurrency:zod.z.number().optional(),cache:zod.z.union([zod.z.boolean(),$e]).optional(),cacheLocation:zod.z.string().optional(),outputFormat:Le.default(v.outputFormat),outputPath:zod.z.string().optional(),failOnSeverity:V.default(v.failOnSeverity),maxWarnings:zod.z.number().default(v.maxWarnings),ignorePatterns:zod.z.array(zod.z.string()).optional(),rules:zod.z.record(zod.z.string(),Z).optional(),overrides:zod.z.array(zod.z.object({files:zod.z.union([zod.z.string(),zod.z.array(zod.z.string())]),rules:zod.z.record(zod.z.string(),Z).optional()})).optional(),parserOptions:we.optional()}),Ue=zod.z.lazy(()=>Q.partial()),ee=Q.extend({profiles:zod.z.record(zod.z.string(),Ue).optional()}).transform(e=>{let t,r=e.maxWorkers??e.concurrency??J();if(e.cache===false)t={...b,enabled:false};else if(e.cache===true||e.cache===void 0){let i=e.cacheLocation??b.location;t={...b,location:i};}else t={...b,...e.cache};return {...e,maxWorkers:r,cache:t,rules:e.rules??{},overrides:e.overrides??[],ignorePatterns:e.ignorePatterns??[]}});var f={NEGATIVE_MAX_WARNINGS:e=>({code:"negative-max-warnings",message:`Value for 'maxWarnings' must be non-negative. Received: ${e}.`,suggestion:"Set 'maxWarnings' to 0 or higher, or remove it to use default (10).",severity:"error"}),WORKERS_BELOW_MINIMUM:{code:"workers-below-minimum",message:"Value for 'maxWorkers' must be at least 1.",suggestion:"Set to 1 or higher, or remove to use default (CPU count - 1).",severity:"error"},NEGATIVE_CACHE_TTL:e=>({code:"negative-cache-ttl",message:`Cache TTL must be non-negative. Received: ${e}ms.`,suggestion:"Set to 0 (default TTL) or higher. Example: 86400000 for 24 hours.",severity:"error"}),WORKERS_EXCESSIVE:(e,t)=>({code:"warn-workers-excessive",message:`Worker count (${e}) exceeds CPU count (${t}). May cause context switching overhead.`,suggestion:`Reduce to ${t} or lower for optimal performance.`,severity:"warning"}),CACHE_TTL_ZERO:{code:"warn-cache-ttl-zero",message:"Cache TTL is set to 0. Using driver default TTL (typically 24 hours).",suggestion:"Set explicit TTL if you need different cache expiration behavior.",severity:"warning"},INVALID_GLOB_PATTERN:(e,t)=>({code:"invalid-glob-pattern",message:`Glob pattern "${e}" is invalid. Error: ${t}.`,suggestion:"Check pattern syntax. Valid examples: 'src/**/*.ts', '**/*.{ts,html}'.",severity:"error"}),EMPTY_INCLUDE:{code:"empty-include",message:"No include patterns defined. Analysis will skip all files.",suggestion:"Add patterns like ['src/**/*.ts', 'src/**/*.html'] to enable analysis.",severity:"error"},EMPTY_EXCLUDE:{code:"warn-empty-exclude",message:"No exclude patterns defined. Performance may degrade.",suggestion:"Add common exclusions: ['node_modules/**', 'dist/**', '**/*.spec.ts'].",severity:"warning"},DUPLICATE_PATTERNS:(e,t)=>({code:"warn-duplicate-patterns",message:`Duplicate patterns found in "${e}": ${t.map(r=>`"${r}"`).join(", ")}.`,suggestion:"Remove duplicate entries to simplify configuration.",severity:"warning"}),EMPTY_GLOB_PATTERN:e=>({code:"empty-glob-pattern",message:`Empty string detected in "${e}" patterns.`,suggestion:"Remove empty strings from the pattern array.",severity:"error"}),TSCONFIG_ROOT_NOT_FOUND:e=>({code:"tsconfig-root-not-found",message:`TSConfig root directory not found: "${e}".`,suggestion:"Verify the directory exists and the path is correct relative to the config file.",severity:"error"}),TSCONFIG_PROJECT_NOT_FOUND:e=>({code:"tsconfig-project-not-found",message:`TSConfig file not found: "${e}".`,suggestion:"Verify the file exists and the path is relative to 'tsconfigRootDir' or config location.",severity:"error"}),OUTPUT_PATH_TRAVERSAL:e=>({code:"output-path-traversal",message:`Output path contains unsafe traversal (..): "${e}".`,suggestion:"Use absolute paths or paths without '..' to prevent security issues.",severity:"error"}),OUTPUT_PATH_SYSTEM_DIR:e=>({code:"output-path-system-dir",message:`Output path points to a system directory: "${e}".`,suggestion:"Choose a safe output location within your project directory.",severity:"error"}),OUTPUT_PATH_NOT_FOUND:e=>({code:"output-path-not-found",message:`Output directory does not exist: "${e}".`,suggestion:"Create the directory or update 'outputPath' to an existing location.",severity:"error"}),OUTPUT_PATH_NOT_WRITABLE:e=>({code:"output-path-not-writable",message:`Output directory is not writable: "${e}".`,suggestion:"Check directory permissions or choose a different output location.",severity:"error"}),CACHE_IN_NODE_MODULES:e=>({code:"cache-in-node-modules",message:`Cache location inside 'node_modules' is unsafe: "${e}". node_modules can be deleted, causing cache loss.`,suggestion:"Use a different directory like '.cache' or 'node_modules/.cache/ngcompass'.",severity:"error"}),CACHE_PARENT_NOT_FOUND:e=>({code:"warn-cache-parent-not-found",message:`Cache parent directory missing: "${e}". It will be created automatically.`,suggestion:"No action needed. Directory will be created on first cache write.",severity:"warning"}),INVALID_RULE_SEVERITY:(e,t)=>({code:"invalid-rule-severity",message:`Rule "${e}" has invalid severity: "${t}".`,suggestion:"Use one of: 'warn', 'error', or 'off'.",severity:"error"}),NO_RULES_CONFIGURED:{code:"warn-no-rules-configured",message:"No rules configured. Analysis effectively skips checks.",suggestion:"Add rules to enable analysis, or extend from a preset like 'recommended'.",severity:"warning"},EMPTY_RULE_NAME:{code:"empty-rule-name",message:"Empty rule name detected. Rule keys must be non-empty strings.",suggestion:"Remove empty keys from 'rules' configuration.",severity:"error"},PROFILE_CIRCULAR_INHERITANCE:e=>({code:"profile-circular-inheritance",message:`Circular profile inheritance detected: ${e.join(" \u2192 ")}.`,suggestion:"Break the circular dependency by removing one 'extends' reference.",severity:"error"}),PROFILE_EMPTY:{code:"warn-profile-empty",message:"Profiles section is defined but empty. Consider removing it.",suggestion:"Remove 'profiles: {}' or add at least one profile like 'dev' or 'ci'.",severity:"warning"},EXTENDS_NOT_FOUND:e=>({code:"extends-not-found",message:`Cannot resolve preset "${e}". Make sure the package is installed.`,suggestion:`Run: npm install --save-dev ${e}`,severity:"error"}),DEPRECATED_CACHE_LOCATION:{code:"warn-deprecated-cache-location",message:"'cacheLocation' is deprecated. Use 'cache.location' instead.",suggestion:`Replace 'cacheLocation: "..."' with 'cache: { location: "..." }'.`,severity:"warning"},DEPRECATED_CONCURRENCY:{code:"warn-deprecated-concurrency",message:"'concurrency' is deprecated. Use 'maxWorkers' instead.",suggestion:"Replace 'concurrency: N' with 'maxWorkers: N'.",severity:"warning"}};function U(e,t,r=[]){let i=[];if(e.maxWorkers!==void 0){let a=2*t.os.cpus().length;e.maxWorkers<1?i.push({...f.WORKERS_BELOW_MINIMUM,path:[...r,"maxWorkers"]}):e.maxWorkers>a&&i.push({...f.WORKERS_EXCESSIVE(e.maxWorkers,a),path:[...r,"maxWorkers"]});}if(e.cache&&typeof e.cache=="object"&&e.cache.ttl!==void 0){let{ttl:a}=e.cache;a<0&&i.push({...f.NEGATIVE_CACHE_TTL(a),path:[...r,"cache","ttl"]});}return {issues:i}}function te(e,t,r=[]){let i=[];e.maxWarnings!==void 0&&e.maxWarnings<0&&i.push({...f.NEGATIVE_MAX_WARNINGS(e.maxWarnings),path:[...r,"maxWarnings"]});let{issues:a}=U(e,t,r);return i.push(...a),{issues:i}}function re(e,t=[]){let r=[];return e&&typeof e=="object"&&("cacheLocation"in e&&e.cacheLocation!==void 0&&r.push({...f.DEPRECATED_CACHE_LOCATION,path:[...t,"cacheLocation"]}),"concurrency"in e&&e.concurrency!==void 0&&r.push({...f.DEPRECATED_CONCURRENCY,path:[...t,"concurrency"]})),{issues:r}}function ie(e,t,r){let i=[];if(!e.extends)return {issues:i};let a=Array.isArray(e.extends),o=a?e.extends:[e.extends];for(let l=0;l<o.length;l++){let n=o[l];if(typeof n!="string"||n.trim()===""||n.startsWith(".")||O__namespace.default.isAbsolute(n)||n.includes(":")||(function(u,g){try{let p=O__namespace.default.join(g,"__resolve_anchor__.cjs");return module$1.createRequire(p).resolve(u)}catch{return null}})(n,r)!==null)continue;let s=[...t,"extends"];a&&s.push(l),i.push({...f.EXTENDS_NOT_FOUND(n),path:s});}return {issues:i}}var ke=/\/\/\//,Fe=/\{/g,Me=/\}/g,We=/\[/g,Ve=/\]/g;function ne(e,t=[]){let r=[];for(let i of ["include","exclude","ignorePatterns"]){let a=e[i];if(!Array.isArray(a))continue;for(let l=0;l<a.length;l++)r.push(...(function(n,s,u,g){let p=[],m=[...g,n,u];if(!s||s.trim()==="")return p.push({...f.EMPTY_GLOB_PATTERN(n),path:m}),p;if((s.match(We)||[]).length!==(s.match(Ve)||[]).length)return p.push({...f.INVALID_GLOB_PATTERN(s,"unmatched character class brackets"),path:m}),p;if(ke.test(s)||s.startsWith("///"))return p.push({...f.INVALID_GLOB_PATTERN(s,"invalid path pattern with multiple slashes"),path:m}),p;(s.endsWith("\\")||s.endsWith("/"))&&p.push({...f.INVALID_GLOB_PATTERN(s,"trailing slash not allowed"),path:m}),(s.match(Fe)||[]).length!==(s.match(Me)||[]).length&&p.push({...f.INVALID_GLOB_PATTERN(s,"unmatched braces"),path:m});try{minimatch.minimatch("sample.ts",s);}catch(d){let h=d instanceof Error?d.message:String(d);p.push({...f.INVALID_GLOB_PATTERN(s,h),path:m});}return p})(i,a[l],l,t));let o=(function(l){let n=new Set,s=new Set;for(let u of l)n.has(u)?s.add(u):n.add(u);return [...s]})(a);o.length>0&&r.push({...f.DUPLICATE_PATTERNS(i,o),path:[...t,i]});}return e.include&&e.include.length!==0||r.push({...f.EMPTY_INCLUDE,path:[...t,"include"]}),e.exclude&&e.exclude.length!==0||r.push({...f.EMPTY_EXCLUDE,path:[...t,"exclude"]}),{issues:r}}var Ge=["/etc/","\\etc\\","/var/","\\var\\"],se=/[\\/]/;function le(e,t,r=[]){let i=[],a=o=>t.path.isAbsolute(o)?o:t.path.resolve(t.cwd,o);if(e.outputPath){let{outputPath:o}=e,l=[...r,"outputPath"];o.includes("..")&&i.push({...f.OUTPUT_PATH_TRAVERSAL(o),path:l}),Ge.some(s=>o.includes(s))&&i.push({...f.OUTPUT_PATH_SYSTEM_DIR(o),path:l});let n=t.path.dirname(a(o));if(t.fs.existsSync(n))try{t.fs.accessSync(n,$__namespace.constants.W_OK);}catch{i.push({...f.OUTPUT_PATH_NOT_WRITABLE(n),path:l});}else i.push({...f.OUTPUT_PATH_NOT_FOUND(n),path:l});}if(e.cache&&typeof e.cache=="object"&&e.cache.enabled){let{location:o}=e.cache;if(o){let l,n,s=[...r,"cache","location"];o.split(se).includes("node_modules")&&((n=(l=o.split(se)).indexOf("node_modules"))===-1||l[n+1]!==".cache")&&i.push({...f.CACHE_IN_NODE_MODULES(o),path:s});let u=t.path.dirname(a(o));t.fs.existsSync(u)||i.push({...f.CACHE_PARENT_NOT_FOUND(u),path:s});}}if(e.parserOptions){let{project:o,tsconfigRootDir:l}=e.parserOptions;if(o){let n=a(o);t.fs.existsSync(n)||i.push({...f.TSCONFIG_PROJECT_NOT_FOUND(o),path:[...r,"parserOptions","project"]});}if(l){let n=a(l);t.fs.existsSync(n)||i.push({...f.TSCONFIG_ROOT_NOT_FOUND(l),path:[...r,"parserOptions","tsconfigRootDir"]});}}return {issues:i}}function ce(e,t){let r=[];if(!e.profiles||typeof e.profiles!="object")return {issues:r};let i=e.profiles,a=Object.keys(i);if(a.length===0)return r.push({...f.PROFILE_EMPTY,path:["profiles"]}),{issues:r};for(let[l,n]of Object.entries(i)){if(!n||typeof n!="object")continue;let{issues:s}=U(n,t,["profiles",l]);r.push(...s);}let o=new Set;for(let l of a)(function(n,s,u,g){let p=[],m=n;for(;m!==void 0;){if(u.has(m))return;if(p.includes(m)){for(let d of(g.push({...f.PROFILE_CIRCULAR_INHERITANCE([...p,m]),path:["profiles",p[0],"extends"]}),p))u.add(d);return}p.push(m),m=(function(d){if(!d||typeof d!="object")return;let h=d.extends;return typeof h=="string"?h:void 0})(s[m]);}for(let d of p)u.add(d);})(l,i,o,r);return {issues:r}}var ue=["warn","error","off"];function fe(e,t=[]){var r;let i=[],a=Object.entries(e.rules||{});for(let[o,l]of(a.length>0||(Array.isArray(r=e.extends)?r.length>0:r)||i.push({...f.NO_RULES_CONFIGURED,path:[...t,"rules"]}),a)){if(!o||o.trim()===""){i.push({...f.EMPTY_RULE_NAME,path:[...t,"rules"]});continue}if(typeof l=="object"&&l!==null){let{severity:n}=l;n&&!ue.includes(n)&&i.push({...f.INVALID_RULE_SEVERITY(o,n),path:[...t,"rules",o,"severity"]});}}return {issues:i}}function D(e){return He__default.default.createHash("sha1").update(e).digest("hex")}function de(e,t){let r=common.ASTUtils.parse(e,t);return common.ASTUtils.generateLocationMap(r)}async function Ye(e,t,r,i){if(!r)return de(e,t);let a=`v${common.CACHE_VERSION}:${i}`,o=await r.get(a);if(o&&(function(n){if(!n||typeof n!="object")return false;for(let s of Object.values(n))return !!(s&&typeof s=="object"&&"line"in s&&"column"in s);return true})(o.ast))return o.ast;let l=de(e,t);return await r.set(a,{filePath:t,ast:l}),l}async function me(e,t,r,i,a){if(e.length===0)return;let o=a??D(t),l=await Ye(t,r,i,o);for(let n of e){if(n.file||(n.file=r),!((!n.line||n.line===1)&&n.path))continue;let s=l[n.path.join(".")];s&&(n.line=s.line,n.column=s.column);}}var qe=new Set(["recommended","strict","performance","reactivity","all"]);async function ze(e,t,r,i,a){if(r)return void await me(e,r,t,i,a);for(let o of e)o.file||(o.file=t);}function ge(e,t){let r,i=[...(r=new Set,e.filter(o=>{let l=o.path?o.path.join("."):"",n=`${o.code}:${o.message}:${l}`;return !r.has(n)&&(r.add(n),true)}))].sort((o,l)=>o.severity===l.severity?0:o.severity==="error"?-1:1),a=!i.some(o=>o.severity==="error");return {config:a?t:void 0,report:{valid:a,issues:i}}}async function G(e){let t,{config:r,context:i,basePath:a=[],filePath:o,fileContent:l,astCache:n,contentHash:s}=e,{issues:u,validated:g,success:p}=(t=ee.safeParse(r)).success?{issues:[],validated:t.data,success:true}:{issues:t.error.issues.map(d=>({code:d.code.replace(/_/g,"-"),message:d.message,path:[...a,...d.path],severity:"error",file:o})),validated:r,success:false},m=[...u,...(function(d,h,y,E,A){let x=[];for(let T of [{name:"cross-fields",run:()=>te(d,y,E).issues},{name:"glob-patterns",run:()=>ne(d,E).issues},{name:"paths",run:()=>le(d,y,E).issues},{name:"rules",run:()=>fe(d,E).issues},{name:"extends-chain",run:()=>ie(d,E,y.cwd).issues},{name:"profiles",run:()=>ce(d,y).issues},{name:"deprecated",run:()=>re(h,E).issues}])try{x.push(...T.run());}catch(C){let I=C instanceof Error?C.message:String(C);x.push({code:"check-failed",message:`Check "${T.name}" encountered an unexpected error: ${I}`,path:E,severity:"error",file:A});}return x})(g,r,i,a,o)];return o&&await ze(m,o,l,n,s),{issues:m,validated:p?g:void 0}}async function he(e,t=w(),r,i,a,o){let l={context:t,filePath:r,fileContent:i,astCache:a,contentHash:o},n=(function(p){if(!p||typeof p!="object")return {};let m=p.profiles;return m&&typeof m=="object"?m:{}})(e);if(t.profile){let p=n[t.profile];if(!p){var s;let y,E,A;return s=t.profile,y=Object.keys(n).join(", "),E=s.replace(/^ngcompass:/,""),A=qe.has(E)?` "${s}" is a built-in preset, not a config profile. Use 'extends: "ngcompass:${E}"' in your config instead.`:"",{config:void 0,report:{valid:false,issues:[{code:"error-profile-not-found",message:`Profile "${s}" not found. Available: [${y}]${A}`,path:["profiles",s],severity:"error",file:r}]}}}let m=await G({...l,config:e}),d=defu.defu(p,e),h=await G({...l,config:d,basePath:["profiles",t.profile]});return ge([...m.issues,...h.issues],h.validated)}let{issues:u,validated:g}=await G({...l,config:e});return ge(u,g)}var _="ngcompass",et=[`${_}.config.ts`,`${_}.config.js`,`${_}.config.mjs`,`${_}.config.cjs`,`${_}.config.json`,`.${_}rc`,`.${_}rc.json`,"package.json"],k=e=>{let t=url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));return jiti.createJiti(e,{alias:{"@ngcompass/config":O__namespace.default.basename(t).startsWith("index.")?t:url.fileURLToPath(new URL("../index.ts",(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))))}}).import(e).then(r=>r&&typeof r=="object"&&"default"in r?r.default??r:r)},ve=(e,t)=>JSON.parse(t.replace(/^\uFEFF/,"")),Te=async e=>{common.time("config-discovery"),common.debug("discovery",`Searching for config in: ${e}`);let t=lilconfig.lilconfig(_,{searchPlaces:et,loaders:{".ts":k,".js":k,".mjs":k,".cjs":k,".json":ve,noExt:ve}}),r=await t.search(e);if(!r)return common.debug("discovery","No config file found"),common.timeEnd("config-discovery"),null;common.debug("discovery",`Found config: ${r.filepath}`);let i="",a="";common.time("content-hash");try{i=$__namespace.default.readFileSync(r.filepath,"utf-8"),a=D(i);let l=common.timeEnd("content-hash");common.debug("discovery",`Content hash: ${a.substring(0,8)}... (${l.toFixed(1)}ms)`);}catch(l){common.timeEnd("content-hash");let n=l instanceof Error?l.message:String(l);common.debug("discovery",`Failed to re-read config file for hashing: ${n}`);}let o=common.timeEnd("config-discovery");return common.debug("discovery",`Discovery complete: ${o.toFixed(1)}ms`),{config:r.config,filepath:r.filepath,content:i,contentHash:a,isEmpty:r.isEmpty}};var Ae=async e=>{common.time("config-resolution");let{cwd:t,profile:r,cache:i}=e;common.debug("loader",`Starting config resolution (cwd: ${t}, profile: ${r||"none"})`);let a=await Te(t),{hash:o,cachedResult:l}=await it(a,r,i);if(l){let u=common.timeEnd("config-resolution");return common.debug("loader",`Cache HIT - returning cached result (${u.toFixed(1)}ms)`),l}common.debug("loader","Cache MISS - running validation");let n=await nt(a,r,i);common.debug("loader",`Validation complete: ${n.report.valid?"valid":`invalid (${n.report.issues.length} issues)`}`),i&&o&&(await i.configs.set(o,n),common.debug("loader",`Cached validation result: key=${o.substring(0,8)}...`));let s=common.timeEnd("config-resolution");return common.debug("loader",`Config resolution complete: ${s.toFixed(1)}ms`),n};async function it(e,t,r){if(!r)return {};let i=[e?.contentHash??"",t??"",common.PACKAGE_VERSION,common.CACHE_VERSION].join("::"),a=r.computeHash(i);common.debug("loader",`Cache lookup: key=${a.substring(0,8)}...`);let o=await r.configs.get(a);return {hash:a,cachedResult:o}}async function nt(e,t,r){return he(e?.config??{},w({profile:t}),e?.filepath,e?.content,r?.asts,e?.contentHash)}async function Sr(e){try{return await Ae(e)}catch(t){return {config:void 0,report:{valid:false,issues:[{code:"error-conf-semantic",message:t instanceof Error?t.message:String(t),path:[],severity:"error"}]}}}}var st=(e={})=>{let t=e.include??v.include,r=e.exclude??v.exclude,i=t.map(o=>` '${o}',`).join(` | ||
| `),a=r.map(o=>` '${o}',`).join(` | ||
| `);return `import { defineConfig } from '@ngcompass/config'; | ||
@@ -7,14 +9,7 @@ export default defineConfig({ | ||
| include: [ | ||
| 'src/**/*.ts', | ||
| 'src/**/*.html', | ||
| ${i} | ||
| ], | ||
| exclude: [ | ||
| 'node_modules/**', | ||
| 'dist/**', | ||
| 'build/**', | ||
| 'coverage/**', | ||
| '**/*.d.ts', | ||
| '**/*.spec.ts', | ||
| '**/*.test.ts', | ||
| ${a} | ||
| ], | ||
@@ -29,6 +24,6 @@ | ||
| }); | ||
| `;async function vr(e={}){let t=e.cwd??process.cwd(),r=C__namespace.default.join(t,"ngcompass.config.ts"),s=await U(t);if(s&&!e.force)return {success:false,filePath:s.filepath,alreadyExists:true};try{return await ot__default.default.writeFile(r,nt,"utf-8"),{success:!0,filePath:r}}catch{return {success:false,filePath:r}}}async function xr(e={}){try{return await ve(e)}catch(t){return {config:void 0,report:{valid:false,issues:[{code:"error-conf-semantic",message:t instanceof Error?t.message:String(t),path:[],severity:"error"}]}}}}function Sr(e){return e}var ct={typeCheckingEnabled:false,templateASTEnabled:true,cssASTEnabled:true},lt=async(e,t,r,s=ct)=>{if(e.length===0)return;common.debug("plugin-loader",`Initializing loader for ${e.length} plugin(s) at ${t}`);let i=module$1.createRequire(t+"/package.json"),o=[];for(let n of e)try{let c;try{c=i.resolve(n);}catch{c=n;}let l=await import(c),d=l.default??l,y=Array.isArray(d)?d:[d],E=0;for(let f of y){if(!(function(g){if(!g||typeof g!="object")return !1;let m=g.handler;return typeof g.name=="string"&&g.name.length>0&&m?.handle instanceof Function})(f)){common.warn("plugin-loader",`Plugin "${n}" exported an invalid structure. Skipping.`);continue}let{manifest:p}=f;if(p){let g=(function(m,h){let b=(function(v,O,j,xe){let N=O.trim();if(!N||N==="*")return null;let H=G(v);if(!H)return null;let B=N.startsWith("^")?(function(I){let x=G(I);return x?`>=${I} <${x[0]+1}.0.0`:null})(N.slice(1)):N;if(!B)return null;for(let I of B.split(/\s+/).filter(Boolean)){let x=I.match(/^(>=|<=|>|<|=|==)(\d+\.\d+\.\d+.*)$/);if(!x)continue;let $=x[1],Y=G(x[2]);if(!Y)continue;let R=(function(q,X){for(let A=0;A<3;A++)if(q[A]!==X[A])return q[A]>X[A]?1:-1;return 0})(H,Y);if(!($===">="?R>=0:$==="<="?R<=0:$===">"?R>0:$==="<"?R<0:R===0))return `Plugin "${j}@${xe}" requires engine "${O}", found "${v}".`}return null})(common.PACKAGE_VERSION.replace(/^v/,""),m.engineVersionRange,m.name,m.version);if(b)return b;for(let v of [{key:"requiresTypeInfo",current:h.typeCheckingEnabled,label:"Type Information"},{key:"requiresTemplateAST",current:h.templateASTEnabled,label:"Template AST"},{key:"requiresCssAST",current:h.cssASTEnabled,label:"CSS AST"}])if(m.capabilities?.[v.key]&&!v.current)return `Plugin "${m.name}@${m.version}" requires ${v.label} support, which is currently disabled.`;return null})(p,s);if(g)throw Error(g);common.debug("plugin-loader",`\u276F Validated: ${p.name}@${p.version}`);}else common.warn("plugin-loader",`Plugin "${n}" is missing a manifest. Please update for future compatibility.`);r.register(f),E++,common.debug("plugin-loader",`\u276F Registered Rule: ${f.name}`);}common.debug("plugin-loader",`Plugin "${n}" processed: ${E} rules active.`);}catch(c){let l=c instanceof Error?c.message:String(c);o.push(`- "${n}": ${l}`);}if(o.length>0)throw Error(`[ngcompass] Plugin Load Failure: | ||
| `},at=async e=>{try{return await B__default.default.access(e),!0}catch(t){return common.debug("init",`Path does not exist or is inaccessible: ${e}`),common.debug("init",Y(t)),false}};async function lt(e){let t,r=O__namespace.default.join(e,"angular.json"),i=await ct(r);if(!i)return;let a=(function(s,u){try{let g=JSON.parse(s);return H(g)?g:void 0}catch(g){common.debug("init",`Angular workspace detection skipped for ${u}: ${Y(g)}`);return}})(i,r);if(!a)return;let o=H(t=a.projects)?t:void 0;if(!o)return;let l=(function(s){let u=[],g=new Set;for(let p of Object.values(s)){let m=(function(d){if(!H(d))return;let h=d.sourceRoot;if(typeof h=="string"&&h.trim()!=="")return Se(h);let y=d.root;if(typeof y=="string"&&y.trim()!=="")return Se(y)})(p);!m||g.has(m)||(g.add(m),u.push(m));}return u.sort((p,m)=>p.localeCompare(m))})(o);if(l.length!==0){var n=l;let s=[];for(let u of n)s.push(`${u}/**/*.ts`),s.push(`${u}/**/*.html`);return s}}async function Pr(e={}){let t=e.cwd??process.cwd(),r=O__namespace.default.join(t,"ngcompass.config.ts");if(!e.force&&await at(r))return {success:false,filePath:r,alreadyExists:true};let i=await lt(t);return await B__default.default.writeFile(r,st({include:i}),"utf-8"),{success:true,filePath:r}}async function ct(e){try{return await B__default.default.readFile(e,"utf-8")}catch(t){common.debug("init",`Angular workspace detection skipped for ${e}: ${Y(t)}`);return}}function Se(e){return e.replace(/\\/g,"/").replace(/^\/+/,"").replace(/\/+$/,"")}function H(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Y(e){return e instanceof Error?e.message:String(e)}function Ir(e){return e}var dt={typeCheckingEnabled:false,templateASTEnabled:true,cssASTEnabled:true},mt=async(e,t,r,i=dt)=>{if(e.length===0)return;common.debug("plugin-loader",`Initializing loader for ${e.length} plugin(s) at ${t}`);let a=module$1.createRequire(O__namespace.default.join(t,"package.json")),o=[];for(let l of e){let n=await gt(l,a,i,r);n&&o.push(`- "${l}": ${n}`);}if(o.length>0)throw Error(`[ngcompass] Plugin Load Failure: | ||
| ${o.join(` | ||
| `)} | ||
| Ensure plugins are installed and satisfy version requirements.`)};function G(e){let t=e.trim().match(/^v?\.?(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/);return t?[Number(t[1]),Number(t[2]),Number(t[3])]:null}exports.AnalyzerConfigSchema=Z;exports.ConfigExistsError=Te;exports.DEFAULT_CACHE_OPTIONS=P;exports.DEFAULT_CONFIG=S;exports.MESSAGES=u;exports.ProfileConfigSchema=Ne;exports.SEVERITY_LEVELS=Ge;exports.VALID_RULE_SEVERITIES=le;exports.VALID_SEVERITIES=He;exports.createDefaultContext=k;exports.defineConfig=Sr;exports.findAndLoadConfig=U;exports.getDefaultMaxWorkers=z;exports.initConfig=vr;exports.loadPlugins=lt;exports.resolveConfig=ve;exports.validateConfig=xr;exports.validateConfigBlock=W;exports.validateConfiguration=ye;//# sourceMappingURL=index.cjs.map | ||
| Ensure plugins are installed and satisfy version requirements.`)};async function gt(e,t,r,i){try{let a=(function(s,u){try{return u.resolve(s)}catch{return s}})(e,t),o=await ht(a),l=Array.isArray(o)?o:[o],n=0;for(let s of l){if(!(function(u){if(!u||typeof u!="object")return !1;let g=u.handler;return typeof u.name=="string"&&u.name.length>0&&typeof g?.handle=="function"})(s)){common.warn("plugin-loader",`Plugin "${e}" exported an invalid structure. Skipping.`);continue}if(s.manifest){let u=(function(g,p){let m=(function(d,h,y,E){var A;let x,T=h.trim();if(!T||T==="*")return null;let C=K(d);if(!C)return null;let I=T.startsWith("^")?(x=K(A=T.slice(1)))?`>=${A} <${x[0]+1}.0.0`:null:T;if(!I)return null;for(let Oe of I.split(/\s+/).filter(Boolean)){let W=Oe.match(Et);if(!W)continue;let L=W[1],q=K(W[2]);if(!q)continue;let P=(function(z,X){for(let R=0;R<3;R++)if(z[R]!==X[R])return z[R]>X[R]?1:-1;return 0})(C,q);if(!(L===">="?P>=0:L==="<="?P<=0:L===">"?P>0:L==="<"?P<0:P===0))return `Plugin "${y}@${E}" requires engine "${h}", found "${d}".`}return null})(common.PACKAGE_VERSION.replace(/^v/,""),g.engineVersionRange,g.name,g.version);if(m)return m;for(let d of [{key:"requiresTypeInfo",current:p.typeCheckingEnabled,label:"Type Information"},{key:"requiresTemplateAST",current:p.templateASTEnabled,label:"Template AST"},{key:"requiresCssAST",current:p.cssASTEnabled,label:"CSS AST"}])if(g.capabilities?.[d.key]&&!d.current)return `Plugin "${g.name}@${g.version}" requires ${d.label} support, which is currently disabled.`;return null})(s.manifest,r);if(u)throw Error(u);common.debug("plugin-loader",`\u276F Validated: ${s.manifest.name}@${s.manifest.version}`);}else common.warn("plugin-loader",`Plugin "${e}" is missing a manifest. Please update for future compatibility.`);i.register(s),n++,common.debug("plugin-loader",`\u276F Registered Rule: ${s.name}`);}return common.debug("plugin-loader",`Plugin "${e}" processed: ${n} rules active.`),null}catch(a){return a instanceof Error?a.message:String(a)}}async function ht(e){let t=O__namespace.default.isAbsolute(e)?url.pathToFileURL(e).href:e,r=await import(t);return r.default??r}var yt=/^v?(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/,Et=/^(>=|<=|>|<|=|==)(\d+\.\d+\.\d+.*)$/;function K(e){let t=e.trim().match(yt);return t?[Number(t[1]),Number(t[2]),Number(t[3])]:null}exports.AnalyzerConfigSchema=ee;exports.DEFAULT_CACHE_OPTIONS=b;exports.DEFAULT_CONFIG=v;exports.MESSAGES=f;exports.ProfileConfigSchema=Ue;exports.VALID_RULE_SEVERITIES=ue;exports.createDefaultContext=w;exports.defineConfig=Ir;exports.detectAngularWorkspaceIncludes=lt;exports.findAndLoadConfig=Te;exports.getDefaultMaxWorkers=J;exports.initConfig=Pr;exports.loadPlugins=mt;exports.renderConfigTemplate=st;exports.resolveConfig=Ae;exports.validateConfig=Sr;exports.validateConfigBlock=U;exports.validateConfiguration=he;exports.validateCrossFields=te;exports.validateDeprecatedFields=re;exports.validateExtendsChain=ie;exports.validateGlobPatterns=ne;exports.validatePaths=le;exports.validateProfiles=ce;exports.validateRules=fe;//# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
+345
-142
@@ -0,9 +1,28 @@ | ||
| import { ConfigValidationResult, InitResult, AnalyzerConfig as AnalyzerConfig$1, CacheOptions, ConfigIssue, OutputFormat, FailSeverity, RuleRegistry } from '@ngcompass/common'; | ||
| import { CacheContext, AstCache } from '@ngcompass/cache'; | ||
| import { z } from 'zod'; | ||
| import { ConfigValidationResult, ConfigIssue, CacheOptions, OutputFormat, FailSeverity, InitResult, AnalyzerConfig as AnalyzerConfig$1, RuleRegistry } from '@ngcompass/common'; | ||
| import { CacheContext, AstCache } from '@ngcompass/cache'; | ||
| /** | ||
| * Base Analyzer Configuration Schema | ||
| * Defines the core fields available in both the root configuration and profiles. | ||
| */ | ||
| interface ValidateConfigOptions { | ||
| cwd: string; | ||
| profile?: string; | ||
| cache?: CacheContext; | ||
| } | ||
| declare const resolveConfig: (options: ValidateConfigOptions) => Promise<ConfigValidationResult>; | ||
| declare function validateConfig(options: ValidateConfigOptions): Promise<ConfigValidationResult>; | ||
| interface InitOptions { | ||
| cwd?: string; | ||
| force?: boolean; | ||
| } | ||
| interface ConfigTemplateOptions { | ||
| readonly include?: ReadonlyArray<string>; | ||
| readonly exclude?: ReadonlyArray<string>; | ||
| } | ||
| declare const renderConfigTemplate: (options?: ConfigTemplateOptions) => string; | ||
| declare function detectAngularWorkspaceIncludes(cwd: string): Promise<ReadonlyArray<string> | undefined>; | ||
| declare function initConfig(options?: InitOptions): Promise<InitResult>; | ||
| declare function defineConfig<TConfig extends AnalyzerConfig$1>(config: TConfig): TConfig; | ||
| declare const BaseAnalyzerConfigSchema: z.ZodObject<{ | ||
@@ -71,47 +90,282 @@ extends: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>; | ||
| }, z.core.$strip>; | ||
| /** | ||
| * Exported Types | ||
| * Derived from the Zod schemas to ensure type sync. | ||
| */ | ||
| type AnalyzerConfig = z.infer<typeof BaseAnalyzerConfigSchema> & { | ||
| profiles?: Record<string, unknown>; | ||
| }; | ||
| /** | ||
| * Profile Schema | ||
| * Profiles allow partial overrides of the base configuration. | ||
| */ | ||
| declare const ProfileConfigSchema: z.ZodType<Partial<z.infer<typeof BaseAnalyzerConfigSchema>>>; | ||
| /** | ||
| * Main Analyzer Config Schema | ||
| * This schema handles the 'normalization' phase. It resolves aliases, | ||
| * merges defaults with cache settings, and ensures non-nullable arrays. | ||
| */ | ||
| declare const AnalyzerConfigSchema: z.ZodType<AnalyzerConfig>; | ||
| declare const AnalyzerConfigSchema: z.ZodPipe<z.ZodObject<{ | ||
| extends: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>; | ||
| include: z.ZodDefault<z.ZodArray<z.ZodString>>; | ||
| exclude: z.ZodDefault<z.ZodArray<z.ZodString>>; | ||
| maxWorkers: z.ZodOptional<z.ZodNumber>; | ||
| concurrency: z.ZodOptional<z.ZodNumber>; | ||
| cache: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{ | ||
| enabled: z.ZodOptional<z.ZodBoolean>; | ||
| location: z.ZodOptional<z.ZodString>; | ||
| strategy: z.ZodOptional<z.ZodEnum<{ | ||
| local: "local"; | ||
| memory: "memory"; | ||
| }>>; | ||
| ttl: z.ZodOptional<z.ZodNumber>; | ||
| }, z.core.$strip>]>>; | ||
| cacheLocation: z.ZodOptional<z.ZodString>; | ||
| outputFormat: z.ZodDefault<z.ZodEnum<{ | ||
| text: "text"; | ||
| json: "json"; | ||
| sarif: "sarif"; | ||
| html: "html"; | ||
| }>>; | ||
| outputPath: z.ZodOptional<z.ZodString>; | ||
| failOnSeverity: z.ZodDefault<z.ZodEnum<{ | ||
| error: "error"; | ||
| warn: "warn"; | ||
| }>>; | ||
| maxWarnings: z.ZodDefault<z.ZodNumber>; | ||
| ignorePatterns: z.ZodOptional<z.ZodArray<z.ZodString>>; | ||
| rules: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{ | ||
| error: "error"; | ||
| warn: "warn"; | ||
| }>, z.ZodLiteral<"off">, z.ZodObject<{ | ||
| severity: z.ZodUnion<readonly [z.ZodEnum<{ | ||
| error: "error"; | ||
| warn: "warn"; | ||
| }>, z.ZodLiteral<"off">]>; | ||
| options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | ||
| }, z.core.$strip>]>>>; | ||
| overrides: z.ZodOptional<z.ZodArray<z.ZodObject<{ | ||
| files: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>; | ||
| rules: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{ | ||
| error: "error"; | ||
| warn: "warn"; | ||
| }>, z.ZodLiteral<"off">, z.ZodObject<{ | ||
| severity: z.ZodUnion<readonly [z.ZodEnum<{ | ||
| error: "error"; | ||
| warn: "warn"; | ||
| }>, z.ZodLiteral<"off">]>; | ||
| options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | ||
| }, z.core.$strip>]>>>; | ||
| }, z.core.$strip>>>; | ||
| parserOptions: z.ZodOptional<z.ZodObject<{ | ||
| project: z.ZodOptional<z.ZodString>; | ||
| tsconfigRootDir: z.ZodOptional<z.ZodString>; | ||
| sourceType: z.ZodOptional<z.ZodEnum<{ | ||
| module: "module"; | ||
| commonjs: "commonjs"; | ||
| }>>; | ||
| ecmaVersion: z.ZodOptional<z.ZodNumber>; | ||
| }, z.core.$strip>>; | ||
| profiles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<Partial<{ | ||
| include: string[]; | ||
| exclude: string[]; | ||
| outputFormat: "text" | "json" | "sarif" | "html"; | ||
| failOnSeverity: "error" | "warn"; | ||
| maxWarnings: number; | ||
| extends?: string | string[] | undefined; | ||
| maxWorkers?: number | undefined; | ||
| concurrency?: number | undefined; | ||
| cache?: boolean | { | ||
| enabled?: boolean | undefined; | ||
| location?: string | undefined; | ||
| strategy?: "local" | "memory" | undefined; | ||
| ttl?: number | undefined; | ||
| } | undefined; | ||
| cacheLocation?: string | undefined; | ||
| outputPath?: string | undefined; | ||
| ignorePatterns?: string[] | undefined; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| overrides?: { | ||
| files: string | string[]; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| }[] | undefined; | ||
| parserOptions?: { | ||
| project?: string | undefined; | ||
| tsconfigRootDir?: string | undefined; | ||
| sourceType?: "module" | "commonjs" | undefined; | ||
| ecmaVersion?: number | undefined; | ||
| } | undefined; | ||
| }>, unknown, z.core.$ZodTypeInternals<Partial<{ | ||
| include: string[]; | ||
| exclude: string[]; | ||
| outputFormat: "text" | "json" | "sarif" | "html"; | ||
| failOnSeverity: "error" | "warn"; | ||
| maxWarnings: number; | ||
| extends?: string | string[] | undefined; | ||
| maxWorkers?: number | undefined; | ||
| concurrency?: number | undefined; | ||
| cache?: boolean | { | ||
| enabled?: boolean | undefined; | ||
| location?: string | undefined; | ||
| strategy?: "local" | "memory" | undefined; | ||
| ttl?: number | undefined; | ||
| } | undefined; | ||
| cacheLocation?: string | undefined; | ||
| outputPath?: string | undefined; | ||
| ignorePatterns?: string[] | undefined; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| overrides?: { | ||
| files: string | string[]; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| }[] | undefined; | ||
| parserOptions?: { | ||
| project?: string | undefined; | ||
| tsconfigRootDir?: string | undefined; | ||
| sourceType?: "module" | "commonjs" | undefined; | ||
| ecmaVersion?: number | undefined; | ||
| } | undefined; | ||
| }>, unknown>>>>; | ||
| }, z.core.$strip>, z.ZodTransform<{ | ||
| maxWorkers: number; | ||
| cache: Required<CacheOptions>; | ||
| rules: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }>; | ||
| overrides: { | ||
| files: string | string[]; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| }[]; | ||
| ignorePatterns: string[]; | ||
| include: string[]; | ||
| exclude: string[]; | ||
| outputFormat: "text" | "json" | "sarif" | "html"; | ||
| failOnSeverity: "error" | "warn"; | ||
| maxWarnings: number; | ||
| extends?: string | string[] | undefined; | ||
| concurrency?: number | undefined; | ||
| cacheLocation?: string | undefined; | ||
| outputPath?: string | undefined; | ||
| parserOptions?: { | ||
| project?: string | undefined; | ||
| tsconfigRootDir?: string | undefined; | ||
| sourceType?: "module" | "commonjs" | undefined; | ||
| ecmaVersion?: number | undefined; | ||
| } | undefined; | ||
| profiles?: Record<string, Partial<{ | ||
| include: string[]; | ||
| exclude: string[]; | ||
| outputFormat: "text" | "json" | "sarif" | "html"; | ||
| failOnSeverity: "error" | "warn"; | ||
| maxWarnings: number; | ||
| extends?: string | string[] | undefined; | ||
| maxWorkers?: number | undefined; | ||
| concurrency?: number | undefined; | ||
| cache?: boolean | { | ||
| enabled?: boolean | undefined; | ||
| location?: string | undefined; | ||
| strategy?: "local" | "memory" | undefined; | ||
| ttl?: number | undefined; | ||
| } | undefined; | ||
| cacheLocation?: string | undefined; | ||
| outputPath?: string | undefined; | ||
| ignorePatterns?: string[] | undefined; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| overrides?: { | ||
| files: string | string[]; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| }[] | undefined; | ||
| parserOptions?: { | ||
| project?: string | undefined; | ||
| tsconfigRootDir?: string | undefined; | ||
| sourceType?: "module" | "commonjs" | undefined; | ||
| ecmaVersion?: number | undefined; | ||
| } | undefined; | ||
| }>> | undefined; | ||
| }, { | ||
| include: string[]; | ||
| exclude: string[]; | ||
| outputFormat: "text" | "json" | "sarif" | "html"; | ||
| failOnSeverity: "error" | "warn"; | ||
| maxWarnings: number; | ||
| extends?: string | string[] | undefined; | ||
| maxWorkers?: number | undefined; | ||
| concurrency?: number | undefined; | ||
| cache?: boolean | { | ||
| enabled?: boolean | undefined; | ||
| location?: string | undefined; | ||
| strategy?: "local" | "memory" | undefined; | ||
| ttl?: number | undefined; | ||
| } | undefined; | ||
| cacheLocation?: string | undefined; | ||
| outputPath?: string | undefined; | ||
| ignorePatterns?: string[] | undefined; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| overrides?: { | ||
| files: string | string[]; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| }[] | undefined; | ||
| parserOptions?: { | ||
| project?: string | undefined; | ||
| tsconfigRootDir?: string | undefined; | ||
| sourceType?: "module" | "commonjs" | undefined; | ||
| ecmaVersion?: number | undefined; | ||
| } | undefined; | ||
| profiles?: Record<string, Partial<{ | ||
| include: string[]; | ||
| exclude: string[]; | ||
| outputFormat: "text" | "json" | "sarif" | "html"; | ||
| failOnSeverity: "error" | "warn"; | ||
| maxWarnings: number; | ||
| extends?: string | string[] | undefined; | ||
| maxWorkers?: number | undefined; | ||
| concurrency?: number | undefined; | ||
| cache?: boolean | { | ||
| enabled?: boolean | undefined; | ||
| location?: string | undefined; | ||
| strategy?: "local" | "memory" | undefined; | ||
| ttl?: number | undefined; | ||
| } | undefined; | ||
| cacheLocation?: string | undefined; | ||
| outputPath?: string | undefined; | ||
| ignorePatterns?: string[] | undefined; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| overrides?: { | ||
| files: string | string[]; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| }[] | undefined; | ||
| parserOptions?: { | ||
| project?: string | undefined; | ||
| tsconfigRootDir?: string | undefined; | ||
| sourceType?: "module" | "commonjs" | undefined; | ||
| ecmaVersion?: number | undefined; | ||
| } | undefined; | ||
| }>> | undefined; | ||
| }>>; | ||
| interface ValidateConfigOptions { | ||
| cwd?: string; | ||
| profile?: string; | ||
| cache?: CacheContext; | ||
| } | ||
| declare function validateConfig(options?: ValidateConfigOptions): Promise<ConfigValidationResult>; | ||
| /** | ||
| * Resolves the configuration by searching, merging profiles, and performing full validation. | ||
| * | ||
| * Cache key formula (RFC §7.1): | ||
| * key = computeHash( | ||
| * contentHash // SHA-1 of raw config file bytes — catches any content change | ||
| * + "::" + (profile ?? "") // profile name (empty string for default) | ||
| * + "::" + toolVersion // package version — invalidates on tool upgrade | ||
| * + "::" + schemaVersion // CACHE_VERSION — invalidates on schema change | ||
| * ) | ||
| */ | ||
| declare const resolveConfig: (options: ValidateConfigOptions) => Promise<ConfigValidationResult>; | ||
| type ValidatedConfig = ReturnType<typeof AnalyzerConfigSchema.parse>; | ||
| type CacheConfig = ValidatedConfig["cache"]; | ||
| type ValidatedConfig = z.infer<typeof AnalyzerConfigSchema>; | ||
| type CacheConfig = ValidatedConfig['cache']; | ||
| interface ValidationContext { | ||
| profile?: string; | ||
| /** Working directory used for module resolution (e.g. extends chain). Defaults to process.cwd(). */ | ||
| cwd?: string; | ||
| cwd: string; | ||
| fs: { | ||
@@ -134,3 +388,8 @@ existsSync: (path: string) => boolean; | ||
| maxWorkers?: number; | ||
| cache?: CacheConfig; | ||
| cache?: boolean | { | ||
| readonly enabled?: boolean; | ||
| readonly location?: string; | ||
| readonly strategy?: 'memory' | 'local'; | ||
| readonly ttl?: number; | ||
| }; | ||
| } | ||
@@ -140,19 +399,24 @@ interface ConfigBlockValidation { | ||
| } | ||
| type WritableIssue = { | ||
| -readonly [K in keyof ConfigIssue]: ConfigIssue[K]; | ||
| }; | ||
| /** | ||
| * Validates a raw configuration object against the full schema and semantic rule set. | ||
| * | ||
| * When a `context.profile` is specified the matching profile is deep-merged over | ||
| * the base config before validation, so profile-level overrides are respected. | ||
| * | ||
| * @param rawConfig - The raw, unparsed configuration (from file or programmatic source). | ||
| * @param context - Runtime validation context supplying fs/os/path abstractions. | ||
| * @param filePath - Source file path; used for issue attribution and location enrichment. | ||
| * @param fileContent - Raw file text; required for accurate line/column enrichment. | ||
| * @param astCache - Optional AST cache to avoid redundant parses during enrichment. | ||
| * @param contentHash - Optional content hash to key the AST cache lookup. | ||
| * @returns A `ConfigValidationResult` with the resolved config (if valid) and the issue report. | ||
| */ | ||
| declare function validateConfiguration(rawConfig: unknown, context?: ValidationContext, filePath?: string, fileContent?: string, astCache?: AstCache, contentHash?: string): Promise<ConfigValidationResult>; | ||
| declare function validateConfigBlock(block: ConfigBlock, context: ValidationContext, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| declare function validateCrossFields(config: ValidatedConfig, context: ValidationContext, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| declare function validateDeprecatedFields(rawConfig: unknown, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| declare function validateExtendsChain(config: ValidatedConfig, basePath: (string | number)[], cwd: string): ConfigBlockValidation; | ||
| declare function validateGlobPatterns(config: ValidatedConfig, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| declare function validatePaths(config: ValidatedConfig, context: ValidationContext, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| declare function validateProfiles(config: ValidatedConfig, context: ValidationContext): ConfigBlockValidation; | ||
| declare function validateRules(config: ValidatedConfig, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| declare const VALID_RULE_SEVERITIES: readonly string[]; | ||
| declare function createDefaultContext(overrides?: Partial<ValidationContext>): ValidationContext; | ||
@@ -163,9 +427,9 @@ | ||
| NEGATIVE_MAX_WARNINGS: (val: number) => IssueTemplate; | ||
| WORKERS_BELOW_MINIMUM: () => IssueTemplate; | ||
| WORKERS_BELOW_MINIMUM: IssueTemplate; | ||
| NEGATIVE_CACHE_TTL: (val: number) => IssueTemplate; | ||
| WORKERS_EXCESSIVE: (workers: number, limit: number) => IssueTemplate; | ||
| CACHE_TTL_ZERO: () => IssueTemplate; | ||
| CACHE_TTL_ZERO: IssueTemplate; | ||
| INVALID_GLOB_PATTERN: (pattern: string, error: string) => IssueTemplate; | ||
| EMPTY_INCLUDE: () => IssueTemplate; | ||
| EMPTY_EXCLUDE: () => IssueTemplate; | ||
| EMPTY_INCLUDE: IssueTemplate; | ||
| EMPTY_EXCLUDE: IssueTemplate; | ||
| DUPLICATE_PATTERNS: (field: string, patterns: string[]) => IssueTemplate; | ||
@@ -182,46 +446,24 @@ EMPTY_GLOB_PATTERN: (field: string) => IssueTemplate; | ||
| INVALID_RULE_SEVERITY: (ruleName: string, severity: string) => IssueTemplate; | ||
| NO_RULES_CONFIGURED: () => IssueTemplate; | ||
| EMPTY_RULE_NAME: () => IssueTemplate; | ||
| NO_RULES_CONFIGURED: IssueTemplate; | ||
| EMPTY_RULE_NAME: IssueTemplate; | ||
| PROFILE_CIRCULAR_INHERITANCE: (chain: string[]) => IssueTemplate; | ||
| PROFILE_EMPTY: () => IssueTemplate; | ||
| PROFILE_EMPTY: IssueTemplate; | ||
| EXTENDS_NOT_FOUND: (preset: string) => IssueTemplate; | ||
| DEPRECATED_CACHE_LOCATION: () => IssueTemplate; | ||
| DEPRECATED_CONCURRENCY: () => IssueTemplate; | ||
| DEPRECATED_CACHE_LOCATION: IssueTemplate; | ||
| DEPRECATED_CONCURRENCY: IssueTemplate; | ||
| }; | ||
| declare const SEVERITY_LEVELS: Record<string, number>; | ||
| declare const VALID_SEVERITIES: string[]; | ||
| declare const VALID_RULE_SEVERITIES: string[]; | ||
| declare function validateConfiguration(rawConfig: unknown, context?: ValidationContext, filePath?: string, fileContent?: string, astCache?: AstCache, contentHash?: string): Promise<ConfigValidationResult>; | ||
| /** | ||
| * Performs a comprehensive validation of a configuration block, which can represent | ||
| * either the root configuration or a specific profile. | ||
| * | ||
| * @param block - The configuration object to validate. | ||
| * @param context - The validation context providing access to environmental data like CPU count. | ||
| * @param basePath - The breadcrumb path used for accurate error reporting in nested structures. | ||
| * @returns A validation result object containing any discovered issues. | ||
| */ | ||
| declare function validateConfigBlock(block: ConfigBlock, context: ValidationContext, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| interface ConfigDiscoveryResult { | ||
| config: unknown; | ||
| filepath: string; | ||
| content: string; | ||
| contentHash: string; | ||
| isEmpty?: boolean; | ||
| } | ||
| declare const findAndLoadConfig: (cwd: string) => Promise<ConfigDiscoveryResult | null>; | ||
| /** | ||
| * Calculates the recommended default number of worker threads based on | ||
| * the host's hardware. It reserves at least one core for the main | ||
| * process and caps the default for system responsiveness during heavy | ||
| * analysis. Users can still opt into more parallelism with `maxWorkers`. | ||
| * | ||
| * @returns {number} The suggested number of CPU cores to utilize. | ||
| */ | ||
| declare const getDefaultMaxWorkers: () => number; | ||
| /** | ||
| * Standard configuration for the persistent caching layer. | ||
| * These settings determine where analysis results are stored and | ||
| * how long they remain valid before expiration. | ||
| */ | ||
| declare const DEFAULT_CACHE_OPTIONS: Required<CacheOptions>; | ||
| /** | ||
| * Default global configuration values for the ngcompass engine. | ||
| * These values are used as the baseline when a user-provided | ||
| * configuration is missing specific keys. | ||
| */ | ||
| declare const DEFAULT_CONFIG: { | ||
@@ -231,37 +473,6 @@ readonly outputFormat: OutputFormat; | ||
| readonly maxWarnings: 10; | ||
| readonly include: readonly ["src/**/*.ts"]; | ||
| readonly exclude: readonly ["node_modules/**", "dist/**", "**/*.spec.ts", "**/*.test.ts"]; | ||
| readonly include: readonly ["**/*.ts", "**/*.html"]; | ||
| readonly exclude: readonly ["**/node_modules/**", "**/dist/**", "**/build/**", "**/*.spec.ts", "**/*.test.ts"]; | ||
| }; | ||
| declare class ConfigExistsError extends Error { | ||
| constructor(path: string); | ||
| } | ||
| interface InitOptions { | ||
| cwd?: string; | ||
| force?: boolean; | ||
| } | ||
| declare function initConfig(options?: InitOptions): Promise<InitResult>; | ||
| /** | ||
| * Discovery result interface. | ||
| */ | ||
| interface ConfigDiscoveryResult { | ||
| config: unknown; | ||
| filepath: string; | ||
| content: string; | ||
| contentHash: string; | ||
| isEmpty?: boolean; | ||
| } | ||
| /** | ||
| * Finds and loads the configuration file. | ||
| */ | ||
| declare const findAndLoadConfig: (cwd?: string) => Promise<ConfigDiscoveryResult | null>; | ||
| declare function defineConfig<TConfig extends AnalyzerConfig$1>(config: TConfig): TConfig; | ||
| /** | ||
| * Engine capabilities available at load time. | ||
| * These are used to ensure a plugin doesn't request a feature (like Type Checking) | ||
| * that isn't currently active in the engine. | ||
| */ | ||
| interface EngineCapabilities { | ||
@@ -272,12 +483,4 @@ readonly typeCheckingEnabled: boolean; | ||
| } | ||
| /** | ||
| * Orchestrates the resolution, importing, and registration of external rule plugins. | ||
| * * @param plugins - Specifiers for plugins (npm packages or relative paths). | ||
| * @param configDir - The directory of the configuration file, used as the resolution root. | ||
| * @param registry - The registry where validated rules will be stored. | ||
| * @param capabilities - The current engine feature set for compatibility checks. | ||
| * * @throws {Error} Aggregate error if one or more plugins fail to load or validate. | ||
| */ | ||
| declare const loadPlugins: (plugins: string[], configDir: string, registry: RuleRegistry, capabilities?: EngineCapabilities) => Promise<void>; | ||
| export { type AnalyzerConfig, AnalyzerConfigSchema, type CacheConfig, type ConfigBlock, type ConfigBlockValidation, type ConfigDiscoveryResult, ConfigExistsError, DEFAULT_CACHE_OPTIONS, DEFAULT_CONFIG, type InitOptions, MESSAGES, ProfileConfigSchema, SEVERITY_LEVELS, VALID_RULE_SEVERITIES, VALID_SEVERITIES, type ValidateConfigOptions, type ValidatedConfig, type ValidationContext, createDefaultContext, defineConfig, findAndLoadConfig, getDefaultMaxWorkers, initConfig, loadPlugins, resolveConfig, validateConfig, validateConfigBlock, validateConfiguration }; | ||
| export { type AnalyzerConfig, AnalyzerConfigSchema, type CacheConfig, type ConfigBlock, type ConfigBlockValidation, type ConfigDiscoveryResult, type ConfigTemplateOptions, DEFAULT_CACHE_OPTIONS, DEFAULT_CONFIG, type InitOptions, MESSAGES, ProfileConfigSchema, VALID_RULE_SEVERITIES, type ValidateConfigOptions, type ValidatedConfig, type ValidationContext, type WritableIssue, createDefaultContext, defineConfig, detectAngularWorkspaceIncludes, findAndLoadConfig, getDefaultMaxWorkers, initConfig, loadPlugins, renderConfigTemplate, resolveConfig, validateConfig, validateConfigBlock, validateConfiguration, validateCrossFields, validateDeprecatedFields, validateExtendsChain, validateGlobPatterns, validatePaths, validateProfiles, validateRules }; |
+345
-142
@@ -0,9 +1,28 @@ | ||
| import { ConfigValidationResult, InitResult, AnalyzerConfig as AnalyzerConfig$1, CacheOptions, ConfigIssue, OutputFormat, FailSeverity, RuleRegistry } from '@ngcompass/common'; | ||
| import { CacheContext, AstCache } from '@ngcompass/cache'; | ||
| import { z } from 'zod'; | ||
| import { ConfigValidationResult, ConfigIssue, CacheOptions, OutputFormat, FailSeverity, InitResult, AnalyzerConfig as AnalyzerConfig$1, RuleRegistry } from '@ngcompass/common'; | ||
| import { CacheContext, AstCache } from '@ngcompass/cache'; | ||
| /** | ||
| * Base Analyzer Configuration Schema | ||
| * Defines the core fields available in both the root configuration and profiles. | ||
| */ | ||
| interface ValidateConfigOptions { | ||
| cwd: string; | ||
| profile?: string; | ||
| cache?: CacheContext; | ||
| } | ||
| declare const resolveConfig: (options: ValidateConfigOptions) => Promise<ConfigValidationResult>; | ||
| declare function validateConfig(options: ValidateConfigOptions): Promise<ConfigValidationResult>; | ||
| interface InitOptions { | ||
| cwd?: string; | ||
| force?: boolean; | ||
| } | ||
| interface ConfigTemplateOptions { | ||
| readonly include?: ReadonlyArray<string>; | ||
| readonly exclude?: ReadonlyArray<string>; | ||
| } | ||
| declare const renderConfigTemplate: (options?: ConfigTemplateOptions) => string; | ||
| declare function detectAngularWorkspaceIncludes(cwd: string): Promise<ReadonlyArray<string> | undefined>; | ||
| declare function initConfig(options?: InitOptions): Promise<InitResult>; | ||
| declare function defineConfig<TConfig extends AnalyzerConfig$1>(config: TConfig): TConfig; | ||
| declare const BaseAnalyzerConfigSchema: z.ZodObject<{ | ||
@@ -71,47 +90,282 @@ extends: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>; | ||
| }, z.core.$strip>; | ||
| /** | ||
| * Exported Types | ||
| * Derived from the Zod schemas to ensure type sync. | ||
| */ | ||
| type AnalyzerConfig = z.infer<typeof BaseAnalyzerConfigSchema> & { | ||
| profiles?: Record<string, unknown>; | ||
| }; | ||
| /** | ||
| * Profile Schema | ||
| * Profiles allow partial overrides of the base configuration. | ||
| */ | ||
| declare const ProfileConfigSchema: z.ZodType<Partial<z.infer<typeof BaseAnalyzerConfigSchema>>>; | ||
| /** | ||
| * Main Analyzer Config Schema | ||
| * This schema handles the 'normalization' phase. It resolves aliases, | ||
| * merges defaults with cache settings, and ensures non-nullable arrays. | ||
| */ | ||
| declare const AnalyzerConfigSchema: z.ZodType<AnalyzerConfig>; | ||
| declare const AnalyzerConfigSchema: z.ZodPipe<z.ZodObject<{ | ||
| extends: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>; | ||
| include: z.ZodDefault<z.ZodArray<z.ZodString>>; | ||
| exclude: z.ZodDefault<z.ZodArray<z.ZodString>>; | ||
| maxWorkers: z.ZodOptional<z.ZodNumber>; | ||
| concurrency: z.ZodOptional<z.ZodNumber>; | ||
| cache: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{ | ||
| enabled: z.ZodOptional<z.ZodBoolean>; | ||
| location: z.ZodOptional<z.ZodString>; | ||
| strategy: z.ZodOptional<z.ZodEnum<{ | ||
| local: "local"; | ||
| memory: "memory"; | ||
| }>>; | ||
| ttl: z.ZodOptional<z.ZodNumber>; | ||
| }, z.core.$strip>]>>; | ||
| cacheLocation: z.ZodOptional<z.ZodString>; | ||
| outputFormat: z.ZodDefault<z.ZodEnum<{ | ||
| text: "text"; | ||
| json: "json"; | ||
| sarif: "sarif"; | ||
| html: "html"; | ||
| }>>; | ||
| outputPath: z.ZodOptional<z.ZodString>; | ||
| failOnSeverity: z.ZodDefault<z.ZodEnum<{ | ||
| error: "error"; | ||
| warn: "warn"; | ||
| }>>; | ||
| maxWarnings: z.ZodDefault<z.ZodNumber>; | ||
| ignorePatterns: z.ZodOptional<z.ZodArray<z.ZodString>>; | ||
| rules: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{ | ||
| error: "error"; | ||
| warn: "warn"; | ||
| }>, z.ZodLiteral<"off">, z.ZodObject<{ | ||
| severity: z.ZodUnion<readonly [z.ZodEnum<{ | ||
| error: "error"; | ||
| warn: "warn"; | ||
| }>, z.ZodLiteral<"off">]>; | ||
| options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | ||
| }, z.core.$strip>]>>>; | ||
| overrides: z.ZodOptional<z.ZodArray<z.ZodObject<{ | ||
| files: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>; | ||
| rules: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{ | ||
| error: "error"; | ||
| warn: "warn"; | ||
| }>, z.ZodLiteral<"off">, z.ZodObject<{ | ||
| severity: z.ZodUnion<readonly [z.ZodEnum<{ | ||
| error: "error"; | ||
| warn: "warn"; | ||
| }>, z.ZodLiteral<"off">]>; | ||
| options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | ||
| }, z.core.$strip>]>>>; | ||
| }, z.core.$strip>>>; | ||
| parserOptions: z.ZodOptional<z.ZodObject<{ | ||
| project: z.ZodOptional<z.ZodString>; | ||
| tsconfigRootDir: z.ZodOptional<z.ZodString>; | ||
| sourceType: z.ZodOptional<z.ZodEnum<{ | ||
| module: "module"; | ||
| commonjs: "commonjs"; | ||
| }>>; | ||
| ecmaVersion: z.ZodOptional<z.ZodNumber>; | ||
| }, z.core.$strip>>; | ||
| profiles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<Partial<{ | ||
| include: string[]; | ||
| exclude: string[]; | ||
| outputFormat: "text" | "json" | "sarif" | "html"; | ||
| failOnSeverity: "error" | "warn"; | ||
| maxWarnings: number; | ||
| extends?: string | string[] | undefined; | ||
| maxWorkers?: number | undefined; | ||
| concurrency?: number | undefined; | ||
| cache?: boolean | { | ||
| enabled?: boolean | undefined; | ||
| location?: string | undefined; | ||
| strategy?: "local" | "memory" | undefined; | ||
| ttl?: number | undefined; | ||
| } | undefined; | ||
| cacheLocation?: string | undefined; | ||
| outputPath?: string | undefined; | ||
| ignorePatterns?: string[] | undefined; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| overrides?: { | ||
| files: string | string[]; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| }[] | undefined; | ||
| parserOptions?: { | ||
| project?: string | undefined; | ||
| tsconfigRootDir?: string | undefined; | ||
| sourceType?: "module" | "commonjs" | undefined; | ||
| ecmaVersion?: number | undefined; | ||
| } | undefined; | ||
| }>, unknown, z.core.$ZodTypeInternals<Partial<{ | ||
| include: string[]; | ||
| exclude: string[]; | ||
| outputFormat: "text" | "json" | "sarif" | "html"; | ||
| failOnSeverity: "error" | "warn"; | ||
| maxWarnings: number; | ||
| extends?: string | string[] | undefined; | ||
| maxWorkers?: number | undefined; | ||
| concurrency?: number | undefined; | ||
| cache?: boolean | { | ||
| enabled?: boolean | undefined; | ||
| location?: string | undefined; | ||
| strategy?: "local" | "memory" | undefined; | ||
| ttl?: number | undefined; | ||
| } | undefined; | ||
| cacheLocation?: string | undefined; | ||
| outputPath?: string | undefined; | ||
| ignorePatterns?: string[] | undefined; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| overrides?: { | ||
| files: string | string[]; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| }[] | undefined; | ||
| parserOptions?: { | ||
| project?: string | undefined; | ||
| tsconfigRootDir?: string | undefined; | ||
| sourceType?: "module" | "commonjs" | undefined; | ||
| ecmaVersion?: number | undefined; | ||
| } | undefined; | ||
| }>, unknown>>>>; | ||
| }, z.core.$strip>, z.ZodTransform<{ | ||
| maxWorkers: number; | ||
| cache: Required<CacheOptions>; | ||
| rules: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }>; | ||
| overrides: { | ||
| files: string | string[]; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| }[]; | ||
| ignorePatterns: string[]; | ||
| include: string[]; | ||
| exclude: string[]; | ||
| outputFormat: "text" | "json" | "sarif" | "html"; | ||
| failOnSeverity: "error" | "warn"; | ||
| maxWarnings: number; | ||
| extends?: string | string[] | undefined; | ||
| concurrency?: number | undefined; | ||
| cacheLocation?: string | undefined; | ||
| outputPath?: string | undefined; | ||
| parserOptions?: { | ||
| project?: string | undefined; | ||
| tsconfigRootDir?: string | undefined; | ||
| sourceType?: "module" | "commonjs" | undefined; | ||
| ecmaVersion?: number | undefined; | ||
| } | undefined; | ||
| profiles?: Record<string, Partial<{ | ||
| include: string[]; | ||
| exclude: string[]; | ||
| outputFormat: "text" | "json" | "sarif" | "html"; | ||
| failOnSeverity: "error" | "warn"; | ||
| maxWarnings: number; | ||
| extends?: string | string[] | undefined; | ||
| maxWorkers?: number | undefined; | ||
| concurrency?: number | undefined; | ||
| cache?: boolean | { | ||
| enabled?: boolean | undefined; | ||
| location?: string | undefined; | ||
| strategy?: "local" | "memory" | undefined; | ||
| ttl?: number | undefined; | ||
| } | undefined; | ||
| cacheLocation?: string | undefined; | ||
| outputPath?: string | undefined; | ||
| ignorePatterns?: string[] | undefined; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| overrides?: { | ||
| files: string | string[]; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| }[] | undefined; | ||
| parserOptions?: { | ||
| project?: string | undefined; | ||
| tsconfigRootDir?: string | undefined; | ||
| sourceType?: "module" | "commonjs" | undefined; | ||
| ecmaVersion?: number | undefined; | ||
| } | undefined; | ||
| }>> | undefined; | ||
| }, { | ||
| include: string[]; | ||
| exclude: string[]; | ||
| outputFormat: "text" | "json" | "sarif" | "html"; | ||
| failOnSeverity: "error" | "warn"; | ||
| maxWarnings: number; | ||
| extends?: string | string[] | undefined; | ||
| maxWorkers?: number | undefined; | ||
| concurrency?: number | undefined; | ||
| cache?: boolean | { | ||
| enabled?: boolean | undefined; | ||
| location?: string | undefined; | ||
| strategy?: "local" | "memory" | undefined; | ||
| ttl?: number | undefined; | ||
| } | undefined; | ||
| cacheLocation?: string | undefined; | ||
| outputPath?: string | undefined; | ||
| ignorePatterns?: string[] | undefined; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| overrides?: { | ||
| files: string | string[]; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| }[] | undefined; | ||
| parserOptions?: { | ||
| project?: string | undefined; | ||
| tsconfigRootDir?: string | undefined; | ||
| sourceType?: "module" | "commonjs" | undefined; | ||
| ecmaVersion?: number | undefined; | ||
| } | undefined; | ||
| profiles?: Record<string, Partial<{ | ||
| include: string[]; | ||
| exclude: string[]; | ||
| outputFormat: "text" | "json" | "sarif" | "html"; | ||
| failOnSeverity: "error" | "warn"; | ||
| maxWarnings: number; | ||
| extends?: string | string[] | undefined; | ||
| maxWorkers?: number | undefined; | ||
| concurrency?: number | undefined; | ||
| cache?: boolean | { | ||
| enabled?: boolean | undefined; | ||
| location?: string | undefined; | ||
| strategy?: "local" | "memory" | undefined; | ||
| ttl?: number | undefined; | ||
| } | undefined; | ||
| cacheLocation?: string | undefined; | ||
| outputPath?: string | undefined; | ||
| ignorePatterns?: string[] | undefined; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| overrides?: { | ||
| files: string | string[]; | ||
| rules?: Record<string, "error" | "warn" | "off" | { | ||
| severity: "error" | "warn" | "off"; | ||
| options?: Record<string, unknown> | undefined; | ||
| }> | undefined; | ||
| }[] | undefined; | ||
| parserOptions?: { | ||
| project?: string | undefined; | ||
| tsconfigRootDir?: string | undefined; | ||
| sourceType?: "module" | "commonjs" | undefined; | ||
| ecmaVersion?: number | undefined; | ||
| } | undefined; | ||
| }>> | undefined; | ||
| }>>; | ||
| interface ValidateConfigOptions { | ||
| cwd?: string; | ||
| profile?: string; | ||
| cache?: CacheContext; | ||
| } | ||
| declare function validateConfig(options?: ValidateConfigOptions): Promise<ConfigValidationResult>; | ||
| /** | ||
| * Resolves the configuration by searching, merging profiles, and performing full validation. | ||
| * | ||
| * Cache key formula (RFC §7.1): | ||
| * key = computeHash( | ||
| * contentHash // SHA-1 of raw config file bytes — catches any content change | ||
| * + "::" + (profile ?? "") // profile name (empty string for default) | ||
| * + "::" + toolVersion // package version — invalidates on tool upgrade | ||
| * + "::" + schemaVersion // CACHE_VERSION — invalidates on schema change | ||
| * ) | ||
| */ | ||
| declare const resolveConfig: (options: ValidateConfigOptions) => Promise<ConfigValidationResult>; | ||
| type ValidatedConfig = ReturnType<typeof AnalyzerConfigSchema.parse>; | ||
| type CacheConfig = ValidatedConfig["cache"]; | ||
| type ValidatedConfig = z.infer<typeof AnalyzerConfigSchema>; | ||
| type CacheConfig = ValidatedConfig['cache']; | ||
| interface ValidationContext { | ||
| profile?: string; | ||
| /** Working directory used for module resolution (e.g. extends chain). Defaults to process.cwd(). */ | ||
| cwd?: string; | ||
| cwd: string; | ||
| fs: { | ||
@@ -134,3 +388,8 @@ existsSync: (path: string) => boolean; | ||
| maxWorkers?: number; | ||
| cache?: CacheConfig; | ||
| cache?: boolean | { | ||
| readonly enabled?: boolean; | ||
| readonly location?: string; | ||
| readonly strategy?: 'memory' | 'local'; | ||
| readonly ttl?: number; | ||
| }; | ||
| } | ||
@@ -140,19 +399,24 @@ interface ConfigBlockValidation { | ||
| } | ||
| type WritableIssue = { | ||
| -readonly [K in keyof ConfigIssue]: ConfigIssue[K]; | ||
| }; | ||
| /** | ||
| * Validates a raw configuration object against the full schema and semantic rule set. | ||
| * | ||
| * When a `context.profile` is specified the matching profile is deep-merged over | ||
| * the base config before validation, so profile-level overrides are respected. | ||
| * | ||
| * @param rawConfig - The raw, unparsed configuration (from file or programmatic source). | ||
| * @param context - Runtime validation context supplying fs/os/path abstractions. | ||
| * @param filePath - Source file path; used for issue attribution and location enrichment. | ||
| * @param fileContent - Raw file text; required for accurate line/column enrichment. | ||
| * @param astCache - Optional AST cache to avoid redundant parses during enrichment. | ||
| * @param contentHash - Optional content hash to key the AST cache lookup. | ||
| * @returns A `ConfigValidationResult` with the resolved config (if valid) and the issue report. | ||
| */ | ||
| declare function validateConfiguration(rawConfig: unknown, context?: ValidationContext, filePath?: string, fileContent?: string, astCache?: AstCache, contentHash?: string): Promise<ConfigValidationResult>; | ||
| declare function validateConfigBlock(block: ConfigBlock, context: ValidationContext, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| declare function validateCrossFields(config: ValidatedConfig, context: ValidationContext, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| declare function validateDeprecatedFields(rawConfig: unknown, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| declare function validateExtendsChain(config: ValidatedConfig, basePath: (string | number)[], cwd: string): ConfigBlockValidation; | ||
| declare function validateGlobPatterns(config: ValidatedConfig, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| declare function validatePaths(config: ValidatedConfig, context: ValidationContext, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| declare function validateProfiles(config: ValidatedConfig, context: ValidationContext): ConfigBlockValidation; | ||
| declare function validateRules(config: ValidatedConfig, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| declare const VALID_RULE_SEVERITIES: readonly string[]; | ||
| declare function createDefaultContext(overrides?: Partial<ValidationContext>): ValidationContext; | ||
@@ -163,9 +427,9 @@ | ||
| NEGATIVE_MAX_WARNINGS: (val: number) => IssueTemplate; | ||
| WORKERS_BELOW_MINIMUM: () => IssueTemplate; | ||
| WORKERS_BELOW_MINIMUM: IssueTemplate; | ||
| NEGATIVE_CACHE_TTL: (val: number) => IssueTemplate; | ||
| WORKERS_EXCESSIVE: (workers: number, limit: number) => IssueTemplate; | ||
| CACHE_TTL_ZERO: () => IssueTemplate; | ||
| CACHE_TTL_ZERO: IssueTemplate; | ||
| INVALID_GLOB_PATTERN: (pattern: string, error: string) => IssueTemplate; | ||
| EMPTY_INCLUDE: () => IssueTemplate; | ||
| EMPTY_EXCLUDE: () => IssueTemplate; | ||
| EMPTY_INCLUDE: IssueTemplate; | ||
| EMPTY_EXCLUDE: IssueTemplate; | ||
| DUPLICATE_PATTERNS: (field: string, patterns: string[]) => IssueTemplate; | ||
@@ -182,46 +446,24 @@ EMPTY_GLOB_PATTERN: (field: string) => IssueTemplate; | ||
| INVALID_RULE_SEVERITY: (ruleName: string, severity: string) => IssueTemplate; | ||
| NO_RULES_CONFIGURED: () => IssueTemplate; | ||
| EMPTY_RULE_NAME: () => IssueTemplate; | ||
| NO_RULES_CONFIGURED: IssueTemplate; | ||
| EMPTY_RULE_NAME: IssueTemplate; | ||
| PROFILE_CIRCULAR_INHERITANCE: (chain: string[]) => IssueTemplate; | ||
| PROFILE_EMPTY: () => IssueTemplate; | ||
| PROFILE_EMPTY: IssueTemplate; | ||
| EXTENDS_NOT_FOUND: (preset: string) => IssueTemplate; | ||
| DEPRECATED_CACHE_LOCATION: () => IssueTemplate; | ||
| DEPRECATED_CONCURRENCY: () => IssueTemplate; | ||
| DEPRECATED_CACHE_LOCATION: IssueTemplate; | ||
| DEPRECATED_CONCURRENCY: IssueTemplate; | ||
| }; | ||
| declare const SEVERITY_LEVELS: Record<string, number>; | ||
| declare const VALID_SEVERITIES: string[]; | ||
| declare const VALID_RULE_SEVERITIES: string[]; | ||
| declare function validateConfiguration(rawConfig: unknown, context?: ValidationContext, filePath?: string, fileContent?: string, astCache?: AstCache, contentHash?: string): Promise<ConfigValidationResult>; | ||
| /** | ||
| * Performs a comprehensive validation of a configuration block, which can represent | ||
| * either the root configuration or a specific profile. | ||
| * | ||
| * @param block - The configuration object to validate. | ||
| * @param context - The validation context providing access to environmental data like CPU count. | ||
| * @param basePath - The breadcrumb path used for accurate error reporting in nested structures. | ||
| * @returns A validation result object containing any discovered issues. | ||
| */ | ||
| declare function validateConfigBlock(block: ConfigBlock, context: ValidationContext, basePath?: (string | number)[]): ConfigBlockValidation; | ||
| interface ConfigDiscoveryResult { | ||
| config: unknown; | ||
| filepath: string; | ||
| content: string; | ||
| contentHash: string; | ||
| isEmpty?: boolean; | ||
| } | ||
| declare const findAndLoadConfig: (cwd: string) => Promise<ConfigDiscoveryResult | null>; | ||
| /** | ||
| * Calculates the recommended default number of worker threads based on | ||
| * the host's hardware. It reserves at least one core for the main | ||
| * process and caps the default for system responsiveness during heavy | ||
| * analysis. Users can still opt into more parallelism with `maxWorkers`. | ||
| * | ||
| * @returns {number} The suggested number of CPU cores to utilize. | ||
| */ | ||
| declare const getDefaultMaxWorkers: () => number; | ||
| /** | ||
| * Standard configuration for the persistent caching layer. | ||
| * These settings determine where analysis results are stored and | ||
| * how long they remain valid before expiration. | ||
| */ | ||
| declare const DEFAULT_CACHE_OPTIONS: Required<CacheOptions>; | ||
| /** | ||
| * Default global configuration values for the ngcompass engine. | ||
| * These values are used as the baseline when a user-provided | ||
| * configuration is missing specific keys. | ||
| */ | ||
| declare const DEFAULT_CONFIG: { | ||
@@ -231,37 +473,6 @@ readonly outputFormat: OutputFormat; | ||
| readonly maxWarnings: 10; | ||
| readonly include: readonly ["src/**/*.ts"]; | ||
| readonly exclude: readonly ["node_modules/**", "dist/**", "**/*.spec.ts", "**/*.test.ts"]; | ||
| readonly include: readonly ["**/*.ts", "**/*.html"]; | ||
| readonly exclude: readonly ["**/node_modules/**", "**/dist/**", "**/build/**", "**/*.spec.ts", "**/*.test.ts"]; | ||
| }; | ||
| declare class ConfigExistsError extends Error { | ||
| constructor(path: string); | ||
| } | ||
| interface InitOptions { | ||
| cwd?: string; | ||
| force?: boolean; | ||
| } | ||
| declare function initConfig(options?: InitOptions): Promise<InitResult>; | ||
| /** | ||
| * Discovery result interface. | ||
| */ | ||
| interface ConfigDiscoveryResult { | ||
| config: unknown; | ||
| filepath: string; | ||
| content: string; | ||
| contentHash: string; | ||
| isEmpty?: boolean; | ||
| } | ||
| /** | ||
| * Finds and loads the configuration file. | ||
| */ | ||
| declare const findAndLoadConfig: (cwd?: string) => Promise<ConfigDiscoveryResult | null>; | ||
| declare function defineConfig<TConfig extends AnalyzerConfig$1>(config: TConfig): TConfig; | ||
| /** | ||
| * Engine capabilities available at load time. | ||
| * These are used to ensure a plugin doesn't request a feature (like Type Checking) | ||
| * that isn't currently active in the engine. | ||
| */ | ||
| interface EngineCapabilities { | ||
@@ -272,12 +483,4 @@ readonly typeCheckingEnabled: boolean; | ||
| } | ||
| /** | ||
| * Orchestrates the resolution, importing, and registration of external rule plugins. | ||
| * * @param plugins - Specifiers for plugins (npm packages or relative paths). | ||
| * @param configDir - The directory of the configuration file, used as the resolution root. | ||
| * @param registry - The registry where validated rules will be stored. | ||
| * @param capabilities - The current engine feature set for compatibility checks. | ||
| * * @throws {Error} Aggregate error if one or more plugins fail to load or validate. | ||
| */ | ||
| declare const loadPlugins: (plugins: string[], configDir: string, registry: RuleRegistry, capabilities?: EngineCapabilities) => Promise<void>; | ||
| export { type AnalyzerConfig, AnalyzerConfigSchema, type CacheConfig, type ConfigBlock, type ConfigBlockValidation, type ConfigDiscoveryResult, ConfigExistsError, DEFAULT_CACHE_OPTIONS, DEFAULT_CONFIG, type InitOptions, MESSAGES, ProfileConfigSchema, SEVERITY_LEVELS, VALID_RULE_SEVERITIES, VALID_SEVERITIES, type ValidateConfigOptions, type ValidatedConfig, type ValidationContext, createDefaultContext, defineConfig, findAndLoadConfig, getDefaultMaxWorkers, initConfig, loadPlugins, resolveConfig, validateConfig, validateConfigBlock, validateConfiguration }; | ||
| export { type AnalyzerConfig, AnalyzerConfigSchema, type CacheConfig, type ConfigBlock, type ConfigBlockValidation, type ConfigDiscoveryResult, type ConfigTemplateOptions, DEFAULT_CACHE_OPTIONS, DEFAULT_CONFIG, type InitOptions, MESSAGES, ProfileConfigSchema, VALID_RULE_SEVERITIES, type ValidateConfigOptions, type ValidatedConfig, type ValidationContext, type WritableIssue, createDefaultContext, defineConfig, detectAngularWorkspaceIncludes, findAndLoadConfig, getDefaultMaxWorkers, initConfig, loadPlugins, renderConfigTemplate, resolveConfig, validateConfig, validateConfigBlock, validateConfiguration, validateCrossFields, validateDeprecatedFields, validateExtendsChain, validateGlobPatterns, validatePaths, validateProfiles, validateRules }; |
+7
-12
@@ -1,2 +0,4 @@ | ||
| import {z as z$1}from'zod';import Ae,{cpus}from'os';import {lilconfig}from'lilconfig';import {createJiti}from'jiti';import*as D from'fs';import D__default from'fs';import be from'crypto';import*as C from'path';import C__default from'path';import {fileURLToPath}from'url';import {time,debug,timeEnd,PACKAGE_VERSION,CACHE_VERSION,warn,ASTUtils}from'@ngcompass/common';import {defu}from'defu';import Ue from'process';import {createRequire}from'module';import {minimatch}from'minimatch';import ot from'fs/promises';var z=()=>Math.max(1,Math.min(4,Ae.cpus().length-1)),P={enabled:true,location:"node_modules/.cache/ngcompass",strategy:"local",ttl:864e5},S={outputFormat:"text",failOnSeverity:"error",maxWarnings:10,include:["src/**/*.ts"],exclude:["node_modules/**","dist/**","**/*.spec.ts","**/*.test.ts"]};var M=z$1.enum(["warn","error"]),Se=z$1.enum(["json","text","sarif","html"]),K=z$1.union([M,z$1.literal("off"),z$1.object({severity:z$1.union([M,z$1.literal("off")]),options:z$1.record(z$1.string(),z$1.unknown()).optional()})]),Ce=z$1.object({enabled:z$1.boolean().optional(),location:z$1.string().optional(),strategy:z$1.enum(["memory","local"]).optional(),ttl:z$1.number().optional()}),Oe=z$1.object({project:z$1.string().optional(),tsconfigRootDir:z$1.string().optional(),sourceType:z$1.enum(["module","commonjs"]).optional(),ecmaVersion:z$1.number().optional()}),J=z$1.object({extends:z$1.union([z$1.string(),z$1.array(z$1.string())]).optional(),include:z$1.array(z$1.string()).default([...S.include]),exclude:z$1.array(z$1.string()).default([...S.exclude]),maxWorkers:z$1.number().optional(),concurrency:z$1.number().optional(),cache:z$1.union([z$1.boolean(),Ce]).optional(),cacheLocation:z$1.string().optional(),outputFormat:Se.default(S.outputFormat),outputPath:z$1.string().optional(),failOnSeverity:M.default(S.failOnSeverity),maxWarnings:z$1.number().default(S.maxWarnings),ignorePatterns:z$1.array(z$1.string()).optional(),rules:z$1.record(z$1.string(),K).optional(),overrides:z$1.array(z$1.object({files:z$1.union([z$1.string(),z$1.array(z$1.string())]),rules:z$1.record(z$1.string(),K).optional()})).optional(),parserOptions:Oe.optional()}),Ne=z$1.lazy(()=>J.partial()),Z=J.extend({profiles:z$1.record(z$1.string(),Ne).optional()}).transform(e=>{let t,r=e.maxWorkers??e.concurrency??z();if(e.cache===false)t={...P,enabled:false};else if(e.cache===true||e.cache===void 0){let s=e.cacheLocation??P.location;t={...P,location:s};}else t={...P,...e.cache};return {...e,maxWorkers:r,cache:t,rules:e.rules??{},overrides:e.overrides??[],ignorePatterns:e.ignorePatterns??[]}});var T="ngcompass",$e=[`${T}.config.ts`,`${T}.config.js`,`${T}.config.mjs`,`${T}.config.cjs`,`${T}.config.json`,`.${T}rc`,`.${T}rc.json`,"package.json"],w=e=>{let t=fileURLToPath(import.meta.url);return createJiti(e,{alias:{"@ngcompass/config":C__default.basename(t).startsWith("index.")?t:fileURLToPath(new URL("../index.ts",import.meta.url))}}).import(e).then(r=>r&&typeof r=="object"&&"default"in r?r.default??r:r)},te=(e,t)=>JSON.parse(t.replace(/^\uFEFF/,"")),U=async(e=process.cwd())=>{time("config-discovery"),debug("discovery",`Searching for config in: ${e}`);let t=lilconfig(T,{searchPlaces:$e,loaders:{".ts":w,".js":w,".mjs":w,".cjs":w,".json":te,noExt:te}}),r=await t.search(e);if(!r)return debug("discovery","No config file found"),timeEnd("config-discovery"),null;debug("discovery",`Found config: ${r.filepath}`);let s="",i="";time("content-hash");try{s=D__default.readFileSync(r.filepath,"utf-8"),i=be.createHash("sha1").update(s).digest("hex");let n=timeEnd("content-hash");debug("discovery",`Content hash: ${i.substring(0,8)}... (${n.toFixed(1)}ms)`);}catch{}let o=timeEnd("config-discovery");return debug("discovery",`Discovery complete: ${o.toFixed(1)}ms`),{config:r.config,filepath:r.filepath,content:s,contentHash:i,isEmpty:r.isEmpty}};function k(e){return {cwd:Ue.cwd(),fs:{existsSync:D.existsSync,accessSync:(t,r)=>D.accessSync(t,r)},os:{cpus:cpus},path:{dirname:C.dirname,resolve:C.resolve,isAbsolute:C.isAbsolute},...e}}var u={NEGATIVE_MAX_WARNINGS:e=>({code:"negative-max-warnings",message:`Value for 'maxWarnings' must be non-negative. Received: ${e}.`,suggestion:"Set 'maxWarnings' to 0 or higher, or remove it to use default (10).",severity:"error"}),WORKERS_BELOW_MINIMUM:()=>({code:"workers-below-minimum",message:"Value for 'maxWorkers' must be at least 1.",suggestion:"Set to 1 or higher, or remove to use default (CPU count - 1).",severity:"error"}),NEGATIVE_CACHE_TTL:e=>({code:"negative-cache-ttl",message:`Cache TTL must be non-negative. Received: ${e}ms.`,suggestion:"Set to 0 (default TTL) or higher. Example: 86400000 for 24 hours.",severity:"error"}),WORKERS_EXCESSIVE:(e,t)=>({code:"warn-workers-excessive",message:`Worker count (${e}) exceeds CPU count (${t}). May cause context switching overhead.`,suggestion:`Reduce to ${t} or lower for optimal performance.`,severity:"warning"}),CACHE_TTL_ZERO:()=>({code:"warn-cache-ttl-zero",message:"Cache TTL is set to 0. Using driver default TTL (typically 24 hours).",suggestion:"Set explicit TTL if you need different cache expiration behavior.",severity:"warning"}),INVALID_GLOB_PATTERN:(e,t)=>({code:"invalid-glob-pattern",message:`Glob pattern "${e}" is invalid. Error: ${t}.`,suggestion:"Check pattern syntax. Valid examples: 'src/**/*.ts', '**/*.{ts,html}'.",severity:"error"}),EMPTY_INCLUDE:()=>({code:"empty-include",message:"No include patterns defined. Analysis will skip all files.",suggestion:"Add patterns like ['src/**/*.ts', 'src/**/*.html'] to enable analysis.",severity:"error"}),EMPTY_EXCLUDE:()=>({code:"warn-empty-exclude",message:"No exclude patterns defined. Performance may degrade.",suggestion:"Add common exclusions: ['node_modules/**', 'dist/**', '**/*.spec.ts'].",severity:"warning"}),DUPLICATE_PATTERNS:(e,t)=>({code:"warn-duplicate-patterns",message:`Duplicate patterns found in "${e}": ${t.map(r=>`"${r}"`).join(", ")}.`,suggestion:"Remove duplicate entries to simplify configuration.",severity:"warning"}),EMPTY_GLOB_PATTERN:e=>({code:"empty-glob-pattern",message:`Empty string detected in "${e}" patterns.`,suggestion:"Remove empty strings from the pattern array.",severity:"error"}),TSCONFIG_ROOT_NOT_FOUND:e=>({code:"tsconfig-root-not-found",message:`TSConfig root directory not found: "${e}".`,suggestion:"Verify the directory exists and the path is correct relative to the config file.",severity:"error"}),TSCONFIG_PROJECT_NOT_FOUND:e=>({code:"tsconfig-project-not-found",message:`TSConfig file not found: "${e}".`,suggestion:"Verify the file exists and the path is relative to 'tsconfigRootDir' or config location.",severity:"error"}),OUTPUT_PATH_TRAVERSAL:e=>({code:"output-path-traversal",message:`Output path contains unsafe traversal (..): "${e}".`,suggestion:"Use absolute paths or paths without '..' to prevent security issues.",severity:"error"}),OUTPUT_PATH_SYSTEM_DIR:e=>({code:"output-path-system-dir",message:`Output path points to a system directory: "${e}".`,suggestion:"Choose a safe output location within your project directory.",severity:"error"}),OUTPUT_PATH_NOT_FOUND:e=>({code:"output-path-not-found",message:`Output directory does not exist: "${e}".`,suggestion:"Create the directory or update 'outputPath' to an existing location.",severity:"error"}),OUTPUT_PATH_NOT_WRITABLE:e=>({code:"output-path-not-writable",message:`Output directory is not writable: "${e}".`,suggestion:"Check directory permissions or choose a different output location.",severity:"error"}),CACHE_IN_NODE_MODULES:e=>({code:"cache-in-node-modules",message:`Cache location inside 'node_modules' is unsafe: "${e}". node_modules can be deleted, causing cache loss.`,suggestion:"Use a different directory like '.cache' or 'node_modules/.cache/ngcompass'.",severity:"error"}),CACHE_PARENT_NOT_FOUND:e=>({code:"warn-cache-parent-not-found",message:`Cache parent directory missing: "${e}". It will be created automatically.`,suggestion:"No action needed. Directory will be created on first cache write.",severity:"warning"}),INVALID_RULE_SEVERITY:(e,t)=>({code:"invalid-rule-severity",message:`Rule "${e}" has invalid severity: "${t}".`,suggestion:"Use valid severities: 'off', 'info', 'low', 'moderate', 'high', or 'critical'.",severity:"error"}),NO_RULES_CONFIGURED:()=>({code:"warn-no-rules-configured",message:"No rules configured. Analysis effectively skips checks.",suggestion:"Add rules to enable analysis, or extend from a preset like 'recommended'.",severity:"warning"}),EMPTY_RULE_NAME:()=>({code:"empty-rule-name",message:"Empty rule name detected. Rule keys must be non-empty strings.",suggestion:"Remove empty keys from 'rules' configuration.",severity:"error"}),PROFILE_CIRCULAR_INHERITANCE:e=>({code:"profile-circular-inheritance",message:`Circular profile inheritance detected: ${e.join(" \u2192 ")}.`,suggestion:"Break the circular dependency by removing one 'extends' reference.",severity:"error"}),PROFILE_EMPTY:()=>({code:"warn-profile-empty",message:"Profiles section is defined but empty. Consider removing it.",suggestion:"Remove 'profiles: {}' or add at least one profile like 'dev' or 'ci'.",severity:"warning"}),EXTENDS_NOT_FOUND:e=>({code:"extends-not-found",message:`Cannot resolve preset "${e}". Make sure the package is installed.`,suggestion:`Run: npm install --save-dev ${e}`,severity:"error"}),DEPRECATED_CACHE_LOCATION:()=>({code:"warn-deprecated-cache-location",message:"'cacheLocation' is deprecated. Use 'cache.location' instead.",suggestion:`Replace 'cacheLocation: "..."' with 'cache: { location: "..." }'.`,severity:"warning"}),DEPRECATED_CONCURRENCY:()=>({code:"warn-deprecated-concurrency",message:"'concurrency' is deprecated. Use 'maxWorkers' instead.",suggestion:"Replace 'concurrency: N' with 'maxWorkers: N'.",severity:"warning"})};function W(e,t,r=[]){let s=[];if(e.maxWorkers!==void 0){let i=2*t.os.cpus().length;e.maxWorkers<1?s.push({...u.WORKERS_BELOW_MINIMUM(),path:[...r,"maxWorkers"]}):e.maxWorkers>i&&s.push({...u.WORKERS_EXCESSIVE(e.maxWorkers,i),path:[...r,"maxWorkers"]});}if(e.cache&&typeof e.cache=="object"&&e.cache.ttl!==void 0){let{ttl:i}=e.cache,o=[...r,"cache","ttl"];i<0&&s.push({...u.NEGATIVE_CACHE_TTL(i),path:o});}return {issues:s}}function re(e,t,r=[]){let s=[];if(e.maxWarnings!==void 0){let{maxWarnings:o}=e;o<0&&s.push({...u.NEGATIVE_MAX_WARNINGS(o),path:[...r,"maxWarnings"]});}let{issues:i}=W(e,t,r);return s.push(...i),{issues:s}}function se(e,t=[],r=Ue.cwd()){let s=[];if(!e.extends)return {issues:s};let i=Array.isArray(e.extends)?e.extends:[e.extends],o=Array.isArray(e.extends);for(let n=0;n<i.length;n++){let c=i[n];if(!(typeof c!="string"||c.trim()===""||(function(l){let d=l.startsWith("."),y=C__default.isAbsolute(l),E=l.includes(":");return d||y||E})(c))&&(function(l,d){try{let y=C__default.join(d,"__resolve_anchor__.cjs");return createRequire(y).resolve(l)}catch{return null}})(c,r)===null){let l=[...t,"extends"];o&&l.push(n),s.push({...u.EXTENDS_NOT_FOUND(c),path:l});}}return {issues:s}}var je=/\/\/\//,Me=/\{/g,Ve=/\}/g;function ne(e,t=[]){let r=[];for(let s of ["include","exclude","ignorePatterns"]){let i=e[s];if(!Array.isArray(i))continue;i.forEach((n,c)=>{r.push(...(function(l,d,y,E){let f=[],p=[...E,l,y];if(!d||d.trim()==="")return f.push({...u.EMPTY_GLOB_PATTERN(l),path:p}),f;if(d.includes("[")&&!d.includes("]"))return f.push({...u.INVALID_GLOB_PATTERN(d,"unclosed bracket"),path:p}),f;if(je.test(d)||d.startsWith("///"))return f.push({...u.INVALID_GLOB_PATTERN(d,"invalid path pattern with multiple slashes"),path:p}),f;(d.endsWith("\\")||d.endsWith("/"))&&f.push({...u.INVALID_GLOB_PATTERN(d,"trailing slash not allowed"),path:p}),(d.match(Me)||[]).length!==(d.match(Ve)||[]).length&&f.push({...u.INVALID_GLOB_PATTERN(d,"unmatched braces"),path:p});try{minimatch("sample.ts",d);}catch(g){f.push({...u.INVALID_GLOB_PATTERN(d,g.message),path:p});}return f})(s,n,c,t));});let o=i.filter((n,c)=>i.indexOf(n)!==c);o.length>0&&r.push({...u.DUPLICATE_PATTERNS(s,[...new Set(o)]),path:[...t,s]});}return e.include&&e.include.length!==0||r.push({...u.EMPTY_INCLUDE(),path:[...t,"include"]}),e.exclude&&e.exclude.length!==0||r.push({...u.EMPTY_EXCLUDE(),path:[...t,"exclude"]}),{issues:r}}var We=["/etc/","\\etc\\","/var/","\\var\\"],ie="node_modules";function ce(e,t,r=[]){let s=[],i=o=>t.path.isAbsolute(o)?o:t.path.resolve(t.cwd??process.cwd(),o);if(e.outputPath){let{outputPath:o}=e,n=[...r,"outputPath"];o.includes("..")&&s.push({...u.OUTPUT_PATH_TRAVERSAL(o),path:n}),We.some(l=>o.includes(l))&&s.push({...u.OUTPUT_PATH_SYSTEM_DIR(o),path:n});let c=t.path.dirname(i(o));if(t.fs.existsSync(c))try{t.fs.accessSync(c,D.constants.W_OK);}catch{s.push({...u.OUTPUT_PATH_NOT_WRITABLE(c),path:n});}else s.push({...u.OUTPUT_PATH_NOT_FOUND(c),path:n});}if(e.cache&&typeof e.cache=="object"&&e.cache.enabled){let{location:o}=e.cache;if(o){let n=[...r,"cache","location"],c=o.includes(ie),l=o.includes(`${ie}/.cache`);c&&!l&&s.push({...u.CACHE_IN_NODE_MODULES(o),path:n});let d=t.path.dirname(i(o));t.fs.existsSync(d)||s.push({...u.CACHE_PARENT_NOT_FOUND(d),path:n});}}if(e.parserOptions){let{project:o,tsconfigRootDir:n}=e.parserOptions,c=o?i(o):void 0,l=n?i(n):void 0;c&&!t.fs.existsSync(c)&&s.push({...u.TSCONFIG_PROJECT_NOT_FOUND(o),path:[...r,"parserOptions","project"]}),l&&!t.fs.existsSync(l)&&s.push({...u.TSCONFIG_ROOT_NOT_FOUND(n),path:[...r,"parserOptions","tsconfigRootDir"]});}return {issues:s}}var Ge={info:0,low:1,warning:2,warn:2,moderate:2,high:3,error:4,critical:4},He=Object.keys(Ge),le=[...He,"off"];function ue(e,t=[]){let r=[],s=(Array.isArray(e.extends)||!!e.extends)&&e.extends.length>0,i=Object.entries(e.rules||{});for(let[o,n]of(i.length>0||s||r.push({...u.NO_RULES_CONFIGURED(),path:[...t,"rules"]}),i)){if(!o||o.trim()===""){r.push({...u.EMPTY_RULE_NAME(),path:[...t,"rules"]});continue}if(typeof n=="object"&&n!==null){let{severity:c}=n;c&&!le.includes(c)&&r.push({...u.INVALID_RULE_SEVERITY(o,c),path:[...t,"rules",o,"severity"]});}}return {issues:r}}function de(e,t=[]){let r=[];return e&&typeof e=="object"&&("cacheLocation"in e&&e.cacheLocation!==void 0&&r.push({...u.DEPRECATED_CACHE_LOCATION(),path:[...t,"cacheLocation"]}),"concurrency"in e&&e.concurrency!==void 0&&r.push({...u.DEPRECATED_CONCURRENCY(),path:[...t,"concurrency"]})),{issues:r}}function fe(e,t){let r=ASTUtils.parse(e,t);return ASTUtils.generateLocationMap(r)}async function qe(e,t,r,s){if(!r)return fe(e,t);let i=`v${CACHE_VERSION}:${s}`,o=await r.get(i);if(o)return o.ast;let n=fe(e,t);return await r.set(i,{filePath:t,ast:n}),n}async function me(e,t,r,s,i){if(e.length===0)return;let o=i??be.createHash("sha1").update(t).digest("hex"),n=await qe(t,r,s,o);for(let c of e){if(c.file||(c.file=r),!((!c.line||c.line===1)&&c.path))continue;let l=n[c.path.join(".")];l&&(c.line=l.line,c.column=l.column);}}var ze=new Set(["recommended","strict","performance","reactivity","all"]);async function Ke(e,t,r,s,i){if(r)return void await me(e,r,t,s,i);for(let o of e)o.file||(o.file=t);}function ge(e,t){let r,s=[...(r=new Set,e.filter(o=>{let n=`${o.code}:${o.message}:${JSON.stringify(o.path)}`;return !r.has(n)&&(r.add(n),true)}))].sort((o,n)=>o.severity===n.severity?0:o.severity==="error"?-1:1),i=!s.some(o=>o.severity==="error");return {config:i?t:void 0,report:{valid:i,issues:s}}}async function he(e){let t,{config:r,context:s,basePath:i=[],filePath:o,fileContent:n,astCache:c,contentHash:l}=e,{issues:d,validated:y,success:E}=(t=Z.safeParse(r)).success?{issues:[],validated:t.data,success:true}:{issues:t.error.issues.map(p=>({code:p.code.replace(/_/g,"-"),message:p.message,path:[...i,...p.path],severity:"error",file:o})),validated:r,success:false},f=[...d,...(function(p,g,m,h,b){let v=[];for(let O of [{name:"cross-fields",run:()=>re(p,m,h).issues},{name:"glob-patterns",run:()=>ne(p,h).issues},{name:"paths",run:()=>ce(p,m,h).issues},{name:"rules",run:()=>ue(p,h).issues},{name:"extends-chain",run:()=>se(p,h,m.cwd).issues},{name:"deprecated",run:()=>de(g,h).issues}])try{v.push(...O.run());}catch(j){v.push({code:"check-failed",message:`Check "${O.name}" encountered an unexpected error: ${j.message}`,path:h,severity:"error",file:b});}return v})(y,r,s,i,o)];return o&&await Ke(f,o,n,c,l),{issues:f,validated:E?y:void 0}}async function ye(e,t=k(),r,s,i,o){var n;let c={context:t,filePath:r,fileContent:s,astCache:i,contentHash:o},l=e===null||typeof e!="object"?{}:e.profiles??{};if(t.profile){let E=l[t.profile];if(!E){let m,h;return n=t.profile,m=Object.keys(l).join(", "),h=ze.has(n.replace(/^ngcompass:/,""))?` "${n}" is a built-in preset, not a config profile. Use 'extends: "ngcompass:${n.replace(/^ngcompass:/,"")}"' in your config instead.`:"",{config:void 0,report:{valid:false,issues:[{code:"error-profile-not-found",message:`Profile "${n}" not found. Available: [${m}]${h}`,path:["profiles",n],severity:"error",file:r}]}}}let f=defu(E,e),{issues:p,validated:g}=await he({...c,config:f,basePath:["profiles",t.profile]});return ge(p,g)}let{issues:d,validated:y}=await he({...c,config:e});return ge(d,y)}var ve=async e=>{time("config-resolution");let{cwd:t=Ue.cwd(),profile:r,cache:s}=e;debug("loader",`Starting config resolution (cwd: ${t}, profile: ${r||"none"})`);let i=await U(t),{hash:o,cachedResult:n}=await tt(i,r,s);if(n){let d=timeEnd("config-resolution");return debug("loader",`Cache HIT - returning cached result (${d.toFixed(1)}ms)`),n}debug("loader","Cache MISS - running validation");let c=await rt(i,r,s);debug("loader",`Validation complete: ${c.report.valid?"valid":`invalid (${c.report.issues.length} issues)`}`),s&&o&&(await s.configs.set(o,c),debug("loader",`Cached validation result: key=${o.substring(0,8)}...`));let l=timeEnd("config-resolution");return debug("loader",`Config resolution complete: ${l.toFixed(1)}ms`),c};async function tt(e,t,r){if(!r)return {};let s=[e?.contentHash??"",t??"",PACKAGE_VERSION,CACHE_VERSION].join("::"),i=r.computeHash(s);debug("loader",`Cache lookup: key=${i.substring(0,8)}...`);let o=await r.configs.get(i);return {hash:i,cachedResult:o}}async function rt(e,t,r){return ye(e?.config??{},k({profile:t}),e?.filepath,e?.content,r?.asts,e?.contentHash)}var Te=class extends Error{constructor(t){super(`Configuration file already exists at: ${t}`),this.name="ConfigExistsError";}},nt=`import { defineConfig } from '@ngcompass/config'; | ||
| import {DEFAULT_INCLUDE_PATTERNS,time,debug,timeEnd,PACKAGE_VERSION,CACHE_VERSION,warn,ASTUtils}from'@ngcompass/common';import*as $ from'fs';import $__default from'fs';import*as O from'path';import O__default from'path';import Ie,{cpus}from'os';import Pe from'process';import {defu}from'defu';import {z}from'zod';import {createRequire}from'module';import {minimatch}from'minimatch';import He from'crypto';import {pathToFileURL,fileURLToPath}from'url';import {createJiti}from'jiti';import {lilconfig}from'lilconfig';import B from'fs/promises';function w(e={}){return {cwd:Pe.cwd(),fs:{existsSync:$.existsSync,accessSync:(t,r)=>$.accessSync(t,r)},os:{cpus:cpus},path:{dirname:O.dirname,resolve:O.resolve,isAbsolute:O.isAbsolute},...e}}var J=()=>Math.max(1,Math.min(4,Ie.cpus().length-1)),b={enabled:true,location:"node_modules/.cache/ngcompass",strategy:"local",ttl:864e5},v={outputFormat:"text",failOnSeverity:"error",maxWarnings:10,include:DEFAULT_INCLUDE_PATTERNS,exclude:["**/node_modules/**","**/dist/**","**/build/**","**/*.spec.ts","**/*.test.ts"]};var V=z.enum(["warn","error"]),Le=z.enum(["json","text","sarif","html"]),Z=z.union([V,z.literal("off"),z.object({severity:z.union([V,z.literal("off")]),options:z.record(z.string(),z.unknown()).optional()})]),$e=z.object({enabled:z.boolean().optional(),location:z.string().optional(),strategy:z.enum(["memory","local"]).optional(),ttl:z.number().optional()}),we=z.object({project:z.string().optional(),tsconfigRootDir:z.string().optional(),sourceType:z.enum(["module","commonjs"]).optional(),ecmaVersion:z.number().optional()}),Q=z.object({extends:z.union([z.string(),z.array(z.string())]).optional(),include:z.array(z.string()).default(()=>[...v.include]),exclude:z.array(z.string()).default(()=>[...v.exclude]),maxWorkers:z.number().optional(),concurrency:z.number().optional(),cache:z.union([z.boolean(),$e]).optional(),cacheLocation:z.string().optional(),outputFormat:Le.default(v.outputFormat),outputPath:z.string().optional(),failOnSeverity:V.default(v.failOnSeverity),maxWarnings:z.number().default(v.maxWarnings),ignorePatterns:z.array(z.string()).optional(),rules:z.record(z.string(),Z).optional(),overrides:z.array(z.object({files:z.union([z.string(),z.array(z.string())]),rules:z.record(z.string(),Z).optional()})).optional(),parserOptions:we.optional()}),Ue=z.lazy(()=>Q.partial()),ee=Q.extend({profiles:z.record(z.string(),Ue).optional()}).transform(e=>{let t,r=e.maxWorkers??e.concurrency??J();if(e.cache===false)t={...b,enabled:false};else if(e.cache===true||e.cache===void 0){let i=e.cacheLocation??b.location;t={...b,location:i};}else t={...b,...e.cache};return {...e,maxWorkers:r,cache:t,rules:e.rules??{},overrides:e.overrides??[],ignorePatterns:e.ignorePatterns??[]}});var f={NEGATIVE_MAX_WARNINGS:e=>({code:"negative-max-warnings",message:`Value for 'maxWarnings' must be non-negative. Received: ${e}.`,suggestion:"Set 'maxWarnings' to 0 or higher, or remove it to use default (10).",severity:"error"}),WORKERS_BELOW_MINIMUM:{code:"workers-below-minimum",message:"Value for 'maxWorkers' must be at least 1.",suggestion:"Set to 1 or higher, or remove to use default (CPU count - 1).",severity:"error"},NEGATIVE_CACHE_TTL:e=>({code:"negative-cache-ttl",message:`Cache TTL must be non-negative. Received: ${e}ms.`,suggestion:"Set to 0 (default TTL) or higher. Example: 86400000 for 24 hours.",severity:"error"}),WORKERS_EXCESSIVE:(e,t)=>({code:"warn-workers-excessive",message:`Worker count (${e}) exceeds CPU count (${t}). May cause context switching overhead.`,suggestion:`Reduce to ${t} or lower for optimal performance.`,severity:"warning"}),CACHE_TTL_ZERO:{code:"warn-cache-ttl-zero",message:"Cache TTL is set to 0. Using driver default TTL (typically 24 hours).",suggestion:"Set explicit TTL if you need different cache expiration behavior.",severity:"warning"},INVALID_GLOB_PATTERN:(e,t)=>({code:"invalid-glob-pattern",message:`Glob pattern "${e}" is invalid. Error: ${t}.`,suggestion:"Check pattern syntax. Valid examples: 'src/**/*.ts', '**/*.{ts,html}'.",severity:"error"}),EMPTY_INCLUDE:{code:"empty-include",message:"No include patterns defined. Analysis will skip all files.",suggestion:"Add patterns like ['src/**/*.ts', 'src/**/*.html'] to enable analysis.",severity:"error"},EMPTY_EXCLUDE:{code:"warn-empty-exclude",message:"No exclude patterns defined. Performance may degrade.",suggestion:"Add common exclusions: ['node_modules/**', 'dist/**', '**/*.spec.ts'].",severity:"warning"},DUPLICATE_PATTERNS:(e,t)=>({code:"warn-duplicate-patterns",message:`Duplicate patterns found in "${e}": ${t.map(r=>`"${r}"`).join(", ")}.`,suggestion:"Remove duplicate entries to simplify configuration.",severity:"warning"}),EMPTY_GLOB_PATTERN:e=>({code:"empty-glob-pattern",message:`Empty string detected in "${e}" patterns.`,suggestion:"Remove empty strings from the pattern array.",severity:"error"}),TSCONFIG_ROOT_NOT_FOUND:e=>({code:"tsconfig-root-not-found",message:`TSConfig root directory not found: "${e}".`,suggestion:"Verify the directory exists and the path is correct relative to the config file.",severity:"error"}),TSCONFIG_PROJECT_NOT_FOUND:e=>({code:"tsconfig-project-not-found",message:`TSConfig file not found: "${e}".`,suggestion:"Verify the file exists and the path is relative to 'tsconfigRootDir' or config location.",severity:"error"}),OUTPUT_PATH_TRAVERSAL:e=>({code:"output-path-traversal",message:`Output path contains unsafe traversal (..): "${e}".`,suggestion:"Use absolute paths or paths without '..' to prevent security issues.",severity:"error"}),OUTPUT_PATH_SYSTEM_DIR:e=>({code:"output-path-system-dir",message:`Output path points to a system directory: "${e}".`,suggestion:"Choose a safe output location within your project directory.",severity:"error"}),OUTPUT_PATH_NOT_FOUND:e=>({code:"output-path-not-found",message:`Output directory does not exist: "${e}".`,suggestion:"Create the directory or update 'outputPath' to an existing location.",severity:"error"}),OUTPUT_PATH_NOT_WRITABLE:e=>({code:"output-path-not-writable",message:`Output directory is not writable: "${e}".`,suggestion:"Check directory permissions or choose a different output location.",severity:"error"}),CACHE_IN_NODE_MODULES:e=>({code:"cache-in-node-modules",message:`Cache location inside 'node_modules' is unsafe: "${e}". node_modules can be deleted, causing cache loss.`,suggestion:"Use a different directory like '.cache' or 'node_modules/.cache/ngcompass'.",severity:"error"}),CACHE_PARENT_NOT_FOUND:e=>({code:"warn-cache-parent-not-found",message:`Cache parent directory missing: "${e}". It will be created automatically.`,suggestion:"No action needed. Directory will be created on first cache write.",severity:"warning"}),INVALID_RULE_SEVERITY:(e,t)=>({code:"invalid-rule-severity",message:`Rule "${e}" has invalid severity: "${t}".`,suggestion:"Use one of: 'warn', 'error', or 'off'.",severity:"error"}),NO_RULES_CONFIGURED:{code:"warn-no-rules-configured",message:"No rules configured. Analysis effectively skips checks.",suggestion:"Add rules to enable analysis, or extend from a preset like 'recommended'.",severity:"warning"},EMPTY_RULE_NAME:{code:"empty-rule-name",message:"Empty rule name detected. Rule keys must be non-empty strings.",suggestion:"Remove empty keys from 'rules' configuration.",severity:"error"},PROFILE_CIRCULAR_INHERITANCE:e=>({code:"profile-circular-inheritance",message:`Circular profile inheritance detected: ${e.join(" \u2192 ")}.`,suggestion:"Break the circular dependency by removing one 'extends' reference.",severity:"error"}),PROFILE_EMPTY:{code:"warn-profile-empty",message:"Profiles section is defined but empty. Consider removing it.",suggestion:"Remove 'profiles: {}' or add at least one profile like 'dev' or 'ci'.",severity:"warning"},EXTENDS_NOT_FOUND:e=>({code:"extends-not-found",message:`Cannot resolve preset "${e}". Make sure the package is installed.`,suggestion:`Run: npm install --save-dev ${e}`,severity:"error"}),DEPRECATED_CACHE_LOCATION:{code:"warn-deprecated-cache-location",message:"'cacheLocation' is deprecated. Use 'cache.location' instead.",suggestion:`Replace 'cacheLocation: "..."' with 'cache: { location: "..." }'.`,severity:"warning"},DEPRECATED_CONCURRENCY:{code:"warn-deprecated-concurrency",message:"'concurrency' is deprecated. Use 'maxWorkers' instead.",suggestion:"Replace 'concurrency: N' with 'maxWorkers: N'.",severity:"warning"}};function U(e,t,r=[]){let i=[];if(e.maxWorkers!==void 0){let a=2*t.os.cpus().length;e.maxWorkers<1?i.push({...f.WORKERS_BELOW_MINIMUM,path:[...r,"maxWorkers"]}):e.maxWorkers>a&&i.push({...f.WORKERS_EXCESSIVE(e.maxWorkers,a),path:[...r,"maxWorkers"]});}if(e.cache&&typeof e.cache=="object"&&e.cache.ttl!==void 0){let{ttl:a}=e.cache;a<0&&i.push({...f.NEGATIVE_CACHE_TTL(a),path:[...r,"cache","ttl"]});}return {issues:i}}function te(e,t,r=[]){let i=[];e.maxWarnings!==void 0&&e.maxWarnings<0&&i.push({...f.NEGATIVE_MAX_WARNINGS(e.maxWarnings),path:[...r,"maxWarnings"]});let{issues:a}=U(e,t,r);return i.push(...a),{issues:i}}function re(e,t=[]){let r=[];return e&&typeof e=="object"&&("cacheLocation"in e&&e.cacheLocation!==void 0&&r.push({...f.DEPRECATED_CACHE_LOCATION,path:[...t,"cacheLocation"]}),"concurrency"in e&&e.concurrency!==void 0&&r.push({...f.DEPRECATED_CONCURRENCY,path:[...t,"concurrency"]})),{issues:r}}function ie(e,t,r){let i=[];if(!e.extends)return {issues:i};let a=Array.isArray(e.extends),o=a?e.extends:[e.extends];for(let l=0;l<o.length;l++){let n=o[l];if(typeof n!="string"||n.trim()===""||n.startsWith(".")||O__default.isAbsolute(n)||n.includes(":")||(function(u,g){try{let p=O__default.join(g,"__resolve_anchor__.cjs");return createRequire(p).resolve(u)}catch{return null}})(n,r)!==null)continue;let s=[...t,"extends"];a&&s.push(l),i.push({...f.EXTENDS_NOT_FOUND(n),path:s});}return {issues:i}}var ke=/\/\/\//,Fe=/\{/g,Me=/\}/g,We=/\[/g,Ve=/\]/g;function ne(e,t=[]){let r=[];for(let i of ["include","exclude","ignorePatterns"]){let a=e[i];if(!Array.isArray(a))continue;for(let l=0;l<a.length;l++)r.push(...(function(n,s,u,g){let p=[],m=[...g,n,u];if(!s||s.trim()==="")return p.push({...f.EMPTY_GLOB_PATTERN(n),path:m}),p;if((s.match(We)||[]).length!==(s.match(Ve)||[]).length)return p.push({...f.INVALID_GLOB_PATTERN(s,"unmatched character class brackets"),path:m}),p;if(ke.test(s)||s.startsWith("///"))return p.push({...f.INVALID_GLOB_PATTERN(s,"invalid path pattern with multiple slashes"),path:m}),p;(s.endsWith("\\")||s.endsWith("/"))&&p.push({...f.INVALID_GLOB_PATTERN(s,"trailing slash not allowed"),path:m}),(s.match(Fe)||[]).length!==(s.match(Me)||[]).length&&p.push({...f.INVALID_GLOB_PATTERN(s,"unmatched braces"),path:m});try{minimatch("sample.ts",s);}catch(d){let h=d instanceof Error?d.message:String(d);p.push({...f.INVALID_GLOB_PATTERN(s,h),path:m});}return p})(i,a[l],l,t));let o=(function(l){let n=new Set,s=new Set;for(let u of l)n.has(u)?s.add(u):n.add(u);return [...s]})(a);o.length>0&&r.push({...f.DUPLICATE_PATTERNS(i,o),path:[...t,i]});}return e.include&&e.include.length!==0||r.push({...f.EMPTY_INCLUDE,path:[...t,"include"]}),e.exclude&&e.exclude.length!==0||r.push({...f.EMPTY_EXCLUDE,path:[...t,"exclude"]}),{issues:r}}var Ge=["/etc/","\\etc\\","/var/","\\var\\"],se=/[\\/]/;function le(e,t,r=[]){let i=[],a=o=>t.path.isAbsolute(o)?o:t.path.resolve(t.cwd,o);if(e.outputPath){let{outputPath:o}=e,l=[...r,"outputPath"];o.includes("..")&&i.push({...f.OUTPUT_PATH_TRAVERSAL(o),path:l}),Ge.some(s=>o.includes(s))&&i.push({...f.OUTPUT_PATH_SYSTEM_DIR(o),path:l});let n=t.path.dirname(a(o));if(t.fs.existsSync(n))try{t.fs.accessSync(n,$.constants.W_OK);}catch{i.push({...f.OUTPUT_PATH_NOT_WRITABLE(n),path:l});}else i.push({...f.OUTPUT_PATH_NOT_FOUND(n),path:l});}if(e.cache&&typeof e.cache=="object"&&e.cache.enabled){let{location:o}=e.cache;if(o){let l,n,s=[...r,"cache","location"];o.split(se).includes("node_modules")&&((n=(l=o.split(se)).indexOf("node_modules"))===-1||l[n+1]!==".cache")&&i.push({...f.CACHE_IN_NODE_MODULES(o),path:s});let u=t.path.dirname(a(o));t.fs.existsSync(u)||i.push({...f.CACHE_PARENT_NOT_FOUND(u),path:s});}}if(e.parserOptions){let{project:o,tsconfigRootDir:l}=e.parserOptions;if(o){let n=a(o);t.fs.existsSync(n)||i.push({...f.TSCONFIG_PROJECT_NOT_FOUND(o),path:[...r,"parserOptions","project"]});}if(l){let n=a(l);t.fs.existsSync(n)||i.push({...f.TSCONFIG_ROOT_NOT_FOUND(l),path:[...r,"parserOptions","tsconfigRootDir"]});}}return {issues:i}}function ce(e,t){let r=[];if(!e.profiles||typeof e.profiles!="object")return {issues:r};let i=e.profiles,a=Object.keys(i);if(a.length===0)return r.push({...f.PROFILE_EMPTY,path:["profiles"]}),{issues:r};for(let[l,n]of Object.entries(i)){if(!n||typeof n!="object")continue;let{issues:s}=U(n,t,["profiles",l]);r.push(...s);}let o=new Set;for(let l of a)(function(n,s,u,g){let p=[],m=n;for(;m!==void 0;){if(u.has(m))return;if(p.includes(m)){for(let d of(g.push({...f.PROFILE_CIRCULAR_INHERITANCE([...p,m]),path:["profiles",p[0],"extends"]}),p))u.add(d);return}p.push(m),m=(function(d){if(!d||typeof d!="object")return;let h=d.extends;return typeof h=="string"?h:void 0})(s[m]);}for(let d of p)u.add(d);})(l,i,o,r);return {issues:r}}var ue=["warn","error","off"];function fe(e,t=[]){var r;let i=[],a=Object.entries(e.rules||{});for(let[o,l]of(a.length>0||(Array.isArray(r=e.extends)?r.length>0:r)||i.push({...f.NO_RULES_CONFIGURED,path:[...t,"rules"]}),a)){if(!o||o.trim()===""){i.push({...f.EMPTY_RULE_NAME,path:[...t,"rules"]});continue}if(typeof l=="object"&&l!==null){let{severity:n}=l;n&&!ue.includes(n)&&i.push({...f.INVALID_RULE_SEVERITY(o,n),path:[...t,"rules",o,"severity"]});}}return {issues:i}}function D(e){return He.createHash("sha1").update(e).digest("hex")}function de(e,t){let r=ASTUtils.parse(e,t);return ASTUtils.generateLocationMap(r)}async function Ye(e,t,r,i){if(!r)return de(e,t);let a=`v${CACHE_VERSION}:${i}`,o=await r.get(a);if(o&&(function(n){if(!n||typeof n!="object")return false;for(let s of Object.values(n))return !!(s&&typeof s=="object"&&"line"in s&&"column"in s);return true})(o.ast))return o.ast;let l=de(e,t);return await r.set(a,{filePath:t,ast:l}),l}async function me(e,t,r,i,a){if(e.length===0)return;let o=a??D(t),l=await Ye(t,r,i,o);for(let n of e){if(n.file||(n.file=r),!((!n.line||n.line===1)&&n.path))continue;let s=l[n.path.join(".")];s&&(n.line=s.line,n.column=s.column);}}var qe=new Set(["recommended","strict","performance","reactivity","all"]);async function ze(e,t,r,i,a){if(r)return void await me(e,r,t,i,a);for(let o of e)o.file||(o.file=t);}function ge(e,t){let r,i=[...(r=new Set,e.filter(o=>{let l=o.path?o.path.join("."):"",n=`${o.code}:${o.message}:${l}`;return !r.has(n)&&(r.add(n),true)}))].sort((o,l)=>o.severity===l.severity?0:o.severity==="error"?-1:1),a=!i.some(o=>o.severity==="error");return {config:a?t:void 0,report:{valid:a,issues:i}}}async function G(e){let t,{config:r,context:i,basePath:a=[],filePath:o,fileContent:l,astCache:n,contentHash:s}=e,{issues:u,validated:g,success:p}=(t=ee.safeParse(r)).success?{issues:[],validated:t.data,success:true}:{issues:t.error.issues.map(d=>({code:d.code.replace(/_/g,"-"),message:d.message,path:[...a,...d.path],severity:"error",file:o})),validated:r,success:false},m=[...u,...(function(d,h,y,E,A){let x=[];for(let T of [{name:"cross-fields",run:()=>te(d,y,E).issues},{name:"glob-patterns",run:()=>ne(d,E).issues},{name:"paths",run:()=>le(d,y,E).issues},{name:"rules",run:()=>fe(d,E).issues},{name:"extends-chain",run:()=>ie(d,E,y.cwd).issues},{name:"profiles",run:()=>ce(d,y).issues},{name:"deprecated",run:()=>re(h,E).issues}])try{x.push(...T.run());}catch(C){let I=C instanceof Error?C.message:String(C);x.push({code:"check-failed",message:`Check "${T.name}" encountered an unexpected error: ${I}`,path:E,severity:"error",file:A});}return x})(g,r,i,a,o)];return o&&await ze(m,o,l,n,s),{issues:m,validated:p?g:void 0}}async function he(e,t=w(),r,i,a,o){let l={context:t,filePath:r,fileContent:i,astCache:a,contentHash:o},n=(function(p){if(!p||typeof p!="object")return {};let m=p.profiles;return m&&typeof m=="object"?m:{}})(e);if(t.profile){let p=n[t.profile];if(!p){var s;let y,E,A;return s=t.profile,y=Object.keys(n).join(", "),E=s.replace(/^ngcompass:/,""),A=qe.has(E)?` "${s}" is a built-in preset, not a config profile. Use 'extends: "ngcompass:${E}"' in your config instead.`:"",{config:void 0,report:{valid:false,issues:[{code:"error-profile-not-found",message:`Profile "${s}" not found. Available: [${y}]${A}`,path:["profiles",s],severity:"error",file:r}]}}}let m=await G({...l,config:e}),d=defu(p,e),h=await G({...l,config:d,basePath:["profiles",t.profile]});return ge([...m.issues,...h.issues],h.validated)}let{issues:u,validated:g}=await G({...l,config:e});return ge(u,g)}var _="ngcompass",et=[`${_}.config.ts`,`${_}.config.js`,`${_}.config.mjs`,`${_}.config.cjs`,`${_}.config.json`,`.${_}rc`,`.${_}rc.json`,"package.json"],k=e=>{let t=fileURLToPath(import.meta.url);return createJiti(e,{alias:{"@ngcompass/config":O__default.basename(t).startsWith("index.")?t:fileURLToPath(new URL("../index.ts",import.meta.url))}}).import(e).then(r=>r&&typeof r=="object"&&"default"in r?r.default??r:r)},ve=(e,t)=>JSON.parse(t.replace(/^\uFEFF/,"")),Te=async e=>{time("config-discovery"),debug("discovery",`Searching for config in: ${e}`);let t=lilconfig(_,{searchPlaces:et,loaders:{".ts":k,".js":k,".mjs":k,".cjs":k,".json":ve,noExt:ve}}),r=await t.search(e);if(!r)return debug("discovery","No config file found"),timeEnd("config-discovery"),null;debug("discovery",`Found config: ${r.filepath}`);let i="",a="";time("content-hash");try{i=$__default.readFileSync(r.filepath,"utf-8"),a=D(i);let l=timeEnd("content-hash");debug("discovery",`Content hash: ${a.substring(0,8)}... (${l.toFixed(1)}ms)`);}catch(l){timeEnd("content-hash");let n=l instanceof Error?l.message:String(l);debug("discovery",`Failed to re-read config file for hashing: ${n}`);}let o=timeEnd("config-discovery");return debug("discovery",`Discovery complete: ${o.toFixed(1)}ms`),{config:r.config,filepath:r.filepath,content:i,contentHash:a,isEmpty:r.isEmpty}};var Ae=async e=>{time("config-resolution");let{cwd:t,profile:r,cache:i}=e;debug("loader",`Starting config resolution (cwd: ${t}, profile: ${r||"none"})`);let a=await Te(t),{hash:o,cachedResult:l}=await it(a,r,i);if(l){let u=timeEnd("config-resolution");return debug("loader",`Cache HIT - returning cached result (${u.toFixed(1)}ms)`),l}debug("loader","Cache MISS - running validation");let n=await nt(a,r,i);debug("loader",`Validation complete: ${n.report.valid?"valid":`invalid (${n.report.issues.length} issues)`}`),i&&o&&(await i.configs.set(o,n),debug("loader",`Cached validation result: key=${o.substring(0,8)}...`));let s=timeEnd("config-resolution");return debug("loader",`Config resolution complete: ${s.toFixed(1)}ms`),n};async function it(e,t,r){if(!r)return {};let i=[e?.contentHash??"",t??"",PACKAGE_VERSION,CACHE_VERSION].join("::"),a=r.computeHash(i);debug("loader",`Cache lookup: key=${a.substring(0,8)}...`);let o=await r.configs.get(a);return {hash:a,cachedResult:o}}async function nt(e,t,r){return he(e?.config??{},w({profile:t}),e?.filepath,e?.content,r?.asts,e?.contentHash)}async function Sr(e){try{return await Ae(e)}catch(t){return {config:void 0,report:{valid:false,issues:[{code:"error-conf-semantic",message:t instanceof Error?t.message:String(t),path:[],severity:"error"}]}}}}var st=(e={})=>{let t=e.include??v.include,r=e.exclude??v.exclude,i=t.map(o=>` '${o}',`).join(` | ||
| `),a=r.map(o=>` '${o}',`).join(` | ||
| `);return `import { defineConfig } from '@ngcompass/config'; | ||
@@ -7,14 +9,7 @@ export default defineConfig({ | ||
| include: [ | ||
| 'src/**/*.ts', | ||
| 'src/**/*.html', | ||
| ${i} | ||
| ], | ||
| exclude: [ | ||
| 'node_modules/**', | ||
| 'dist/**', | ||
| 'build/**', | ||
| 'coverage/**', | ||
| '**/*.d.ts', | ||
| '**/*.spec.ts', | ||
| '**/*.test.ts', | ||
| ${a} | ||
| ], | ||
@@ -29,6 +24,6 @@ | ||
| }); | ||
| `;async function vr(e={}){let t=e.cwd??process.cwd(),r=C__default.join(t,"ngcompass.config.ts"),s=await U(t);if(s&&!e.force)return {success:false,filePath:s.filepath,alreadyExists:true};try{return await ot.writeFile(r,nt,"utf-8"),{success:!0,filePath:r}}catch{return {success:false,filePath:r}}}async function xr(e={}){try{return await ve(e)}catch(t){return {config:void 0,report:{valid:false,issues:[{code:"error-conf-semantic",message:t instanceof Error?t.message:String(t),path:[],severity:"error"}]}}}}function Sr(e){return e}var ct={typeCheckingEnabled:false,templateASTEnabled:true,cssASTEnabled:true},lt=async(e,t,r,s=ct)=>{if(e.length===0)return;debug("plugin-loader",`Initializing loader for ${e.length} plugin(s) at ${t}`);let i=createRequire(t+"/package.json"),o=[];for(let n of e)try{let c;try{c=i.resolve(n);}catch{c=n;}let l=await import(c),d=l.default??l,y=Array.isArray(d)?d:[d],E=0;for(let f of y){if(!(function(g){if(!g||typeof g!="object")return !1;let m=g.handler;return typeof g.name=="string"&&g.name.length>0&&m?.handle instanceof Function})(f)){warn("plugin-loader",`Plugin "${n}" exported an invalid structure. Skipping.`);continue}let{manifest:p}=f;if(p){let g=(function(m,h){let b=(function(v,O,j,xe){let N=O.trim();if(!N||N==="*")return null;let H=G(v);if(!H)return null;let B=N.startsWith("^")?(function(I){let x=G(I);return x?`>=${I} <${x[0]+1}.0.0`:null})(N.slice(1)):N;if(!B)return null;for(let I of B.split(/\s+/).filter(Boolean)){let x=I.match(/^(>=|<=|>|<|=|==)(\d+\.\d+\.\d+.*)$/);if(!x)continue;let $=x[1],Y=G(x[2]);if(!Y)continue;let R=(function(q,X){for(let A=0;A<3;A++)if(q[A]!==X[A])return q[A]>X[A]?1:-1;return 0})(H,Y);if(!($===">="?R>=0:$==="<="?R<=0:$===">"?R>0:$==="<"?R<0:R===0))return `Plugin "${j}@${xe}" requires engine "${O}", found "${v}".`}return null})(PACKAGE_VERSION.replace(/^v/,""),m.engineVersionRange,m.name,m.version);if(b)return b;for(let v of [{key:"requiresTypeInfo",current:h.typeCheckingEnabled,label:"Type Information"},{key:"requiresTemplateAST",current:h.templateASTEnabled,label:"Template AST"},{key:"requiresCssAST",current:h.cssASTEnabled,label:"CSS AST"}])if(m.capabilities?.[v.key]&&!v.current)return `Plugin "${m.name}@${m.version}" requires ${v.label} support, which is currently disabled.`;return null})(p,s);if(g)throw Error(g);debug("plugin-loader",`\u276F Validated: ${p.name}@${p.version}`);}else warn("plugin-loader",`Plugin "${n}" is missing a manifest. Please update for future compatibility.`);r.register(f),E++,debug("plugin-loader",`\u276F Registered Rule: ${f.name}`);}debug("plugin-loader",`Plugin "${n}" processed: ${E} rules active.`);}catch(c){let l=c instanceof Error?c.message:String(c);o.push(`- "${n}": ${l}`);}if(o.length>0)throw Error(`[ngcompass] Plugin Load Failure: | ||
| `},at=async e=>{try{return await B.access(e),!0}catch(t){return debug("init",`Path does not exist or is inaccessible: ${e}`),debug("init",Y(t)),false}};async function lt(e){let t,r=O__default.join(e,"angular.json"),i=await ct(r);if(!i)return;let a=(function(s,u){try{let g=JSON.parse(s);return H(g)?g:void 0}catch(g){debug("init",`Angular workspace detection skipped for ${u}: ${Y(g)}`);return}})(i,r);if(!a)return;let o=H(t=a.projects)?t:void 0;if(!o)return;let l=(function(s){let u=[],g=new Set;for(let p of Object.values(s)){let m=(function(d){if(!H(d))return;let h=d.sourceRoot;if(typeof h=="string"&&h.trim()!=="")return Se(h);let y=d.root;if(typeof y=="string"&&y.trim()!=="")return Se(y)})(p);!m||g.has(m)||(g.add(m),u.push(m));}return u.sort((p,m)=>p.localeCompare(m))})(o);if(l.length!==0){var n=l;let s=[];for(let u of n)s.push(`${u}/**/*.ts`),s.push(`${u}/**/*.html`);return s}}async function Pr(e={}){let t=e.cwd??process.cwd(),r=O__default.join(t,"ngcompass.config.ts");if(!e.force&&await at(r))return {success:false,filePath:r,alreadyExists:true};let i=await lt(t);return await B.writeFile(r,st({include:i}),"utf-8"),{success:true,filePath:r}}async function ct(e){try{return await B.readFile(e,"utf-8")}catch(t){debug("init",`Angular workspace detection skipped for ${e}: ${Y(t)}`);return}}function Se(e){return e.replace(/\\/g,"/").replace(/^\/+/,"").replace(/\/+$/,"")}function H(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Y(e){return e instanceof Error?e.message:String(e)}function Ir(e){return e}var dt={typeCheckingEnabled:false,templateASTEnabled:true,cssASTEnabled:true},mt=async(e,t,r,i=dt)=>{if(e.length===0)return;debug("plugin-loader",`Initializing loader for ${e.length} plugin(s) at ${t}`);let a=createRequire(O__default.join(t,"package.json")),o=[];for(let l of e){let n=await gt(l,a,i,r);n&&o.push(`- "${l}": ${n}`);}if(o.length>0)throw Error(`[ngcompass] Plugin Load Failure: | ||
| ${o.join(` | ||
| `)} | ||
| Ensure plugins are installed and satisfy version requirements.`)};function G(e){let t=e.trim().match(/^v?\.?(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/);return t?[Number(t[1]),Number(t[2]),Number(t[3])]:null}export{Z as AnalyzerConfigSchema,Te as ConfigExistsError,P as DEFAULT_CACHE_OPTIONS,S as DEFAULT_CONFIG,u as MESSAGES,Ne as ProfileConfigSchema,Ge as SEVERITY_LEVELS,le as VALID_RULE_SEVERITIES,He as VALID_SEVERITIES,k as createDefaultContext,Sr as defineConfig,U as findAndLoadConfig,z as getDefaultMaxWorkers,vr as initConfig,lt as loadPlugins,ve as resolveConfig,xr as validateConfig,W as validateConfigBlock,ye as validateConfiguration};//# sourceMappingURL=index.js.map | ||
| Ensure plugins are installed and satisfy version requirements.`)};async function gt(e,t,r,i){try{let a=(function(s,u){try{return u.resolve(s)}catch{return s}})(e,t),o=await ht(a),l=Array.isArray(o)?o:[o],n=0;for(let s of l){if(!(function(u){if(!u||typeof u!="object")return !1;let g=u.handler;return typeof u.name=="string"&&u.name.length>0&&typeof g?.handle=="function"})(s)){warn("plugin-loader",`Plugin "${e}" exported an invalid structure. Skipping.`);continue}if(s.manifest){let u=(function(g,p){let m=(function(d,h,y,E){var A;let x,T=h.trim();if(!T||T==="*")return null;let C=K(d);if(!C)return null;let I=T.startsWith("^")?(x=K(A=T.slice(1)))?`>=${A} <${x[0]+1}.0.0`:null:T;if(!I)return null;for(let Oe of I.split(/\s+/).filter(Boolean)){let W=Oe.match(Et);if(!W)continue;let L=W[1],q=K(W[2]);if(!q)continue;let P=(function(z,X){for(let R=0;R<3;R++)if(z[R]!==X[R])return z[R]>X[R]?1:-1;return 0})(C,q);if(!(L===">="?P>=0:L==="<="?P<=0:L===">"?P>0:L==="<"?P<0:P===0))return `Plugin "${y}@${E}" requires engine "${h}", found "${d}".`}return null})(PACKAGE_VERSION.replace(/^v/,""),g.engineVersionRange,g.name,g.version);if(m)return m;for(let d of [{key:"requiresTypeInfo",current:p.typeCheckingEnabled,label:"Type Information"},{key:"requiresTemplateAST",current:p.templateASTEnabled,label:"Template AST"},{key:"requiresCssAST",current:p.cssASTEnabled,label:"CSS AST"}])if(g.capabilities?.[d.key]&&!d.current)return `Plugin "${g.name}@${g.version}" requires ${d.label} support, which is currently disabled.`;return null})(s.manifest,r);if(u)throw Error(u);debug("plugin-loader",`\u276F Validated: ${s.manifest.name}@${s.manifest.version}`);}else warn("plugin-loader",`Plugin "${e}" is missing a manifest. Please update for future compatibility.`);i.register(s),n++,debug("plugin-loader",`\u276F Registered Rule: ${s.name}`);}return debug("plugin-loader",`Plugin "${e}" processed: ${n} rules active.`),null}catch(a){return a instanceof Error?a.message:String(a)}}async function ht(e){let t=O__default.isAbsolute(e)?pathToFileURL(e).href:e,r=await import(t);return r.default??r}var yt=/^v?(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/,Et=/^(>=|<=|>|<|=|==)(\d+\.\d+\.\d+.*)$/;function K(e){let t=e.trim().match(yt);return t?[Number(t[1]),Number(t[2]),Number(t[3])]:null}export{ee as AnalyzerConfigSchema,b as DEFAULT_CACHE_OPTIONS,v as DEFAULT_CONFIG,f as MESSAGES,Ue as ProfileConfigSchema,ue as VALID_RULE_SEVERITIES,w as createDefaultContext,Ir as defineConfig,lt as detectAngularWorkspaceIncludes,Te as findAndLoadConfig,J as getDefaultMaxWorkers,Pr as initConfig,mt as loadPlugins,st as renderConfigTemplate,Ae as resolveConfig,Sr as validateConfig,U as validateConfigBlock,he as validateConfiguration,te as validateCrossFields,re as validateDeprecatedFields,ie as validateExtendsChain,ne as validateGlobPatterns,le as validatePaths,ce as validateProfiles,fe as validateRules};//# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
+3
-3
| { | ||
| "name": "@ngcompass/config", | ||
| "version": "0.1.6-beta", | ||
| "version": "0.1.7-beta", | ||
| "description": "Config loading, resolution and validation for ngcompass", | ||
@@ -30,4 +30,4 @@ "sideEffects": false, | ||
| "zod-validation-error": "^5.0.0", | ||
| "@ngcompass/cache": "0.1.6-beta", | ||
| "@ngcompass/common": "0.1.6-beta" | ||
| "@ngcompass/cache": "0.1.7-beta", | ||
| "@ngcompass/common": "0.1.7-beta" | ||
| }, | ||
@@ -34,0 +34,0 @@ "peerDependencies": { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
278152
19.82%689
42.65%1
Infinity%+ Added
+ Added
- Removed
- Removed
Updated
Updated