archicat 0.0.6 → 0.0.7

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
@@ -125,7 +125,13 @@ import { MediaRepository } from '../../media/impl/repository';
125
125
  import { defineArchicatConfig } from 'archicat';
126
126
 
127
127
  export default defineArchicatConfig({
128
- tsconfig: './tsconfig.json',
128
+ typescript: {
129
+ tsConfig: {
130
+ extends: '../../tsconfig.node.json',
131
+ include: ['bootstrap.ts', 'src/app', 'src/libraries', 'src/modules', 'types'],
132
+ exclude: ['node_modules', 'dist'],
133
+ },
134
+ },
129
135
 
130
136
  alias: {
131
137
  '@app': './src/app/index.ts',
@@ -146,16 +152,20 @@ export default defineArchicatConfig({
146
152
  });
147
153
  ```
148
154
 
149
- Root `tsconfig.json`:
155
+ App `tsconfig.json`:
150
156
 
151
157
  ```json
152
158
  {
153
- "extends": "./.archicat/tsconfig.json"
159
+ "extends": "./.archicat/tsconfig.json",
160
+ "compilerOptions": {
161
+ "rootDir": ".",
162
+ "outDir": "./dist"
163
+ }
154
164
  }
155
165
  ```
156
166
 
157
167
  > [!IMPORTANT]
158
- > Put user aliases in `archicat.config.ts`, not in root `compilerOptions.paths`.
168
+ > Generated `.archicat/tsconfig.json` extends `typescript.tsConfig.extends`, therefore put user aliases in `archicat.config.ts`, not in `compilerOptions.paths`.
159
169
 
160
170
  ## Output
161
171
 
@@ -1,34 +1,33 @@
1
- import e from"node:path";import t from"node:fs";import{createJiti as n}from"jiti";import r from"typescript";const i=Object.freeze({root:`.`,outDir:`.archicat`,alias: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([])})});async function a(n=`archicat.config.ts`){let r=process.cwd(),i=e.resolve(r,n);if(!t.existsSync(i))throw Error(`Archicat config was not found: ${i}`);let a=await o(i,r);l(a,i);let u=s(a),d=e.resolve(r,u.root),f=e.resolve(d,u.outDir),p=e.resolve(f,`reports`),m=c(d,u.tsconfig);return{configFilePath:i,rootDir:d,outDir:f,reportsDir:p,...m?{tsconfigPath:m}:{},config:a,resolvedConfig:u}}async function o(e,t){return await n(t,{interopDefault:!0,extensions:[`.js`,`.cjs`,`.mjs`,`.ts`,`.cts`,`.mts`,`.json`]}).import(e,{default:!0})}function s(e){return{root:e.root??i.root,outDir:e.outDir??i.outDir,alias:{...i.alias,...e.alias??{}},...e.tsconfig===void 0?{}:{tsconfig:e.tsconfig},prefixes:{module:e.prefixes?.module??i.prefixes.module,library:e.prefixes?.library??i.prefixes.library},modules:{include:[...e.modules?.include??i.modules.include]},libraries:{include:[...e.libraries?.include??i.libraries.include]},apps:{include:[...e.apps?.include??i.apps.include]}}}function c(n,r){if(r){let i=e.resolve(n,r);if(!t.existsSync(i))throw Error(`Configured Archicat tsconfig was not found: ${i}`);return i}return[`tsconfig.base.json`,`tsconfig.json`].map(t=>e.join(n,t)).find(e=>t.existsSync(e))}function l(e,t){if(typeof e!=`object`||!e)throw Error(`Invalid Archicat config: ${t}`);let n=e;u(n.root,`root`,t),u(n.outDir,`outDir`,t),u(n.tsconfig,`tsconfig`,t),d(n.modules?.include,`modules.include`,t),d(n.libraries?.include,`libraries.include`,t),d(n.apps?.include,`apps.include`,t),p(n.alias,`alias`,t),f(n.prefixes?.module,`prefixes.module`,t),f(n.prefixes?.library,`prefixes.library`,t)}function u(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 d(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 f(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 p(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 m(e,t,n){let r=t.flatMap(t=>ee(e,t,n));return Array.from(new Set(r)).sort((e,t)=>e.localeCompare(t))}function ee(n,r,i){let a=e.resolve(n,r);if(r.includes(`*`))return te(n,r).filter(t=>e.basename(t)===i);if(!t.existsSync(a))return[];let o=t.statSync(a);return o.isFile()?e.basename(a)===i?[a]:[]:o.isDirectory()?h(a,i):[]}function h(n,r){let i=[],a=t.readdirSync(n,{withFileTypes:!0});for(let t of a){if(re(t.name))continue;let a=e.join(n,t.name);if(t.isDirectory()){i.push(...h(a,r));continue}t.isFile()&&t.name===r&&i.push(a)}return i}function te(n,r){let i=e.resolve(n,r).split(e.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(e.sep)||e.sep,s=i[a]??`*`,c=i.slice(a+1),l=ne(s);return t.existsSync(o)?t.readdirSync(o,{withFileTypes:!0}).filter(e=>e.isDirectory()).filter(e=>l.test(e.name)).map(t=>e.join(o,t.name,...c)).filter(e=>t.existsSync(e)&&t.statSync(e).isFile()):[]}function ne(e){let t=e.replace(/[.+?^${}()|[\]\\]/gu,`\\$&`).replace(/\*/gu,`.*`);return RegExp(`^${t}$`,`u`)}function re(e){return[`node_modules`,`.git`,`.archicat`,`archicat-report`,`dist`,`build`,`coverage`].includes(e)}async function g(e,t){switch(t){case`module`:return ie(e);case`library`:return ae(e);case`app`:return oe(e)}}async function ie(t){let n=await _(t,e.dirname(t));return v(n,t,`module`),{kind:`module`,contractFilePath:t,definitionDir:e.dirname(t),contract:n}}async function ae(t){let n=await _(t,e.dirname(t));return v(n,t,`library`),{kind:`library`,contractFilePath:t,definitionDir:e.dirname(t),contract:n}}async function oe(t){let n=await _(t,e.dirname(t));return v(n,t,`app`),{kind:`app`,contractFilePath:t,definitionDir:e.dirname(t),contract:n}}async function _(e,t){return await n(t,{interopDefault:!0,extensions:[`.js`,`.cjs`,`.mjs`,`.ts`,`.cts`,`.mts`,`.json`]}).import(e,{default:!0})}function v(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${se(n)}(...): ${t}`);if(typeof r.name!=`string`||r.name.trim()===``)throw Error(`Archicat ${n} must define a non-empty name: ${t}`);if(n===`app`){x(r.root,`root`,t),b(r.dependencies,t,n);return}let i=r;y(i.api,`api`,t,n),y(i.impl,`impl`,t,n)}function y(e,t,n,r){if(typeof e!=`object`||!e)throw Error(`Archicat ${r}.${t} must be a surface object: ${n}`);x(e.root,`${t}.root`,n),b(e.dependencies,n,`${r}.${t}`)}function b(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 x(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 se(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}function ce(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())S(e,t,n,r,[])}function S(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)??[])S(a,t,n,r,[...i,e]);n.delete(e),r.add(e)}}function le(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 ue(e){return`${e.kind}.${e.surface}`}function C(e,t,n){let r=le(t);if(!r)throw Error(`${w(e)} declares invalid dependency target "${t}".`);if(!n.has(t))throw Error(`${w(e)} declares unknown dependency "${t}".`);if(e.kind===r.kind&&e.name===r.name)throw Error(`${w(e)} cannot depend on itself: ${t}`);if(!de(e,r))throw Error(`${w(e)} cannot depend on ${ue(r)} target "${t}".`)}function de(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 w(e){return e.kind===`app`?`App "${e.name}"`:`${fe(e.kind)} "${e.name}" ${e.surface}`}function fe(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}function pe(e,t){let n=t.filter(e=>e.kind===`module`).map(t=>me(e,t)),r=t.filter(e=>e.kind===`library`).map(t=>he(e,t)),i=t.filter(e=>e.kind===`app`).map(e=>ge(e)),a=[...n,...r];ve([...a,...i]);let o=_e(a,i);return ye(a,i,o.targets),ce(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 me(t,n){let{contract:r,contractFilePath:i,definitionDir:a}=n;D(r.name,i,`module`);let o=r.api.root?E(a,r.api.root,`api`,r.name):void 0,s=r.impl.root?E(a,r.impl.root,`impl`,r.name):void 0,c=`${t.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:T(o,r.api.dependencies,e.join(t.outDir,`modules`,r.name,`api`)),impl:T(s,r.impl.dependencies,e.join(t.outDir,`modules`,r.name,`impl`))}}function he(t,n){let{contract:r,contractFilePath:i,definitionDir:a}=n;D(r.name,i,`library`);let o=r.api.root?E(a,r.api.root,`api`,r.name):void 0,s=r.impl.root?E(a,r.impl.root,`impl`,r.name):void 0,c=`${t.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:T(o,r.api.dependencies,e.join(t.outDir,`libraries`,r.name,`api`)),impl:T(s,r.impl.dependencies,e.join(t.outDir,`libraries`,r.name,`impl`))}}function ge(e){let{contract:t,contractFilePath:n,definitionDir:r}=e;return D(t.name,n,`app`),{kind:`app`,name:t.name,target:`app.${t.name}`,contractFilePath:n,definitionDir:r,rootPath:t.root?E(r,t.root,`app`,t.name):r,dependencies:[...t.dependencies]}}function T(e,t,n){return{...e?{rootPath:e}:{},mirrorRootPath:n,dependencies:[...t]}}function E(n,r,i,a){let o=e.resolve(n,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 _e(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 D(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 ve(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 ye(e,t,n){let r=new Set(n.map(e=>e.key));for(let t of e){for(let e of t.api.dependencies)C(O(t,`api`),e,r);for(let e of t.impl.dependencies)C(O(t,`impl`),e,r)}for(let e of t)for(let t of e.dependencies)C({kind:`app`,name:e.name,surface:`app`,target:e.target},t,r)}function O(e,t){return{kind:e.kind,name:e.name,surface:t,target:t===`api`?e.apiTarget:e.implTarget}}async function k(e){let t=await a(e),n=m(t.rootDir,t.resolvedConfig.modules.include,`archicat.module.ts`),r=m(t.rootDir,t.resolvedConfig.libraries.include,`archicat.library.ts`),i=m(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 pe(t,[...await Promise.all(n.map(e=>g(e,`module`))),...await Promise.all(r.map(e=>g(e,`library`))),...await Promise.all(i.map(e=>g(e,`app`)))])}function A(t){return t.split(e.sep).join(`/`)}function be(t,n){let r=e.dirname(t),i=e.parse(n),a=e.join(i.dir,i.name),o=A(e.relative(r,a));return o.startsWith(`.`)||(o=`./${o}`),`${o}.js`}function j(t,n){let r=e.relative(n,t);return r===``||!!r&&!r.startsWith(`..`)&&!e.isAbsolute(r)}function M(e){return e.replace(/\.(?:js|mjs|cjs|ts|mts|cts|tsx)$/u,``)}function N(t,n){return A(e.relative(t,n))}function P(e){return t.existsSync(e)?t.statSync(e).isFile()?F(e)?[e]:[]:I(e).filter(F).sort((e,t)=>e.localeCompare(t)):[]}function F(e){return/\.(?:ts|mts|cts|tsx)$/u.test(e)&&!/\.d\.(?:ts|mts|cts)$/u.test(e)}function I(n){let r=[],i=t.readdirSync(n,{withFileTypes:!0});for(let t of i){let i=e.join(n,t.name);if(t.isDirectory()){r.push(...I(i));continue}t.isFile()&&r.push(i)}return r}function xe(e){let n=r.createSourceFile(e,t.readFileSync(e,`utf8`),r.ScriptTarget.Latest,!0),i=[],a=e=>{if(r.isImportDeclaration(e)&&r.isStringLiteral(e.moduleSpecifier)&&i.push({moduleSpecifier:e.moduleSpecifier.text,kind:`import`}),r.isExportDeclaration(e)&&e.moduleSpecifier&&r.isStringLiteral(e.moduleSpecifier)&&i.push({moduleSpecifier:e.moduleSpecifier.text,kind:`export`}),r.isCallExpression(e)&&e.expression.kind===r.SyntaxKind.ImportKeyword){let[t]=e.arguments;t&&r.isStringLiteral(t)&&i.push({moduleSpecifier:t.text,kind:`dynamic-import`})}r.forEachChild(e,a)};return a(n),i}function Se(e){let n=r.createSourceFile(e,t.readFileSync(e,`utf8`),r.ScriptTarget.Latest,!0),i=!1,a=e=>{if(!i){if(r.isExportAssignment(e)&&!e.isExportEquals){i=!0;return}if(Ce(e)){i=!0;return}if(r.isExportDeclaration(e)&&e.exportClause&&r.isNamedExports(e.exportClause))for(let t of e.exportClause.elements){let e=t.name.text,n=t.propertyName?.text;if(e==="default"||n==="default"){i=!0;return}}r.forEachChild(e,a)}};return a(n),i}function Ce(e){let t=r.canHaveModifiers(e)?r.getModifiers(e):void 0;if(!t)return!1;let n=t.some(e=>e.kind===r.SyntaxKind.ExportKeyword),i=t.some(e=>e.kind===r.SyntaxKind.DefaultKeyword);return n&&i}async function we(e){return Te(await k(e))}function Te(e){let t=[],n=[...e.definitions.flatMap(e=>Ee(e)),...e.apps.flatMap(e=>P(e.rootPath))];for(let r of n){let n=L(e,r);if(n)for(let i of xe(r)){let a=De(e,n,r,i.moduleSpecifier);a&&t.push(a)}}return t}function Ee(e){return[...e.api.rootPath?P(e.api.rootPath):[],...e.impl.rootPath?P(e.impl.rootPath):[]]}function De(e,t,n,r){let i=je(e,r);if(i)return Me(t,i)?void 0:i.surface===`impl`&&t.kind!==`app`?R(e,n,r,`${z(t)} cannot import implementation target "${i.target}". Implementation imports are allowed only from app composition roots.`):Ne(e,t.target,i.target)?void 0:R(e,n,r,`${z(t)} imports "${i.target}" but does not declare a dependency that allows it.`);if(r.startsWith(`.`)||r.startsWith(`/`))return Oe(e,t,n,r)}function Oe(e,t,n,r){let i=L(e,ke(n,r));if(!(!i||Ae(t,i)))return R(e,n,r,`${z(t)} imports ${z(i)} through a source path. Use an Archicat alias instead.`)}function L(e,t){let n=M(t);for(let t of e.definitions){if(t.api.rootPath&&j(n,M(t.api.rootPath)))return{kind:t.kind,name:t.name,surface:`api`,target:t.apiTarget,definition:t};if(t.impl.rootPath&&j(n,M(t.impl.rootPath)))return{kind:t.kind,name:t.name,surface:`impl`,target:t.implTarget,definition:t}}for(let t of e.apps)if(j(n,M(t.rootPath)))return{kind:`app`,name:t.name,surface:`app`,target:t.target,app:t}}function ke(t,n){return M(n.startsWith(`/`)?n:e.resolve(e.dirname(t),n))}function Ae(e,t){return e.kind===t.kind&&e.name===t.name}function je(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 Me(e,t){return e.kind===t.kind&&e.name===t.name&&t.surface===`api`}function Ne(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 R(e,t,n,r){return{filePath:N(e.rootDir,t),importPath:n,message:r}}function z(e){return e.kind===`app`?`App "${e.name}"`:`${Pe(e.kind)} "${e.name}" ${e.surface}`}function Pe(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}function B(e){return{exitCode:0,lines:e.map(e=>({kind:`success`,message:e}))}}function Fe(e){return{exitCode:1,lines:e.map(e=>({kind:`error`,message:e}))}}async function Ie(e){let t=await we(e.config);return t.length===0?B([`Architecture check passed.`]):Fe(t.map(e=>`${e.filePath}\n import: ${e.importPath}\n ${e.message}`))}async function Le(e){let t=await k(e);return[...Re(t),...ze(t),...Be(t)]}function Re(n){let r=e.join(n.outDir,`tsconfig.json`);return t.existsSync(r)?[]:[{severity:`warning`,message:`Generated tsconfig does not exist yet: ${r}. Run archicat generate.`}]}function ze(n){let i=e.join(n.rootDir,`tsconfig.json`);if(!t.existsSync(i))return[{severity:`warning`,message:`Root tsconfig.json was not found: ${i}`}];let a=r.parseConfigFileTextToJson(i,t.readFileSync(i,`utf8`));if(a.error)return[{severity:`warning`,message:`Failed to parse root tsconfig.json: ${r.flattenDiagnosticMessageText(a.error.messageText,`
2
- `)}`}];let o=a.config,s=[];return o.extends!==`./.archicat/tsconfig.json`&&o.extends!==`.archicat/tsconfig.json`&&s.push({severity:`warning`,message:`Root tsconfig.json should extend ./.archicat/tsconfig.json for Archicat aliases to work like Nuxt.`}),(o.compilerOptions?.rootDir===`src`||o.compilerOptions?.rootDir===`./src`)&&s.push({severity:`warning`,message:`compilerOptions.rootDir is set to src. Generated .archicat files live outside src and may break tsc.`}),o.compilerOptions?.paths!==void 0&&s.push({severity:`warning`,message:`compilerOptions.paths should move to archicat.config.ts alias. Root tsconfig paths can override generated Archicat aliases.`}),s}function Be(n){let r=[];for(let i of n.definitions){let n=e.join(i.definitionDir,`api`),a=e.join(i.definitionDir,`impl`);!i.api.rootPath&&t.existsSync(n)&&r.push({severity:`warning`,message:`${V(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:`${V(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 V(e){return`${e.charAt(0).toUpperCase()}${e.slice(1)}`}async function Ve(e){let t=await Le(e.config);return t.length===0?B([`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 He(e){t.existsSync(e)&&t.rmSync(e,{recursive:!0,force:!0}),t.mkdirSync(e,{recursive:!0})}function H(n,r){t.mkdirSync(e.dirname(n),{recursive:!0}),t.writeFileSync(n,r,`utf8`)}function U(e,t){H(e,`${JSON.stringify(t,null,2)}\n`)}function Ue(t){let n=[...t.modules.map(e=>e.apiTarget),...t.libraries.map(e=>e.apiTarget)],r=n,i=t.libraries.map(e=>e.apiTarget),a=i,o=t.graph.targets.map(e=>e.key),s=`import 'archicat';
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';
3
3
 
4
4
  declare module 'archicat' {
5
- ${W(`ArchicatModuleApiDependencies`,n)}
5
+ ${G(`ArchicatModuleApiDependencies`,n)}
6
6
 
7
- ${W(`ArchicatModuleImplDependencies`,r)}
7
+ ${G(`ArchicatModuleImplDependencies`,r)}
8
8
 
9
- ${W(`ArchicatLibraryApiDependencies`,i)}
9
+ ${G(`ArchicatLibraryApiDependencies`,i)}
10
10
 
11
- ${W(`ArchicatLibraryImplDependencies`,a)}
11
+ ${G(`ArchicatLibraryImplDependencies`,a)}
12
12
 
13
- ${W(`ArchicatAppDependencies`,o)}
13
+ ${G(`ArchicatAppDependencies`,o)}
14
14
  }
15
15
 
16
16
  export {};
17
- `;H(e.join(t.outDir,`types`,`graph.d.ts`),s)}function W(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 We(e){for(let t of e)switch(t.kind){case`module`:Ge(t);break;case`library`:Ke(t);break}}function Ge(e){G(e.api),K(e,`module`)}function Ke(e){G(e.api),K(e,`library`)}function G(t){if(!t.rootPath){H(e.join(t.mirrorRootPath,`index.ts`),`${J()}export {};
19
- `);return}let n=P(t.rootPath),r=new Set;for(let i of n){let n=A(e.relative(t.rootPath,i));r.add(n),q(e.join(t.mirrorRootPath,n),i)}r.has(`index.ts`)||H(e.join(t.mirrorRootPath,`index.ts`),`${J()}export {};
20
- `)}function K(t,n){let r=t.impl.rootPath?qe(t.impl.rootPath):void 0;if(!r){let r=n===`module`?`ArchicatModuleImplementation`:`ArchicatLibraryImplementation`,i=`${J()}
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()}
21
21
  export const ${r} = {
22
- name: '${t.name}',
22
+ name: '${e.name}',
23
23
  assemblies: [],
24
24
  schemas: [],
25
25
  routes: [],
26
26
  } as const;
27
27
 
28
28
  export default ${r};
29
- `;H(e.join(t.impl.mirrorRootPath,`index.ts`),i);return}q(e.join(t.impl.mirrorRootPath,`index.ts`),r)}function q(e,t){let n=be(e,t),r=Se(t)?`export { default } from '${n}';\n`:``;H(e,`${J()}
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()}
30
30
  export * from '${n}';
31
- ${r}`)}function qe(t){for(let n of[`index.ts`,`index.mts`,`index.cts`,`index.tsx`]){let r=e.join(t,n);if(P(r).length>0)return r}}function J(){return`// Mirrored by Archicat.
32
- `}function Je(t){U(e.join(t.reportsDir,`build.report.json`),Ye(t)),U(e.join(t.reportsDir,`graph.report.json`),Xe(t))}function Ye(e){return{generatedBy:`archicat`,schemaVersion:1,prefixes:e.config.prefixes,outputs:{outDir:N(e.rootDir,e.outDir),reportsDir:N(e.rootDir,e.reportsDir)},targets:e.graph.targets.map(e=>e.key),definitions:[...e.definitions.map(t=>Ze(e,t)),...e.apps.map(t=>({kind:t.kind,name:t.name,targets:{app:t.target},aliases:{},dependencies:t.dependencies,contractFilePath:N(e.rootDir,t.contractFilePath),source:{root:N(e.rootDir,t.rootPath)},mirror:{}}))],dependencies:e.graph.dependencies}}function Xe(e){return{generatedBy:`archicat`,schemaVersion:1,targets:e.graph.targets.map(e=>e.key),dependencies:e.graph.dependencies}}function Ze(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:N(e.rootDir,t.contractFilePath),source:{root:N(e.rootDir,t.definitionDir),api:t.api.rootPath?N(e.rootDir,t.api.rootPath):void 0,impl:t.impl.rootPath?N(e.rootDir,t.impl.rootPath):void 0},mirror:{api:N(e.rootDir,t.api.mirrorRootPath),impl:N(e.rootDir,t.impl.mirrorRootPath)}}}function Qe(t){let n=nt(t.tsconfigPath?tt(t.tsconfigPath):{}),r=rt(n,t.tsconfigPath);if(Object.keys(r).length>0)throw Error(`Root tsconfig compilerOptions.paths is not supported by Archicat. Move aliases into archicat.config.ts alias.`);let i=et(t),a=$e(t);X(t,i,a);let o={compilerOptions:{...it(t,ot(n,[`baseUrl`,`paths`])),paths:{...i,...a}},include:[`../src/**/*.ts`,`./**/*.ts`,`./types/**/*.d.ts`],exclude:[`../node_modules`,`../dist`]};U(e.join(t.outDir,`tsconfig.json`),o)}function $e(t){let n={},r=t.apps.length>0;for(let i of t.definitions)n[i.alias]=[Y(t.outDir,e.join(i.api.mirrorRootPath,`index.ts`))],n[i.aliasGlob]=[Y(t.outDir,e.join(i.api.mirrorRootPath,`*`))],r&&i.implAlias&&i.implAliasGlob&&(n[i.implAlias]=[Y(t.outDir,e.join(i.impl.mirrorRootPath,`index.ts`))],n[i.implAliasGlob]=[Y(t.outDir,e.join(i.impl.mirrorRootPath,`*`))]);return n}function et(t){let n={};for(let[r,i]of Object.entries(t.config.alias)){let a=e.isAbsolute(i)?i:e.resolve(t.rootDir,i);n[r]=[Y(t.outDir,a)]}return n}function tt(e){let n=t.readFileSync(e,`utf8`),i=r.parseConfigFileTextToJson(e,n);if(i.error)throw Error(at(i.error));if(i.config==null||typeof i.config!=`object`||Array.isArray(i.config))throw Error(`Invalid tsconfig object: ${e}`);return i.config}function nt(e){let t=e.compilerOptions;return t&&typeof t==`object`&&!Array.isArray(t)?t:{}}function rt(e,t){let n=e.paths;if(!n||typeof n!=`object`||Array.isArray(n))return{};let r={};for(let[e,i]of Object.entries(n)){if(!Array.isArray(i)||!i.every(e=>typeof e==`string`))throw Error(`Tsconfig paths.${e} must be an array of strings${t?`: ${t}`:``}.`);r[e]=[...i]}return r}function it(t,n){if(!t.tsconfigPath)return n;let r=e.dirname(t.tsconfigPath),i={...n};for(let n of[`rootDir`,`outDir`,`declarationDir`]){let a=i[n];if(typeof a==`string`){let o=e.isAbsolute(a)?a:e.resolve(r,a);i[n]=Y(t.outDir,o)}}return i}function Y(t,n){let r=A(e.relative(t,n));return r.startsWith(`.`)||(r=`./${r}`),r}function X(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 at(e){let t=r.flattenDiagnosticMessageText(e.messageText,`
33
- `);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}function ot(e,t){let n={...e};for(let e of t)delete n[e];return n}async function st(n){let r=await k(n);if(e.resolve(r.outDir)===e.resolve(r.rootDir))throw Error(`Archicat outDir cannot be the project root.`);return He(r.outDir),t.mkdirSync(e.join(r.outDir,`modules`),{recursive:!0}),t.mkdirSync(e.join(r.outDir,`libraries`),{recursive:!0}),t.mkdirSync(e.join(r.outDir,`types`),{recursive:!0}),t.mkdirSync(r.reportsDir,{recursive:!0}),We(r.definitions),Ue(r),Qe(r),Je(r),r}async function ct(e){let t=await st(e.config);return B([`Mirrored modules: ${t.modules.length}`,`Mirrored libraries: ${t.libraries.length}`,`Resolved apps: ${t.apps.length}`])}function lt(e){let t=[`Modules: ${e.modules.length}`,``];for(let n of e.modules)t.push(n.name),t.push(` api: ${n.apiTarget}`),Z(t,e.graph.dependencies.filter(e=>e.from===n.apiTarget),` api dependsOn`),t.push(` impl: ${n.implTarget}`),Z(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}`),Z(t,e.graph.dependencies.filter(e=>e.from===n.apiTarget),` api dependsOn`),t.push(` impl: ${n.implTarget}`),Z(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}`),Z(t,e.graph.dependencies.filter(e=>e.from===n.target),` dependsOn`),t.push(``);return ut(t)}function Z(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 ut(e){let t=[...e];for(;t.at(-1)===``;)t.pop();return t}async function dt(e){return{exitCode:0,lines:lt(await k(e.config)).map(e=>({kind:`info`,message:e}))}}async function ft(e=process.argv.slice(2)){let[t,...n]=e;try{let e=await pt(t,mt(n));if(!e)return;ht(e),process.exitCode=e.exitCode}catch(e){$({kind:`error`,message:e instanceof Error?e.message:String(e)}),process.exitCode=1}}async function pt(e,t){switch(e){case`generate`:return ct(t);case`check`:return Ie(t);case`graph`:return dt(t);case`doctor`:return Ve(t);case`help`:case`--help`:case`-h`:case void 0:Q();return;default:return $({kind:`error`,message:`Unknown command: ${e}`}),Q(),{exitCode:1,lines:[]}}}function mt(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 ht(e){for(let t of e.lines)$(t)}function Q(){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(`
34
- `))}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{ft as runMain};
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};
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){return Object.freeze({kind:`app`,name:e.name,...e.root===void 0?{}:{root:e.root},dependencies:Object.freeze([...e.dependencies??[]])})}function t(e={}){return Object.freeze({...e.root===void 0?{}:{root:e.root},...e.outDir===void 0?{}:{outDir:e.outDir},...e.tsconfig===void 0?{}:{tsconfig:e.tsconfig},...e.alias===void 0?{}:{alias:Object.freeze({...e.alias})},...e.prefixes===void 0?{}:{prefixes:Object.freeze({...e.prefixes.module===void 0?{}:{module:e.prefixes.module},...e.prefixes.library===void 0?{}:{library:e.prefixes.library}})},...e.modules===void 0?{}:{modules:Object.freeze({...e.modules.include===void 0?{}:{include:Object.freeze([...e.modules.include])}})},...e.libraries===void 0?{}:{libraries:Object.freeze({...e.libraries.include===void 0?{}:{include:Object.freeze([...e.libraries.include])}})},...e.apps===void 0?{}:{apps:Object.freeze({...e.apps.include===void 0?{}:{include:Object.freeze([...e.apps.include])}})}})}function n(e){return Object.freeze({kind:`library`,name:e.name,api:r(e.api),impl:r(e.impl)})}function r(e){return Object.freeze(typeof e==`string`?{root:e,dependencies:Object.freeze([])}:{...e?.root===void 0?{}:{root:e.root},dependencies:Object.freeze([...e?.dependencies??[]])})}function i(e){return Object.freeze({kind:`module`,name:e.name,api:a(e.api),impl:a(e.impl)})}function a(e){return Object.freeze(typeof e==`string`?{root:e,dependencies:Object.freeze([])}:{...e?.root===void 0?{}:{root:e.root},dependencies:Object.freeze([...e?.dependencies??[]])})}exports.defineApp=e,exports.defineArchicatConfig=t,exports.defineLibrary=n,exports.defineModule=i;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){return Object.freeze({kind:`app`,name:e.name,...e.root===void 0?{}:{root:e.root},dependencies:Object.freeze([...e.dependencies??[]])})}function t(e){let t={...e};for(let e of Object.keys(t))t[e]===void 0&&delete t[e];return Object.freeze(t)}function n(e={}){return t({root:e.root,outDir:e.outDir,typescript:e.typescript?r(e.typescript):void 0,alias:e.alias?Object.freeze({...e.alias}):void 0,prefixes:e.prefixes?a(e.prefixes):void 0,modules:e.modules?o(e.modules):void 0,libraries:e.libraries?o(e.libraries):void 0,apps:e.apps?o(e.apps):void 0})}function r(e){return t({tsConfig:e.tsConfig?i(e.tsConfig):void 0})}function i(e){return t({extends:e.extends,include:e.include?Object.freeze([...e.include]):void 0,exclude:e.exclude?Object.freeze([...e.exclude]):void 0,files:e.files?Object.freeze([...e.files]):void 0,compilerOptions:e.compilerOptions?Object.freeze({...e.compilerOptions}):void 0})}function a(e){return t({module:e.module,library:e.library})}function o(e){return t({include:e.include?Object.freeze([...e.include]):void 0})}function s(e){return typeof e==`string`?Object.freeze({root:e,dependencies:Object.freeze([])}):t({root:e?.root,dependencies:Object.freeze([...e?.dependencies??[]])})}function c(e){return Object.freeze({kind:`library`,name:e.name,api:s(e.api),impl:s(e.impl)})}function l(e){return Object.freeze({kind:`module`,name:e.name,api:s(e.api),impl:s(e.impl)})}exports.defineApp=e,exports.defineArchicatConfig=n,exports.defineLibrary=c,exports.defineModule=l;
@@ -84,6 +84,49 @@ interface ArchicatDefinitionRootConfig {
84
84
  */
85
85
  readonly include?: readonly string[];
86
86
  }
87
+ /**
88
+ * @description TypeScript config fragment merged into generated `.archicat/tsconfig.json`.
89
+ */
90
+ interface ArchicatTypeScriptTsConfigInput {
91
+ /**
92
+ * @description Base TypeScript config extended by generated `.archicat/tsconfig.json`.
93
+ */
94
+ readonly extends?: string;
95
+ /**
96
+ * @description Project source files merged into generated `.archicat/tsconfig.json` include.
97
+ * Archicat rewrites relative paths to the generated config directory and appends generated type declarations automatically.
98
+ */
99
+ readonly include?: readonly string[];
100
+ /**
101
+ * @description Project paths merged into generated `.archicat/tsconfig.json` exclude.
102
+ * Archicat rewrites relative paths to the generated config directory.
103
+ */
104
+ readonly exclude?: readonly string[];
105
+ /**
106
+ * @description Project files merged into generated `.archicat/tsconfig.json` files.
107
+ * Archicat rewrites relative paths to the generated config directory.
108
+ */
109
+ readonly files?: readonly string[];
110
+ /**
111
+ * @description Unsupported. Put compiler options in the base or app tsconfig. Archicat owns generated `compilerOptions.paths` and does not support `baseUrl`.
112
+ */
113
+ readonly compilerOptions?: {
114
+ readonly paths?: never;
115
+ readonly baseUrl?: never;
116
+ };
117
+ }
118
+ /**
119
+ * @description TypeScript integration options used to generate `.archicat/tsconfig.json`.
120
+ */
121
+ interface ArchicatTypeScriptConfigInput {
122
+ /**
123
+ * @description Partial TypeScript config merged into generated `.archicat/tsconfig.json`.
124
+ * Archicat rewrites relative paths from the project root to `.archicat`, appends generated type declarations to `include`, and injects generated aliases into `compilerOptions.paths`.
125
+ * `compilerOptions` is not supported here. Put compiler policy in the base tsconfig and app build overrides in the app tsconfig.
126
+ * @default {}
127
+ */
128
+ readonly tsConfig?: ArchicatTypeScriptTsConfigInput;
129
+ }
87
130
  /**
88
131
  * @description TypeScript alias prefixes reserved by Archicat.
89
132
  */
@@ -100,7 +143,8 @@ interface ArchicatPrefixConfig {
100
143
  readonly library?: string;
101
144
  }
102
145
  /**
103
- * @description User TypeScript aliases generated into `.archicat/tsconfig.json`.
146
+ * @description User import aliases generated into `.archicat/tsconfig.json` together with Archicat module and library aliases.
147
+ * Aliases are resolved relative to the Archicat project root. Do not define TypeScript `compilerOptions.paths` manually for an Archicat project.
104
148
  * @default {}
105
149
  */
106
150
  type ArchicatAliasConfig = Readonly<Record<string, string>>;
@@ -119,10 +163,10 @@ interface ArchicatConfigInput {
119
163
  */
120
164
  readonly outDir?: string;
121
165
  /**
122
- * @description User tsconfig file to merge into the generated Archicat tsconfig.
123
- * @default Auto-detects tsconfig.base.json, then tsconfig.json.
166
+ * @description TypeScript integration options used to generate `.archicat/tsconfig.json`.
167
+ * @default {}
124
168
  */
125
- readonly tsconfig?: string;
169
+ readonly typescript?: ArchicatTypeScriptConfigInput;
126
170
  /**
127
171
  * @description User TypeScript aliases generated by Archicat.
128
172
  * @default {}
@@ -155,7 +199,18 @@ interface ArchicatConfigInput {
155
199
  type ArchicatConfig = Readonly<{
156
200
  readonly root?: string;
157
201
  readonly outDir?: string;
158
- readonly tsconfig?: string;
202
+ readonly typescript?: Readonly<{
203
+ readonly tsConfig?: Readonly<{
204
+ readonly extends?: string;
205
+ readonly include?: readonly string[];
206
+ readonly exclude?: readonly string[];
207
+ readonly files?: readonly string[];
208
+ readonly compilerOptions?: Readonly<{
209
+ readonly paths?: never;
210
+ readonly baseUrl?: never;
211
+ }>;
212
+ }>;
213
+ }>;
159
214
  readonly alias?: ArchicatAliasConfig;
160
215
  readonly prefixes?: Readonly<{
161
216
  readonly module?: string;
@@ -84,6 +84,49 @@ interface ArchicatDefinitionRootConfig {
84
84
  */
85
85
  readonly include?: readonly string[];
86
86
  }
87
+ /**
88
+ * @description TypeScript config fragment merged into generated `.archicat/tsconfig.json`.
89
+ */
90
+ interface ArchicatTypeScriptTsConfigInput {
91
+ /**
92
+ * @description Base TypeScript config extended by generated `.archicat/tsconfig.json`.
93
+ */
94
+ readonly extends?: string;
95
+ /**
96
+ * @description Project source files merged into generated `.archicat/tsconfig.json` include.
97
+ * Archicat rewrites relative paths to the generated config directory and appends generated type declarations automatically.
98
+ */
99
+ readonly include?: readonly string[];
100
+ /**
101
+ * @description Project paths merged into generated `.archicat/tsconfig.json` exclude.
102
+ * Archicat rewrites relative paths to the generated config directory.
103
+ */
104
+ readonly exclude?: readonly string[];
105
+ /**
106
+ * @description Project files merged into generated `.archicat/tsconfig.json` files.
107
+ * Archicat rewrites relative paths to the generated config directory.
108
+ */
109
+ readonly files?: readonly string[];
110
+ /**
111
+ * @description Unsupported. Put compiler options in the base or app tsconfig. Archicat owns generated `compilerOptions.paths` and does not support `baseUrl`.
112
+ */
113
+ readonly compilerOptions?: {
114
+ readonly paths?: never;
115
+ readonly baseUrl?: never;
116
+ };
117
+ }
118
+ /**
119
+ * @description TypeScript integration options used to generate `.archicat/tsconfig.json`.
120
+ */
121
+ interface ArchicatTypeScriptConfigInput {
122
+ /**
123
+ * @description Partial TypeScript config merged into generated `.archicat/tsconfig.json`.
124
+ * Archicat rewrites relative paths from the project root to `.archicat`, appends generated type declarations to `include`, and injects generated aliases into `compilerOptions.paths`.
125
+ * `compilerOptions` is not supported here. Put compiler policy in the base tsconfig and app build overrides in the app tsconfig.
126
+ * @default {}
127
+ */
128
+ readonly tsConfig?: ArchicatTypeScriptTsConfigInput;
129
+ }
87
130
  /**
88
131
  * @description TypeScript alias prefixes reserved by Archicat.
89
132
  */
@@ -100,7 +143,8 @@ interface ArchicatPrefixConfig {
100
143
  readonly library?: string;
101
144
  }
102
145
  /**
103
- * @description User TypeScript aliases generated into `.archicat/tsconfig.json`.
146
+ * @description User import aliases generated into `.archicat/tsconfig.json` together with Archicat module and library aliases.
147
+ * Aliases are resolved relative to the Archicat project root. Do not define TypeScript `compilerOptions.paths` manually for an Archicat project.
104
148
  * @default {}
105
149
  */
106
150
  type ArchicatAliasConfig = Readonly<Record<string, string>>;
@@ -119,10 +163,10 @@ interface ArchicatConfigInput {
119
163
  */
120
164
  readonly outDir?: string;
121
165
  /**
122
- * @description User tsconfig file to merge into the generated Archicat tsconfig.
123
- * @default Auto-detects tsconfig.base.json, then tsconfig.json.
166
+ * @description TypeScript integration options used to generate `.archicat/tsconfig.json`.
167
+ * @default {}
124
168
  */
125
- readonly tsconfig?: string;
169
+ readonly typescript?: ArchicatTypeScriptConfigInput;
126
170
  /**
127
171
  * @description User TypeScript aliases generated by Archicat.
128
172
  * @default {}
@@ -155,7 +199,18 @@ interface ArchicatConfigInput {
155
199
  type ArchicatConfig = Readonly<{
156
200
  readonly root?: string;
157
201
  readonly outDir?: string;
158
- readonly tsconfig?: string;
202
+ readonly typescript?: Readonly<{
203
+ readonly tsConfig?: Readonly<{
204
+ readonly extends?: string;
205
+ readonly include?: readonly string[];
206
+ readonly exclude?: readonly string[];
207
+ readonly files?: readonly string[];
208
+ readonly compilerOptions?: Readonly<{
209
+ readonly paths?: never;
210
+ readonly baseUrl?: never;
211
+ }>;
212
+ }>;
213
+ }>;
159
214
  readonly alias?: ArchicatAliasConfig;
160
215
  readonly prefixes?: Readonly<{
161
216
  readonly module?: string;
@@ -1 +1 @@
1
- function e(e){return Object.freeze({kind:`app`,name:e.name,...e.root===void 0?{}:{root:e.root},dependencies:Object.freeze([...e.dependencies??[]])})}function t(e={}){return Object.freeze({...e.root===void 0?{}:{root:e.root},...e.outDir===void 0?{}:{outDir:e.outDir},...e.tsconfig===void 0?{}:{tsconfig:e.tsconfig},...e.alias===void 0?{}:{alias:Object.freeze({...e.alias})},...e.prefixes===void 0?{}:{prefixes:Object.freeze({...e.prefixes.module===void 0?{}:{module:e.prefixes.module},...e.prefixes.library===void 0?{}:{library:e.prefixes.library}})},...e.modules===void 0?{}:{modules:Object.freeze({...e.modules.include===void 0?{}:{include:Object.freeze([...e.modules.include])}})},...e.libraries===void 0?{}:{libraries:Object.freeze({...e.libraries.include===void 0?{}:{include:Object.freeze([...e.libraries.include])}})},...e.apps===void 0?{}:{apps:Object.freeze({...e.apps.include===void 0?{}:{include:Object.freeze([...e.apps.include])}})}})}function n(e){return Object.freeze({kind:`library`,name:e.name,api:r(e.api),impl:r(e.impl)})}function r(e){return Object.freeze(typeof e==`string`?{root:e,dependencies:Object.freeze([])}:{...e?.root===void 0?{}:{root:e.root},dependencies:Object.freeze([...e?.dependencies??[]])})}function i(e){return Object.freeze({kind:`module`,name:e.name,api:a(e.api),impl:a(e.impl)})}function a(e){return Object.freeze(typeof e==`string`?{root:e,dependencies:Object.freeze([])}:{...e?.root===void 0?{}:{root:e.root},dependencies:Object.freeze([...e?.dependencies??[]])})}export{e as defineApp,t as defineArchicatConfig,n as defineLibrary,i as defineModule};
1
+ function e(e){return Object.freeze({kind:`app`,name:e.name,...e.root===void 0?{}:{root:e.root},dependencies:Object.freeze([...e.dependencies??[]])})}function t(e){let t={...e};for(let e of Object.keys(t))t[e]===void 0&&delete t[e];return Object.freeze(t)}function n(e={}){return t({root:e.root,outDir:e.outDir,typescript:e.typescript?r(e.typescript):void 0,alias:e.alias?Object.freeze({...e.alias}):void 0,prefixes:e.prefixes?a(e.prefixes):void 0,modules:e.modules?o(e.modules):void 0,libraries:e.libraries?o(e.libraries):void 0,apps:e.apps?o(e.apps):void 0})}function r(e){return t({tsConfig:e.tsConfig?i(e.tsConfig):void 0})}function i(e){return t({extends:e.extends,include:e.include?Object.freeze([...e.include]):void 0,exclude:e.exclude?Object.freeze([...e.exclude]):void 0,files:e.files?Object.freeze([...e.files]):void 0,compilerOptions:e.compilerOptions?Object.freeze({...e.compilerOptions}):void 0})}function a(e){return t({module:e.module,library:e.library})}function o(e){return t({include:e.include?Object.freeze([...e.include]):void 0})}function s(e){return typeof e==`string`?Object.freeze({root:e,dependencies:Object.freeze([])}):t({root:e?.root,dependencies:Object.freeze([...e?.dependencies??[]])})}function c(e){return Object.freeze({kind:`library`,name:e.name,api:s(e.api),impl:s(e.impl)})}function l(e){return Object.freeze({kind:`module`,name:e.name,api:s(e.api),impl:s(e.impl)})}export{e as defineApp,n as defineArchicatConfig,c as defineLibrary,l as defineModule};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archicat",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "M²: modular mirroring for clean architecture.",
5
5
  "keywords": [
6
6
  "m2",
@@ -56,5 +56,5 @@
56
56
  "publishConfig": {
57
57
  "registry": "https://registry.npmjs.org/"
58
58
  },
59
- "gitHead": "edbae12165337e2a6caa43aa0bd4fb53cfb26b4c"
59
+ "gitHead": "557aec7d9b698eb46a1ab1e012afcf78394cbf91"
60
60
  }