@eddacraft/anvil-core 0.1.0
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/LICENSE +14 -0
- package/dist/antipattern/index.d.ts +11 -0
- package/dist/antipattern/index.d.ts.map +1 -0
- package/dist/antipattern/index.js +31 -0
- package/dist/antipattern/patterns-css.d.ts +17 -0
- package/dist/antipattern/patterns-css.d.ts.map +1 -0
- package/dist/antipattern/patterns-css.js +72 -0
- package/dist/antipattern/patterns-html.d.ts +21 -0
- package/dist/antipattern/patterns-html.d.ts.map +1 -0
- package/dist/antipattern/patterns-html.js +139 -0
- package/dist/antipattern/patterns.d.ts +72 -0
- package/dist/antipattern/patterns.d.ts.map +1 -0
- package/dist/antipattern/patterns.js +301 -0
- package/dist/antipattern/scanner.d.ts +32 -0
- package/dist/antipattern/scanner.d.ts.map +1 -0
- package/dist/antipattern/scanner.js +89 -0
- package/dist/antipattern/types.d.ts +318 -0
- package/dist/antipattern/types.d.ts.map +1 -0
- package/dist/antipattern/types.js +278 -0
- package/dist/architecture/analyzer.d.ts +123 -0
- package/dist/architecture/analyzer.d.ts.map +1 -0
- package/dist/architecture/analyzer.js +321 -0
- package/dist/architecture/baseline.d.ts +112 -0
- package/dist/architecture/baseline.d.ts.map +1 -0
- package/dist/architecture/baseline.js +245 -0
- package/dist/architecture/compiler.d.ts +24 -0
- package/dist/architecture/compiler.d.ts.map +1 -0
- package/dist/architecture/compiler.js +57 -0
- package/dist/architecture/context.d.ts +129 -0
- package/dist/architecture/context.d.ts.map +1 -0
- package/dist/architecture/context.js +116 -0
- package/dist/architecture/dc-generator.d.ts +9 -0
- package/dist/architecture/dc-generator.d.ts.map +1 -0
- package/dist/architecture/dc-generator.js +220 -0
- package/dist/architecture/definition-schema.d.ts +128 -0
- package/dist/architecture/definition-schema.d.ts.map +1 -0
- package/dist/architecture/definition-schema.js +94 -0
- package/dist/architecture/edge-detector-html.d.ts +6 -0
- package/dist/architecture/edge-detector-html.d.ts.map +1 -0
- package/dist/architecture/edge-detector-html.js +5 -0
- package/dist/architecture/edge-detector-web.d.ts +32 -0
- package/dist/architecture/edge-detector-web.d.ts.map +1 -0
- package/dist/architecture/edge-detector-web.js +133 -0
- package/dist/architecture/edge-detector.d.ts +116 -0
- package/dist/architecture/edge-detector.d.ts.map +1 -0
- package/dist/architecture/edge-detector.js +229 -0
- package/dist/architecture/entry-detector.d.ts +44 -0
- package/dist/architecture/entry-detector.d.ts.map +1 -0
- package/dist/architecture/entry-detector.js +263 -0
- package/dist/architecture/index.d.ts +21 -0
- package/dist/architecture/index.d.ts.map +1 -0
- package/dist/architecture/index.js +48 -0
- package/dist/architecture/layer-detector.d.ts +60 -0
- package/dist/architecture/layer-detector.d.ts.map +1 -0
- package/dist/architecture/layer-detector.js +331 -0
- package/dist/architecture/rego-generator.d.ts +25 -0
- package/dist/architecture/rego-generator.d.ts.map +1 -0
- package/dist/architecture/rego-generator.js +229 -0
- package/dist/architecture/templates/index.d.ts +39 -0
- package/dist/architecture/templates/index.d.ts.map +1 -0
- package/dist/architecture/templates/index.js +124 -0
- package/dist/architecture/types.d.ts +280 -0
- package/dist/architecture/types.d.ts.map +1 -0
- package/dist/architecture/types.js +269 -0
- package/dist/architecture/yaml-parser.d.ts +13 -0
- package/dist/architecture/yaml-parser.d.ts.map +1 -0
- package/dist/architecture/yaml-parser.js +234 -0
- package/dist/config/constants.d.ts +9 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +20 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +8 -0
- package/dist/config/loader.d.ts +41 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +76 -0
- package/dist/config/nudge-config.d.ts +35 -0
- package/dist/config/nudge-config.d.ts.map +1 -0
- package/dist/config/nudge-config.js +34 -0
- package/dist/config/types.d.ts +30 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +4 -0
- package/dist/contracts/index.d.ts +14 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +13 -0
- package/dist/contracts/schemas/aps.schema.d.ts +269 -0
- package/dist/contracts/schemas/aps.schema.d.ts.map +1 -0
- package/dist/contracts/schemas/aps.schema.js +183 -0
- package/dist/contracts/schemas/index.d.ts +12 -0
- package/dist/contracts/schemas/index.d.ts.map +1 -0
- package/dist/contracts/schemas/index.js +14 -0
- package/dist/contracts/schemas/json-schema.d.ts +14 -0
- package/dist/contracts/schemas/json-schema.d.ts.map +1 -0
- package/dist/contracts/schemas/json-schema.js +31 -0
- package/dist/contracts/schemas/warning.schema.d.ts +171 -0
- package/dist/contracts/schemas/warning.schema.d.ts.map +1 -0
- package/dist/contracts/schemas/warning.schema.js +123 -0
- package/dist/contracts/types/gate.types.d.ts +194 -0
- package/dist/contracts/types/gate.types.d.ts.map +1 -0
- package/dist/contracts/types/gate.types.js +19 -0
- package/dist/contracts/types/index.d.ts +9 -0
- package/dist/contracts/types/index.d.ts.map +1 -0
- package/dist/contracts/types/index.js +8 -0
- package/dist/crypto/hash.d.ts +47 -0
- package/dist/crypto/hash.d.ts.map +1 -0
- package/dist/crypto/hash.js +110 -0
- package/dist/crypto/index.d.ts +7 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +6 -0
- package/dist/drift/index.d.ts +6 -0
- package/dist/drift/index.d.ts.map +1 -0
- package/dist/drift/index.js +5 -0
- package/dist/drift/report-generator.d.ts +21 -0
- package/dist/drift/report-generator.d.ts.map +1 -0
- package/dist/drift/report-generator.js +240 -0
- package/dist/drift/snapshot-capture.d.ts +26 -0
- package/dist/drift/snapshot-capture.d.ts.map +1 -0
- package/dist/drift/snapshot-capture.js +195 -0
- package/dist/drift/snapshot-compare.d.ts +50 -0
- package/dist/drift/snapshot-compare.d.ts.map +1 -0
- package/dist/drift/snapshot-compare.js +142 -0
- package/dist/drift/snapshot-schema.d.ts +197 -0
- package/dist/drift/snapshot-schema.d.ts.map +1 -0
- package/dist/drift/snapshot-schema.js +193 -0
- package/dist/drift/snapshot-storage.d.ts +25 -0
- package/dist/drift/snapshot-storage.d.ts.map +1 -0
- package/dist/drift/snapshot-storage.js +179 -0
- package/dist/explain/antipattern-explainer.d.ts +4 -0
- package/dist/explain/antipattern-explainer.d.ts.map +1 -0
- package/dist/explain/antipattern-explainer.js +196 -0
- package/dist/explain/boundary-explainer.d.ts +5 -0
- package/dist/explain/boundary-explainer.d.ts.map +1 -0
- package/dist/explain/boundary-explainer.js +261 -0
- package/dist/explain/explain-service.d.ts +19 -0
- package/dist/explain/explain-service.d.ts.map +1 -0
- package/dist/explain/explain-service.js +106 -0
- package/dist/explain/index.d.ts +7 -0
- package/dist/explain/index.d.ts.map +1 -0
- package/dist/explain/index.js +5 -0
- package/dist/explain/template-loader.d.ts +9 -0
- package/dist/explain/template-loader.d.ts.map +1 -0
- package/dist/explain/template-loader.js +51 -0
- package/dist/explain/types.d.ts +46 -0
- package/dist/explain/types.d.ts.map +1 -0
- package/dist/explain/types.js +31 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/provenance/collector.d.ts +86 -0
- package/dist/provenance/collector.d.ts.map +1 -0
- package/dist/provenance/collector.js +425 -0
- package/dist/provenance/git-ai-standard/git-notes.d.ts +85 -0
- package/dist/provenance/git-ai-standard/git-notes.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/git-notes.js +292 -0
- package/dist/provenance/git-ai-standard/index.d.ts +44 -0
- package/dist/provenance/git-ai-standard/index.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/index.js +47 -0
- package/dist/provenance/git-ai-standard/serializer.d.ts +54 -0
- package/dist/provenance/git-ai-standard/serializer.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/serializer.js +224 -0
- package/dist/provenance/git-ai-standard/session.d.ts +51 -0
- package/dist/provenance/git-ai-standard/session.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/session.js +118 -0
- package/dist/provenance/git-ai-standard/types.d.ts +173 -0
- package/dist/provenance/git-ai-standard/types.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/types.js +109 -0
- package/dist/provenance/index.d.ts +5 -0
- package/dist/provenance/index.d.ts.map +1 -0
- package/dist/provenance/index.js +6 -0
- package/dist/provenance/store.d.ts +83 -0
- package/dist/provenance/store.d.ts.map +1 -0
- package/dist/provenance/store.js +248 -0
- package/dist/provenance/types.d.ts +160 -0
- package/dist/provenance/types.d.ts.map +1 -0
- package/dist/provenance/types.js +112 -0
- package/dist/suppression/index.d.ts +4 -0
- package/dist/suppression/index.d.ts.map +1 -0
- package/dist/suppression/index.js +3 -0
- package/dist/suppression/parser.d.ts +31 -0
- package/dist/suppression/parser.d.ts.map +1 -0
- package/dist/suppression/parser.js +219 -0
- package/dist/suppression/service.d.ts +29 -0
- package/dist/suppression/service.d.ts.map +1 -0
- package/dist/suppression/service.js +132 -0
- package/dist/suppression/store.d.ts +61 -0
- package/dist/suppression/store.d.ts.map +1 -0
- package/dist/suppression/store.js +169 -0
- package/dist/utils/debug.d.ts +48 -0
- package/dist/utils/debug.d.ts.map +1 -0
- package/dist/utils/debug.js +100 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/path-safety.d.ts +21 -0
- package/dist/utils/path-safety.d.ts.map +1 -0
- package/dist/utils/path-safety.js +49 -0
- package/dist/utils/severity.d.ts +37 -0
- package/dist/utils/severity.d.ts.map +1 -0
- package/dist/utils/severity.js +22 -0
- package/dist/validation/aps-validator.d.ts +66 -0
- package/dist/validation/aps-validator.d.ts.map +1 -0
- package/dist/validation/aps-validator.js +173 -0
- package/dist/validation/errors.d.ts +52 -0
- package/dist/validation/errors.d.ts.map +1 -0
- package/dist/validation/errors.js +115 -0
- package/dist/validation/index.d.ts +8 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +13 -0
- package/dist/warnings/index.d.ts +2 -0
- package/dist/warnings/index.d.ts.map +1 -0
- package/dist/warnings/index.js +1 -0
- package/dist/warnings/warning-id.d.ts +180 -0
- package/dist/warnings/warning-id.d.ts.map +1 -0
- package/dist/warnings/warning-id.js +257 -0
- package/package.json +79 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/architecture/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEL,oBAAoB,EACpB,KAAK,cAAc,EACnB,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,gBAAgB,EAChB,KAAK,UAAU,EAEf,mBAAmB,EACnB,KAAK,aAAa,EAClB,WAAW,EACX,KAAK,KAAK,EACV,YAAY,EACZ,KAAK,MAAM,EAEX,cAAc,EACd,KAAK,QAAQ,EAEb,uBAAuB,EACvB,KAAK,iBAAiB,EAEtB,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,0BAA0B,EAC1B,KAAK,oBAAoB,EAEzB,qBAAqB,EACrB,KAAK,eAAe,EACpB,oBAAoB,EACpB,KAAK,cAAc,EACnB,uBAAuB,EACvB,KAAK,iBAAiB,EAEtB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAGzE,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAGnF,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,qBAAqB,GACtB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,EACnB,aAAa,GACd,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG3E,OAAO,EACL,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,qBAAqB,EACrB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,0BAA0B,EAC1B,KAAK,oBAAoB,EACzB,qBAAqB,EACrB,KAAK,eAAe,EACpB,oBAAoB,EACpB,KAAK,cAAc,EACnB,kBAAkB,EAClB,KAAK,YAAY,EACjB,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,4BAA4B,EAC5B,KAAK,sBAAsB,EAC3B,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,EACf,+BAA+B,EAC/B,8BAA8B,EAC9B,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,0BAA0B,EAC1B,uBAAuB,EACvB,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,YAAY,EACZ,WAAW,EACX,UAAU,EACV,qBAAqB,EACrB,eAAe,EACf,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,WAAW,IAAI,uBAAuB,EACtC,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,2BAA2B,EAC3B,KAAK,qBAAqB,EAC1B,mBAAmB,EACnB,KAAK,aAAa,EAClB,gBAAgB,EAChB,KAAK,UAAU,EACf,gBAAgB,EAChB,KAAK,UAAU,EACf,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,kBAAkB,EAClB,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Architecture analysis module
|
|
3
|
+
*
|
|
4
|
+
* Provides architecture baseline management, layer detection,
|
|
5
|
+
* entry point detection, and boundary violation analysis.
|
|
6
|
+
*/
|
|
7
|
+
// Types
|
|
8
|
+
export {
|
|
9
|
+
// Entry points
|
|
10
|
+
EntryPointTypeSchema, DetectionConfidenceSchema, EntryPointSchema,
|
|
11
|
+
// Layers
|
|
12
|
+
StandardLayerSchema, LayerSchema, LayersSchema,
|
|
13
|
+
// Boundaries
|
|
14
|
+
BoundarySchema,
|
|
15
|
+
// Violations
|
|
16
|
+
BaselineViolationSchema,
|
|
17
|
+
// Baseline
|
|
18
|
+
BaselineSnapshotSchema, ArchitectureBaselineSchema,
|
|
19
|
+
// Analysis results
|
|
20
|
+
LayerAssignmentSchema, DependencyEdgeSchema, BoundaryViolationSchema,
|
|
21
|
+
// Utilities
|
|
22
|
+
createViolationId, isExistingViolation, createDefaultLayers, createDefaultBoundaries, } from './types.js';
|
|
23
|
+
// Layer detection
|
|
24
|
+
export { LayerDetector, createLayerDetector } from './layer-detector.js';
|
|
25
|
+
// Entry point detection
|
|
26
|
+
export { EntryPointDetector, createEntryPointDetector } from './entry-detector.js';
|
|
27
|
+
// Baseline management
|
|
28
|
+
export { BASELINE_FILENAME, ANVIL_DIR, getBaselinePath, baselineExists, loadBaseline, saveBaseline, createBaseline, updateBaseline, mergeViolations, findNewViolations, findFixedViolations, BaselineManager, createBaselineManager, } from './baseline.js';
|
|
29
|
+
// Architecture analyzer
|
|
30
|
+
export { ArchitectureAnalyzer, createArchitectureAnalyzer, analyseArchitecture, inferBaseline, } from './analyzer.js';
|
|
31
|
+
// HTML/CSS edge detection
|
|
32
|
+
export { extractHtmlEdges, extractCssEdges } from './edge-detector-web.js';
|
|
33
|
+
// Edge detection
|
|
34
|
+
export { createEdgeFingerprint, fingerprintEdge, resolveImportPath, extractImports, extractImportsFromFiles, compareToBaseline, toDependencyEdge, deduplicateEdges, filterCrossLayerEdges, } from './edge-detector.js';
|
|
35
|
+
// Architecture definition schema
|
|
36
|
+
export { ArchitectureTemplateSchema, LayerDefinitionSchema, BoundedContextSchema, RuleSeveritySchema, ArchitectureRuleSchema, ArchitectureOptionsSchema, ArchitectureDefinitionSchema, AVAILABLE_TEMPLATES, getAvailableTemplates, isValidTemplate, ARCHITECTURE_DEFINITION_VERSION, validateArchitectureDefinition, getDefaultOptions, } from './definition-schema.js';
|
|
37
|
+
// YAML parser
|
|
38
|
+
export { ARCHITECTURE_YAML_FILENAME, getArchitectureYamlPath, architectureYamlExists, parseArchitectureDefinition, writeArchitectureYaml, getTemplateDefaults, mergeWithTemplate, createDefinitionFromTemplate, } from './yaml-parser.js';
|
|
39
|
+
// DC config generator
|
|
40
|
+
export { DC_CONFIG_FILENAME, getDCConfigPath, dcConfigExists, needsRegeneration, writeDCConfig, generateDCConfig, } from './dc-generator.js';
|
|
41
|
+
// Rego policy generator
|
|
42
|
+
export { GENERATED_POLICIES_DIR, REGO_FILENAME, REGO_PACKAGE, getRegoPath, regoExists, needsRegoRegeneration, writeRegoPolicy, generateRegoPolicy, } from './rego-generator.js';
|
|
43
|
+
// Architecture compiler (DC + Rego orchestration)
|
|
44
|
+
export { compileArchitecture, needsCompilation, } from './compiler.js';
|
|
45
|
+
// Template loader
|
|
46
|
+
export { TemplateLoader, getTemplateLoader, listTemplates, getTemplate as getArchitectureTemplate, validateTemplate, } from './templates/index.js';
|
|
47
|
+
// Architecture context (for OPA)
|
|
48
|
+
export { ArchViolationSeveritySchema, ArchViolationSchema, ModuleInfoSchema, LayerStatsSchema, ArchitectureContextSchema, createEmptyContext, ArchitectureContextBuilder, createContextBuilder, } from './context.js';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer detection heuristics
|
|
3
|
+
*
|
|
4
|
+
* Detects architectural layers from directory structure and file patterns.
|
|
5
|
+
* Supports both single-app and monorepo project structures.
|
|
6
|
+
*/
|
|
7
|
+
import type { Layers, LayerAssignment } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Layer detector using directory heuristics
|
|
10
|
+
*/
|
|
11
|
+
export declare class LayerDetector {
|
|
12
|
+
private patterns;
|
|
13
|
+
private customLayers;
|
|
14
|
+
constructor(customLayers?: Layers);
|
|
15
|
+
/**
|
|
16
|
+
* Convert Layers config to LayerPattern array
|
|
17
|
+
*/
|
|
18
|
+
private layersToPatterns;
|
|
19
|
+
/**
|
|
20
|
+
* Detect layer for a single file
|
|
21
|
+
*
|
|
22
|
+
* Uses position-aware matching to handle monorepo structures where package names
|
|
23
|
+
* may match layer patterns (e.g., packages/api/src/services/user.ts should match
|
|
24
|
+
* 'services', not 'api').
|
|
25
|
+
*/
|
|
26
|
+
detectLayer(filePath: string): LayerAssignment;
|
|
27
|
+
/**
|
|
28
|
+
* Detect layers for multiple files
|
|
29
|
+
*/
|
|
30
|
+
detectLayers(filePaths: string[]): LayerAssignment[];
|
|
31
|
+
/**
|
|
32
|
+
* Get all detected layers from a set of files
|
|
33
|
+
*/
|
|
34
|
+
getDetectedLayers(filePaths: string[]): Set<string>;
|
|
35
|
+
/**
|
|
36
|
+
* Suggest layer structure based on detected patterns
|
|
37
|
+
*/
|
|
38
|
+
suggestLayers(filePaths: string[]): Layers;
|
|
39
|
+
/**
|
|
40
|
+
* Get default dependencies for a layer
|
|
41
|
+
*/
|
|
42
|
+
private getDefaultDependencies;
|
|
43
|
+
/**
|
|
44
|
+
* Get description for a layer
|
|
45
|
+
*/
|
|
46
|
+
private getLayerDescription;
|
|
47
|
+
/**
|
|
48
|
+
* Check if a dependency from one layer to another is allowed
|
|
49
|
+
*/
|
|
50
|
+
isAllowedDependency(fromLayer: string, toLayer: string, layers?: Layers): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Find files with ambiguous layer assignments
|
|
53
|
+
*/
|
|
54
|
+
findAmbiguousAssignments(filePaths: string[]): LayerAssignment[];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Create a layer detector with default patterns
|
|
58
|
+
*/
|
|
59
|
+
export declare function createLayerDetector(customLayers?: Layers): LayerDetector;
|
|
60
|
+
//# sourceMappingURL=layer-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layer-detector.d.ts","sourceRoot":"","sources":["../../src/architecture/layer-detector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAuB,MAAM,YAAY,CAAC;AAoJ/E;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,YAAY,CAAuB;gBAE/B,YAAY,CAAC,EAAE,MAAM;IAWjC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;;;OAMG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe;IAiF9C;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE;IAIpD;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;IAanD;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM;IAkB1C;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAY9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO;IAiBjF;;OAEG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE;CAKjE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,CAExE"}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer detection heuristics
|
|
3
|
+
*
|
|
4
|
+
* Detects architectural layers from directory structure and file patterns.
|
|
5
|
+
* Supports both single-app and monorepo project structures.
|
|
6
|
+
*/
|
|
7
|
+
import { minimatch } from 'minimatch';
|
|
8
|
+
import { createDebugger } from '../utils/debug.js';
|
|
9
|
+
const debug = createDebugger('architecture');
|
|
10
|
+
/**
|
|
11
|
+
* Common source root directories that indicate where the actual source code starts
|
|
12
|
+
*/
|
|
13
|
+
const SOURCE_ROOT_PATTERNS = ['src', 'lib', 'source', 'app'];
|
|
14
|
+
/**
|
|
15
|
+
* Default layer patterns with priorities
|
|
16
|
+
* Priority determines which layer wins when patterns overlap
|
|
17
|
+
*/
|
|
18
|
+
const DEFAULT_LAYER_PATTERNS = [
|
|
19
|
+
{
|
|
20
|
+
layer: 'presentation',
|
|
21
|
+
patterns: [
|
|
22
|
+
'**/controllers/**',
|
|
23
|
+
'**/routes/**',
|
|
24
|
+
'**/api/**',
|
|
25
|
+
'**/handlers/**',
|
|
26
|
+
'**/endpoints/**',
|
|
27
|
+
'**/views/**',
|
|
28
|
+
'**/pages/**',
|
|
29
|
+
],
|
|
30
|
+
priority: 1,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
layer: 'application',
|
|
34
|
+
patterns: [
|
|
35
|
+
'**/services/**',
|
|
36
|
+
'**/use-cases/**',
|
|
37
|
+
'**/usecases/**',
|
|
38
|
+
'**/application/**',
|
|
39
|
+
'**/interactors/**',
|
|
40
|
+
],
|
|
41
|
+
priority: 2,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
layer: 'domain',
|
|
45
|
+
patterns: ['**/domain/**', '**/entities/**', '**/models/**', '**/core/**', '**/business/**'],
|
|
46
|
+
priority: 3,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
layer: 'infrastructure',
|
|
50
|
+
patterns: [
|
|
51
|
+
'**/repositories/**',
|
|
52
|
+
'**/data/**',
|
|
53
|
+
'**/infrastructure/**',
|
|
54
|
+
'**/db/**',
|
|
55
|
+
'**/database/**',
|
|
56
|
+
'**/adapters/**',
|
|
57
|
+
'**/external/**',
|
|
58
|
+
'**/clients/**',
|
|
59
|
+
],
|
|
60
|
+
priority: 4,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
layer: 'shared',
|
|
64
|
+
patterns: [
|
|
65
|
+
'**/utils/**',
|
|
66
|
+
'**/lib/**',
|
|
67
|
+
'**/common/**',
|
|
68
|
+
'**/shared/**',
|
|
69
|
+
'**/helpers/**',
|
|
70
|
+
'**/types/**',
|
|
71
|
+
'**/constants/**',
|
|
72
|
+
'**/config/**',
|
|
73
|
+
],
|
|
74
|
+
priority: 5,
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
/**
|
|
78
|
+
* Extract the directory name that a pattern would match
|
|
79
|
+
* e.g., "**\/controllers\/**" -> "controllers"
|
|
80
|
+
*/
|
|
81
|
+
function getPatternDirectoryName(pattern) {
|
|
82
|
+
// Match patterns like "**/controllers/**" or "src/controllers/**"
|
|
83
|
+
const match = pattern.match(/\*\*\/([^/*]+)\/\*\*/);
|
|
84
|
+
if (match) {
|
|
85
|
+
return match[1];
|
|
86
|
+
}
|
|
87
|
+
// Match patterns like "controllers/**"
|
|
88
|
+
const simpleMatch = pattern.match(/^([^/*]+)\/\*\*/);
|
|
89
|
+
if (simpleMatch) {
|
|
90
|
+
return simpleMatch[1];
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Find the position of a directory in a path (index from end, 0-based)
|
|
96
|
+
* Returns -1 if not found
|
|
97
|
+
*
|
|
98
|
+
* For "packages/web/src/controllers/user.ts" and "controllers":
|
|
99
|
+
* - parts = ["packages", "web", "src", "controllers", "user.ts"]
|
|
100
|
+
* - "controllers" is at index 3, length is 5
|
|
101
|
+
* - position from end = 5 - 3 - 1 = 1 (1 directory from the file)
|
|
102
|
+
*/
|
|
103
|
+
function getDirectoryPositionFromEnd(filePath, dirName) {
|
|
104
|
+
const parts = filePath.split('/');
|
|
105
|
+
const dirIndex = parts.findIndex((part) => part === dirName);
|
|
106
|
+
if (dirIndex === -1)
|
|
107
|
+
return -1;
|
|
108
|
+
return parts.length - dirIndex - 1;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Find the source root position in a path
|
|
112
|
+
* Returns the index of the first source root directory (src, lib, etc.)
|
|
113
|
+
* Returns -1 if no source root is found
|
|
114
|
+
*/
|
|
115
|
+
function findSourceRootIndex(filePath) {
|
|
116
|
+
const parts = filePath.split('/');
|
|
117
|
+
for (let i = 0; i < parts.length; i++) {
|
|
118
|
+
if (SOURCE_ROOT_PATTERNS.includes(parts[i])) {
|
|
119
|
+
return i;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return -1;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Check if a directory name is likely a package/app name rather than a layer directory
|
|
126
|
+
* by checking if it appears before the source root
|
|
127
|
+
*/
|
|
128
|
+
function isBeforeSourceRoot(filePath, dirName) {
|
|
129
|
+
const parts = filePath.split('/');
|
|
130
|
+
const dirIndex = parts.findIndex((part) => part === dirName);
|
|
131
|
+
const sourceRootIndex = findSourceRootIndex(filePath);
|
|
132
|
+
// If no source root found, can't determine
|
|
133
|
+
if (sourceRootIndex === -1)
|
|
134
|
+
return false;
|
|
135
|
+
// If the directory appears before the source root, it's likely a package name
|
|
136
|
+
return dirIndex < sourceRootIndex;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Layer detector using directory heuristics
|
|
140
|
+
*/
|
|
141
|
+
export class LayerDetector {
|
|
142
|
+
patterns;
|
|
143
|
+
customLayers = null;
|
|
144
|
+
constructor(customLayers) {
|
|
145
|
+
if (customLayers) {
|
|
146
|
+
this.customLayers = customLayers;
|
|
147
|
+
this.patterns = this.layersToPatterns(customLayers);
|
|
148
|
+
debug('LayerDetector created with custom layers', Object.keys(customLayers));
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
this.patterns = DEFAULT_LAYER_PATTERNS;
|
|
152
|
+
debug('LayerDetector created with default patterns');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Convert Layers config to LayerPattern array
|
|
157
|
+
*/
|
|
158
|
+
layersToPatterns(layers) {
|
|
159
|
+
const result = [];
|
|
160
|
+
let priority = 1;
|
|
161
|
+
for (const [name, layer] of Object.entries(layers)) {
|
|
162
|
+
result.push({
|
|
163
|
+
layer: name,
|
|
164
|
+
patterns: layer.patterns,
|
|
165
|
+
priority: priority++,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Detect layer for a single file
|
|
172
|
+
*
|
|
173
|
+
* Uses position-aware matching to handle monorepo structures where package names
|
|
174
|
+
* may match layer patterns (e.g., packages/api/src/services/user.ts should match
|
|
175
|
+
* 'services', not 'api').
|
|
176
|
+
*/
|
|
177
|
+
detectLayer(filePath) {
|
|
178
|
+
const matches = [];
|
|
179
|
+
// Normalise path separators
|
|
180
|
+
const normalisedPath = filePath.replace(/\\/g, '/');
|
|
181
|
+
for (const layerPattern of this.patterns) {
|
|
182
|
+
for (const pattern of layerPattern.patterns) {
|
|
183
|
+
if (minimatch(normalisedPath, pattern, { matchBase: true })) {
|
|
184
|
+
const dirName = getPatternDirectoryName(pattern);
|
|
185
|
+
const positionScore = dirName
|
|
186
|
+
? getDirectoryPositionFromEnd(normalisedPath, dirName)
|
|
187
|
+
: 999;
|
|
188
|
+
const beforeSrcRoot = dirName ? isBeforeSourceRoot(normalisedPath, dirName) : false;
|
|
189
|
+
matches.push({
|
|
190
|
+
layer: layerPattern.layer,
|
|
191
|
+
pattern,
|
|
192
|
+
priority: layerPattern.priority,
|
|
193
|
+
positionScore,
|
|
194
|
+
isBeforeSrcRoot: beforeSrcRoot,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (matches.length === 0) {
|
|
200
|
+
return {
|
|
201
|
+
file: filePath,
|
|
202
|
+
layer: null,
|
|
203
|
+
confidence: 'low',
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
// Filter out matches that are before the source root (likely package names)
|
|
207
|
+
// unless ALL matches are before the source root
|
|
208
|
+
const afterSrcRootMatches = matches.filter((m) => !m.isBeforeSrcRoot);
|
|
209
|
+
const effectiveMatches = afterSrcRootMatches.length > 0 ? afterSrcRootMatches : matches;
|
|
210
|
+
// Sort matches by:
|
|
211
|
+
// 1. Position score (closer to file = better, i.e., lower score)
|
|
212
|
+
// 2. Layer priority as tiebreaker (lower = higher priority)
|
|
213
|
+
effectiveMatches.sort((a, b) => {
|
|
214
|
+
// First compare position score
|
|
215
|
+
if (a.positionScore !== b.positionScore) {
|
|
216
|
+
return a.positionScore - b.positionScore;
|
|
217
|
+
}
|
|
218
|
+
// Then compare layer priority
|
|
219
|
+
return a.priority - b.priority;
|
|
220
|
+
});
|
|
221
|
+
const bestMatch = effectiveMatches[0];
|
|
222
|
+
// Determine confidence based on match quality
|
|
223
|
+
let confidence = 'high';
|
|
224
|
+
// If multiple layers matched, reduce confidence
|
|
225
|
+
const uniqueLayers = new Set(effectiveMatches.map((m) => m.layer));
|
|
226
|
+
if (uniqueLayers.size > 1) {
|
|
227
|
+
confidence = 'medium';
|
|
228
|
+
}
|
|
229
|
+
// If the best match was before source root, reduce confidence
|
|
230
|
+
if (bestMatch.isBeforeSrcRoot) {
|
|
231
|
+
confidence = 'medium';
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
file: filePath,
|
|
235
|
+
layer: bestMatch.layer,
|
|
236
|
+
confidence,
|
|
237
|
+
matched_pattern: bestMatch.pattern,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Detect layers for multiple files
|
|
242
|
+
*/
|
|
243
|
+
detectLayers(filePaths) {
|
|
244
|
+
return filePaths.map((path) => this.detectLayer(path));
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Get all detected layers from a set of files
|
|
248
|
+
*/
|
|
249
|
+
getDetectedLayers(filePaths) {
|
|
250
|
+
const layers = new Set();
|
|
251
|
+
for (const path of filePaths) {
|
|
252
|
+
const assignment = this.detectLayer(path);
|
|
253
|
+
if (assignment.layer) {
|
|
254
|
+
layers.add(assignment.layer);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return layers;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Suggest layer structure based on detected patterns
|
|
261
|
+
*/
|
|
262
|
+
suggestLayers(filePaths) {
|
|
263
|
+
const detectedLayers = this.getDetectedLayers(filePaths);
|
|
264
|
+
const result = {};
|
|
265
|
+
// Only include layers that were actually detected
|
|
266
|
+
for (const layerPattern of this.patterns) {
|
|
267
|
+
if (detectedLayers.has(layerPattern.layer)) {
|
|
268
|
+
result[layerPattern.layer] = {
|
|
269
|
+
patterns: layerPattern.patterns,
|
|
270
|
+
depends_on: this.getDefaultDependencies(layerPattern.layer),
|
|
271
|
+
description: this.getLayerDescription(layerPattern.layer),
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return result;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Get default dependencies for a layer
|
|
279
|
+
*/
|
|
280
|
+
getDefaultDependencies(layer) {
|
|
281
|
+
const deps = {
|
|
282
|
+
presentation: ['application', 'shared'],
|
|
283
|
+
application: ['domain', 'infrastructure', 'shared'],
|
|
284
|
+
domain: ['shared'],
|
|
285
|
+
infrastructure: ['domain', 'shared'],
|
|
286
|
+
shared: [],
|
|
287
|
+
};
|
|
288
|
+
return deps[layer] ?? [];
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Get description for a layer
|
|
292
|
+
*/
|
|
293
|
+
getLayerDescription(layer) {
|
|
294
|
+
const descriptions = {
|
|
295
|
+
presentation: 'HTTP handlers, controllers, API routes',
|
|
296
|
+
application: 'Business logic, use cases, services',
|
|
297
|
+
domain: 'Domain entities, value objects, domain logic',
|
|
298
|
+
infrastructure: 'Data access, external services, infrastructure',
|
|
299
|
+
shared: 'Shared utilities, helpers, common code',
|
|
300
|
+
};
|
|
301
|
+
return descriptions[layer] ?? `${layer} layer`;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Check if a dependency from one layer to another is allowed
|
|
305
|
+
*/
|
|
306
|
+
isAllowedDependency(fromLayer, toLayer, layers) {
|
|
307
|
+
const layerConfig = layers ?? this.customLayers;
|
|
308
|
+
if (!layerConfig) {
|
|
309
|
+
// Use default rules
|
|
310
|
+
const defaultDeps = this.getDefaultDependencies(fromLayer);
|
|
311
|
+
return fromLayer === toLayer || defaultDeps.includes(toLayer);
|
|
312
|
+
}
|
|
313
|
+
const fromLayerConfig = layerConfig[fromLayer];
|
|
314
|
+
if (!fromLayerConfig) {
|
|
315
|
+
return true; // Unknown layer, allow
|
|
316
|
+
}
|
|
317
|
+
return fromLayer === toLayer || fromLayerConfig.depends_on.includes(toLayer);
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Find files with ambiguous layer assignments
|
|
321
|
+
*/
|
|
322
|
+
findAmbiguousAssignments(filePaths) {
|
|
323
|
+
return this.detectLayers(filePaths).filter((a) => a.confidence === 'medium' || a.confidence === 'low');
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Create a layer detector with default patterns
|
|
328
|
+
*/
|
|
329
|
+
export function createLayerDetector(customLayers) {
|
|
330
|
+
return new LayerDetector(customLayers);
|
|
331
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ArchitectureDefinition } from './definition-schema.js';
|
|
2
|
+
export declare const GENERATED_POLICIES_DIR = ".anvil/policies/.generated";
|
|
3
|
+
export declare const REGO_FILENAME = "architecture.rego";
|
|
4
|
+
export declare const REGO_PACKAGE = "anvil.policies.architecture";
|
|
5
|
+
/**
|
|
6
|
+
* Get the path to the generated Rego file
|
|
7
|
+
*/
|
|
8
|
+
export declare function getRegoPath(workspaceRoot: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Check if generated Rego file exists
|
|
11
|
+
*/
|
|
12
|
+
export declare function regoExists(workspaceRoot: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Check if Rego needs regeneration based on definition hash
|
|
15
|
+
*/
|
|
16
|
+
export declare function needsRegoRegeneration(workspaceRoot: string, definition: ArchitectureDefinition): Promise<boolean>;
|
|
17
|
+
/**
|
|
18
|
+
* Write generated Rego policy file
|
|
19
|
+
*/
|
|
20
|
+
export declare function writeRegoPolicy(workspaceRoot: string, definition: ArchitectureDefinition): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Generate Rego policy content from architecture definition
|
|
23
|
+
*/
|
|
24
|
+
export declare function generateRegoPolicy(definition: ArchitectureDefinition): string;
|
|
25
|
+
//# sourceMappingURL=rego-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rego-generator.d.ts","sourceRoot":"","sources":["../../src/architecture/rego-generator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAKrE,eAAO,MAAM,sBAAsB,+BAA+B,CAAC;AACnE,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD,eAAO,MAAM,YAAY,gCAAgC,CAAC;AAE1D;;GAEG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,sBAAsB,GACjC,OAAO,CAAC,OAAO,CAAC,CAYlB;AAOD;;GAEG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,sBAAsB,GACjC,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,sBAAsB,GAAG,MAAM,CA8K7E"}
|