arkgate 4.0.1 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +134 -0
- package/README.md +13 -13
- package/bin/ark-check-runtime.mjs +244 -25
- package/bin/ark-check.mjs +10 -1
- package/bin/ark-layer-match.mjs +80 -5
- package/bin/ark-shared.mjs +170 -9
- package/bin/ark.mjs +52 -5
- package/bin/lib/adapter-contract.mjs +7 -1
- package/bin/lib/agent-gates.mjs +2 -0
- package/bin/lib/analysis-engine.mjs +6 -6
- package/bin/lib/ark-gitignore.mjs +88 -0
- package/bin/lib/arkrules-sensors.mjs +63 -22
- package/bin/lib/ci-and-commands.mjs +165 -9
- package/bin/lib/core-ratchet.mjs +9 -4
- package/bin/lib/doctor-advisories.mjs +8 -1
- package/bin/lib/doctor-plan.mjs +287 -61
- package/bin/lib/enforcement-honesty.mjs +408 -27
- package/bin/lib/enforcement-state.mjs +1 -1
- package/bin/lib/field-install.mjs +35 -2
- package/bin/lib/github-enforcement.mjs +152 -4
- package/bin/lib/host-support-matrix.mjs +91 -17
- package/bin/lib/html-report-depth.mjs +178 -3
- package/bin/lib/html-report.mjs +19 -13
- package/bin/lib/install-migrate.mjs +109 -6
- package/bin/lib/managed-upgrade.mjs +99 -0
- package/bin/lib/presets.mjs +314 -46
- package/bin/lib/project-root.mjs +268 -0
- package/bin/lib/remediation.mjs +12 -11
- package/bin/lib/rules-inventory.mjs +71 -29
- package/bin/lib/rules-under-contract.mjs +134 -4
- package/bin/lib/start-preview.mjs +48 -14
- package/bin/lib/suggestions.mjs +118 -3
- package/bin/lib/unavailable-analysis.mjs +2 -0
- package/bin/lib/write-path-capabilities.mjs +38 -9
- package/bin/lib/write-path-detect.mjs +2 -2
- package/dist/eslint/index.cjs +2 -2
- package/dist/eslint/index.d.ts +27 -2
- package/dist/eslint/index.js +2 -2
- package/dist/index.cjs +16 -14
- package/dist/index.d.ts +3 -1
- package/dist/index.js +16 -14
- package/docs/README.md +5 -5
- package/docs/agent-guide.md +5 -3
- package/docs/ai-gates.md +45 -18
- package/docs/brownfield-adoption.md +36 -0
- package/docs/configuration.md +36 -0
- package/docs/develop.md +16 -6
- package/docs/package-surface.md +5 -3
- package/docs/product-voice.md +15 -2
- package/docs/typescript-support.md +9 -5
- package/docs/use.md +3 -1
- package/package.json +3 -1
- package/server.json +3 -3
- package/templates/architecture-playbook.json +3 -0
- package/templates/layers/shared-types.starter.json +29 -0
- package/templates/skills/ark-adopt.md +2 -0
- package/templates/skills/ark-explain.md +5 -0
- package/templates/skills/ark-explore.md +21 -1
- package/templates/skills/ark-fix.md +16 -5
package/dist/eslint/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import I from"fs";import d from"path";var z=new Map;function Z(e){return/[.*+?^${}()|[\]\\]/.test(e)?`\\${e}`:e}function L(e){let t="";for(let n=0;n<e.length;n+=1){let s=e[n];if(s==="\\"&&n+1<e.length){let r=e[n+1];if("*?{}[],".includes(r)||r==="\\"){t+="\\"+r,n+=1;continue}t+="/";continue}t+=s}return t}function Ae(e){let t=0;for(let n=0;n<e.length;n+=1){let s=e[n];if(s==="\\"){n+=1;continue}if(s==="{")t+=1;else if(s==="}"&&(t-=1,t<0))return!1}return t===0}function N(e){let t=z.get(e);if(t)return t;let n=L(e),s=Ae(n),r="",i=0;for(let c=0;c<n.length;c+=1){let g=n[c];g==="\\"&&c+1<n.length?(r+=Z(n[c+1]),c+=1):g==="*"?n[c+1]==="*"?n[c+2]==="/"?(r+="(?:.*/)?",c+=2):(r+=".*",c+=1):r+="[^/]*":g==="?"?r+="[^/]":g==="{"&&s?(r+="(?:",i+=1):g==="}"&&s&&i>0?(r+=")",i-=1):g===","&&s&&i>0?r+="|":r+=Z(g)}let l=new RegExp(`^${r}$`);return z.set(e,l),l}function ke(e){return L(String(e)).split("/").filter(Boolean).filter(n=>n!=="**"&&n!=="*"&&!n.includes("*")&&!n.includes("?")&&!n.includes("{")&&!n.includes("["))}function Q(e,t){let n=L(String(e)),s=ke(n),r=n.replace(/\*/g,"").length,i=s.length*1e4+r;if(t==null||t==="")return i;let l=String(t).split(/[/\\]/).filter(Boolean);if(s.length===0)return r;let c=0,g=-1;for(let f of s){let p=-1;for(let o=c;o<l.length;o+=1)if(l[o]===f){p=o;break}if(p<0)return i;g=p,c=p+1}return(g+1)*1e6+s.length*1e4+r}function w(e,t){let n=String(e).split(/[/\\]/).join("/"),s,r=-1;for(let i of t??[])if(!(i.exclude??[]).some(l=>N(l).test(n))){for(let l of i.patterns??[])if(N(l).test(n)){let c=Q(l,n);c>r&&(r=c,s=i.name)}}return s}function X(e,t){if(!t?.length)return;let n=String(e).split(/[/\\]/).filter(Boolean),s=new Set(t.map(r=>String(r).toLowerCase()));for(let r=0;r<n.length-1;r+=1)if(s.has(n[r].toLowerCase()))return`${n[r].toLowerCase()}/${n[r+1].toLowerCase()}`}function Se(e){let t=new Set;for(let n of e??[]){let r=L(String(n)).split("/").filter(Boolean);for(let i=0;i<r.length;i+=1){let l=r[i];if((l==="**"||l==="*")&&i>0){let c=r[i-1];c&&!c.includes("*")&&!c.includes("{")&&!c.includes("}")&&t.add(c)}}}return[...t]}function Ie(e,t,n){if(Array.isArray(e.sliceFolders)&&e.sliceFolders.length>0)return e.sliceFolders.filter(r=>typeof r=="string"&&r.length>0);let s=(n??[]).find(r=>r.name===t);return Se(s?.patterns)}function $(e,t,n,s){for(let r of e??[])if(!(r.from!==t||r.to!==n)&&r.allowed===!1){if(r.peerIsolation){let i=s?.fromPath,l=s?.toPath;if(!i||!l)return r;let c=Ie(r,t,s?.layers);if(c.length===0)return r;let g=X(i,c),f=X(l,c);if(!g||!f||g!==f)return r;continue}if(t!==n)return r}}function ee(e,t,n,s){return $(e,t,n,s)!==void 0}var Re=["**/*.gen.ts","**/*.gen.tsx","**/*.generated.ts","**/*.generated.tsx"];function xe(e){let t=Array.isArray(e?.exclude)?e.exclude.filter(s=>typeof s=="string"):[];return[...e?.excludeGenerated===!1?[]:Re,...t]}function te(e,t){let n=String(e).split(/[/\\]/).join("/");return xe(t).some(s=>N(s).test(n))}var ne=Object.freeze(["network","filesystem","clock","randomness","environment","process","persistence"]),we=Object.freeze({fetch:"network",XMLHttpRequest:"network",Date:"clock","Date.now":"clock","Math.random":"randomness","process.env":"environment",process:"process"}),Ze=Object.freeze(Object.keys(we).sort()),T=Object.freeze({fs:"filesystem","node:fs":"filesystem","fs/promises":"filesystem","node:fs/promises":"filesystem","fs-extra":"filesystem","graceful-fs":"filesystem",memfs:"filesystem",chokidar:"filesystem",http:"network",https:"network",http2:"network",net:"network",tls:"network",dgram:"network",dns:"network","node:http":"network","node:https":"network","node:http2":"network","node:net":"network","node:tls":"network","node:dgram":"network","node:dns":"network",axios:"network",undici:"network","node-fetch":"network",got:"network",ky:"network",superagent:"network",ws:"network",process:"process","node:process":"process",child_process:"process","node:child_process":"process","@prisma/client":"persistence",prisma:"persistence",pg:"persistence",mysql:"persistence",mysql2:"persistence",mongodb:"persistence",mongoose:"persistence",sqlite3:"persistence","better-sqlite3":"persistence",redis:"persistence",ioredis:"persistence",typeorm:"persistence",knex:"persistence","drizzle-orm":"persistence",sequelize:"persistence",kysely:"persistence","@supabase/supabase-js":"persistence"}),Ee=Object.freeze({process:Object.freeze(["process","node:process"])});function re(e){if(!e||e.startsWith(".")||e.startsWith("/"))return null;let t=T[e];if(t)return t;let n=e.indexOf("/");if(n<0)return null;let s=e.slice(0,n),r=T[s];if(r)return r;let i=e.indexOf("/",n+1);return i<0?null:T[e.slice(0,i)]??null}function j(e,t){for(let n of t)if(Ee[n]?.includes(e))return n;return null}function se(e){if(e?.pure===!0)return[...ne].sort();let n=(e?.capabilities?.deny??[]).filter(s=>ne.includes(s));return[...new Set(n)].sort()}var M="https://unpkg.com/arkgate@2/schemas/ark.config.schema.json",oe=["DomainModel","ApplicationOrchestration","PersistenceAdapters","IntegrationAdapters","WorkflowSagaEngine","BackgroundJobsScheduling","PresentationAdapters","ReportingReadModels","ExtensibilityMetadata","SecurityAuditObservability","Kernel"],Ce=new Set(["PresentationAdapters->ApplicationOrchestration","ApplicationOrchestration->DomainModel","WorkflowSagaEngine->ApplicationOrchestration","WorkflowSagaEngine->DomainModel","BackgroundJobsScheduling->ApplicationOrchestration"]);function Ne(){let e=[];for(let t of oe)for(let n of oe)t===n||Ce.has(`${t}->${n}`)||e.push({from:t,to:n,allowed:!1});return e}var ae=Ne(),D=[{from:"unversioned",to:"1.0"},{from:"1.0",to:"1.1"}],S={type:"array",items:{type:"string",minLength:1},uniqueItems:!0},ie={$schema:"https://json-schema.org/draft/2020-12/schema",$id:M,title:"ArkGate architecture contract",description:"Versioned contract consumed identically by ArkGate CLI, MCP, and ESLint surfaces.",type:"object",additionalProperties:!1,required:["$schema","schemaVersion","include","layers","rules"],properties:{$schema:{type:"string",minLength:1,default:M,description:"Editor-facing URL or local path for this JSON Schema."},schemaVersion:{type:"string",const:"1.1",default:"1.1"},name:{type:"string",minLength:1},include:{...S,minItems:1,default:["src"]},exclude:{...S,default:[]},excludeGenerated:{type:"boolean",default:!0},frameworkOverlay:{type:"string",minLength:1},layers:{type:"array",default:[],items:{$ref:"#/$defs/layer"}},rules:{type:"array",default:ae,items:{$ref:"#/$defs/rule"}},cyclePolicy:{type:"string",enum:["strict","soft","framework-soft","off"],default:"strict"},dynamicImportAllowlist:{...S,default:[]},safety:{$ref:"#/$defs/safety",default:{maxTsSuppressions:0,maxAnyCasts:0,allowInMemory:!1,allowDisabledPeerIsolation:!1}},arkRules:{type:"object",additionalProperties:{type:"string",minLength:1},default:{}}},$defs:{layer:{type:"object",additionalProperties:!1,required:["name","patterns"],properties:{name:{type:"string",minLength:1},patterns:{...S,minItems:1},exclude:S,intentPrefixes:S,description:{type:"string",minLength:1},forbiddenGlobals:S,capabilities:{type:"object",additionalProperties:!1,properties:{deny:{type:"array",uniqueItems:!0,items:{type:"string",enum:["network","filesystem","clock","randomness","environment","process","persistence"]}}}},pure:{type:"boolean"},mayImportInfrastructure:{type:"boolean"},optional:{type:"boolean"}}},rule:{type:"object",additionalProperties:!1,required:["from","to","allowed"],properties:{from:{type:"string",minLength:1},to:{type:"string",minLength:1},allowed:{type:"boolean"},message:{type:"string",minLength:1},peerIsolation:{type:"boolean"},sliceFolders:{...S,minItems:1}}},safety:{type:"object",additionalProperties:!1,properties:{maxTsSuppressions:{type:"integer",minimum:0,default:0},maxAnyCasts:{type:"integer",minimum:0,default:0},allowInMemory:{type:"boolean",default:!1},allowDisabledPeerIsolation:{type:"boolean",default:!1}}}}},k=class extends Error{issues;source;constructor(t,n){super(`Invalid ArkGate config (${t}):
|
|
2
2
|
${n.map(s=>`- ${s.path}: ${s.message}`).join(`
|
|
3
|
-
`)}`),this.name="ArkConfigValidationError",this.source=t,this.issues=n}};function se(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function L(e,t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)?`${e}.${t}`:`${e}[${JSON.stringify(t)}]`}function k(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function xe(e,t){let n="#/$defs/";if(e.startsWith(n))return t.$defs[e.slice(n.length)]}function x(e,t,n,s,r){if(t.$ref){let a=xe(t.$ref,s);if(!a){r.push({path:n,message:`schema reference ${t.$ref} cannot be resolved`});return}x(e,a,n,s,r);return}if(t.const!==void 0&&!Object.is(e,t.const)){r.push({path:n,message:`must equal ${JSON.stringify(t.const)}`});return}if(t.enum&&!t.enum.some(a=>Object.is(a,e))){r.push({path:n,message:`must be one of ${t.enum.map(String).join(", ")}`});return}if(t.type==="object"){if(!se(e)){r.push({path:n,message:`must be an object; received ${k(e)}`});return}let a=t.properties??{};for(let l of t.required??[])e[l]===void 0&&r.push({path:L(n,l),message:"is required"});if(t.additionalProperties===!1)for(let l of Object.keys(e))l in a||r.push({path:L(n,l),message:"unknown field"});else if(t.additionalProperties!==void 0&&t.additionalProperties!==!0&&typeof t.additionalProperties=="object"){let l=t.additionalProperties;for(let c of Object.keys(e))c in a||x(e[c],l,L(n,c),s,r)}for(let[l,c]of Object.entries(a))e[l]!==void 0&&x(e[l],c,L(n,l),s,r);return}if(t.type==="array"){if(!Array.isArray(e)){r.push({path:n,message:`must be an array; received ${k(e)}`});return}if(t.minItems!==void 0&&e.length<t.minItems&&r.push({path:n,message:`must contain at least ${t.minItems} item(s)`}),t.uniqueItems){let a=e.map(l=>JSON.stringify(l));new Set(a).size!==a.length&&r.push({path:n,message:"must not contain duplicate items"})}t.items&&e.forEach((a,l)=>x(a,t.items,`${n}[${l}]`,s,r));return}if(t.type==="string"){if(typeof e!="string"){r.push({path:n,message:`must be a string; received ${k(e)}`});return}t.minLength!==void 0&&e.length<t.minLength&&r.push({path:n,message:`must contain at least ${t.minLength} character(s)`});return}if(t.type==="boolean"){typeof e!="boolean"&&r.push({path:n,message:`must be a boolean; received ${k(e)}`});return}if(t.type==="integer"){if(!Number.isInteger(e)){r.push({path:n,message:`must be an integer; received ${k(e)}`});return}t.minimum!==void 0&&e<t.minimum&&r.push({path:n,message:`must be at least ${t.minimum}`})}}function we(e){return{...e,$schema:e.$schema===void 0?j:e.$schema,schemaVersion:e.schemaVersion===void 0?"1.1":e.schemaVersion,include:e.include===void 0?["src"]:e.include,layers:e.layers===void 0?[]:e.layers,rules:e.rules===void 0?re.map(t=>({...t})):e.rules}}function Ee(){let e=new Set(["1.1"]);for(let t of D)t.from!=="unversioned"&&e.add(t.from),e.add(t.to);return e}function Ce(e,t="ark.config.json"){if(!se(e))throw new h(t,[{path:"$",message:`must be an object; received ${k(e)}`}]);let n=Ee(),s=e.schemaVersion===void 0?"unversioned":typeof e.schemaVersion=="string"?e.schemaVersion:null;if(s===null)throw new h(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(e.schemaVersion)}; expected 1.1`}]);if(s!=="unversioned"&&!n.has(s))throw new h(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(s)}; expected 1.1`}]);let r=s,a={...e},l=0;for(;r!=="1.1"&&l<D.length+1;){l+=1;let g=D.find(m=>m.from===r);if(!g)throw new h(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(r)}; expected 1.1`}]);r=g.to,a.schemaVersion=r}if(r!=="1.1")throw new h(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(s)}; expected 1.1`}]);let c=s==="unversioned"?"unversioned":s==="1.0"?"1.0":null;return{candidate:we(a),migratedFrom:c}}function Ne(e,t="ark.config.json"){let{candidate:n,migratedFrom:s}=Ce(e,t),r=[];if(x(n,ne,"$",ne,r),r.length>0)throw new h(t,r);return{config:n,migratedFrom:s}}function ie(e,t="ark.config.json"){let n;try{n=JSON.parse(e)}catch(s){throw new h(t,[{path:"$",message:`invalid JSON: ${s instanceof Error?s.message:String(s)}`}])}return Ne(n,t)}function y(e){return typeof e=="string"&&e.length>0?e:void 0}function oe(e,t){return Number.isInteger(e)&&Number(e)>0?Number(e):t}function Le(e,t,n){if(e==="LAYER_IMPORT_VIOLATION")return t.typeOnly||n.targetTypeOnlyExports===!0||n.namedBindingsTypeOnly===!0?"Move the referenced type to a mutually allowed layer, use `import type`, then preflight again.":n.peerIsolation===!0?"Extract the shared dependency to a shared layer, then preflight again.":`Define a port in ${t.fromLayer??"the source layer"}, inject the ${t.toLayer??"outer-layer"} implementation, then preflight again.`;if(e==="FORBIDDEN_GLOBAL")return`Inject ${t.target??"the capability"} through a port, then preflight again.`;if(e==="CAPABILITY_VIOLATION")return`Define a ${y(n.capability)??"capability"} port in ${t.fromLayer??"the walled layer"}, bind the implementation outside it, then preflight again.`;if(e==="CIRCULAR_DEPENDENCY")return"Extract the shared dependency into a third module, then preflight again.";if(e==="RAW_EVENT_PUBLISH")return"Publish through a registered intent creator, then run Ark again.";if(e==="PUBLISH_MISSING_SOURCE")return"Add metadata.source to the publish call, then run Ark again.";if(e==="ARKRULE_STRUCTURE"||e==="ARKRULE_INVARIANT"||e==="INVARIANT_UNCOVERED"||e.startsWith("ARKRULE_")){let s=t.arkruleSource??"arkrules/<Layer>.json";return`Fix the structure or invariant for ${t.arkruleId??"the ArkRule"} (declared in ${s}), then preflight again. Do not demote the rule without a hash-bound policy acknowledgement.`}return`Resolve ${e} without weakening ark.config.json, then run Ark again.`}function ae(e,t="error"){let n=y(e.ruleId)??y(e.code)??"ARK_UNKNOWN",s=e.severity==="warning"?"warning":t,r={...y(e.target)?{target:y(e.target)}:{},...y(e.fromLayer)?{fromLayer:y(e.fromLayer)}:{},...y(e.toLayer)?{toLayer:y(e.toLayer)}:{},...typeof e.typeOnly=="boolean"?{typeOnly:e.typeOnly}:{},...typeof e.targetTypeOnlyExports=="boolean"?{targetTypeOnlyExports:e.targetTypeOnlyExports}:{},...typeof e.sourcePureTypeModule=="boolean"?{sourcePureTypeModule:e.sourcePureTypeModule}:{},...typeof e.namedBindingsTypeOnly=="boolean"?{namedBindingsTypeOnly:e.namedBindingsTypeOnly}:{},...typeof e.portProofEligible=="boolean"?{portProofEligible:e.portProofEligible}:{},...typeof e.peerIsolation=="boolean"?{peerIsolation:e.peerIsolation}:{},...y(e.capability)?{capability:y(e.capability)}:{},...y(e.edgeKind)?{edgeKind:y(e.edgeKind)}:{},...y(e.arkruleId)?{arkruleId:y(e.arkruleId)}:{},...y(e.arkruleSource)?{arkruleSource:y(e.arkruleSource)}:{}};return{ruleId:n,severity:s,message:y(e.message)??n,location:{file:y(e.file)??"<unknown>",line:oe(e.line,1),column:oe(e.column,1)},evidence:r,nextAction:y(e.nextAction)??Le(n,r,e)}}var le={RAW_EVENT_PUBLISH:"Publish through a registered intent creator; raw event objects or intent strings bypass Ark contracts and tooling.",PUBLISH_MISSING_SOURCE:"Strict Ark publish calls must include metadata.source."},Ye=Object.freeze([{layer:"DomainModel",prefixes:["Domain."]},{layer:"ApplicationOrchestration",prefixes:["Application."]},{layer:"PersistenceAdapters",prefixes:["Adapter.Persistence.","Adapter.Repository."]},{layer:"IntegrationAdapters",prefixes:["Adapter.Integration.","Adapter.External."]},{layer:"WorkflowSagaEngine",prefixes:["Workflow."]},{layer:"BackgroundJobsScheduling",prefixes:["Job."]},{layer:"PresentationAdapters",prefixes:["Presentation.","Adapter.Presentation.","Adapter.Api."]},{layer:"ReportingReadModels",prefixes:["Reporting."]},{layer:"ExtensibilityMetadata",prefixes:["Metadata."]},{layer:"SecurityAuditObservability",prefixes:["Security.","Audit.","Observability."]},{layer:"Kernel",prefixes:["Kernel."]}]);function Oe(e){return/^(Domain|Application|Adapter|Workflow|Job|Presentation|Reporting|Metadata|Security|Audit|Observability|Kernel)\.[A-Za-z0-9_.]+$/.test(e)}function M(e){if(!e.publishCall)return[];let t=[];return(e.rawIntentName!==void 0&&Oe(e.rawIntentName)||e.objectHasIntent)&&t.push({ruleId:"RAW_EVENT_PUBLISH",message:le.RAW_EVENT_PUBLISH}),e.arkPublishCandidate&&!e.hasSource&&t.push({ruleId:"PUBLISH_MISSING_SOURCE",message:le.PUBLISH_MISSING_SOURCE}),t}function E(e){if(typeof e.physicalFilename=="string"&&e.physicalFilename.length>0)return e.physicalFilename;if(typeof e.filename=="string"&&e.filename.length>0)return e.filename;if(typeof e.getFilename=="function")try{let t=e.getFilename();if(typeof t=="string"&&t.length>0)return t}catch{}return""}function S(e,t,n,s,r){let a=ae({...s,line:s.line??t.loc?.start?.line,column:s.column??(typeof t.loc?.start?.column=="number"?t.loc.start.column+1:void 0)});return e.report({node:t,messageId:n,...r?{data:r}:{},diagnostic:a}),a}function K(e){if(!e||e==="<input>"||e.startsWith("stdin"))return null;let t=p.dirname(p.resolve(e));for(;;){let n=p.join(t,"ark.config.json");if(w.existsSync(n))return n;let s=p.dirname(t);if(s===t)return null;t=s}}var ce=new Map;function H(e){if(!w.existsSync(e))return null;let t=w.readFileSync(e,"utf8"),n=ce.get(e);if(n?.source===t)return n.config;let s=ie(t,e).config;return ce.set(e,{source:t,config:s}),s}function G(e,t){return(e.include??[]).some(s=>{let r=String(s).replace(/\\/g,"/").replace(/^\.\//,"").replace(/\/$/,"");return r==="."||t===r||t.startsWith(`${r}/`)})&&!Z(t,e)}function _e(e,t){if(!t.startsWith("."))return null;let n=p.resolve(p.dirname(e),t),s=[n,`${n}.ts`,`${n}.tsx`,`${n}.mts`,`${n}.cts`,`${n}.js`,`${n}.jsx`,p.join(n,"index.ts"),p.join(n,"index.tsx"),p.join(n,"index.js")];for(let r of s)try{if(w.existsSync(r)&&w.statSync(r).isFile())return r}catch{}return null}function v(e){return typeof e?.value=="string"?e.value:void 0}function B(e){return e?.name??v(e)}function U(e){return e.sourceCode??e.getSourceCode?.()}function de(e,t){let n=U(e)?.getScope?.(t);for(;n;){let s=n.references?.find(r=>r.identifier===t);if(s)return s;n=n.upper??void 0}}function O(e,t,n){let s=de(e,t);if(s?.resolved)return(s.resolved.defs?.length??0)>0;let r=U(e)?.getScope?.(t);for(;r;){let a=r.set?.get(n);if(a)return(a.defs?.length??0)>0;r=r.upper??void 0}return!1}function ve(e,t){let n=de(e,t);return n?n.isValueReference!==!1:t.parent?.type==="VariableDeclarator"&&t.parent.init===t}function pe(e){if(e?.type==="Identifier"&&e.name)return{root:e,segments:[e.name]};if(!e||!(e.type==="MemberExpression"||!!(e.object&&e.property))||e.computed===!0)return;let n=pe(e.object),s=B(e.property);if(!(!n||!s))return{root:n.root,segments:[...n.segments,s]}}function Pe(e){return B(e.callee?.property)}function ue(e,t){return e?.properties?.find(n=>B(n.key)===t)}function _(e,t){return ue(e,t)!==void 0}function $e(e){let t=ue(e,"metadata")?.value;return _(t,"source")}function fe(e){return Pe(e)==="publish"}function V(e){if(e.importKind==="type"||e.exportKind==="type")return!0;let t=e.specifiers??[];return t.length===0?!1:t.every(n=>n.type==="ImportSpecifier")?t.every(n=>n.importKind==="type"):t.every(n=>n.exportKind==="type")}function Te(e){let t=e;for(;t?.parent;)t=t.parent;return t?.type==="Program"?t:void 0}function je(e){let t=Te(e)?.body;if(!t)return!1;let n=!1;for(let s of t){if(s.type==="ImportDeclaration"){if(!V(s))return!1;continue}if(!(s.type==="TSInterfaceDeclaration"||s.type==="TSTypeAliasDeclaration")){if(s.type==="ExportNamedDeclaration"){if(s.declaration){if(s.declaration.type!=="TSInterfaceDeclaration"&&s.declaration.type!=="TSTypeAliasDeclaration")return!1}else if(!V(s))return!1;n=!0;continue}return!1}}return n}var De={meta:{type:"problem",docs:{description:"Disallow imports that violate ark.config.json layer rules (same contract as arkgate-check)."},messages:{forbiddenImport:"Architecture: {{fromLayer}} must not import {{toLayer}} (ark.config.json). Specifier: {{specifier}}",forbiddenImportHeuristic:"Domain code must not import infrastructure, adapters, repositories, or database modules."},schema:[]},create(e){let t=E(e),n=K(t),s=n?H(n):null,r=n?p.dirname(n):null,a=l=>{let c=v(l.source);if(c&&s&&r&&t){let g=p.isAbsolute(t)?t:p.resolve(t),m=p.relative(r,g).split(p.sep).join("/");if(!G(s,m))return;let d=R(m,s.layers);if(!d)return;let i=_e(g,c);if(!i)return;let o=p.relative(r,i).split(p.sep).join("/");if(o.startsWith(".."))return;let u=R(o,s.layers);if(!u)return;if(J(s.rules,d,u,{fromPath:m,toPath:o,layers:s.layers})){let f=l.type?.startsWith("Export")?"export":"import";S(e,l,"forbiddenImport",{ruleId:"LAYER_IMPORT_VIOLATION",file:m,fromLayer:d,toLayer:u,target:o,edgeKind:f,...V(l)?{typeOnly:!0}:{},...je(l)?{sourcePureTypeModule:!0}:{},message:`${d} must not ${f} ${u}.`},{fromLayer:d,toLayer:u,specifier:c})}return}};return{ImportDeclaration:a,ExportNamedDeclaration:a,ExportAllDeclaration:a}}},Me={meta:{type:"problem",docs:{description:"Require event bus publish calls to use registered intent creators instead of raw event objects or intent strings."},messages:{rawPublish:"Publish through a registered intent creator; raw event objects or intent strings bypass Ark contracts."},schema:[]},create(e){return{CallExpression(t){let n=t.arguments?.[0],s=v(n),r=M({publishCall:fe(t),rawIntentName:s,objectHasIntent:_(n,"intent"),arkPublishCandidate:!1,hasSource:!0});if(r.some(a=>a.ruleId==="RAW_EVENT_PUBLISH")){let a=r.find(l=>l.ruleId==="RAW_EVENT_PUBLISH");S(e,t,"rawPublish",{...a,file:E(e)})}}}}},Ve={meta:{type:"problem",docs:{description:"Require event bus publish calls to include source metadata."},messages:{missingSource:"Strict Ark publish calls must include metadata.source."},schema:[]},create(e){return{CallExpression(t){let n=t.arguments?.[0],s=t.arguments?.[2],a=M({publishCall:fe(t),rawIntentName:v(n),objectHasIntent:_(n,"intent"),arkPublishCandidate:!0,hasSource:$e(n)||_(s,"source")}).find(l=>l.ruleId==="PUBLISH_MISSING_SOURCE");a&&S(e,t,"missingSource",{...a,file:E(e)})}}}},Fe={meta:{type:"problem",docs:{description:"Disallow ambient globals from the layer\u2019s forbiddenGlobals in ark.config.json (same purity surface as ark-check). Option `globals` is a standalone fallback when no project config applies."},messages:{forbiddenGlobal:'Ambient global "{{name}}" is forbidden in {{layer}} (ark.config.json); inject the capability through a port instead.',forbiddenGlobalDefault:'Ambient global "{{name}}" is forbidden here; inject the capability through a port instead.',forbiddenModule:'{{layer}} must not use module "{{specifier}}" because it is the import form of forbidden global "{{name}}".'},schema:[{type:"object",properties:{globals:{type:"array",items:{type:"string"}}},additionalProperties:!1}]},create(e){let t=E(e),n=e.options?.[0],s=K(t),r=s?H(s):null,a=s?p.dirname(s):null,l=null,c="this layer";if(r&&a&&t){let i=p.isAbsolute(t)?t:p.resolve(t),o=p.relative(a,i).split(p.sep).join("/");if(!G(r,o))return{};let u=r.layers?.find(f=>f.name===R(o,r.layers));u?.forbiddenGlobals?.length?(l=new Set(u.forbiddenGlobals),c=u.name):l=null}else n?.globals&&(l=new Set(n.globals));if(!l)return{};let g=typeof U(e)?.getScope=="function",m=(i,o)=>{let u=p.isAbsolute(t)?t:p.resolve(t),f=a?p.relative(a,u).split(p.sep).join("/"):t;S(e,i,r?"forbiddenGlobal":"forbiddenGlobalDefault",{ruleId:"FORBIDDEN_GLOBAL",file:f,fromLayer:c,target:o,message:`${c} must not use the ambient global "${o}".`},{name:o,layer:c})},d=(i,o,u,f)=>{if(u||typeof o!="string")return;let b=T(o,l);if(!b)return;let I=p.isAbsolute(t)?t:p.resolve(t),C=a?p.relative(a,I).split(p.sep).join("/"):t;S(e,i,"forbiddenModule",{ruleId:"FORBIDDEN_GLOBAL",file:C,fromLayer:c,target:o,edgeKind:f,message:`${c} must not use module "${o}" because it is the import form of forbidden global "${b}".`},{layer:c,name:b,specifier:o,importKind:f})};return{MemberExpression(i){if(i.parent?.type==="MemberExpression"&&i.parent.object===i)return;let o=pe(i);if(!o||O(e,o.root,o.segments[0]))return;let u=o.segments[0]==="globalThis",f=u?o.segments.slice(1):o.segments,b;for(let I=f.length;I>=(u?1:2);I-=1){let C=f.slice(0,I).join(".");if(l.has(C)){b=C;break}}b?m(i,b):!g&&l.has(o.segments[0])&&m(i,o.segments[0])},CallExpression(i){let o=i;if(o.callee?.type==="Identifier"&&o.callee.name==="require"&&o.arguments?.[0]?.type==="Literal"&&!O(e,i,"require")&&d(i,o.arguments[0].value,!1,"require"),g)return;let u=o.callee?.type==="Identifier"?o.callee.name:void 0;u&&l.has(u)&&m(i,u)},ImportDeclaration(i){let o=i,u=(o.specifiers??[]).filter(b=>b.type==="ImportSpecifier"),f=u.length>0&&u.length===(o.specifiers??[]).length&&u.every(b=>b.importKind==="type");d(i,o.source?.value,o.importKind==="type"||f,"import")},ImportExpression(i){let o=i;o.source?.type==="Literal"&&d(i,o.source.value,!1,"dynamic-import")},TSImportEqualsDeclaration(i){let o=i;d(i,o.moduleReference?.expression?.value,o.importKind==="type"||o.isTypeOnly===!0,"require")},ExportNamedDeclaration(i){let o=i;if(!o.source)return;let u=o.specifiers??[],f=u.length>0&&u.every(b=>b.exportKind==="type");d(i,o.source.value,o.exportKind==="type"||f,"export")},ExportAllDeclaration(i){let o=i;d(i,o.source?.value,o.exportKind==="type","export")},NewExpression(i){if(g)return;let o=i.callee?.type==="Identifier"?i.callee.name:void 0;o&&l.has(o)&&m(i,o)},Identifier(i){!g||!i.name||!l.has(i.name)||!ve(e,i)||O(e,i,i.name)||m(i,i.name)}}}},Ke={meta:{type:"problem",docs:{description:"Disallow importing modules whose effect capability the layer denies (ark.config.json capabilities.deny / pure \u2014 same wall surface as ark-check). Import dimension only: ambient globals stay with no-forbidden-globals and the CLI/hook symbol path."},messages:{deniedCapability:'{{layer}} denies the {{capability}} capability (ark.config.json); "{{specifier}}" imports it. Define a port and bind the implementation in an adapter layer.'},schema:[]},create(e){let t=E(e),n=K(t),s=n?H(n):null,r=n?p.dirname(n):null;if(!s||!r||!t)return{};let a=p.isAbsolute(t)?t:p.resolve(t),l=p.relative(r,a).split(p.sep).join("/");if(!G(s,l))return{};let c=s.layers?.find(d=>d.name===R(l,s.layers));if(!c)return{};let g=new Set(ee(c));if(g.size===0)return{};let m=(d,i,o,u)=>{if(o||typeof i!="string"||T(i,c.forbiddenGlobals??[]))return;let f=Q(i);!f||!g.has(f)||S(e,d,"deniedCapability",{ruleId:"CAPABILITY_VIOLATION",file:l,fromLayer:c.name,target:i,capability:f,edgeKind:u,message:`${c.name} denies the ${f} capability; found import of "${i}".`},{layer:c.name,capability:f,specifier:i})};return{ImportDeclaration(d){let i=d,o=(i.specifiers??[]).filter(f=>f.type==="ImportSpecifier"),u=o.length>0&&o.length===(i.specifiers??[]).length&&o.every(f=>f.importKind==="type");m(d,i.source?.value,i.importKind==="type"||u,"import")},ImportExpression(d){let i=d;i.source?.type==="Literal"&&m(d,i.source.value,!1,"dynamic-import")},TSImportEqualsDeclaration(d){let i=d;m(d,i.moduleReference?.expression?.value,i.importKind==="type"||i.isTypeOnly===!0,"require")},ExportNamedDeclaration(d){let i=d;if(!i.source)return;let o=i.specifiers??[],u=o.length>0&&o.every(f=>f.exportKind==="type");m(d,i.source.value,i.exportKind==="type"||u,"export")},ExportAllDeclaration(d){let i=d;m(d,i.source?.value,i.exportKind==="type","export")},CallExpression(d){let i=d;i.callee?.type==="Identifier"&&i.callee.name==="require"&&i.arguments?.[0]?.type==="Literal"&&!O(e,d,"require")&&m(d,i.arguments[0].value,!1,"require")}}}},He={"no-domain-infra-imports":De,"no-raw-event-publish":Me,"require-publish-source":Ve,"no-forbidden-globals":Fe,"no-denied-capabilities":Ke},F={rules:He};F.configs={recommended:{plugins:{ark:F},rules:{"ark/no-domain-infra-imports":"error","ark/no-raw-event-publish":"error","ark/require-publish-source":"error","ark/no-forbidden-globals":"error","ark/no-denied-capabilities":"error"}}};var rt=F;export{rt as default,K as findConfigPath,N as globToRegExp,J as isEdgeDenied,R as layerForRelativePath,H as loadArkConfig,Ke as noDeniedCapabilities,De as noDomainInfraImports,Fe as noForbiddenGlobals,Me as noRawEventPublish,z as patternSpecificity,F as plugin,Ve as requirePublishSource,_e as resolveRelativeImport};
|
|
3
|
+
`)}`),this.name="ArkConfigValidationError",this.source=t,this.issues=n}};function le(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function O(e,t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)?`${e}.${t}`:`${e}[${JSON.stringify(t)}]`}function R(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function Le(e,t){let n="#/$defs/";if(e.startsWith(n))return t.$defs[e.slice(n.length)]}function E(e,t,n,s,r){if(t.$ref){let i=Le(t.$ref,s);if(!i){r.push({path:n,message:`schema reference ${t.$ref} cannot be resolved`});return}E(e,i,n,s,r);return}if(t.const!==void 0&&!Object.is(e,t.const)){r.push({path:n,message:`must equal ${JSON.stringify(t.const)}`});return}if(t.enum&&!t.enum.some(i=>Object.is(i,e))){r.push({path:n,message:`must be one of ${t.enum.map(String).join(", ")}`});return}if(t.type==="object"){if(!le(e)){r.push({path:n,message:`must be an object; received ${R(e)}`});return}let i=t.properties??{};for(let l of t.required??[])e[l]===void 0&&r.push({path:O(n,l),message:"is required"});if(t.additionalProperties===!1)for(let l of Object.keys(e))l in i||r.push({path:O(n,l),message:"unknown field"});else if(t.additionalProperties!==void 0&&t.additionalProperties!==!0&&typeof t.additionalProperties=="object"){let l=t.additionalProperties;for(let c of Object.keys(e))c in i||E(e[c],l,O(n,c),s,r)}for(let[l,c]of Object.entries(i))e[l]!==void 0&&E(e[l],c,O(n,l),s,r);return}if(t.type==="array"){if(!Array.isArray(e)){r.push({path:n,message:`must be an array; received ${R(e)}`});return}if(t.minItems!==void 0&&e.length<t.minItems&&r.push({path:n,message:`must contain at least ${t.minItems} item(s)`}),t.uniqueItems){let i=e.map(l=>JSON.stringify(l));new Set(i).size!==i.length&&r.push({path:n,message:"must not contain duplicate items"})}t.items&&e.forEach((i,l)=>E(i,t.items,`${n}[${l}]`,s,r));return}if(t.type==="string"){if(typeof e!="string"){r.push({path:n,message:`must be a string; received ${R(e)}`});return}t.minLength!==void 0&&e.length<t.minLength&&r.push({path:n,message:`must contain at least ${t.minLength} character(s)`});return}if(t.type==="boolean"){typeof e!="boolean"&&r.push({path:n,message:`must be a boolean; received ${R(e)}`});return}if(t.type==="integer"){if(!Number.isInteger(e)){r.push({path:n,message:`must be an integer; received ${R(e)}`});return}t.minimum!==void 0&&e<t.minimum&&r.push({path:n,message:`must be at least ${t.minimum}`})}}function Oe(e){return{...e,$schema:e.$schema===void 0?M:e.$schema,schemaVersion:e.schemaVersion===void 0?"1.1":e.schemaVersion,include:e.include===void 0?["src"]:e.include,layers:e.layers===void 0?[]:e.layers,rules:e.rules===void 0?ae.map(t=>({...t})):e.rules}}function _e(){let e=new Set(["1.1"]);for(let t of D)t.from!=="unversioned"&&e.add(t.from),e.add(t.to);return e}function ve(e,t="ark.config.json"){if(!le(e))throw new k(t,[{path:"$",message:`must be an object; received ${R(e)}`}]);let n=_e(),s=e.schemaVersion===void 0?"unversioned":typeof e.schemaVersion=="string"?e.schemaVersion:null;if(s===null)throw new k(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(e.schemaVersion)}; expected 1.1`}]);if(s!=="unversioned"&&!n.has(s))throw new k(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(s)}; expected 1.1`}]);let r=s,i={...e},l=0;for(;r!=="1.1"&&l<D.length+1;){l+=1;let g=D.find(f=>f.from===r);if(!g)throw new k(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(r)}; expected 1.1`}]);r=g.to,i.schemaVersion=r}if(r!=="1.1")throw new k(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(s)}; expected 1.1`}]);let c=s==="unversioned"?"unversioned":s==="1.0"?"1.0":null;return{candidate:Oe(i),migratedFrom:c}}function Pe(e,t="ark.config.json"){let{candidate:n,migratedFrom:s}=ve(e,t),r=[];if(E(n,ie,"$",ie,r),r.length>0)throw new k(t,r);return{config:n,migratedFrom:s}}function ce(e,t="ark.config.json"){let n;try{n=JSON.parse(e)}catch(s){throw new k(t,[{path:"$",message:`invalid JSON: ${s instanceof Error?s.message:String(s)}`}])}return Pe(n,t)}function b(e){return typeof e=="string"&&e.length>0?e:void 0}function pe(e,t){return Number.isInteger(e)&&Number(e)>0?Number(e):t}function $e(e,t,n){if(e==="LAYER_IMPORT_VIOLATION")return t.typeOnly||n.targetTypeOnlyExports===!0||n.namedBindingsTypeOnly===!0?"Move the referenced type to a mutually allowed layer, use `import type`, then preflight again.":n.peerIsolation===!0?"Extract the shared dependency to a shared layer, then preflight again.":`Define a port in ${t.fromLayer??"the source layer"}, inject the ${t.toLayer??"outer-layer"} implementation, then preflight again.`;if(e==="FORBIDDEN_GLOBAL")return`Inject ${t.target??"the capability"} through a port, then preflight again.`;if(e==="CAPABILITY_VIOLATION")return`Define a ${b(n.capability)??"capability"} port in ${t.fromLayer??"the walled layer"}, bind the implementation outside it, then preflight again.`;if(e==="CIRCULAR_DEPENDENCY")return"Extract the shared dependency into a third module, then preflight again.";if(e==="RAW_EVENT_PUBLISH")return"Publish through a registered intent creator, then run Ark again.";if(e==="PUBLISH_MISSING_SOURCE")return"Add metadata.source to the publish call, then run Ark again.";if(e==="ARKRULE_STRUCTURE"||e==="ARKRULE_INVARIANT"||e==="INVARIANT_UNCOVERED"||e.startsWith("ARKRULE_")){let s=t.arkruleSource??"arkrules/<Layer>.json";return`Fix the structure or invariant for ${t.arkruleId??"the ArkRule"} (declared in ${s}), then preflight again. Do not demote the rule without a hash-bound policy acknowledgement.`}return`Resolve ${e} without weakening ark.config.json, then run Ark again.`}function de(e,t="error"){let n=b(e.ruleId)??b(e.code)??"ARK_UNKNOWN",s=e.severity==="warning"||e.failsStrict===!1||e.typeOnly===!0&&e.peerIsolation!==!0?"warning":t,r={...b(e.target)?{target:b(e.target)}:{},...b(e.fromLayer)?{fromLayer:b(e.fromLayer)}:{},...b(e.toLayer)?{toLayer:b(e.toLayer)}:{},...typeof e.typeOnly=="boolean"?{typeOnly:e.typeOnly}:{},...typeof e.targetTypeOnlyExports=="boolean"?{targetTypeOnlyExports:e.targetTypeOnlyExports}:{},...typeof e.sourcePureTypeModule=="boolean"?{sourcePureTypeModule:e.sourcePureTypeModule}:{},...typeof e.namedBindingsTypeOnly=="boolean"?{namedBindingsTypeOnly:e.namedBindingsTypeOnly}:{},...typeof e.portProofEligible=="boolean"?{portProofEligible:e.portProofEligible}:{},...typeof e.peerIsolation=="boolean"?{peerIsolation:e.peerIsolation}:{},...b(e.capability)?{capability:b(e.capability)}:{},...b(e.edgeKind)?{edgeKind:b(e.edgeKind)}:{},...b(e.arkruleId)?{arkruleId:b(e.arkruleId)}:{},...b(e.arkruleSource)?{arkruleSource:b(e.arkruleSource)}:{}};return{ruleId:n,severity:s,message:b(e.message)??n,location:{file:b(e.file)??"<unknown>",line:pe(e.line,1),column:pe(e.column,1)},evidence:r,nextAction:b(e.nextAction)??$e(n,r,e)}}var ue={RAW_EVENT_PUBLISH:"Publish through a registered intent creator; raw event objects or intent strings bypass Ark contracts and tooling.",PUBLISH_MISSING_SOURCE:"Strict Ark publish calls must include metadata.source."},tt=Object.freeze([{layer:"DomainModel",prefixes:["Domain."]},{layer:"ApplicationOrchestration",prefixes:["Application."]},{layer:"PersistenceAdapters",prefixes:["Adapter.Persistence.","Adapter.Repository."]},{layer:"IntegrationAdapters",prefixes:["Adapter.Integration.","Adapter.External."]},{layer:"WorkflowSagaEngine",prefixes:["Workflow."]},{layer:"BackgroundJobsScheduling",prefixes:["Job."]},{layer:"PresentationAdapters",prefixes:["Presentation.","Adapter.Presentation.","Adapter.Api."]},{layer:"ReportingReadModels",prefixes:["Reporting."]},{layer:"ExtensibilityMetadata",prefixes:["Metadata."]},{layer:"SecurityAuditObservability",prefixes:["Security.","Audit.","Observability."]},{layer:"Kernel",prefixes:["Kernel."]}]);function Te(e){return/^(Domain|Application|Adapter|Workflow|Job|Presentation|Reporting|Metadata|Security|Audit|Observability|Kernel)\.[A-Za-z0-9_.]+$/.test(e)}function V(e){if(!e.publishCall)return[];let t=[];return(e.rawIntentName!==void 0&&Te(e.rawIntentName)||e.objectHasIntent)&&t.push({ruleId:"RAW_EVENT_PUBLISH",message:ue.RAW_EVENT_PUBLISH}),e.arkPublishCandidate&&!e.hasSource&&t.push({ruleId:"PUBLISH_MISSING_SOURCE",message:ue.PUBLISH_MISSING_SOURCE}),t}function C(e){if(typeof e.physicalFilename=="string"&&e.physicalFilename.length>0)return e.physicalFilename;if(typeof e.filename=="string"&&e.filename.length>0)return e.filename;if(typeof e.getFilename=="function")try{let t=e.getFilename();if(typeof t=="string"&&t.length>0)return t}catch{}return""}function x(e,t,n,s,r){let i=de({...s,line:s.line??t.loc?.start?.line,column:s.column??(typeof t.loc?.start?.column=="number"?t.loc.start.column+1:void 0)});return e.report({node:t,messageId:n,...r?{data:r}:{},diagnostic:i}),i}function K(e){if(!e||e==="<input>"||e.startsWith("stdin"))return null;let t=d.dirname(d.resolve(e));for(;;){let n=d.join(t,"ark.config.json");if(I.existsSync(n))return n;let s=d.dirname(t);if(s===t)return null;t=s}}var fe=new Map;function G(e){if(!I.existsSync(e))return null;let t=I.readFileSync(e,"utf8"),n=fe.get(e);if(n?.source===t)return n.config;let s=ce(t,e).config;return fe.set(e,{source:t,config:s}),s}function B(e,t){return(e.include??[]).some(s=>{let r=String(s).replace(/\\/g,"/").replace(/^\.\//,"").replace(/\/$/,"");return r==="."||t===r||t.startsWith(`${r}/`)})&&!te(t,e)}function ge(e){let t=[e,`${e}.ts`,`${e}.tsx`,`${e}.mts`,`${e}.cts`,`${e}.js`,`${e}.jsx`,d.join(e,"index.ts"),d.join(e,"index.tsx"),d.join(e,"index.js")];for(let n of t)try{if(I.existsSync(n)&&I.statSync(n).isFile())return n}catch{}return null}function je(e){let t=d.resolve(e),n=null;for(;;){let f=d.join(t,"tsconfig.json");if(I.existsSync(f)){n=f;break}let p=d.dirname(t);if(p===t)break;t=p}if(!n)return{baseUrl:e,aliases:[]};let s=f=>{try{let p=I.readFileSync(f,"utf8");return p=p.replace(/\/\*[\s\S]*?\*\//g,"").replace(/(^|[^:])\/\/.*$/gm,"$1"),JSON.parse(p)}catch{return null}},r=(f,p)=>{if(p>4)return{};let o=s(f);if(!o)return{};let a=o.compilerOptions??{},u=a.baseUrl,m=a.paths,y=o.extends;if(typeof y=="string"&&!y.startsWith("@")){let h=d.resolve(d.dirname(f),y.endsWith(".json")?y:`${y}.json`);if(I.existsSync(h)){let A=r(h,p+1);u=u??A.baseUrl,m={...A.paths??{},...m??{}}}}return{baseUrl:u,paths:m}},i=r(n,0),l=d.dirname(n),c=d.resolve(l,i.baseUrl||"."),g=[];for(let[f,p]of Object.entries(i.paths||{})){if(!Array.isArray(p)||p.length===0)continue;let o=f.replace(/\*$/,"");o&&g.push({from:o,to:String(p[0]).replace(/\*$/,"")})}return g.sort((f,p)=>p.from.length-f.from.length),{baseUrl:c,aliases:g}}function Me(e,t){if(!t.startsWith("."))return null;let n=d.resolve(d.dirname(e),t);return ge(n)}function De(e,t,n){if(!t)return null;if(t.startsWith("."))return Me(e,t);let s=n||d.dirname(e),{baseUrl:r,aliases:i}=je(s),l=i.find(g=>t.startsWith(g.from));if(!l)return null;let c=d.resolve(r,`${l.to}${t.slice(l.from.length)}`);return ge(c)}function P(e){return typeof e?.value=="string"?e.value:void 0}function U(e){return e?.name??P(e)}function q(e){return e.sourceCode??e.getSourceCode?.()}function me(e,t){let n=q(e)?.getScope?.(t);for(;n;){let s=n.references?.find(r=>r.identifier===t);if(s)return s;n=n.upper??void 0}}function _(e,t,n){let s=me(e,t);if(s?.resolved)return(s.resolved.defs?.length??0)>0;let r=q(e)?.getScope?.(t);for(;r;){let i=r.set?.get(n);if(i)return(i.defs?.length??0)>0;r=r.upper??void 0}return!1}function Ve(e,t){let n=me(e,t);return n?n.isValueReference!==!1:t.parent?.type==="VariableDeclarator"&&t.parent.init===t}function ye(e){if(e?.type==="Identifier"&&e.name)return{root:e,segments:[e.name]};if(!e||!(e.type==="MemberExpression"||!!(e.object&&e.property))||e.computed===!0)return;let n=ye(e.object),s=U(e.property);if(!(!n||!s))return{root:n.root,segments:[...n.segments,s]}}function Fe(e){return U(e.callee?.property)}function be(e,t){return e?.properties?.find(n=>U(n.key)===t)}function v(e,t){return be(e,t)!==void 0}function He(e){let t=be(e,"metadata")?.value;return v(t,"source")}function he(e){return Fe(e)==="publish"}function F(e){if(e.importKind==="type"||e.exportKind==="type")return!0;let t=e.specifiers??[];return t.length===0?!1:t.every(n=>n.type==="ImportSpecifier")?t.every(n=>n.importKind==="type"):t.every(n=>n.exportKind==="type")}function Ke(e){let t=e;for(;t?.parent;)t=t.parent;return t?.type==="Program"?t:void 0}function Ge(e){let t=Ke(e)?.body;if(!t)return!1;let n=!1;for(let s of t){if(s.type==="ImportDeclaration"){if(!F(s))return!1;continue}if(!(s.type==="TSInterfaceDeclaration"||s.type==="TSTypeAliasDeclaration")){if(s.type==="ExportNamedDeclaration"){if(s.declaration){if(s.declaration.type!=="TSInterfaceDeclaration"&&s.declaration.type!=="TSTypeAliasDeclaration")return!1}else if(!F(s))return!1;n=!0;continue}return!1}}return n}var Be={meta:{type:"problem",docs:{description:"Disallow imports that violate ark.config.json layer rules (same contract as arkgate-check)."},messages:{forbiddenImport:"Architecture: {{fromLayer}} must not import {{toLayer}} (ark.config.json). Specifier: {{specifier}}",forbiddenImportHeuristic:"Domain code must not import infrastructure, adapters, repositories, or database modules."},schema:[]},create(e){let t=C(e),n=K(t),s=n?G(n):null,r=n?d.dirname(n):null,i=l=>{let c=P(l.source);if(c&&s&&r&&t){let g=d.isAbsolute(t)?t:d.resolve(t),f=d.relative(r,g).split(d.sep).join("/");if(!B(s,f))return;let p=w(f,s.layers);if(!p)return;let o=De(g,c,r);if(!o)return;let a=d.relative(r,o).split(d.sep).join("/");if(a.startsWith(".."))return;let u=w(a,s.layers);if(!u)return;let m={fromPath:f,toPath:a,layers:s.layers},y=$(s.rules,p,u,m);if(y||ee(s.rules,p,u,m)){let h=l.type?.startsWith("Export")?"export":"import",A=F(l),W=!!y?.peerIsolation,Y=A&&!W,J=y?.message??`${p} must not ${h} ${u}.`;x(e,l,"forbiddenImport",{ruleId:"LAYER_IMPORT_VIOLATION",file:f,fromLayer:p,toLayer:u,target:a,edgeKind:h,...W?{peerIsolation:!0}:{},...A?{typeOnly:!0}:{},...Y?{severity:"warning"}:{},...Ge(l)?{sourcePureTypeModule:!0}:{},message:Y?`${J} (type-only \u2014 type placement debt; prefer SharedTypes / owning layer; not runtime coupling)`:J},{fromLayer:p,toLayer:u,specifier:c})}return}};return{ImportDeclaration:i,ExportNamedDeclaration:i,ExportAllDeclaration:i}}},Ue={meta:{type:"problem",docs:{description:"Require event bus publish calls to use registered intent creators instead of raw event objects or intent strings."},messages:{rawPublish:"Publish through a registered intent creator; raw event objects or intent strings bypass Ark contracts."},schema:[]},create(e){return{CallExpression(t){let n=t.arguments?.[0],s=P(n),r=V({publishCall:he(t),rawIntentName:s,objectHasIntent:v(n,"intent"),arkPublishCandidate:!1,hasSource:!0});if(r.some(i=>i.ruleId==="RAW_EVENT_PUBLISH")){let i=r.find(l=>l.ruleId==="RAW_EVENT_PUBLISH");x(e,t,"rawPublish",{...i,file:C(e)})}}}}},qe={meta:{type:"problem",docs:{description:"Require event bus publish calls to include source metadata."},messages:{missingSource:"Strict Ark publish calls must include metadata.source."},schema:[]},create(e){return{CallExpression(t){let n=t.arguments?.[0],s=t.arguments?.[2],i=V({publishCall:he(t),rawIntentName:P(n),objectHasIntent:v(n,"intent"),arkPublishCandidate:!0,hasSource:He(n)||v(s,"source")}).find(l=>l.ruleId==="PUBLISH_MISSING_SOURCE");i&&x(e,t,"missingSource",{...i,file:C(e)})}}}},We={meta:{type:"problem",docs:{description:"Disallow ambient globals from the layer\u2019s forbiddenGlobals in ark.config.json (same purity surface as ark-check). Option `globals` is a standalone fallback when no project config applies."},messages:{forbiddenGlobal:'Ambient global "{{name}}" is forbidden in {{layer}} (ark.config.json); inject the capability through a port instead.',forbiddenGlobalDefault:'Ambient global "{{name}}" is forbidden here; inject the capability through a port instead.',forbiddenModule:'{{layer}} must not use module "{{specifier}}" because it is the import form of forbidden global "{{name}}".'},schema:[{type:"object",properties:{globals:{type:"array",items:{type:"string"}}},additionalProperties:!1}]},create(e){let t=C(e),n=e.options?.[0],s=K(t),r=s?G(s):null,i=s?d.dirname(s):null,l=null,c="this layer";if(r&&i&&t){let o=d.isAbsolute(t)?t:d.resolve(t),a=d.relative(i,o).split(d.sep).join("/");if(!B(r,a))return{};let u=r.layers?.find(m=>m.name===w(a,r.layers));u?.forbiddenGlobals?.length?(l=new Set(u.forbiddenGlobals),c=u.name):l=null}else n?.globals&&(l=new Set(n.globals));if(!l)return{};let g=typeof q(e)?.getScope=="function",f=(o,a)=>{let u=d.isAbsolute(t)?t:d.resolve(t),m=i?d.relative(i,u).split(d.sep).join("/"):t;x(e,o,r?"forbiddenGlobal":"forbiddenGlobalDefault",{ruleId:"FORBIDDEN_GLOBAL",file:m,fromLayer:c,target:a,message:`${c} must not use the ambient global "${a}".`},{name:a,layer:c})},p=(o,a,u,m)=>{if(u||typeof a!="string")return;let y=j(a,l);if(!y)return;let h=d.isAbsolute(t)?t:d.resolve(t),A=i?d.relative(i,h).split(d.sep).join("/"):t;x(e,o,"forbiddenModule",{ruleId:"FORBIDDEN_GLOBAL",file:A,fromLayer:c,target:a,edgeKind:m,message:`${c} must not use module "${a}" because it is the import form of forbidden global "${y}".`},{layer:c,name:y,specifier:a,importKind:m})};return{MemberExpression(o){if(o.parent?.type==="MemberExpression"&&o.parent.object===o)return;let a=ye(o);if(!a||_(e,a.root,a.segments[0]))return;let u=a.segments[0]==="globalThis",m=u?a.segments.slice(1):a.segments,y;for(let h=m.length;h>=(u?1:2);h-=1){let A=m.slice(0,h).join(".");if(l.has(A)){y=A;break}}y?f(o,y):!g&&l.has(a.segments[0])&&f(o,a.segments[0])},CallExpression(o){let a=o;if(a.callee?.type==="Identifier"&&a.callee.name==="require"&&a.arguments?.[0]?.type==="Literal"&&!_(e,o,"require")&&p(o,a.arguments[0].value,!1,"require"),g)return;let u=a.callee?.type==="Identifier"?a.callee.name:void 0;u&&l.has(u)&&f(o,u)},ImportDeclaration(o){let a=o,u=(a.specifiers??[]).filter(y=>y.type==="ImportSpecifier"),m=u.length>0&&u.length===(a.specifiers??[]).length&&u.every(y=>y.importKind==="type");p(o,a.source?.value,a.importKind==="type"||m,"import")},ImportExpression(o){let a=o;a.source?.type==="Literal"&&p(o,a.source.value,!1,"dynamic-import")},TSImportEqualsDeclaration(o){let a=o;p(o,a.moduleReference?.expression?.value,a.importKind==="type"||a.isTypeOnly===!0,"require")},ExportNamedDeclaration(o){let a=o;if(!a.source)return;let u=a.specifiers??[],m=u.length>0&&u.every(y=>y.exportKind==="type");p(o,a.source.value,a.exportKind==="type"||m,"export")},ExportAllDeclaration(o){let a=o;p(o,a.source?.value,a.exportKind==="type","export")},NewExpression(o){if(g)return;let a=o.callee?.type==="Identifier"?o.callee.name:void 0;a&&l.has(a)&&f(o,a)},Identifier(o){!g||!o.name||!l.has(o.name)||!Ve(e,o)||_(e,o,o.name)||f(o,o.name)}}}},Ye={meta:{type:"problem",docs:{description:"Disallow importing modules whose effect capability the layer denies (ark.config.json capabilities.deny / pure \u2014 same wall surface as ark-check). Import dimension only: ambient globals stay with no-forbidden-globals and the CLI/hook symbol path."},messages:{deniedCapability:'{{layer}} denies the {{capability}} capability (ark.config.json); "{{specifier}}" imports it. Define a port and bind the implementation in an adapter layer.'},schema:[]},create(e){let t=C(e),n=K(t),s=n?G(n):null,r=n?d.dirname(n):null;if(!s||!r||!t)return{};let i=d.isAbsolute(t)?t:d.resolve(t),l=d.relative(r,i).split(d.sep).join("/");if(!B(s,l))return{};let c=s.layers?.find(p=>p.name===w(l,s.layers));if(!c)return{};let g=new Set(se(c));if(g.size===0)return{};let f=(p,o,a,u)=>{if(a||typeof o!="string"||j(o,c.forbiddenGlobals??[]))return;let m=re(o);!m||!g.has(m)||x(e,p,"deniedCapability",{ruleId:"CAPABILITY_VIOLATION",file:l,fromLayer:c.name,target:o,capability:m,edgeKind:u,message:`${c.name} denies the ${m} capability; found import of "${o}".`},{layer:c.name,capability:m,specifier:o})};return{ImportDeclaration(p){let o=p,a=(o.specifiers??[]).filter(m=>m.type==="ImportSpecifier"),u=a.length>0&&a.length===(o.specifiers??[]).length&&a.every(m=>m.importKind==="type");f(p,o.source?.value,o.importKind==="type"||u,"import")},ImportExpression(p){let o=p;o.source?.type==="Literal"&&f(p,o.source.value,!1,"dynamic-import")},TSImportEqualsDeclaration(p){let o=p;f(p,o.moduleReference?.expression?.value,o.importKind==="type"||o.isTypeOnly===!0,"require")},ExportNamedDeclaration(p){let o=p;if(!o.source)return;let a=o.specifiers??[],u=a.length>0&&a.every(m=>m.exportKind==="type");f(p,o.source.value,o.exportKind==="type"||u,"export")},ExportAllDeclaration(p){let o=p;f(p,o.source?.value,o.exportKind==="type","export")},CallExpression(p){let o=p;o.callee?.type==="Identifier"&&o.callee.name==="require"&&o.arguments?.[0]?.type==="Literal"&&!_(e,p,"require")&&f(p,o.arguments[0].value,!1,"require")}}}},Je={"no-domain-infra-imports":Be,"no-raw-event-publish":Ue,"require-publish-source":qe,"no-forbidden-globals":We,"no-denied-capabilities":Ye},H={rules:Je};H.configs={recommended:{plugins:{ark:H},rules:{"ark/no-domain-infra-imports":"error","ark/no-raw-event-publish":"error","ark/require-publish-source":"error","ark/no-forbidden-globals":"error","ark/no-denied-capabilities":"error"}}};var pt=H;export{pt as default,K as findConfigPath,N as globToRegExp,ee as isEdgeDenied,w as layerForRelativePath,G as loadArkConfig,Ye as noDeniedCapabilities,Be as noDomainInfraImports,We as noForbiddenGlobals,Ue as noRawEventPublish,Q as patternSpecificity,H as plugin,je as readTsconfigPathAliases,qe as requirePublishSource,De as resolveImportSpecifier,Me as resolveRelativeImport};
|