archicat 0.0.7 → 0.0.8

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/README.md CHANGED
@@ -12,10 +12,11 @@ npm i -D archicat
12
12
 
13
13
  ## Why
14
14
 
15
- TypeScript asks: can this import resolve?
16
-
15
+ TypeScript asks: will this import resolve?
17
16
  Archicat asks: should this import exist?
18
17
 
18
+ One is a compiler. The other is an architect.
19
+
19
20
  ## Definitions
20
21
 
21
22
  ### Module
@@ -183,8 +184,8 @@ App `tsconfig.json`:
183
184
  ## Commands
184
185
 
185
186
  ```bash
186
- archicat generate
187
- archicat check
187
+ archicat build
188
+ archicat validate
188
189
  archicat graph
189
190
  archicat doctor
190
191
  ```
@@ -1,8 +1,8 @@
1
- import{createRequire as e}from"node:module";import t from"node:path";import n from"node:fs";import{createJiti as r}from"jiti";import i from"typescript";const a=Object.freeze({configFileName:`archicat.config.ts`,root:`.`,outDir:`.archicat`,alias:Object.freeze({}),generated:Object.freeze({reportsDirName:`reports`,buildReportFileName:`build.report.json`,graphReportFileName:`graph.report.json`,tsconfigFileName:`tsconfig.json`,typesInclude:`./types/**/*.d.ts`,ignoredDirectoryNames:Object.freeze([`node_modules`,`.git`,`.archicat`,`archicat-report`,`dist`,`build`,`coverage`])}),typescript:Object.freeze({consumerTsconfigFileName:`tsconfig.json`,tsConfig:Object.freeze({include:Object.freeze([]),exclude:Object.freeze([]),files:Object.freeze([])})}),prefixes:Object.freeze({module:`@module`,library:`@library`}),modules:Object.freeze({include:Object.freeze([`./src/modules`])}),libraries:Object.freeze({include:Object.freeze([])}),apps:Object.freeze({include:Object.freeze([])})});function o(e){let t=n.readFileSync(e,`utf8`),r=i.parseConfigFileTextToJson(e,t);if(r.error)throw Error(ee(r.error));if(r.config==null||typeof r.config!=`object`||Array.isArray(r.config))throw Error(`Invalid tsconfig object: ${e}`);return r.config}function s(e,t=`tsconfig`){let n=e.compilerOptions;if(n==null)return{};if(typeof n!=`object`||Array.isArray(n))throw Error(`Tsconfig compilerOptions must be an object: ${t}`);return n}function c(e,t){let n=e.extends;if(n===void 0)return[];if(typeof n==`string`)return[u(t,n)];if(Array.isArray(n)&&n.every(e=>typeof e==`string`))return n.map(e=>u(t,e));throw Error(`Tsconfig extends must be a string or string array: ${t}`)}function l(n,r){return t.isAbsolute(r)||r.startsWith(`.`)?f(t.resolve(n,r),r):d(e(t.join(n,a.configFileName)),r,r)}function u(n,r){return t.isAbsolute(r)||r.startsWith(`.`)?f(t.resolve(t.dirname(n),r),n):d(e(n),r,n)}function d(e,t,n){for(let n of p(t))try{return e.resolve(n)}catch{continue}throw Error(`Unable to resolve tsconfig extends "${t}": ${n}`)}function f(e,t){for(let t of p(e))if(n.existsSync(t)&&n.statSync(t).isFile())return t;throw Error(`Unable to resolve tsconfig extends "${e}": ${t}`)}function p(e){return[e,`${e}.json`,t.join(e,a.typescript.consumerTsconfigFileName)]}function ee(e){let t=i.flattenDiagnosticMessageText(e.messageText,`
2
- `);if(e.file&&e.start!==void 0){let n=e.file.getLineAndCharacterOfPosition(e.start);return`${e.file.fileName}:${n.line+1}:${n.character+1} - ${t}`}return t}async function te(e=a.configFileName){let r=process.cwd(),i=t.resolve(r,e);if(!n.existsSync(i))throw Error(`Archicat config was not found: ${i}`);let o=await ne(i,r);oe(o,i);let s=re(o),c=t.resolve(r,s.root),l=t.resolve(c,s.outDir),u=t.resolve(l,a.generated.reportsDirName),d=ae(c,s.typescript.tsConfig.extends);return{configFilePath:i,rootDir:c,outDir:l,reportsDir:u,...d?{tsconfigPath:d}:{},config:o,resolvedConfig:s}}async function ne(e,t){return await r(t,{interopDefault:!0,extensions:[`.js`,`.cjs`,`.mjs`,`.ts`,`.cts`,`.mts`,`.json`]}).import(e,{default:!0})}function re(e){return{root:e.root??a.root,outDir:e.outDir??a.outDir,typescript:ie(e),alias:{...a.alias,...e.alias??{}},prefixes:{module:e.prefixes?.module??a.prefixes.module,library:e.prefixes?.library??a.prefixes.library},modules:m(e.modules,a.modules),libraries:m(e.libraries,a.libraries),apps:m(e.apps,a.apps)}}function ie(e){let t=e.typescript?.tsConfig,n=a.typescript.tsConfig,r={include:[...t?.include??n.include],exclude:[...t?.exclude??n.exclude],files:[...t?.files??n.files]};return t?.extends&&(r.extends=t.extends),{tsConfig:r}}function m(e,t){return{include:[...e?.include??t.include]}}function ae(e,t){if(t)return l(e,t)}function oe(e,t){if(typeof e!=`object`||!e)throw Error(`Invalid Archicat config: ${t}`);let n=e;h(n.root,`root`,t),h(n.outDir,`outDir`,t),se(n.typescript?.tsConfig,t),g(n.modules?.include,`modules.include`,t),g(n.libraries?.include,`libraries.include`,t),g(n.apps?.include,`apps.include`,t),le(n.alias,`alias`,t),_(n.prefixes?.module,`prefixes.module`,t),_(n.prefixes?.library,`prefixes.library`,t)}function se(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Archicat config typescript.tsConfig must be an object: ${t}`);let n=e;h(n.extends,`typescript.tsConfig.extends`,t),g(n.include,`typescript.tsConfig.include`,t),g(n.exclude,`typescript.tsConfig.exclude`,t),g(n.files,`typescript.tsConfig.files`,t),ce(n.compilerOptions,t)}function ce(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Archicat config typescript.tsConfig.compilerOptions must be an object: ${t}`);let n=e;if(Object.hasOwn(n,`paths`))throw Error(`Archicat config typescript.tsConfig.compilerOptions.paths is not supported. Move aliases into archicat.config.ts alias.`);if(Object.hasOwn(n,`baseUrl`))throw Error(`Archicat config typescript.tsConfig.compilerOptions.baseUrl is not supported. Move aliases into archicat.config.ts alias.`);if(Object.keys(n).length>0)throw Error(`Archicat config typescript.tsConfig.compilerOptions is not supported. Put compiler options in the base or app tsconfig.`)}function h(e,t,n){if(e!==void 0&&(typeof e!=`string`||e.trim()===``))throw Error(`Archicat ${t} must be a non-empty string when defined: ${n}`)}function g(e,t,n){if(e!==void 0&&(!Array.isArray(e)||e.some(e=>typeof e!=`string`||e.trim()===``)))throw Error(`Archicat config ${t} must be an array of non-empty strings: ${n}`)}function _(e,t,n){if(e!==void 0&&(typeof e!=`string`||e.trim()===``||e.includes(`*`)||e.endsWith(`/`)))throw Error(`Archicat config ${t} must be a non-empty prefix without wildcard or trailing slash: ${n}`)}function le(e,t,n){if(e!==void 0){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Archicat config ${t} must be an object of non-empty string aliases: ${n}`);for(let[r,i]of Object.entries(e))if(r.trim()===``||typeof i!=`string`||i.trim()===``)throw Error(`Archicat config ${t} must contain non-empty string aliases: ${n}`)}}function v(e,t,n){let r=t.flatMap(t=>ue(e,t,n));return Array.from(new Set(r)).sort((e,t)=>e.localeCompare(t))}function ue(e,r,i){let a=t.resolve(e,r);if(r.includes(`*`))return de(e,r).filter(e=>t.basename(e)===i);if(!n.existsSync(a))return[];let o=n.statSync(a);return o.isFile()?t.basename(a)===i?[a]:[]:o.isDirectory()?y(a,i):[]}function y(e,r){let i=[],a=n.readdirSync(e,{withFileTypes:!0});for(let n of a){if(pe(n.name))continue;let a=t.join(e,n.name);if(n.isDirectory()){i.push(...y(a,r));continue}n.isFile()&&n.name===r&&i.push(a)}return i}function de(e,r){let i=t.resolve(e,r).split(t.sep);if(i.filter(e=>e.includes(`*`)).length!==1)throw Error(`Archicat supports exactly one wildcard segment per include pattern: ${r}`);let a=i.findIndex(e=>e.includes(`*`)),o=i.slice(0,a).join(t.sep)||t.sep,s=i[a]??`*`,c=i.slice(a+1),l=fe(s);return n.existsSync(o)?n.readdirSync(o,{withFileTypes:!0}).filter(e=>e.isDirectory()).filter(e=>l.test(e.name)).map(e=>t.join(o,e.name,...c)).filter(e=>n.existsSync(e)&&n.statSync(e).isFile()):[]}function fe(e){let t=e.replace(/[.+?^${}()|[\]\\]/gu,`\\$&`).replace(/\*/gu,`.*`);return RegExp(`^${t}$`,`u`)}function pe(e){return a.generated.ignoredDirectoryNames.includes(e)}async function b(e,t){switch(t){case`module`:return me(e);case`library`:return he(e);case`app`:return ge(e)}}async function me(e){let n=await x(e,t.dirname(e));return S(n,e,`module`),{kind:`module`,contractFilePath:e,definitionDir:t.dirname(e),contract:n}}async function he(e){let n=await x(e,t.dirname(e));return S(n,e,`library`),{kind:`library`,contractFilePath:e,definitionDir:t.dirname(e),contract:n}}async function ge(e){let n=await x(e,t.dirname(e));return S(n,e,`app`),{kind:`app`,contractFilePath:e,definitionDir:t.dirname(e),contract:n}}async function x(e,t){return await r(t,{interopDefault:!0,extensions:[`.js`,`.cjs`,`.mjs`,`.ts`,`.cts`,`.mts`,`.json`]}).import(e,{default:!0})}function S(e,t,n){if(typeof e!=`object`||!e)throw Error(`Invalid Archicat ${n} definition: ${t}`);let r=e;if(r.kind!==n)throw Error(`Archicat ${n} file must export define${ve(n)}(...): ${t}`);if(typeof r.name!=`string`||r.name.trim()===``)throw Error(`Archicat ${n} must define a non-empty name: ${t}`);if(n===`app`){_e(r.root,`root`,t),w(r.dependencies,t,n);return}let i=r;C(i.api,`api`,t,n),C(i.impl,`impl`,t,n)}function C(e,t,n,r){if(typeof e!=`object`||!e)throw Error(`Archicat ${r}.${t} must be a surface object: ${n}`);_e(e.root,`${t}.root`,n),w(e.dependencies,n,`${r}.${t}`)}function w(e,t,n){if(!Array.isArray(e)||e.some(e=>typeof e!=`string`||e.trim()===``))throw Error(`Archicat ${n} dependencies must be an array of non-empty strings: ${t}`)}function _e(e,t,n){if(e!==void 0&&(typeof e!=`string`||e.trim()===``))throw Error(`Archicat ${t} must be a non-empty string when defined: ${n}`)}function ve(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}function ye(e){let t=new Map;for(let n of e){let e=t.get(n.from)??[];e.push(n.to),t.set(n.from,e)}let n=new Set,r=new Set;for(let e of t.keys())T(e,t,n,r,[])}function T(e,t,n,r,i){if(!r.has(e)){if(n.has(e)){let t=i.indexOf(e),n=[...i.slice(t<0?0:t),e];throw Error(`Cyclic Archicat dependency detected: ${n.join(` -> `)}`)}n.add(e);for(let a of t.get(e)??[])T(a,t,n,r,[...i,e]);n.delete(e),r.add(e)}}function be(e){let t=/^(module|library)\.([a-z][a-z0-9-]*)\.(api|impl)$/u.exec(e);if(t)return{kind:t[1],name:t[2],surface:t[3]}}function xe(e){return`${e.kind}.${e.surface}`}function E(e,t,n){let r=be(t);if(!r)throw Error(`${D(e)} declares invalid dependency target "${t}".`);if(!n.has(t))throw Error(`${D(e)} declares unknown dependency "${t}".`);if(e.kind===r.kind&&e.name===r.name)throw Error(`${D(e)} cannot depend on itself: ${t}`);if(!Se(e,r))throw Error(`${D(e)} cannot depend on ${xe(r)} target "${t}".`)}function Se(e,t){switch(e.surface){case`api`:return e.kind===`module`?t.surface===`api`&&(t.kind===`module`||t.kind===`library`):e.kind===`library`?t.surface===`api`&&t.kind===`library`:!1;case`impl`:return e.kind===`module`?t.surface===`api`&&(t.kind===`module`||t.kind===`library`):e.kind===`library`?t.surface===`api`&&t.kind===`library`:!1;case`app`:return t.kind===`module`||t.kind===`library`}}function D(e){return e.kind===`app`?`App "${e.name}"`:`${Ce(e.kind)} "${e.name}" ${e.surface}`}function Ce(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}function we(e,t){let n=t.filter(e=>e.kind===`module`).map(t=>Te(e,t)),r=t.filter(e=>e.kind===`library`).map(t=>Ee(e,t)),i=t.filter(e=>e.kind===`app`).map(e=>De(e)),a=[...n,...r];ke([...a,...i]);let o=Oe(a,i);return Ae(a,i,o.targets),ye(o.dependencies),{rootDir:e.rootDir,outDir:e.outDir,reportsDir:e.reportsDir,...e.tsconfigPath?{tsconfigPath:e.tsconfigPath}:{},configFilePath:e.configFilePath,config:e.resolvedConfig,modules:n,libraries:r,apps:i,definitions:a,graph:o}}function Te(e,n){let{contract:r,contractFilePath:i,definitionDir:a}=n;A(r.name,i,`module`);let o=r.api.root?k(a,r.api.root,`api`,r.name):void 0,s=r.impl.root?k(a,r.impl.root,`impl`,r.name):void 0,c=`${e.resolvedConfig.prefixes.module}/${r.name}`;return{kind:`module`,name:r.name,apiTarget:`module.${r.name}.api`,implTarget:`module.${r.name}.impl`,alias:c,aliasGlob:`${c}/*`,implAlias:`${c}/impl`,implAliasGlob:`${c}/impl/*`,contractFilePath:i,definitionDir:a,api:O(o,r.api.dependencies,t.join(e.outDir,`modules`,r.name,`api`)),impl:O(s,r.impl.dependencies,t.join(e.outDir,`modules`,r.name,`impl`))}}function Ee(e,n){let{contract:r,contractFilePath:i,definitionDir:a}=n;A(r.name,i,`library`);let o=r.api.root?k(a,r.api.root,`api`,r.name):void 0,s=r.impl.root?k(a,r.impl.root,`impl`,r.name):void 0,c=`${e.resolvedConfig.prefixes.library}/${r.name}`;return{kind:`library`,name:r.name,apiTarget:`library.${r.name}.api`,implTarget:`library.${r.name}.impl`,alias:c,aliasGlob:`${c}/*`,implAlias:`${c}/impl`,implAliasGlob:`${c}/impl/*`,contractFilePath:i,definitionDir:a,api:O(o,r.api.dependencies,t.join(e.outDir,`libraries`,r.name,`api`)),impl:O(s,r.impl.dependencies,t.join(e.outDir,`libraries`,r.name,`impl`))}}function De(e){let{contract:t,contractFilePath:n,definitionDir:r}=e;return A(t.name,n,`app`),{kind:`app`,name:t.name,target:`app.${t.name}`,contractFilePath:n,definitionDir:r,rootPath:t.root?k(r,t.root,`app`,t.name):r,dependencies:[...t.dependencies]}}function O(e,t,n){return{...e?{rootPath:e}:{},mirrorRootPath:n,dependencies:[...t]}}function k(e,r,i,a){let o=t.resolve(e,r);if(!n.existsSync(o))throw Error(`Definition "${a}" declares ${i} root that does not exist: ${o}`);if(!n.statSync(o).isDirectory())throw Error(`Definition "${a}" declares ${i} root that is not a directory: ${o}`);return o}function Oe(e,t){let n=e.flatMap(e=>[{key:e.apiTarget,kind:e.kind,name:e.name,surface:`api`},{key:e.implTarget,kind:e.kind,name:e.name,surface:`impl`}]),r=[...e.flatMap(e=>[...e.api.dependencies.map(t=>({from:e.apiTarget,to:t,origin:`declared`})),...e.impl.dependencies.map(t=>({from:e.implTarget,to:t,origin:`declared`}))]),...t.flatMap(e=>e.dependencies.map(t=>({from:e.target,to:t,origin:`declared`})))];return{targets:n,dependencies:[...e.map(e=>({from:e.implTarget,to:e.apiTarget,origin:`derived`})),...r]}}function A(e,t,n){if(!/^[a-z][a-z0-9-]*$/u.test(e))throw Error(`Invalid Archicat ${n} name "${e}" in ${t}. Use ^[a-z][a-z0-9-]*$`)}function ke(e){let t=new Map;for(let n of e){let e=`${n.kind}.${n.name}`,r=t.get(e);if(r)throw Error(`Duplicate Archicat ${n.kind} name "${n.name}" in ${r} and ${n.contractFilePath}`);t.set(e,n.contractFilePath)}}function Ae(e,t,n){let r=new Set(n.map(e=>e.key));for(let t of e){for(let e of t.api.dependencies)E(je(t,`api`),e,r);for(let e of t.impl.dependencies)E(je(t,`impl`),e,r)}for(let e of t)for(let t of e.dependencies)E({kind:`app`,name:e.name,surface:`app`,target:e.target},t,r)}function je(e,t){return{kind:e.kind,name:e.name,surface:t,target:t===`api`?e.apiTarget:e.implTarget}}async function j(e){let t=await te(e),n=v(t.rootDir,t.resolvedConfig.modules.include,`archicat.module.ts`),r=v(t.rootDir,t.resolvedConfig.libraries.include,`archicat.library.ts`),i=v(t.rootDir,t.resolvedConfig.apps.include,`archicat.app.ts`);if(n.length===0&&r.length===0&&i.length===0)throw Error(`No Archicat definition files matched configured include roots.`);return we(t,[...await Promise.all(n.map(e=>b(e,`module`))),...await Promise.all(r.map(e=>b(e,`library`))),...await Promise.all(i.map(e=>b(e,`app`)))])}function M(e){return e.split(t.sep).join(`/`)}function Me(e,n){let r=t.dirname(e),i=t.parse(n),a=t.join(i.dir,i.name),o=M(t.relative(r,a));return o.startsWith(`.`)||(o=`./${o}`),`${o}.js`}function N(e,n){let r=t.relative(n,e);return r===``||!!r&&!r.startsWith(`..`)&&!t.isAbsolute(r)}function P(e){return e.replace(/\.(?:js|mjs|cjs|ts|mts|cts|tsx)$/u,``)}function F(e,n){return M(t.relative(e,n))}function I(e){return n.existsSync(e)?n.statSync(e).isFile()?Ne(e)?[e]:[]:Pe(e).filter(Ne).sort((e,t)=>e.localeCompare(t)):[]}function Ne(e){return/\.(?:ts|mts|cts|tsx)$/u.test(e)&&!/\.d\.(?:ts|mts|cts)$/u.test(e)}function Pe(e){let r=[],i=n.readdirSync(e,{withFileTypes:!0});for(let n of i){let i=t.join(e,n.name);if(n.isDirectory()){r.push(...Pe(i));continue}n.isFile()&&r.push(i)}return r}function Fe(e){let t=i.createSourceFile(e,n.readFileSync(e,`utf8`),i.ScriptTarget.Latest,!0),r=[],a=e=>{if(i.isImportDeclaration(e)&&i.isStringLiteral(e.moduleSpecifier)&&r.push({moduleSpecifier:e.moduleSpecifier.text,kind:`import`}),i.isExportDeclaration(e)&&e.moduleSpecifier&&i.isStringLiteral(e.moduleSpecifier)&&r.push({moduleSpecifier:e.moduleSpecifier.text,kind:`export`}),i.isCallExpression(e)&&e.expression.kind===i.SyntaxKind.ImportKeyword){let[t]=e.arguments;t&&i.isStringLiteral(t)&&r.push({moduleSpecifier:t.text,kind:`dynamic-import`})}i.forEachChild(e,a)};return a(t),r}function Ie(e){let t=i.createSourceFile(e,n.readFileSync(e,`utf8`),i.ScriptTarget.Latest,!0),r=!1,a=e=>{if(!r){if(i.isExportAssignment(e)&&!e.isExportEquals){r=!0;return}if(Le(e)){r=!0;return}if(i.isExportDeclaration(e)&&e.exportClause&&i.isNamedExports(e.exportClause))for(let t of e.exportClause.elements){let e=t.name.text,n=t.propertyName?.text;if(e==="default"||n==="default"){r=!0;return}}i.forEachChild(e,a)}};return a(t),r}function Le(e){let t=i.canHaveModifiers(e)?i.getModifiers(e):void 0;if(!t)return!1;let n=t.some(e=>e.kind===i.SyntaxKind.ExportKeyword),r=t.some(e=>e.kind===i.SyntaxKind.DefaultKeyword);return n&&r}async function Re(e){return ze(await j(e))}function ze(e){let t=[],n=[...e.definitions.flatMap(e=>Be(e)),...e.apps.flatMap(e=>I(e.rootPath))];for(let r of n){let n=Ue(e,r);if(n)for(let i of Fe(r)){let a=Ve(e,n,r,i.moduleSpecifier);a&&t.push(a)}}return t}function Be(e){return[...e.api.rootPath?I(e.api.rootPath):[],...e.impl.rootPath?I(e.impl.rootPath):[]]}function Ve(e,t,n,r){let i=Ke(e,r);if(i)return qe(t,i)?void 0:i.surface===`impl`&&t.kind!==`app`?L(e,n,r,`${R(t)} cannot import implementation target "${i.target}". Implementation imports are allowed only from app composition roots.`):Je(e,t.target,i.target)?void 0:L(e,n,r,`${R(t)} imports "${i.target}" but does not declare a dependency that allows it.`);if(r.startsWith(`.`)||r.startsWith(`/`))return He(e,t,n,r)}function He(e,t,n,r){let i=Ue(e,We(n,r));if(!(!i||Ge(t,i)))return L(e,n,r,`${R(t)} imports ${R(i)} through a source path. Use an Archicat alias instead.`)}function Ue(e,t){let n=P(t);for(let t of e.definitions){if(t.api.rootPath&&N(n,P(t.api.rootPath)))return{kind:t.kind,name:t.name,surface:`api`,target:t.apiTarget,definition:t};if(t.impl.rootPath&&N(n,P(t.impl.rootPath)))return{kind:t.kind,name:t.name,surface:`impl`,target:t.implTarget,definition:t}}for(let t of e.apps)if(N(n,P(t.rootPath)))return{kind:`app`,name:t.name,surface:`app`,target:t.target,app:t}}function We(e,n){return P(n.startsWith(`/`)?n:t.resolve(t.dirname(e),n))}function Ge(e,t){return e.kind===t.kind&&e.name===t.name}function Ke(e,t){for(let n of e.definitions){if(n.implAlias&&(t===n.implAlias||t.startsWith(`${n.implAlias}/`)))return{kind:n.kind,name:n.name,surface:`impl`,target:n.implTarget};if(t===n.alias||t.startsWith(`${n.alias}/`))return{kind:n.kind,name:n.name,surface:`api`,target:n.apiTarget}}}function qe(e,t){return e.kind===t.kind&&e.name===t.name&&t.surface===`api`}function Je(e,t,n){let r=new Set,i=[t];for(;i.length>0;){let t=i.shift();if(t===n)return!0;if(!r.has(t)){r.add(t);for(let n of e.graph.dependencies.filter(e=>e.from===t))i.push(n.to)}}return!1}function L(e,t,n,r){return{filePath:F(e.rootDir,t),importPath:n,message:r}}function R(e){return e.kind===`app`?`App "${e.name}"`:`${Ye(e.kind)} "${e.name}" ${e.surface}`}function Ye(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}function z(e){return{exitCode:0,lines:e.map(e=>({kind:`success`,message:e}))}}function Xe(e){return{exitCode:1,lines:e.map(e=>({kind:`error`,message:e}))}}async function Ze(e){let t=await Re(e.config);return t.length===0?z([`Architecture check passed.`]):Xe(t.map(e=>`${e.filePath}\n import: ${e.importPath}\n ${e.message}`))}async function Qe(e){let t=await j(e);return[...$e(t),...et(t),...ct(t)]}function $e(e){let t=B(e);return n.existsSync(t)?[]:[{severity:`warning`,message:`Generated tsconfig does not exist yet: ${t}. Run archicat generate.`}]}function et(e){let t=lt(e);if(!n.existsSync(t))return[{severity:`warning`,message:`Consumer tsconfig was not found: ${t}`}];let r=[],i=tt(t,r);if(!i)return r;let a=nt(i,t,r);return a?(rt(r,e,i),it(r,a),at(r,a),ot(r,a),st(r,i),r):r}function tt(e,t){try{return o(e)}catch(e){t.push({severity:`warning`,message:`Failed to parse consumer tsconfig: ${V(e)}`});return}}function nt(e,t,n){try{return s(e,t)}catch(e){n.push({severity:`warning`,message:V(e)});return}}function rt(e,t,n){let r=ut(t);n.extends!==r&&e.push({severity:`warning`,message:`Consumer tsconfig should extend ${r} for generated Archicat aliases to work.`})}function it(e,t){let n=t.rootDir;n!==`src`&&n!==`./src`||e.push({severity:`warning`,message:`compilerOptions.rootDir is set to src. Generated .archicat files live outside src and may break tsc.`})}function at(e,t){Object.hasOwn(t,`paths`)&&e.push({severity:`warning`,message:`compilerOptions.paths should move to archicat.config.ts alias. Consumer tsconfig paths can override generated Archicat aliases.`})}function ot(e,t){Object.hasOwn(t,`baseUrl`)&&e.push({severity:`warning`,message:`compilerOptions.baseUrl is not supported. Move aliases into archicat.config.ts alias.`})}function st(e,t){t.include===void 0&&t.exclude===void 0&&t.files===void 0||e.push({severity:`warning`,message:`Consumer tsconfig include/exclude/files should move to archicat.config.ts typescript.tsConfig so generated Archicat types stay included.`})}function ct(e){let r=[];for(let i of e.definitions){let e=t.join(i.definitionDir,`api`),a=t.join(i.definitionDir,`impl`);!i.api.rootPath&&n.existsSync(e)&&r.push({severity:`warning`,message:`${H(i.kind)} "${i.name}" has a physical api directory but its contract omits api.root. Archicat treats the public API as empty.`}),!i.impl.rootPath&&n.existsSync(a)&&r.push({severity:`warning`,message:`${H(i.kind)} "${i.name}" has a physical impl directory but its contract omits impl.root. Archicat treats the implementation as no-op.`})}return r}function lt(e){return t.join(e.rootDir,a.typescript.consumerTsconfigFileName)}function B(e){return t.join(e.outDir,a.generated.tsconfigFileName)}function ut(e){let n=M(t.relative(e.rootDir,B(e)));return dt(n)||(n=`./${n}`),n}function dt(e){return e.startsWith(`./`)||e.startsWith(`../`)}function V(e){return e instanceof Error?e.message:String(e)}function H(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}async function ft(e){let t=await Qe(e.config);return t.length===0?z([`Doctor found no issues.`]):{exitCode:+!!t.some(e=>e.severity===`error`),lines:t.map(e=>({kind:e.severity===`error`?`error`:`warning`,message:e.message}))}}function pt(e){n.existsSync(e)&&n.rmSync(e,{recursive:!0,force:!0}),n.mkdirSync(e,{recursive:!0})}function U(e,r){n.mkdirSync(t.dirname(e),{recursive:!0}),n.writeFileSync(e,r,`utf8`)}function W(e,t){U(e,`${JSON.stringify(t,null,2)}\n`)}function mt(e){let n=[...e.modules.map(e=>e.apiTarget),...e.libraries.map(e=>e.apiTarget)],r=n,i=e.libraries.map(e=>e.apiTarget),a=i,o=e.graph.targets.map(e=>e.key),s=`import 'archicat';
1
+ import{createRequire as e}from"node:module";import t from"node:fs";import n from"node:path";import{createJiti as r}from"jiti";import i from"typescript";import{consola as a}from"consola";const o=Object.freeze({configFileName:`archicat.config.ts`,root:`.`,outDir:`.archicat`,alias:Object.freeze({}),generated:Object.freeze({reportsDirName:`reports`,buildReportFileName:`build.report.json`,graphReportFileName:`graph.report.json`,tsconfigFileName:`tsconfig.json`,typesInclude:`./types/**/*.d.ts`,ignoredDirectoryNames:Object.freeze([`node_modules`,`.git`,`.archicat`,`archicat-report`,`dist`,`build`,`coverage`])}),typescript:Object.freeze({consumerTsconfigFileName:`tsconfig.json`,tsConfig:Object.freeze({include:Object.freeze([]),exclude:Object.freeze([]),files:Object.freeze([])})}),prefixes:Object.freeze({module:`@module`,library:`@library`}),modules:Object.freeze({include:Object.freeze([`./src/modules`])}),libraries:Object.freeze({include:Object.freeze([])}),apps:Object.freeze({include:Object.freeze([])})});function s(e){let n=t.readFileSync(e,`utf8`),r=i.parseConfigFileTextToJson(e,n);if(r.error)throw Error(ne(r.error));if(r.config==null||typeof r.config!=`object`||Array.isArray(r.config))throw Error(`Invalid tsconfig object: ${e}`);return r.config}function c(e,t=`tsconfig`){let n=e.compilerOptions;if(n==null)return{};if(typeof n!=`object`||Array.isArray(n))throw Error(`Tsconfig compilerOptions must be an object: ${t}`);return n}function l(e,t){let n=e.extends;if(n===void 0)return[];if(typeof n==`string`)return[u(t,n)];if(Array.isArray(n)&&n.every(e=>typeof e==`string`))return n.map(e=>u(t,e));throw Error(`Tsconfig extends must be a string or string array: ${t}`)}function ee(t,r){return n.isAbsolute(r)||r.startsWith(`.`)?d(n.resolve(t,r),r):te(e(n.join(t,o.configFileName)),r,r)}function u(t,r){return n.isAbsolute(r)||r.startsWith(`.`)?d(n.resolve(n.dirname(t),r),t):te(e(t),r,t)}function te(e,t,n){for(let n of f(t))try{return e.resolve(n)}catch{continue}throw Error(`Unable to resolve tsconfig extends "${t}": ${n}`)}function d(e,n){for(let n of f(e))if(t.existsSync(n)&&t.statSync(n).isFile())return n;throw Error(`Unable to resolve tsconfig extends "${e}": ${n}`)}function f(e){return[e,`${e}.json`,n.join(e,o.typescript.consumerTsconfigFileName)]}function ne(e){let t=i.flattenDiagnosticMessageText(e.messageText,`
2
+ `);if(e.file&&e.start!==void 0){let n=e.file.getLineAndCharacterOfPosition(e.start);return`${e.file.fileName}:${n.line+1}:${n.character+1} - ${t}`}return t}async function re(e=o.configFileName){let r=process.cwd(),i=n.resolve(r,e);if(!t.existsSync(i))throw Error(`Archicat config was not found: ${i}`);let a=await ie(i,r);ce(a,i);let s=ae(a),c=n.resolve(r,s.root),l=n.resolve(c,s.outDir),ee=n.resolve(l,o.generated.reportsDirName),u=se(c,s.typescript.tsConfig.extends);return{configFilePath:i,rootDir:c,outDir:l,reportsDir:ee,...u?{tsconfigPath:u}:{},config:a,resolvedConfig:s}}async function ie(e,t){return await r(t,{interopDefault:!0,extensions:[`.js`,`.cjs`,`.mjs`,`.ts`,`.cts`,`.mts`,`.json`]}).import(e,{default:!0})}function ae(e){return{root:e.root??o.root,outDir:e.outDir??o.outDir,typescript:oe(e),alias:{...o.alias,...e.alias??{}},prefixes:{module:e.prefixes?.module??o.prefixes.module,library:e.prefixes?.library??o.prefixes.library},modules:p(e.modules,o.modules),libraries:p(e.libraries,o.libraries),apps:p(e.apps,o.apps)}}function oe(e){let t=e.typescript?.tsConfig,n=o.typescript.tsConfig,r={include:[...t?.include??n.include],exclude:[...t?.exclude??n.exclude],files:[...t?.files??n.files]};return t?.extends&&(r.extends=t.extends),{tsConfig:r}}function p(e,t){return{include:[...e?.include??t.include]}}function se(e,t){if(t)return ee(e,t)}function ce(e,t){if(typeof e!=`object`||!e)throw Error(`Invalid Archicat config: ${t}`);let n=e;m(n.root,`root`,t),m(n.outDir,`outDir`,t),le(n.typescript?.tsConfig,t),h(n.modules?.include,`modules.include`,t),h(n.libraries?.include,`libraries.include`,t),h(n.apps?.include,`apps.include`,t),de(n.alias,`alias`,t),g(n.prefixes?.module,`prefixes.module`,t),g(n.prefixes?.library,`prefixes.library`,t)}function le(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Archicat config typescript.tsConfig must be an object: ${t}`);let n=e;m(n.extends,`typescript.tsConfig.extends`,t),h(n.include,`typescript.tsConfig.include`,t),h(n.exclude,`typescript.tsConfig.exclude`,t),h(n.files,`typescript.tsConfig.files`,t),ue(n.compilerOptions,t)}function ue(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Archicat config typescript.tsConfig.compilerOptions must be an object: ${t}`);let n=e;if(Object.hasOwn(n,`paths`))throw Error(`Archicat config typescript.tsConfig.compilerOptions.paths is not supported. Move aliases into archicat.config.ts alias.`);if(Object.hasOwn(n,`baseUrl`))throw Error(`Archicat config typescript.tsConfig.compilerOptions.baseUrl is not supported. Move aliases into archicat.config.ts alias.`);if(Object.keys(n).length>0)throw Error(`Archicat config typescript.tsConfig.compilerOptions is not supported. Put compiler options in the base or app tsconfig.`)}function m(e,t,n){if(e!==void 0&&(typeof e!=`string`||e.trim()===``))throw Error(`Archicat ${t} must be a non-empty string when defined: ${n}`)}function h(e,t,n){if(e!==void 0&&(!Array.isArray(e)||e.some(e=>typeof e!=`string`||e.trim()===``)))throw Error(`Archicat config ${t} must be an array of non-empty strings: ${n}`)}function g(e,t,n){if(e!==void 0&&(typeof e!=`string`||e.trim()===``||e.includes(`*`)||e.endsWith(`/`)))throw Error(`Archicat config ${t} must be a non-empty prefix without wildcard or trailing slash: ${n}`)}function de(e,t,n){if(e!==void 0){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Archicat config ${t} must be an object of non-empty string aliases: ${n}`);for(let[r,i]of Object.entries(e))if(r.trim()===``||typeof i!=`string`||i.trim()===``)throw Error(`Archicat config ${t} must contain non-empty string aliases: ${n}`)}}function _(e,t,n){let r=t.flatMap(t=>fe(e,t,n));return Array.from(new Set(r)).sort((e,t)=>e.localeCompare(t))}function fe(e,r,i){let a=n.resolve(e,r);if(r.includes(`*`))return pe(e,r).filter(e=>n.basename(e)===i);if(!t.existsSync(a))return[];let o=t.statSync(a);return o.isFile()?n.basename(a)===i?[a]:[]:o.isDirectory()?v(a,i):[]}function v(e,r){let i=[],a=t.readdirSync(e,{withFileTypes:!0});for(let t of a){if(he(t.name))continue;let a=n.join(e,t.name);if(t.isDirectory()){i.push(...v(a,r));continue}t.isFile()&&t.name===r&&i.push(a)}return i}function pe(e,r){let i=n.resolve(e,r).split(n.sep);if(i.filter(e=>e.includes(`*`)).length!==1)throw Error(`Archicat supports exactly one wildcard segment per include pattern: ${r}`);let a=i.findIndex(e=>e.includes(`*`)),o=i.slice(0,a).join(n.sep)||n.sep,s=i[a]??`*`,c=i.slice(a+1),l=me(s);return t.existsSync(o)?t.readdirSync(o,{withFileTypes:!0}).filter(e=>e.isDirectory()).filter(e=>l.test(e.name)).map(e=>n.join(o,e.name,...c)).filter(e=>t.existsSync(e)&&t.statSync(e).isFile()):[]}function me(e){let t=e.replace(/[.+?^${}()|[\]\\]/gu,`\\$&`).replace(/\*/gu,`.*`);return RegExp(`^${t}$`,`u`)}function he(e){return o.generated.ignoredDirectoryNames.includes(e)}async function y(e,t){switch(t){case`module`:return ge(e);case`library`:return _e(e);case`app`:return ve(e)}}async function ge(e){let t=await b(e,n.dirname(e));return x(t,e,`module`),{kind:`module`,contractFilePath:e,definitionDir:n.dirname(e),contract:t}}async function _e(e){let t=await b(e,n.dirname(e));return x(t,e,`library`),{kind:`library`,contractFilePath:e,definitionDir:n.dirname(e),contract:t}}async function ve(e){let t=await b(e,n.dirname(e));return x(t,e,`app`),{kind:`app`,contractFilePath:e,definitionDir:n.dirname(e),contract:t}}async function b(e,t){return await r(t,{interopDefault:!0,extensions:[`.js`,`.cjs`,`.mjs`,`.ts`,`.cts`,`.mts`,`.json`]}).import(e,{default:!0})}function x(e,t,n){if(typeof e!=`object`||!e)throw Error(`Invalid Archicat ${n} definition: ${t}`);let r=e;if(r.kind!==n)throw Error(`Archicat ${n} file must export define${ye(n)}(...): ${t}`);if(typeof r.name!=`string`||r.name.trim()===``)throw Error(`Archicat ${n} must define a non-empty name: ${t}`);if(n===`app`){w(r.root,`root`,t),C(r.dependencies,t,n);return}let i=r;S(i.api,`api`,t,n),S(i.impl,`impl`,t,n)}function S(e,t,n,r){if(typeof e!=`object`||!e)throw Error(`Archicat ${r}.${t} must be a surface object: ${n}`);w(e.root,`${t}.root`,n),C(e.dependencies,n,`${r}.${t}`)}function C(e,t,n){if(!Array.isArray(e)||e.some(e=>typeof e!=`string`||e.trim()===``))throw Error(`Archicat ${n} dependencies must be an array of non-empty strings: ${t}`)}function w(e,t,n){if(e!==void 0&&(typeof e!=`string`||e.trim()===``))throw Error(`Archicat ${t} must be a non-empty string when defined: ${n}`)}function ye(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}function be(e){let t=new Map;for(let n of e){let e=t.get(n.from)??[];e.push(n.to),t.set(n.from,e)}let n=new Set,r=new Set;for(let e of t.keys())xe(e,t,n,r,[])}function xe(e,t,n,r,i){if(!r.has(e)){if(n.has(e)){let t=i.indexOf(e),n=[...i.slice(t<0?0:t),e];throw Error(`Cyclic Archicat dependency detected: ${n.join(` -> `)}`)}n.add(e);for(let a of t.get(e)??[])xe(a,t,n,r,[...i,e]);n.delete(e),r.add(e)}}function Se(e){let t=/^(module|library)\.([a-z][a-z0-9-]*)\.(api|impl)$/u.exec(e);if(t)return{kind:t[1],name:t[2],surface:t[3]}}function Ce(e){return`${e.kind}.${e.surface}`}function T(e,t,n){let r=Se(t);if(!r)throw Error(`${E(e)} declares invalid dependency target "${t}".`);if(!n.has(t))throw Error(`${E(e)} declares unknown dependency "${t}".`);if(e.kind===r.kind&&e.name===r.name)throw Error(`${E(e)} cannot depend on itself: ${t}`);if(!we(e,r))throw Error(`${E(e)} cannot depend on ${Ce(r)} target "${t}".`)}function we(e,t){switch(e.surface){case`api`:return e.kind===`module`?t.surface===`api`&&(t.kind===`module`||t.kind===`library`):e.kind===`library`?t.surface===`api`&&t.kind===`library`:!1;case`impl`:return e.kind===`module`?t.surface===`api`&&(t.kind===`module`||t.kind===`library`):e.kind===`library`?t.surface===`api`&&t.kind===`library`:!1;case`app`:return t.kind===`module`||t.kind===`library`}}function E(e){return e.kind===`app`?`App "${e.name}"`:`${Te(e.kind)} "${e.name}" ${e.surface}`}function Te(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}function Ee(e,t){let n=t.filter(e=>e.kind===`module`).map(t=>De(e,t)),r=t.filter(e=>e.kind===`library`).map(t=>Oe(e,t)),i=t.filter(e=>e.kind===`app`).map(e=>ke(e)),a=[...n,...r];je([...a,...i]);let o=Ae(a,i);return Me(a,i,o.targets),be(o.dependencies),{rootDir:e.rootDir,outDir:e.outDir,reportsDir:e.reportsDir,...e.tsconfigPath?{tsconfigPath:e.tsconfigPath}:{},configFilePath:e.configFilePath,config:e.resolvedConfig,modules:n,libraries:r,apps:i,definitions:a,graph:o}}function De(e,t){let{contract:r,contractFilePath:i,definitionDir:a}=t;k(r.name,i,`module`);let o=r.api.root?O(a,r.api.root,`api`,r.name):void 0,s=r.impl.root?O(a,r.impl.root,`impl`,r.name):void 0,c=`${e.resolvedConfig.prefixes.module}/${r.name}`;return{kind:`module`,name:r.name,apiTarget:`module.${r.name}.api`,implTarget:`module.${r.name}.impl`,alias:c,aliasGlob:`${c}/*`,implAlias:`${c}/impl`,implAliasGlob:`${c}/impl/*`,contractFilePath:i,definitionDir:a,api:D(o,r.api.dependencies,n.join(e.outDir,`modules`,r.name,`api`)),impl:D(s,r.impl.dependencies,n.join(e.outDir,`modules`,r.name,`impl`))}}function Oe(e,t){let{contract:r,contractFilePath:i,definitionDir:a}=t;k(r.name,i,`library`);let o=r.api.root?O(a,r.api.root,`api`,r.name):void 0,s=r.impl.root?O(a,r.impl.root,`impl`,r.name):void 0,c=`${e.resolvedConfig.prefixes.library}/${r.name}`;return{kind:`library`,name:r.name,apiTarget:`library.${r.name}.api`,implTarget:`library.${r.name}.impl`,alias:c,aliasGlob:`${c}/*`,implAlias:`${c}/impl`,implAliasGlob:`${c}/impl/*`,contractFilePath:i,definitionDir:a,api:D(o,r.api.dependencies,n.join(e.outDir,`libraries`,r.name,`api`)),impl:D(s,r.impl.dependencies,n.join(e.outDir,`libraries`,r.name,`impl`))}}function ke(e){let{contract:t,contractFilePath:n,definitionDir:r}=e;return k(t.name,n,`app`),{kind:`app`,name:t.name,target:`app.${t.name}`,contractFilePath:n,definitionDir:r,rootPath:t.root?O(r,t.root,`app`,t.name):r,dependencies:[...t.dependencies]}}function D(e,t,n){return{...e?{rootPath:e}:{},mirrorRootPath:n,dependencies:[...t]}}function O(e,r,i,a){let o=n.resolve(e,r);if(!t.existsSync(o))throw Error(`Definition "${a}" declares ${i} root that does not exist: ${o}`);if(!t.statSync(o).isDirectory())throw Error(`Definition "${a}" declares ${i} root that is not a directory: ${o}`);return o}function Ae(e,t){let n=e.flatMap(e=>[{key:e.apiTarget,kind:e.kind,name:e.name,surface:`api`},{key:e.implTarget,kind:e.kind,name:e.name,surface:`impl`}]),r=[...e.flatMap(e=>[...e.api.dependencies.map(t=>({from:e.apiTarget,to:t,origin:`declared`})),...e.impl.dependencies.map(t=>({from:e.implTarget,to:t,origin:`declared`}))]),...t.flatMap(e=>e.dependencies.map(t=>({from:e.target,to:t,origin:`declared`})))];return{targets:n,dependencies:[...e.map(e=>({from:e.implTarget,to:e.apiTarget,origin:`derived`})),...r]}}function k(e,t,n){if(!/^[a-z][a-z0-9-]*$/u.test(e))throw Error(`Invalid Archicat ${n} name "${e}" in ${t}. Use ^[a-z][a-z0-9-]*$`)}function je(e){let t=new Map;for(let n of e){let e=`${n.kind}.${n.name}`,r=t.get(e);if(r)throw Error(`Duplicate Archicat ${n.kind} name "${n.name}" in ${r} and ${n.contractFilePath}`);t.set(e,n.contractFilePath)}}function Me(e,t,n){let r=new Set(n.map(e=>e.key));for(let t of e){for(let e of t.api.dependencies)T(A(t,`api`),e,r);for(let e of t.impl.dependencies)T(A(t,`impl`),e,r)}for(let e of t)for(let t of e.dependencies)T({kind:`app`,name:e.name,surface:`app`,target:e.target},t,r)}function A(e,t){return{kind:e.kind,name:e.name,surface:t,target:t===`api`?e.apiTarget:e.implTarget}}async function Ne(e){let t=await re(e),n=_(t.rootDir,t.resolvedConfig.modules.include,`archicat.module.ts`),r=_(t.rootDir,t.resolvedConfig.libraries.include,`archicat.library.ts`),i=_(t.rootDir,t.resolvedConfig.apps.include,`archicat.app.ts`);if(n.length===0&&r.length===0&&i.length===0)throw Error(`No Archicat definition files matched configured include roots.`);return Ee(t,[...await Promise.all(n.map(e=>y(e,`module`))),...await Promise.all(r.map(e=>y(e,`library`))),...await Promise.all(i.map(e=>y(e,`app`)))])}var Pe=class{options;project;constructor(e){this.options=e}async getProject(){return this.project??=await Ne(this.options.config),this.project}},j=class e{name;steps=[];constructor(e){this.name=e}static build(t){return new e(t)}use(e){return this.steps.push(e),this}async run(e){let t=new Pe(e),n=Date.now(),r=[{kind:`info`,message:`Archicat ${this.name}`},{kind:`info`,message:``}];for(let e of this.steps){let i=await e.run(t);if(r.push(...i.lines),i.exitCode!==0)return r.push({kind:`info`,message:``}),r.push({kind:`error`,message:`Failed in ${Date.now()-n}ms`}),{exitCode:i.exitCode,lines:r}}return r.push({kind:`info`,message:``}),r.push({kind:`success`,message:`Done in ${Date.now()-n}ms`}),{exitCode:0,lines:r}}};function M(e){return e.split(n.sep).join(`/`)}function Fe(e,t){let r=n.dirname(e),i=n.parse(t),a=n.join(i.dir,i.name),o=M(n.relative(r,a));return o.startsWith(`.`)||(o=`./${o}`),`${o}.js`}function N(e,t){let r=n.relative(t,e);return r===``||!!r&&!r.startsWith(`..`)&&!n.isAbsolute(r)}function P(e){return e.replace(/\.(?:js|mjs|cjs|ts|mts|cts|tsx)$/u,``)}function F(e,t){return M(n.relative(e,t))}function Ie(e){return[...Le(e),...Ge(e)]}function Le(e){let n=Ke(e);if(!t.existsSync(n))return[{severity:`warning`,message:`Consumer tsconfig was not found: ${n}`}];let r=[],i=Re(n,r);if(!i)return r;let a=ze(i,n,r);return a?(Be(r,e,i),Ve(r,a),He(r,a),Ue(r,a),We(r,i),r):r}function Re(e,t){try{return s(e)}catch(e){t.push({severity:`warning`,message:`Failed to parse consumer tsconfig: ${Xe(e)}`});return}}function ze(e,t,n){try{return c(e,t)}catch(e){n.push({severity:`warning`,message:Xe(e)});return}}function Be(e,t,n){let r=Je(t);n.extends!==r&&e.push({severity:`warning`,message:`Consumer tsconfig should extend ${r} for generated Archicat aliases to work.`})}function Ve(e,t){let n=t.rootDir;n!==`src`&&n!==`./src`||e.push({severity:`warning`,message:`compilerOptions.rootDir is set to src. Generated .archicat files live outside src and may break tsc.`})}function He(e,t){Object.hasOwn(t,`paths`)&&e.push({severity:`warning`,message:`compilerOptions.paths should move to archicat.config.ts alias. Consumer tsconfig paths can override generated Archicat aliases.`})}function Ue(e,t){Object.hasOwn(t,`baseUrl`)&&e.push({severity:`warning`,message:`compilerOptions.baseUrl is not supported. Move aliases into archicat.config.ts alias.`})}function We(e,t){t.include===void 0&&t.exclude===void 0&&t.files===void 0||e.push({severity:`warning`,message:`Consumer tsconfig include/exclude/files should move to archicat.config.ts typescript.tsConfig so generated Archicat types stay included.`})}function Ge(e){let r=[];for(let i of e.definitions){let e=n.join(i.definitionDir,`api`),a=n.join(i.definitionDir,`impl`);!i.api.rootPath&&t.existsSync(e)&&r.push({severity:`warning`,message:`${I(i.kind)} "${i.name}" has a physical api directory but its contract omits api.root. Archicat treats the public API as empty.`}),!i.impl.rootPath&&t.existsSync(a)&&r.push({severity:`warning`,message:`${I(i.kind)} "${i.name}" has a physical impl directory but its contract omits impl.root. Archicat treats the implementation as no-op.`})}return r}function Ke(e){return n.join(e.rootDir,o.typescript.consumerTsconfigFileName)}function qe(e){return n.join(e.outDir,o.generated.tsconfigFileName)}function Je(e){let t=M(n.relative(e.rootDir,qe(e)));return Ye(t)||(t=`./${t}`),t}function Ye(e){return e.startsWith(`./`)||e.startsWith(`../`)}function Xe(e){return e instanceof Error?e.message:String(e)}function I(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}function L(e){return t.existsSync(e)?t.statSync(e).isFile()?R(e)?[e]:[]:z(e).filter(R).sort((e,t)=>e.localeCompare(t)):[]}function R(e){return/\.(?:ts|mts|cts|tsx)$/u.test(e)&&!/\.d\.(?:ts|mts|cts)$/u.test(e)}function z(e){let r=[],i=t.readdirSync(e,{withFileTypes:!0});for(let t of i){let i=n.join(e,t.name);if(t.isDirectory()){r.push(...z(i));continue}t.isFile()&&r.push(i)}return r}function Ze(e){let n=i.createSourceFile(e,t.readFileSync(e,`utf8`),i.ScriptTarget.Latest,!0),r=[],a=e=>{if(i.isImportDeclaration(e)&&i.isStringLiteral(e.moduleSpecifier)&&r.push({moduleSpecifier:e.moduleSpecifier.text,kind:`import`}),i.isExportDeclaration(e)&&e.moduleSpecifier&&i.isStringLiteral(e.moduleSpecifier)&&r.push({moduleSpecifier:e.moduleSpecifier.text,kind:`export`}),i.isCallExpression(e)&&e.expression.kind===i.SyntaxKind.ImportKeyword){let[t]=e.arguments;t&&i.isStringLiteral(t)&&r.push({moduleSpecifier:t.text,kind:`dynamic-import`})}i.forEachChild(e,a)};return a(n),r}function Qe(e){let n=i.createSourceFile(e,t.readFileSync(e,`utf8`),i.ScriptTarget.Latest,!0),r=!1,a=e=>{if(!r){if(i.isExportAssignment(e)&&!e.isExportEquals){r=!0;return}if($e(e)){r=!0;return}if(i.isExportDeclaration(e)&&e.exportClause&&i.isNamedExports(e.exportClause))for(let t of e.exportClause.elements){let e=t.name.text,n=t.propertyName?.text;if(e==="default"||n==="default"){r=!0;return}}i.forEachChild(e,a)}};return a(n),r}function $e(e){let t=i.canHaveModifiers(e)?i.getModifiers(e):void 0;if(!t)return!1;let n=t.some(e=>e.kind===i.SyntaxKind.ExportKeyword),r=t.some(e=>e.kind===i.SyntaxKind.DefaultKeyword);return n&&r}function et(e){return nt(e)}function tt(e){return`${e.filePath}\n import: ${e.importPath}\n ${e.message}`}function nt(e){let t=[],n=[...e.definitions.flatMap(e=>rt(e)),...e.apps.flatMap(e=>L(e.rootPath))];for(let r of n){let n=B(e,r);if(n)for(let i of Ze(r)){let a=it(e,n,r,i.moduleSpecifier);a&&t.push(a)}}return t}function rt(e){return[...e.api.rootPath?L(e.api.rootPath):[],...e.impl.rootPath?L(e.impl.rootPath):[]]}function it(e,t,n,r){let i=ct(e,r);if(i)return lt(t,i)?void 0:i.surface===`impl`&&t.kind!==`app`?V(e,n,r,`${H(t)} cannot import implementation target "${i.target}". Implementation imports are allowed only from app composition roots.`):ut(e,t.target,i.target)?void 0:V(e,n,r,`${H(t)} imports "${i.target}" but does not declare a dependency that allows it.`);if(r.startsWith(`.`)||r.startsWith(`/`))return at(e,t,n,r)}function at(e,t,n,r){let i=B(e,ot(n,r));if(!(!i||st(t,i)))return V(e,n,r,`${H(t)} imports ${H(i)} through a source path. Use an Archicat alias instead.`)}function B(e,t){let n=P(t);for(let t of e.definitions){if(t.api.rootPath&&N(n,P(t.api.rootPath)))return{kind:t.kind,name:t.name,surface:`api`,target:t.apiTarget,definition:t};if(t.impl.rootPath&&N(n,P(t.impl.rootPath)))return{kind:t.kind,name:t.name,surface:`impl`,target:t.implTarget,definition:t}}for(let t of e.apps)if(N(n,P(t.rootPath)))return{kind:`app`,name:t.name,surface:`app`,target:t.target,app:t}}function ot(e,t){return P(t.startsWith(`/`)?t:n.resolve(n.dirname(e),t))}function st(e,t){return e.kind===t.kind&&e.name===t.name}function ct(e,t){for(let n of e.definitions){if(n.implAlias&&(t===n.implAlias||t.startsWith(`${n.implAlias}/`)))return{kind:n.kind,name:n.name,surface:`impl`,target:n.implTarget};if(t===n.alias||t.startsWith(`${n.alias}/`))return{kind:n.kind,name:n.name,surface:`api`,target:n.apiTarget}}}function lt(e,t){return e.kind===t.kind&&e.name===t.name&&t.surface===`api`}function ut(e,t,n){let r=new Set,i=[t];for(;i.length>0;){let t=i.shift();if(t===n)return!0;if(!r.has(t)){r.add(t);for(let n of e.graph.dependencies.filter(e=>e.from===t))i.push(n.to)}}return!1}function V(e,t,n,r){return{filePath:F(e.rootDir,t),importPath:n,message:r}}function H(e){return e.kind===`app`?`App "${e.name}"`:`${dt(e.kind)} "${e.name}" ${e.surface}`}function dt(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}function ft(e){t.existsSync(e)&&t.rmSync(e,{recursive:!0,force:!0}),t.mkdirSync(e,{recursive:!0})}function U(e,r){t.mkdirSync(n.dirname(e),{recursive:!0}),t.writeFileSync(e,r,`utf8`)}function W(e,t){U(e,`${JSON.stringify(t,null,2)}\n`)}function pt(e){let t=[...e.modules.map(e=>e.apiTarget),...e.libraries.map(e=>e.apiTarget)],r=t,i=e.libraries.map(e=>e.apiTarget),a=i,o=e.graph.targets.map(e=>e.key),s=`import 'archicat';
3
3
 
4
4
  declare module 'archicat' {
5
- ${G(`ArchicatModuleApiDependencies`,n)}
5
+ ${G(`ArchicatModuleApiDependencies`,t)}
6
6
 
7
7
  ${G(`ArchicatModuleImplDependencies`,r)}
8
8
 
@@ -14,10 +14,10 @@ ${G(`ArchicatAppDependencies`,o)}
14
14
  }
15
15
 
16
16
  export {};
17
- `;U(t.join(e.outDir,`types`,`graph.d.ts`),s)}function G(e,t){return` interface ${e} {\n${Array.from(new Set(t)).sort((e,t)=>e.localeCompare(t)).map(e=>` '${e}': true;`).join(`
18
- `)}\n }`}function ht(e){for(let t of e)switch(t.kind){case`module`:gt(t);break;case`library`:_t(t);break}}function gt(e){K(e.api),q(e,`module`)}function _t(e){K(e.api),q(e,`library`)}function K(e){if(!e.rootPath){U(t.join(e.mirrorRootPath,`index.ts`),`${Y()}export {};
19
- `);return}let n=I(e.rootPath),r=new Set;for(let i of n){let n=M(t.relative(e.rootPath,i));r.add(n),J(t.join(e.mirrorRootPath,n),i)}r.has(`index.ts`)||U(t.join(e.mirrorRootPath,`index.ts`),`${Y()}export {};
20
- `)}function q(e,n){let r=e.impl.rootPath?vt(e.impl.rootPath):void 0;if(!r){let r=n===`module`?`ArchicatModuleImplementation`:`ArchicatLibraryImplementation`,i=`${Y()}
17
+ `;U(n.join(e.outDir,`types`,`graph.d.ts`),s)}function G(e,t){return` interface ${e} {\n${Array.from(new Set(t)).sort((e,t)=>e.localeCompare(t)).map(e=>` '${e}': true;`).join(`
18
+ `)}\n }`}function mt(e){for(let t of e)switch(t.kind){case`module`:ht(t);break;case`library`:gt(t);break}}function ht(e){K(e.api),q(e,`module`)}function gt(e){K(e.api),q(e,`library`)}function K(e){if(!e.rootPath){U(n.join(e.mirrorRootPath,`index.ts`),`${Y()}export {};
19
+ `);return}let t=L(e.rootPath),r=new Set;for(let i of t){let t=M(n.relative(e.rootPath,i));r.add(t),J(n.join(e.mirrorRootPath,t),i)}r.has(`index.ts`)||U(n.join(e.mirrorRootPath,`index.ts`),`${Y()}export {};
20
+ `)}function q(e,t){let r=e.impl.rootPath?_t(e.impl.rootPath):void 0;if(!r){let r=t===`module`?`ArchicatModuleImplementation`:`ArchicatLibraryImplementation`,i=`${Y()}
21
21
  export const ${r} = {
22
22
  name: '${e.name}',
23
23
  assemblies: [],
@@ -26,8 +26,8 @@ export const ${r} = {
26
26
  } as const;
27
27
 
28
28
  export default ${r};
29
- `;U(t.join(e.impl.mirrorRootPath,`index.ts`),i);return}J(t.join(e.impl.mirrorRootPath,`index.ts`),r)}function J(e,t){let n=Me(e,t),r=Ie(t)?`export { default } from '${n}';\n`:``;U(e,`${Y()}
29
+ `;U(n.join(e.impl.mirrorRootPath,`index.ts`),i);return}J(n.join(e.impl.mirrorRootPath,`index.ts`),r)}function J(e,t){let n=Fe(e,t),r=Qe(t)?`export { default } from '${n}';\n`:``;U(e,`${Y()}
30
30
  export * from '${n}';
31
- ${r}`)}function vt(e){for(let n of[`index.ts`,`index.mts`,`index.cts`,`index.tsx`]){let r=t.join(e,n);if(I(r).length>0)return r}}function Y(){return`// Mirrored by Archicat.
32
- `}function yt(e){W(t.join(e.reportsDir,a.generated.buildReportFileName),bt(e)),W(t.join(e.reportsDir,a.generated.graphReportFileName),xt(e))}function bt(e){return{generatedBy:`archicat`,schemaVersion:1,prefixes:e.config.prefixes,outputs:{outDir:F(e.rootDir,e.outDir),reportsDir:F(e.rootDir,e.reportsDir)},targets:e.graph.targets.map(e=>e.key),definitions:[...e.definitions.map(t=>St(e,t)),...e.apps.map(t=>({kind:t.kind,name:t.name,targets:{app:t.target},aliases:{},dependencies:t.dependencies,contractFilePath:F(e.rootDir,t.contractFilePath),source:{root:F(e.rootDir,t.rootPath)},mirror:{}}))],dependencies:e.graph.dependencies}}function xt(e){return{generatedBy:`archicat`,schemaVersion:1,targets:e.graph.targets.map(e=>e.key),dependencies:e.graph.dependencies}}function St(e,t){return{kind:t.kind,name:t.name,targets:{api:t.apiTarget,impl:t.implTarget},aliases:{api:t.alias,impl:e.apps.length>0?t.implAlias:void 0},dependencies:{api:t.api.dependencies,impl:t.impl.dependencies},contractFilePath:F(e.rootDir,t.contractFilePath),source:{root:F(e.rootDir,t.definitionDir),api:t.api.rootPath?F(e.rootDir,t.api.rootPath):void 0,impl:t.impl.rootPath?F(e.rootDir,t.impl.rootPath):void 0},mirror:{api:F(e.rootDir,t.api.mirrorRootPath),impl:F(e.rootDir,t.impl.mirrorRootPath)}}}function Ct(e){Nt(e.tsconfigPath),W(t.join(e.outDir,a.generated.tsconfigFileName),wt(e))}function wt(e){let t={compilerOptions:Tt(e),include:Dt(e)},n=Et(e),r=Ot(e),i=kt(e);return n&&(t.extends=n),r.length>0&&(t.exclude=r),i.length>0&&(t.files=i),t}function Tt(e){let t=jt(e),n=At(e);return Lt(e,t,n),{paths:{...t,...n}}}function Et(e){return e.tsconfigPath?Z(e.outDir,e.tsconfigPath):void 0}function Dt(e){return Mt([...X(e,e.config.typescript.tsConfig.include),a.generated.typesInclude])}function Ot(e){return X(e,e.config.typescript.tsConfig.exclude)}function kt(e){return X(e,e.config.typescript.tsConfig.files)}function At(e){let n={},r=e.apps.length>0;for(let i of e.definitions)n[i.alias]=[Z(e.outDir,t.join(i.api.mirrorRootPath,`index.ts`))],n[i.aliasGlob]=[Z(e.outDir,t.join(i.api.mirrorRootPath,`*`))],r&&i.implAlias&&i.implAliasGlob&&(n[i.implAlias]=[Z(e.outDir,t.join(i.impl.mirrorRootPath,`index.ts`))],n[i.implAliasGlob]=[Z(e.outDir,t.join(i.impl.mirrorRootPath,`*`))]);return n}function jt(e){let n={};for(let[r,i]of Object.entries(e.config.alias)){let a=t.isAbsolute(i)?i:t.resolve(e.rootDir,i);n[r]=[Z(e.outDir,a)]}return n}function X(e,n){return n.map(n=>{let r=t.isAbsolute(n)?n:t.resolve(e.rootDir,n);return Z(e.outDir,r)})}function Z(e,n){let r=M(t.relative(e,n));return r.startsWith(`.`)||(r=`./${r}`),r}function Mt(e){return[...new Set(e)]}function Nt(e){e&&Pt(e,new Set,new Set)}function Pt(e,n,r){let i=t.resolve(e);if(r.has(i))return;if(n.has(i))throw Error(`Circular tsconfig extends chain detected: ${i}`);n.add(i);let a=o(i),l=s(a,i);Ft(l,i),It(l,i);for(let e of c(a,i))Pt(e,n,r);n.delete(i),r.add(i)}function Ft(e,t){if(Object.hasOwn(e,`paths`))throw Error(`Base tsconfig compilerOptions.paths is not supported by Archicat. Move aliases into archicat.config.ts alias: ${t}`)}function It(e,t){if(Object.hasOwn(e,`baseUrl`))throw Error(`Base tsconfig compilerOptions.baseUrl is not supported by Archicat. Move aliases into archicat.config.ts alias: ${t}`)}function Lt(e,t,n){let r=Object.keys(t),i=Object.keys(n),a=Object.values(e.config.prefixes);for(let e of r){if(i.includes(e))throw Error(`Alias conflict: archicat.config.ts alias already defines "${e}", but Archicat needs it.`);for(let t of a)if(e===t||e===`${t}/*`||e.startsWith(`${t}/`))throw Error(`Alias conflict: archicat.config.ts alias "${e}" is inside Archicat reserved prefix "${t}". Remove the alias or configure another Archicat prefix.`)}}async function Rt(e){let r=await j(e);if(t.resolve(r.outDir)===t.resolve(r.rootDir))throw Error(`Archicat outDir cannot be the project root.`);return pt(r.outDir),n.mkdirSync(t.join(r.outDir,`modules`),{recursive:!0}),n.mkdirSync(t.join(r.outDir,`libraries`),{recursive:!0}),n.mkdirSync(t.join(r.outDir,`types`),{recursive:!0}),n.mkdirSync(r.reportsDir,{recursive:!0}),ht(r.definitions),mt(r),Ct(r),yt(r),r}async function zt(e){let t=await Rt(e.config);return z([`Mirrored modules: ${t.modules.length}`,`Mirrored libraries: ${t.libraries.length}`,`Resolved apps: ${t.apps.length}`])}function Bt(e){let t=[`Modules: ${e.modules.length}`,``];for(let n of e.modules)t.push(n.name),t.push(` api: ${n.apiTarget}`),Q(t,e.graph.dependencies.filter(e=>e.from===n.apiTarget),` api dependsOn`),t.push(` impl: ${n.implTarget}`),Q(t,e.graph.dependencies.filter(e=>e.from===n.implTarget),` impl dependsOn`),t.push(``);t.push(`Libraries: ${e.libraries.length}`),e.libraries.length>0&&t.push(``);for(let n of e.libraries)t.push(n.name),t.push(` api: ${n.apiTarget}`),Q(t,e.graph.dependencies.filter(e=>e.from===n.apiTarget),` api dependsOn`),t.push(` impl: ${n.implTarget}`),Q(t,e.graph.dependencies.filter(e=>e.from===n.implTarget),` impl dependsOn`),t.push(``);t.push(`Apps: ${e.apps.length}`),e.apps.length>0&&t.push(``);for(let n of e.apps)t.push(n.name),t.push(` app: ${n.target}`),Q(t,e.graph.dependencies.filter(e=>e.from===n.target),` dependsOn`),t.push(``);return Vt(t)}function Q(e,t,n){if(t.length===0){e.push(`${n}: none`);return}e.push(`${n}:`);for(let n of t){let t=n.origin===`derived`?` (derived)`:``;e.push(` ${n.to}${t}`)}}function Vt(e){let t=[...e];for(;t.at(-1)===``;)t.pop();return t}async function Ht(e){return{exitCode:0,lines:Bt(await j(e.config)).map(e=>({kind:`info`,message:e}))}}async function Ut(e=process.argv.slice(2)){let[t,...n]=e;try{let e=await Wt(t,Gt(n));if(!e)return;Kt(e),process.exitCode=e.exitCode}catch(e){$({kind:`error`,message:e instanceof Error?e.message:String(e)}),process.exitCode=1}}async function Wt(e,t){switch(e){case`generate`:return zt(t);case`check`:return Ze(t);case`graph`:return Ht(t);case`doctor`:return ft(t);case`help`:case`--help`:case`-h`:case void 0:qt();return;default:return $({kind:`error`,message:`Unknown command: ${e}`}),qt(),{exitCode:1,lines:[]}}}function Gt(e){let t={};for(let n=0;n<e.length;n+=1){let r=e[n];if(r===`--config`||r===`-c`){let i=e[n+1];if(!i)throw Error(`${r} requires a value.`);t.config=i,n+=1}}return t}function Kt(e){for(let t of e.lines)$(t)}function qt(){console.log([`Archicat`,``,`Usage:`,` archicat generate [--config archicat.config.ts]`,` archicat check [--config archicat.config.ts]`,` archicat graph [--config archicat.config.ts]`,` archicat doctor [--config archicat.config.ts]`,``].join(`
33
- `))}function $(e){switch(e.kind){case`success`:console.log(`✓ ${e.message}`);return;case`warning`:console.warn(`! ${e.message}`);return;case`error`:console.error(`✗ ${e.message}`);return;case`info`:console.log(e.message);return}}export{Ut as runMain};
31
+ ${r}`)}function _t(e){for(let t of[`index.ts`,`index.mts`,`index.cts`,`index.tsx`]){let r=n.join(e,t);if(L(r).length>0)return r}}function Y(){return`// Mirrored by Archicat.
32
+ `}function vt(e){W(n.join(e.reportsDir,o.generated.buildReportFileName),yt(e)),W(n.join(e.reportsDir,o.generated.graphReportFileName),bt(e))}function yt(e){return{generatedBy:`archicat`,schemaVersion:1,prefixes:e.config.prefixes,outputs:{outDir:F(e.rootDir,e.outDir),reportsDir:F(e.rootDir,e.reportsDir)},targets:e.graph.targets.map(e=>e.key),definitions:[...e.definitions.map(t=>xt(e,t)),...e.apps.map(t=>({kind:t.kind,name:t.name,targets:{app:t.target},aliases:{},dependencies:t.dependencies,contractFilePath:F(e.rootDir,t.contractFilePath),source:{root:F(e.rootDir,t.rootPath)},mirror:{}}))],dependencies:e.graph.dependencies}}function bt(e){return{generatedBy:`archicat`,schemaVersion:1,targets:e.graph.targets.map(e=>e.key),dependencies:e.graph.dependencies}}function xt(e,t){return{kind:t.kind,name:t.name,targets:{api:t.apiTarget,impl:t.implTarget},aliases:{api:t.alias,impl:e.apps.length>0?t.implAlias:void 0},dependencies:{api:t.api.dependencies,impl:t.impl.dependencies},contractFilePath:F(e.rootDir,t.contractFilePath),source:{root:F(e.rootDir,t.definitionDir),api:t.api.rootPath?F(e.rootDir,t.api.rootPath):void 0,impl:t.impl.rootPath?F(e.rootDir,t.impl.rootPath):void 0},mirror:{api:F(e.rootDir,t.api.mirrorRootPath),impl:F(e.rootDir,t.impl.mirrorRootPath)}}}function St(e){Mt(e.tsconfigPath),W(n.join(e.outDir,o.generated.tsconfigFileName),Ct(e))}function Ct(e){let t={compilerOptions:wt(e),include:Et(e)},n=Tt(e),r=Dt(e),i=Ot(e);return n&&(t.extends=n),r.length>0&&(t.exclude=r),i.length>0&&(t.files=i),t}function wt(e){let t=At(e),n=kt(e);return It(e,t,n),{paths:{...t,...n}}}function Tt(e){return e.tsconfigPath?Z(e.outDir,e.tsconfigPath):void 0}function Et(e){return jt([...X(e,e.config.typescript.tsConfig.include),o.generated.typesInclude])}function Dt(e){return X(e,e.config.typescript.tsConfig.exclude)}function Ot(e){return X(e,e.config.typescript.tsConfig.files)}function kt(e){let t={},r=e.apps.length>0;for(let i of e.definitions)t[i.alias]=[Z(e.outDir,n.join(i.api.mirrorRootPath,`index.ts`))],t[i.aliasGlob]=[Z(e.outDir,n.join(i.api.mirrorRootPath,`*`))],r&&i.implAlias&&i.implAliasGlob&&(t[i.implAlias]=[Z(e.outDir,n.join(i.impl.mirrorRootPath,`index.ts`))],t[i.implAliasGlob]=[Z(e.outDir,n.join(i.impl.mirrorRootPath,`*`))]);return t}function At(e){let t={};for(let[r,i]of Object.entries(e.config.alias)){let a=n.isAbsolute(i)?i:n.resolve(e.rootDir,i);t[r]=[Z(e.outDir,a)]}return t}function X(e,t){return t.map(t=>{let r=n.isAbsolute(t)?t:n.resolve(e.rootDir,t);return Z(e.outDir,r)})}function Z(e,t){let r=M(n.relative(e,t));return r.startsWith(`.`)||(r=`./${r}`),r}function jt(e){return[...new Set(e)]}function Mt(e){e&&Nt(e,new Set,new Set)}function Nt(e,t,r){let i=n.resolve(e);if(r.has(i))return;if(t.has(i))throw Error(`Circular tsconfig extends chain detected: ${i}`);t.add(i);let a=s(i),o=c(a,i);Pt(o,i),Ft(o,i);for(let e of l(a,i))Nt(e,t,r);t.delete(i),r.add(i)}function Pt(e,t){if(Object.hasOwn(e,`paths`))throw Error(`Base tsconfig compilerOptions.paths is not supported by Archicat. Move aliases into archicat.config.ts alias: ${t}`)}function Ft(e,t){if(Object.hasOwn(e,`baseUrl`))throw Error(`Base tsconfig compilerOptions.baseUrl is not supported by Archicat. Move aliases into archicat.config.ts alias: ${t}`)}function It(e,t,n){let r=Object.keys(t),i=Object.keys(n),a=Object.values(e.config.prefixes);for(let e of r){if(i.includes(e))throw Error(`Alias conflict: archicat.config.ts alias already defines "${e}", but Archicat needs it.`);for(let t of a)if(e===t||e===`${t}/*`||e.startsWith(`${t}/`))throw Error(`Alias conflict: archicat.config.ts alias "${e}" is inside Archicat reserved prefix "${t}". Remove the alias or configure another Archicat prefix.`)}}function Lt(e){Rt(e),ft(e.outDir),t.mkdirSync(n.join(e.outDir,`modules`),{recursive:!0}),t.mkdirSync(n.join(e.outDir,`libraries`),{recursive:!0}),t.mkdirSync(n.join(e.outDir,`types`),{recursive:!0}),t.mkdirSync(e.reportsDir,{recursive:!0}),mt(e.definitions),pt(e),St(e),vt(e)}function Rt(e){if(n.resolve(e.outDir)===n.resolve(e.rootDir))throw Error(`Archicat outDir cannot be the project root.`)}function zt(){return{name:`doctor`,async run(e){let t=Ie(await e.getProject());if(t.length===0)return Ht(`doctor`,`Project diagnostics passed.`);let n=t.some(e=>e.severity===`error`);return{exitCode:+!!n,lines:[{kind:n?`error`:`warning`,message:Q(`doctor`,n?`Project diagnostics failed.`:`Project diagnostics completed with warnings.`)},...t.map(e=>({kind:e.severity===`error`?`error`:`warning`,message:` ${e.message}`}))]}}}}function Bt(){return{name:`validate`,async run(e){let t=et(await e.getProject());return t.length===0?Ht(`validate`,`Architecture boundaries passed.`):{exitCode:1,lines:[{kind:`error`,message:Q(`validate`,`Architecture validation failed.`)},...t.map(e=>({kind:`error`,message:tt(e)}))]}}}}function Vt(){return{name:`build`,async run(e){let t=await e.getProject();return Lt(t),{exitCode:0,lines:[{kind:`success`,message:Q(`build`,`Mirrored ${t.modules.length} modules.`)},{kind:`success`,message:Q(`build`,`Mirrored ${t.libraries.length} libraries.`)},{kind:`success`,message:Q(`build`,`Resolved ${t.apps.length} apps.`)}]}}}}function Ht(e,t){return{exitCode:0,lines:[{kind:`success`,message:Q(e,t)}]}}function Q(e,t){return`${e.padEnd(10,` `)} ${t}`}async function Ut(e){return await j.build(`build`).use(zt()).use(Bt()).use(Vt()).run(e)}async function Wt(e){return await j.build(`validate`).use(Bt()).run(e)}async function Gt(e){return await Wt(e)}async function Kt(e){return await j.build(`doctor`).use(zt()).run(e)}async function qt(e){return await Ut(e)}function Jt(e){let t=[`Modules: ${e.modules.length}`,``];for(let n of e.modules)t.push(n.name),t.push(` api: ${n.apiTarget}`),$(t,e.graph.dependencies.filter(e=>e.from===n.apiTarget),` api dependsOn`),t.push(` impl: ${n.implTarget}`),$(t,e.graph.dependencies.filter(e=>e.from===n.implTarget),` impl dependsOn`),t.push(``);t.push(`Libraries: ${e.libraries.length}`),e.libraries.length>0&&t.push(``);for(let n of e.libraries)t.push(n.name),t.push(` api: ${n.apiTarget}`),$(t,e.graph.dependencies.filter(e=>e.from===n.apiTarget),` api dependsOn`),t.push(` impl: ${n.implTarget}`),$(t,e.graph.dependencies.filter(e=>e.from===n.implTarget),` impl dependsOn`),t.push(``);t.push(`Apps: ${e.apps.length}`),e.apps.length>0&&t.push(``);for(let n of e.apps)t.push(n.name),t.push(` app: ${n.target}`),$(t,e.graph.dependencies.filter(e=>e.from===n.target),` dependsOn`),t.push(``);return Yt(t)}function $(e,t,n){if(t.length===0){e.push(`${n}: none`);return}e.push(`${n}:`);for(let n of t){let t=n.origin===`derived`?` (derived)`:``;e.push(` ${n.to}${t}`)}}function Yt(e){let t=[...e];for(;t.at(-1)===``;)t.pop();return t}async function Xt(e){return{exitCode:0,lines:Jt(await Ne(e.config)).map(e=>({kind:`info`,message:e}))}}var Zt=class{result(e){for(let t of e.lines)this.line(t)}line(e){if(e.message.length===0){a.log(``);return}switch(e.kind){case`success`:a.success(e.message);return;case`warning`:a.warn(e.message);return;case`error`:a.error(e.message);return;case`info`:a.info(e.message);return}}help(){a.log([`Archicat`,``,`Usage:`,` archicat build [--config archicat.config.ts]`,` archicat validate [--config archicat.config.ts]`,` archicat graph [--config archicat.config.ts]`,` archicat doctor [--config archicat.config.ts]`,``,`Aliases:`,` archicat generate -> archicat build`,` archicat check -> archicat validate`,``].join(`
33
+ `))}};async function Qt(e=process.argv.slice(2)){let[t,...n]=e,r=new Zt;try{let e=await $t(t,en(n),r);if(!e)return;r.result(e),process.exitCode=e.exitCode}catch(e){r.line({kind:`error`,message:e instanceof Error?e.message:String(e)}),process.exitCode=1}}async function $t(e,t,n){switch(e){case`build`:return await Ut(t);case`generate`:return await qt(t);case`validate`:return await Wt(t);case`check`:return await Gt(t);case`graph`:return await Xt(t);case`doctor`:return await Kt(t);case`help`:case`--help`:case`-h`:case void 0:n.help();return;default:return n.line({kind:`error`,message:`Unknown command: ${e}`}),n.help(),{exitCode:1,lines:[]}}}function en(e){let t={};for(let n=0;n<e.length;n+=1){let r=e[n];if(r===`--config`||r===`-c`){let i=e[n+1];if(!i)throw Error(`${r} requires a value.`);t.config=i,n+=1}}return t}export{Qt as runMain};
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "archicat",
3
- "version": "0.0.7",
4
- "description": "M²: modular mirroring for clean architecture.",
3
+ "version": "0.0.8",
4
+ "description": "Modular mirroring (M²) for clean architecture.",
5
5
  "keywords": [
6
6
  "m2",
7
- "modular-mirroring",
7
+ "mirroring",
8
+ "modular",
8
9
  "module-system",
9
- "clean-architecture",
10
- "architecture"
10
+ "clean-architecture"
11
11
  ],
12
12
  "license": "MIT",
13
13
  "author": "Simon Rastislav Kovačič",
@@ -38,6 +38,7 @@
38
38
  "typecheck": "tsc -p tsconfig.json --noEmit"
39
39
  },
40
40
  "dependencies": {
41
+ "consola": "3.4.2",
41
42
  "jiti": "2.7.0",
42
43
  "typescript": "6.0.3"
43
44
  },
@@ -56,5 +57,5 @@
56
57
  "publishConfig": {
57
58
  "registry": "https://registry.npmjs.org/"
58
59
  },
59
- "gitHead": "557aec7d9b698eb46a1ab1e012afcf78394cbf91"
60
+ "gitHead": "a12dcca4618ace0754ea2097848bc818ffd21a14"
60
61
  }