speckeeper 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -551,6 +551,16 @@ interface DeepValidationConfig<T> {
551
551
  ddl?: DeepValidationRule<T, DDLValidationMapping>;
552
552
  [sourceType: string]: DeepValidationRule<T, unknown> | undefined;
553
553
  }
554
+ /**
555
+ * Lookup key configuration keyed by source type.
556
+ * When a model's spec ID differs from the external identifier
557
+ * (e.g. entity ID "user" vs DDL table name "users"),
558
+ * define a mapper per source type to derive the external key.
559
+ * If not defined for a source type, spec.id is used as-is.
560
+ */
561
+ interface LookupKeyConfig<T> {
562
+ [sourceType: string]: ((spec: T) => string) | undefined;
563
+ }
554
564
  /**
555
565
  * Coverage result
556
566
  */
@@ -648,6 +658,8 @@ declare abstract class Model<TSchema extends ZodType> {
648
658
  protected externalChecker?: ExternalChecker<z.infer<TSchema>>;
649
659
  /** Deep validation rules keyed by source type (replaces externalChecker) */
650
660
  protected deepValidation?: DeepValidationConfig<z.infer<TSchema>>;
661
+ /** Lookup key overrides per source type (when spec ID differs from external identifier) */
662
+ protected lookupKeys?: LookupKeyConfig<z.infer<TSchema>>;
651
663
  /** Coverage checker (optional) */
652
664
  protected coverageChecker?: CoverageChecker<z.infer<TSchema>>;
653
665
  /** Model level (set in _models/) */
@@ -729,6 +741,15 @@ declare abstract class Model<TSchema extends ZodType> {
729
741
  * Get deep validation config
730
742
  */
731
743
  getDeepValidation(): DeepValidationConfig<z.infer<TSchema>> | undefined;
744
+ /**
745
+ * Get lookup key config
746
+ */
747
+ getLookupKeys(): LookupKeyConfig<z.infer<TSchema>> | undefined;
748
+ /**
749
+ * Resolve the lookup key for a spec and source type.
750
+ * Returns the lookup key if an override is defined, otherwise spec.id.
751
+ */
752
+ resolveLookupKey(spec: z.infer<TSchema>, sourceType: string): string;
732
753
  /**
733
754
  * Get lint rules
734
755
  */
@@ -1054,4 +1075,4 @@ declare function createLintRule<T>(config: {
1054
1075
  */
1055
1076
  declare function loadSpeckeeperConfig(configPath?: string): Promise<ResolvedSpeckeeperConfig | null>;
1056
1077
 
1057
- export { defineConfig as $, type ArtifactConfig as A, type BaseModelInstance as B, type CheckContext as C, type ReferenceDefinition as D, type ExportContext as E, ReferenceDefinitionSchema as F, type Relation as G, RelationSchema as H, type InferModelType as I, type JsonSchemaExporter as J, type RelationValidationError as K, type LintContext as L, type ModelDefinition as M, RelationsFieldSchema as N, type RenderContext as O, type Renderer as P, type ResolvedSpeckeeperConfig as Q, RELATION_CONSTRAINTS as R, type SourceConfig as S, type SourceMatch as T, type SourceScanner as U, type SpecModule as V, type SpeckeeperConfigInput as W, buildRegistryFromConfig as X, createLintRule as Y, createMarkdownExporter as Z, createMermaidExporter as _, type CheckResult$1 as a, defineModel as a0, defineSpecs as a1, detectCycles as a2, findModelTypeFromConfig as a3, getLevelIndex as a4, getSpecsFromConfig as a5, inferModelIdFromSpecId as a6, loadSpeckeeperConfig as a7, mergeSpecs as a8, validateRelationLevel as a9, type DeepValidationConfig as aa, type MetaModelRegistry as b, type LintRule$1 as c, type LintIssue as d, type SpecEntry as e, type CheckError as f, CheckErrorSchema as g, type CheckResult as h, CheckResultSchema as i, type CheckWarning as j, CheckWarningSchema as k, type CoverageChecker as l, type CoverageResult as m, type Exporter as n, type ExternalChecker as o, LintIssueSchema as p, type LintResult as q, type LintRule as r, type MarkdownExporter as s, type MergedDesign as t, type MermaidExporter as u, type MetaModelConfig as v, Model as w, type ModelDefinitionInput as x, type ModelLevel as y, RELATION_TYPES as z };
1078
+ export { type SpeckeeperConfigInput as $, type ArtifactConfig as A, type BaseModelInstance as B, type CheckContext as C, type DDLValidationMapping as D, type ExportContext as E, type ModelDefinitionInput as F, type ModelLevel as G, RELATION_TYPES as H, type InferModelType as I, type JsonSchemaExporter as J, type ReferenceDefinition as K, type LintContext as L, type ModelDefinition as M, ReferenceDefinitionSchema as N, type OpenAPIValidationMapping as O, type Relation as P, RelationSchema as Q, RELATION_CONSTRAINTS as R, type SourceConfig as S, type RelationValidationError as T, RelationsFieldSchema as U, type RenderContext as V, type Renderer as W, type ResolvedSpeckeeperConfig as X, type SourceMatch as Y, type SourceScanner as Z, type SpecModule as _, type CheckResult$1 as a, buildRegistryFromConfig as a0, createLintRule as a1, createMarkdownExporter as a2, createMermaidExporter as a3, defineConfig as a4, defineModel as a5, defineSpecs as a6, detectCycles as a7, findModelTypeFromConfig as a8, getLevelIndex as a9, getSpecsFromConfig as aa, inferModelIdFromSpecId as ab, loadSpeckeeperConfig as ac, mergeSpecs as ad, validateRelationLevel as ae, type MetaModelRegistry as b, type LintRule$1 as c, type LintIssue as d, type SpecEntry as e, type CheckError as f, CheckErrorSchema as g, type CheckResult as h, CheckResultSchema as i, type CheckWarning as j, CheckWarningSchema as k, type CoverageChecker as l, type CoverageResult as m, type DeepValidationConfig as n, type DeepValidationRule as o, type Exporter as p, type ExternalChecker as q, LintIssueSchema as r, type LintResult as s, type LintRule as t, type LookupKeyConfig as u, type MarkdownExporter as v, type MergedDesign as w, type MermaidExporter as x, type MetaModelConfig as y, Model as z };
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { r as LintRule, n as Exporter, l as CoverageChecker, A as ArtifactConfig, T as SourceMatch, U as SourceScanner, aa as DeepValidationConfig, h as CheckResult, S as SourceConfig } from '../config-api-BDl4otlv.js';
2
+ import { t as LintRule, p as Exporter, l as CoverageChecker, A as ArtifactConfig, Y as SourceMatch, Z as SourceScanner, n as DeepValidationConfig, h as CheckResult, S as SourceConfig } from '../config-api-CfxXt9Zt.js';
3
3
 
4
4
  /**
5
5
  * Core DSL — Base spec schema
@@ -226,15 +226,27 @@ interface GlobalScanOutput {
226
226
  matches: GlobalScanResult;
227
227
  warnings: ScanWarning[];
228
228
  }
229
+ /**
230
+ * Lookup key map: specId -> Record<sourceType, lookupKey>.
231
+ * When a model's spec ID differs from the external identifier
232
+ * (e.g. entity "user" vs DDL table "users"), the check command
233
+ * builds this map so the scanner searches for the correct key.
234
+ */
235
+ type LookupKeyMap = Map<string, Record<string, string>>;
229
236
  /**
230
237
  * Run global scan across all configured sources.
231
238
  * Returns a map of specId -> matches for all spec IDs found.
239
+ *
240
+ * @param sources - Source configurations to scan
241
+ * @param specIds - All known spec IDs
242
+ * @param basePath - Base directory for resolving file paths
243
+ * @param lookupKeyMap - Optional per-spec, per-source-type key overrides
232
244
  */
233
- declare function runGlobalScan(sources: SourceConfig[], specIds: string[], basePath?: string): GlobalScanOutput;
245
+ declare function runGlobalScan(sources: SourceConfig[], specIds: string[], basePath?: string, lookupKeyMap?: LookupKeyMap): GlobalScanOutput;
234
246
  /**
235
247
  * Run deep validation for a spec against its matched sources.
236
248
  * Uses the model's deepValidation config to perform Level 2/3 checks.
237
249
  */
238
250
  declare function runDeepValidation(specId: string, matches: GlobalScanMatch[], deepValidation: DeepValidationConfig<any>, spec: unknown): CheckResult;
239
251
 
240
- export { type AnnotationCoverageConfig, type BaseSpec, type GlobalScanMatch, type GlobalScanOutput, type GlobalScanResult, type ImplementsRelation, ImplementsRelationSchema, type MarkdownExporterConfig, type ScanWarning, type VerifiedByRelation, VerifiedByRelationSchema, annotationCoverage, annotationScanner, arrayMinLength, baseSpecSchema, childIdFormat, createAnnotationScanner, ddlScanner, getArtifactsConfig, idFormat, isTypeContainedBy, markdownExporter, openapiScanner, relationCoverage, requireField, runDeepValidation, runGlobalScan, setArtifactsConfig };
252
+ export { type AnnotationCoverageConfig, type BaseSpec, type GlobalScanMatch, type GlobalScanOutput, type GlobalScanResult, type ImplementsRelation, ImplementsRelationSchema, type LookupKeyMap, type MarkdownExporterConfig, type ScanWarning, type VerifiedByRelation, VerifiedByRelationSchema, annotationCoverage, annotationScanner, arrayMinLength, baseSpecSchema, childIdFormat, createAnnotationScanner, ddlScanner, getArtifactsConfig, idFormat, isTypeContainedBy, markdownExporter, openapiScanner, relationCoverage, requireField, runDeepValidation, runGlobalScan, setArtifactsConfig };
package/dist/dsl/index.js CHANGED
@@ -610,7 +610,7 @@ function loadFileContent(filePath, sourceType) {
610
610
  }
611
611
  return content;
612
612
  }
613
- function runGlobalScan(sources, specIds, basePath) {
613
+ function runGlobalScan(sources, specIds, basePath, lookupKeyMap) {
614
614
  const cwd = basePath ?? process.cwd();
615
615
  const result = /* @__PURE__ */ new Map();
616
616
  const warnings = [];
@@ -623,6 +623,13 @@ function runGlobalScan(sources, specIds, basePath) {
623
623
  });
624
624
  continue;
625
625
  }
626
+ const keyToSpecId = /* @__PURE__ */ new Map();
627
+ for (const specId of specIds) {
628
+ const overrides = lookupKeyMap?.get(specId);
629
+ const key = overrides?.[source.type] ?? specId;
630
+ keyToSpecId.set(key, specId);
631
+ }
632
+ const keysToSearch = Array.from(keyToSpecId.keys());
626
633
  const allFiles = /* @__PURE__ */ new Set();
627
634
  for (const pattern of source.paths) {
628
635
  const found = glob.sync(pattern, {
@@ -651,7 +658,7 @@ function runGlobalScan(sources, specIds, basePath) {
651
658
  if (content == null) continue;
652
659
  let matches;
653
660
  try {
654
- matches = scanner.findSpecIds(content, specIds, relPath);
661
+ matches = scanner.findSpecIds(content, keysToSearch, relPath);
655
662
  } catch (e) {
656
663
  const msg = e instanceof Error ? e.message : String(e);
657
664
  warnings.push({
@@ -662,17 +669,19 @@ function runGlobalScan(sources, specIds, basePath) {
662
669
  continue;
663
670
  }
664
671
  for (const match of matches) {
672
+ const originalSpecId = keyToSpecId.get(match.specId) ?? match.specId;
665
673
  const globalMatch = {
666
674
  ...match,
675
+ specId: originalSpecId,
667
676
  sourceType: source.type,
668
677
  relation: source.relation,
669
678
  filePath: relPath
670
679
  };
671
- const existing = result.get(match.specId);
680
+ const existing = result.get(originalSpecId);
672
681
  if (existing) {
673
682
  existing.push(globalMatch);
674
683
  } else {
675
- result.set(match.specId, [globalMatch]);
684
+ result.set(originalSpecId, [globalMatch]);
676
685
  }
677
686
  }
678
687
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/relation.ts","../../src/core/dsl/schema.ts","../../src/core/dsl/lint-rules.ts","../../src/core/dsl/exporters.ts","../../src/core/dsl/checkers.ts","../../src/core/dsl/type-compat.ts","../../src/core/dsl/relation-schemas.ts","../../src/core/global-scanner.ts"],"names":["z","extractSpecIds","readFileSync","parseYaml","glob","join"],"mappings":";;;;;;;;AAqCO,IAAM,cAAA,GAAiB;AAAA,EAC5B,WAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA;AAOO,IAAM,cAAA,GAAiB,EAAE,MAAA,CAAO;AAAA;AAAA,EAErC,IAAA,EAAM,CAAA,CAAE,IAAA,CAAK,cAAc,CAAA;AAAA;AAAA,EAE3B,MAAA,EAAQ,EAAE,MAAA,EAAO;AAAA;AAAA,EAEjB,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAC1B,CAAC,CAAA;AAMmC,CAAA,CAAE,KAAA,CAAM,cAAc,EAAE,QAAA;;;AC3DrD,IAAM,cAAA,GAAiBA,EAAE,MAAA,CAAO;AAAA,EACrC,EAAA,EAAIA,EAAE,MAAA,EAAO;AAAA,EACb,IAAA,EAAMA,CAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACtB,WAAA,EAAaA,EAAE,MAAA,EAAO;AAAA,EACtB,SAAA,EAAWA,CAAAA,CAAE,KAAA,CAAM,cAAc,EAAE,QAAA;AACrC,CAAC;;;ACHM,SAAS,YAAA,CACd,KAAA,EACA,QAAA,GAAyC,SAAA,EAC5B;AACb,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,OAAO,KAAK,CAAA,CAAA;AAAA,IAChB,QAAA;AAAA,IACA,OAAA,EAAS,GAAG,KAAK,CAAA,kBAAA,CAAA;AAAA,IACjB,KAAA,EAAO,CAAC,IAAA,KAAS;AACf,MAAA,MAAM,KAAA,GAAS,KAAiC,KAAK,CAAA;AACrD,MAAA,OAAO,CAAC,KAAA,IAAU,OAAO,UAAU,QAAA,IAAY,KAAA,CAAM,MAAK,KAAM,EAAA;AAAA,IAClE;AAAA,GACF;AACF;AAKO,SAAS,cAAA,CACd,KAAA,EACA,GAAA,EACA,QAAA,GAAgC,OAAA,EACnB;AACb,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,CAAA,EAAG,KAAK,CAAA,KAAA,EAAQ,GAAG,CAAA,CAAA;AAAA,IACvB,QAAA;AAAA,IACA,OAAA,EAAS,CAAA,EAAG,KAAK,CAAA,oBAAA,EAAuB,GAAG,CAAA,QAAA,CAAA;AAAA,IAC3C,KAAA,EAAO,CAAC,IAAA,KAAS;AACf,MAAA,MAAM,KAAA,GAAS,KAAiC,KAAK,CAAA;AACrD,MAAA,OAAO,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,MAAM,MAAA,GAAS,GAAA;AAAA,IACjD;AAAA,GACF;AACF;AAQO,SAAS,QAAA,CACd,QACA,IAAA,EACa;AACb,EAAA,MAAM,OAAA,GAAU,IAAA,EAAM,OAAA,IACjB,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,MAAM,CAAA,KAAA,EAAQ,IAAA,EAAM,MAAA,IAAU,CAAC,CAAA,EAAA,CAAI,CAAA;AAEvD,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,WAAA;AAAA,IACJ,QAAA,EAAU,SAAA;AAAA,IACV,OAAA,EAAS,0BAA0B,OAAO,CAAA,CAAA;AAAA,IAC1C,KAAA,EAAO,CAAC,IAAA,KAAS;AACf,MAAA,MAAM,EAAA,GAAM,KAAiC,IAAI,CAAA;AACjD,MAAA,OAAO,OAAO,EAAA,KAAO,QAAA,IAAY,CAAC,OAAA,CAAQ,KAAK,EAAE,CAAA;AAAA,IACnD;AAAA,GACF;AACF;AAKO,SAAS,aAAA,CACd,YACA,OAAA,EACa;AACb,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,GAAG,UAAU,CAAA,UAAA,CAAA;AAAA,IACjB,QAAA,EAAU,SAAA;AAAA,IACV,OAAA,EAAS,GAAG,UAAU,CAAA,oCAAA,CAAA;AAAA,IACtB,KAAA,EAAO,CAAC,IAAA,KAAS;AACf,MAAA,MAAM,QAAA,GAAY,KAAiC,IAAI,CAAA;AACvD,MAAA,MAAM,QAAA,GAAY,KAAiC,UAAU,CAAA;AAC7D,MAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,IAAK,CAAC,UAAU,OAAO,KAAA;AAClD,MAAA,OAAO,QAAA,CAAS,IAAA,CAAK,CAAC,KAAA,KAAmC;AACvD,QAAA,MAAM,OAAA,GAAU,MAAM,OAAO,CAAA;AAC7B,QAAA,OAAO,OAAO,OAAA,KAAY,QAAA,IAAY,CAAC,OAAA,CAAQ,UAAA,CAAW,WAAW,GAAG,CAAA;AAAA,MAC1E,CAAC,CAAA;AAAA,IACH;AAAA,GACF;AACF;;;ACjDO,SAAS,iBACd,MAAA,EACa;AACb,EAAA,MAAM,QAAA,GAAwB;AAAA,IAC5B,MAAA,EAAQ,UAAA;AAAA,IACR,WAAW,MAAA,CAAO,SAAA;AAAA,IAClB,QAAA,EAAU,CAAC,IAAA,KAAS,IAAA,CAAK;AAAA,GAC3B;AAEA,EAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,IAAA,MAAM,YAAY,MAAA,CAAO,MAAA;AACzB,IAAA,QAAA,CAAS,MAAA,GAAS,CAAC,IAAA,KAAS;AAC1B,MAAA,MAAM,QAAkB,EAAC;AAEzB,MAAA,MAAM,KAAA,GAAQ,OAAO,SAAA,CAAU,KAAA,KAAU,aACrC,SAAA,CAAU,KAAA,CAAM,IAAI,CAAA,GACpB,MAAA,CAAQ,IAAA,CAAiC,SAAA,CAAU,KAAK,KAAK,EAAE,CAAA;AACnE,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,EAAI,EAAE,CAAA;AAE3B,MAAA,IAAI,UAAU,IAAA,EAAM;AAClB,QAAA,KAAA,MAAW,CAAA,IAAK,UAAU,IAAA,EAAM;AAC9B,UAAA,MAAM,GAAA,GAAM,OAAO,CAAA,KAAM,QAAA,GAAW,IAAI,CAAA,CAAE,GAAA;AAC1C,UAAA,MAAM,QAAQ,OAAO,CAAA,KAAM,WAAW,GAAA,GAAO,CAAA,CAAE,SAAS,CAAA,CAAE,GAAA;AAC1D,UAAA,MAAM,KAAA,GAAS,KAAiC,GAAG,CAAA;AACnD,UAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AACzC,YAAA,KAAA,CAAM,KAAK,CAAA,EAAA,EAAK,KAAK,OAAO,MAAA,CAAO,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,UAC7C;AAAA,QACF;AACA,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,MACf;AAEA,MAAA,IAAI,UAAU,QAAA,EAAU;AACtB,QAAA,KAAA,MAAW,OAAA,IAAW,UAAU,QAAA,EAAU;AACxC,UAAA,IAAI,OAAA;AACJ,UAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,YAAA,OAAA,GAAU,OAAA,CAAQ,OAAO,IAAI,CAAA;AAAA,UAC/B,CAAA,MAAA,IAAW,QAAQ,KAAA,EAAO;AACxB,YAAA,MAAM,KAAA,GAAS,IAAA,CAAiC,OAAA,CAAQ,KAAK,CAAA;AAC7D,YAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAA,GAAU,KAAA;AAAA,UAC3C;AACA,UAAA,IAAI,OAAA,CAAQ,QAAA,IAAY,CAAC,OAAA,EAAS;AAClC,UAAA,KAAA,CAAM,IAAA,CAAK,CAAA,GAAA,EAAM,OAAA,CAAQ,OAAO,IAAI,EAAE,CAAA;AACtC,UAAA,IAAI,OAAA,EAAS,KAAA,CAAM,IAAA,CAAK,OAAA,EAAS,EAAE,CAAA;AAAA,QACrC;AAAA,MACF;AAEA,MAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,IACxB,CAAA;AAAA,EACF;AAEA,EAAA,IAAI,OAAO,KAAA,EAAO;AAChB,IAAA,MAAM,WAAW,MAAA,CAAO,KAAA;AACxB,IAAA,QAAA,CAAS,KAAA,GAAQ,CAAC,KAAA,KAAU;AAC1B,MAAA,MAAM,QAAkB,EAAC;AACzB,MAAA,MAAM,KAAA,GAAQ,SAAS,KAAA,IAAS,OAAA;AAChC,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,EAAI,EAAE,CAAA;AAE3B,MAAA,MAAM,OAAA,GAAU,SAAS,OAAA,CAAQ,GAAA;AAAA,QAAI,CAAA,CAAA,KACnC,OAAO,CAAA,KAAM,QAAA,GAAW,EAAE,GAAA,EAAK,CAAA,EAAG,OAAO,CAAA,EAAE,GAAI,EAAE,GAAA,EAAK,CAAA,CAAE,KAAK,KAAA,EAAO,CAAA,CAAE,SAAS,CAAA,CAAE,GAAA,EAAK,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAO,OACzG;AAEA,MAAA,KAAA,CAAM,IAAA,CAAK,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,KAAK,CAAA,CAAE,IAAA,CAAK,KAAK,CAAA,GAAI,IAAI,CAAA;AAC9D,MAAA,KAAA,CAAM,IAAA,CAAK,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,MAAM,KAAK,CAAA,CAAE,IAAA,CAAK,KAAK,CAAA,GAAI,IAAI,CAAA;AAE7D,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,CAAA,GAAA,KAAO;AAC/B,UAAA,MAAM,KAAA,GAAS,IAAA,CAAiC,GAAA,CAAI,GAAG,CAAA;AACvD,UAAA,IAAI,QAAA,IAAY,OAAO,GAAA,CAAI,MAAA,SAAe,GAAA,CAAI,MAAA,CAAO,OAAO,IAAI,CAAA;AAChE,UAAA,IAAI,IAAI,GAAA,KAAQ,IAAA,SAAa,CAAA,CAAA,EAAI,KAAK,OAAO,KAAK,CAAA,IAAA,CAAA;AAClD,UAAA,OAAO,MAAA,CAAO,SAAS,GAAG,CAAA;AAAA,QAC5B,CAAC,CAAA;AACD,QAAA,KAAA,CAAM,KAAK,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,KAAK,IAAI,IAAI,CAAA;AAAA,MAC5C;AAEA,MAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,IACxB,CAAA;AAAA,EACF;AAEA,EAAA,OAAO,QAAA;AACT;ACrGA,SAAS,yBAAyB,YAAA,EAA8C;AAC9E,EAAA,OAAO,YAAA,KAAiB,eAAe,UAAA,GAAa,YAAA;AACtD;AAEA,SAAS,6BAA6B,YAAA,EAA8C;AAClF,EAAA,MAAM,GAAA,GAAM,yBAAyB,YAAY,CAAA;AACjD,EAAA,OAAO,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,GAAG,oCAAoC,GAAG,CAAA;AAClE;AAEA,SAAS,eAAe,QAAA,EAA4B;AAClD,EAAA,OAAO,QAAA,CAAS,KAAA,CAAM,QAAQ,CAAA,CAAE,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA;AACnE;AAEA,IAAI,gBAAA;AAEG,SAAS,mBAAmB,MAAA,EAA8C;AAC/E,EAAA,gBAAA,GAAmB,MAAA;AACrB;AAEO,SAAS,kBAAA,GAAiE;AAC/E,EAAA,OAAO,gBAAA;AACT;AAaO,SAAS,mBACd,MAAA,EACoB;AACpB,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,YAAA;AAAA,IACb,aAAa,MAAA,CAAO,WAAA;AAAA,IACpB,KAAA,EAAO,CAAC,KAAA,EAAO,SAAA,KAA8B;AAC3C,MAAA,MAAM,QAAA,GAAW,QAAQ,GAAA,EAAI;AAC7B,MAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,KAAA,CAAM,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AACjD,MAAA,MAAM,UAAA,uBAAiB,GAAA,EAAY;AAEnC,MAAA,MAAM,kBAAkB,kBAAA,EAAmB;AAC3C,MAAA,MAAM,cAAA,GAAiB,eAAA,GAAkB,MAAA,CAAO,QAAQ,CAAA;AACxD,MAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,QAAA,OAAO;AAAA,UACL,OAAO,UAAA,CAAW,IAAA;AAAA,UAClB,OAAA,EAAS,CAAA;AAAA,UACT,WAAW,UAAA,CAAW,IAAA;AAAA,UACtB,eAAA,EAAiB,CAAA;AAAA,UACjB,cAAc,EAAC;AAAA,UACf,cAAA,EAAgB,KAAA,CAAM,IAAA,CAAK,UAAU,CAAA,CAAE,IAAI,CAAC,EAAA,MAAQ,EAAE,EAAA,EAAG,CAAE;AAAA,SAC7D;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AACjC,MAAA,KAAA,MAAW,OAAA,IAAW,eAAe,KAAA,EAAO;AAC1C,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS;AAAA,UAC/B,GAAA,EAAK,QAAA;AAAA,UACL,MAAA,EAAQ,cAAA,CAAe,OAAA,IAAW;AAAC,SACpC,CAAA;AACD,QAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,UAAA,QAAA,CAAS,IAAI,CAAC,CAAA;AAAA,QAChB;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,GACJ,OAAO,eAAA,IACP,cAAA,CAAe,mBACf,CAAC,4BAAA,CAA6B,MAAA,CAAO,YAAY,CAAC,CAAA;AAEpD,MAAA,MAAM,cAAc,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,GAAI,QAAA,GAAW,CAAC,QAAQ,CAAA;AAElE,MAAA,KAAA,MAAW,YAAY,QAAA,EAAU;AAC/B,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,EAAU,QAAQ,CAAA;AACxC,QAAA,IAAI,OAAA;AACJ,QAAA,IAAI;AACF,UAAA,OAAA,GAAU,YAAA,CAAa,UAAU,OAAO,CAAA;AAAA,QAC1C,CAAA,CAAA,MAAQ;AACN,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AAChC,QAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,UAAA,KAAA,MAAW,MAAM,WAAA,EAAa;AAC5B,YAAA,MAAM,OAAO,IAAI,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,GAAG,KAAK,CAAA;AAC3C,YAAA,IAAI,CAAA;AACJ,YAAA,OAAA,CAAQ,CAAA,GAAI,IAAA,CAAK,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AACrC,cAAA,MAAM,GAAA,GAAM,cAAA,CAAe,CAAA,CAAE,CAAC,KAAK,EAAE,CAAA;AACrC,cAAA,KAAA,MAAW,MAAM,GAAA,EAAK;AACpB,gBAAA,IAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,EAAG;AACtB,kBAAA,UAAA,CAAW,IAAI,EAAE,CAAA;AAAA,gBACnB;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,MAAA,MAAM,YAAA,GAAe,KAAA,CAAM,IAAA,CAAK,UAAU,CAAA,CAAE,IAAI,CAAC,EAAA,MAAQ,EAAE,EAAA,EAAG,CAAE,CAAA;AAChE,MAAA,MAAM,iBAAiB,KAAA,CAAM,IAAA,CAAK,UAAU,CAAA,CACzC,MAAA,CAAO,CAAC,EAAA,KAAO,CAAC,WAAW,GAAA,CAAI,EAAE,CAAC,CAAA,CAClC,GAAA,CAAI,CAAC,EAAA,MAAQ,EAAE,IAAG,CAAE,CAAA;AAEvB,MAAA,MAAM,QAAQ,UAAA,CAAW,IAAA;AACzB,MAAA,MAAM,UAAU,YAAA,CAAa,MAAA;AAC7B,MAAA,MAAM,eAAA,GAAkB,QAAQ,CAAA,GAAI,IAAA,CAAK,MAAO,OAAA,GAAU,KAAA,GAAS,GAAG,CAAA,GAAI,GAAA;AAE1E,MAAA,OAAO;AAAA,QACL,KAAA;AAAA,QACA,OAAA;AAAA,QACA,WAAW,KAAA,GAAQ,OAAA;AAAA,QACnB,eAAA;AAAA,QACA,YAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAAA,GACF;AACF;AAaO,SAAS,iBACd,MAAA,EACoB;AACpB,EAAA,OAAO;AAAA,IACL,aAAa,MAAA,CAAO,WAAA;AAAA,IACpB,aAAa,MAAA,CAAO,WAAA;AAAA,IACpB,KAAA,EAAO,CAAC,KAAA,EAAO,QAAA,KAA6B;AAC1C,MAAA,MAAM,OAAA,GAAU,QAAA,CAAS,MAAA,CAAO,WAAW,CAAA;AAC3C,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,GAAG,SAAA,EAAW,CAAA,EAAG,eAAA,EAAiB,GAAA,EAAK,YAAA,EAAc,EAAC,EAAG,cAAA,EAAgB,EAAC,EAAE;AAAA,MAC1G;AAEA,MAAA,MAAM,YAAA,uBAAmB,GAAA,EAAY;AACrC,MAAA,MAAM,kBAAA,uBAAyB,GAAA,EAAoB;AACnD,MAAA,KAAA,MAAW,CAAA,IAAK,OAAA,CAAQ,MAAA,EAAO,EAA4E;AACzG,QAAA,IAAI,MAAA,CAAO,gBAAgB,CAAC,CAAA,CAAE,GAAG,UAAA,CAAW,MAAA,CAAO,YAAY,CAAA,EAAG;AAClE,QAAA,YAAA,CAAa,GAAA,CAAI,EAAE,EAAE,CAAA;AACrB,QAAA,kBAAA,CAAmB,GAAA,CAAI,EAAE,EAAA,EAAI,CAAA,CAAE,QAAQ,CAAA,CAAE,WAAA,IAAe,EAAE,EAAE,CAAA;AAAA,MAC9D;AAEA,MAAA,MAAM,UAAA,uBAAiB,GAAA,EAAY;AACnC,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACrB,QAAA,KAAA,MAAW,GAAA,IAAO,KAAK,SAAA,EAAW;AAChC,UAAA,IAAI,MAAA,CAAO,YAAA,IAAgB,GAAA,CAAI,IAAA,KAAS,OAAO,YAAA,EAAc;AAC7D,UAAA,IAAI,YAAA,CAAa,IAAI,GAAA,CAAI,MAAM,GAAG,UAAA,CAAW,GAAA,CAAI,IAAI,MAAM,CAAA;AAAA,QAC7D;AAAA,MACF;AAEA,MAAA,MAAM,eAA+C,EAAC;AACtD,MAAA,MAAM,iBAAmD,EAAC;AAC1D,MAAA,KAAA,MAAW,MAAM,YAAA,EAAc;AAC7B,QAAA,MAAM,IAAA,GAAO,kBAAA,CAAmB,GAAA,CAAI,EAAE,CAAA;AACtC,QAAA,IAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,EAAG;AACtB,UAAA,YAAA,CAAa,IAAA,CAAK,EAAE,EAAA,EAAI,WAAA,EAAa,MAAM,CAAA;AAAA,QAC7C,CAAA,MAAO;AACL,UAAA,cAAA,CAAe,IAAA,CAAK,EAAE,EAAA,EAAI,WAAA,EAAa,MAAM,CAAA;AAAA,QAC/C;AAAA,MACF;AAEA,MAAA,MAAM,QAAQ,YAAA,CAAa,IAAA;AAC3B,MAAA,MAAM,UAAU,YAAA,CAAa,MAAA;AAC7B,MAAA,MAAM,eAAA,GAAkB,QAAQ,CAAA,GAAI,IAAA,CAAK,MAAO,OAAA,GAAU,KAAA,GAAS,GAAG,CAAA,GAAI,GAAA;AAE1E,MAAA,OAAO,EAAE,OAAO,OAAA,EAAS,SAAA,EAAW,QAAQ,OAAA,EAAS,eAAA,EAAiB,cAAc,cAAA,EAAe;AAAA,IACrG;AAAA,GACF;AACF;;;AC1LA,IAAM,OAAA,GAAkC;AAAA,EACtC,OAAA,EAAS,KAAA;AAAA,EACT,IAAA,EAAM,SAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,kBAAA,EAAoB,QAAA;AAAA,EACpB,MAAA,EAAQ,KAAA;AAAA,EACR,SAAA,EAAW,QAAA;AAAA,EACX,WAAA,EAAa,UAAA;AAAA,EACb,WAAA,EAAa,WAAA;AAAA,EACb,0BAAA,EAA4B,WAAA;AAAA,EAC5B,6BAAA,EAA+B,WAAA;AAAA,EAC/B,mBAAA,EAAqB,SAAA;AAAA,EACrB,SAAA,EAAW,MAAA;AAAA,EACX,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,KAAA;AAAA,EACN,IAAA,EAAM,QAAA;AAAA,EACN,MAAA,EAAQ,OAAA;AAAA,EACR,MAAA,EAAQ;AACV,CAAA;AAEA,IAAM,kBAAA,GAAiC;AAAA,EACrC,CAAC,UAAA,EAAY,KAAA,EAAO,QAAQ,CAAA;AAAA,EAC5B,CAAC,SAAS,QAAQ,CAAA;AAAA,EAClB,CAAC,MAAA,EAAQ,SAAA,EAAW,MAAM,CAAA;AAAA,EAC1B,CAAC,WAAW,QAAQ;AACtB,CAAA;AAEA,SAAS,UAAU,GAAA,EAAyB;AAC1C,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,IAAA,EAAK,CAAE,WAAA,EAAY;AAEvC,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,oDAAoD,CAAA;AAChF,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,EAAE,MAAM,OAAA,EAAQ;AAAA,EACzB;AAEA,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK;AAE3B,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,MAAA,EAAQ,MAAM,CAAC,CAAA,KAAM,SAAY,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA,GAAI,MAAA;AAAA,IACpD,SAAA,EAAW,MAAM,CAAC,CAAA,KAAM,SAAY,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA,GAAI,MAAA;AAAA,IACvD,KAAA,EAAO,MAAM,CAAC,CAAA,KAAM,SAAY,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA,GAAI;AAAA,GACrD;AACF;AAEA,SAAS,UAAU,IAAA,EAAsB;AACvC,EAAA,OAAO,OAAA,CAAQ,IAAI,CAAA,IAAK,IAAA;AAC1B;AAEA,SAAS,qBAAA,CACP,MACA,MAAA,EAC2C;AAC3C,EAAA,MAAM,UAAqD,EAAC;AAC5D,EAAA,MAAM,QAAA,GAAW,UAAU,IAAI,CAAA;AAC/B,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,IAAI,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA;AAC5B,IAAA,IAAI,GAAA,KAAQ,EAAA,EAAI,GAAA,GAAM,KAAA,CAAM,QAAQ,QAAQ,CAAA;AAC5C,IAAA,IAAI,GAAA,KAAQ,IAAI,OAAA,CAAQ,IAAA,CAAK,EAAE,KAAA,EAAO,KAAA,EAAO,KAAK,CAAA;AAAA,EACpD;AACA,EAAA,OAAO,OAAA;AACT;AAWO,SAAS,iBAAA,CAAkB,UAAkB,OAAA,EAA0B;AAC5E,EAAA,MAAM,IAAA,GAAO,UAAU,QAAQ,CAAA;AAC/B,EAAA,MAAM,GAAA,GAAM,UAAU,OAAO,CAAA;AAE7B,EAAA,MAAM,QAAA,GAAW,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AACpC,EAAA,MAAM,OAAA,GAAU,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AAElC,EAAA,IAAI,aAAa,OAAA,EAAS;AACxB,IAAA,IAAI,QAAA,KAAa,SAAA,IAAa,QAAA,KAAa,SAAA,EAAW;AACpD,MAAA,IAAI,IAAA,CAAK,SAAA,KAAc,MAAA,IAAa,GAAA,CAAI,cAAc,MAAA,EAAW;AAC/D,QAAA,IAAI,GAAA,CAAI,SAAA,GAAY,IAAA,CAAK,SAAA,EAAW,OAAO,KAAA;AAAA,MAC7C;AACA,MAAA,IAAI,IAAA,CAAK,KAAA,KAAU,MAAA,IAAa,GAAA,CAAI,UAAU,MAAA,EAAW;AACvD,QAAA,IAAI,GAAA,CAAI,KAAA,GAAQ,IAAA,CAAK,KAAA,EAAO,OAAO,KAAA;AAAA,MACrC;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,IAAA,CAAK,MAAA,KAAW,MAAA,IAAa,GAAA,CAAI,WAAW,MAAA,EAAW;AACzD,MAAA,OAAO,GAAA,CAAI,UAAU,IAAA,CAAK,MAAA;AAAA,IAC5B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,aAAA,GAAgB,qBAAA,CAAsB,IAAA,CAAK,IAAA,EAAM,kBAAkB,CAAA;AACzE,EAAA,MAAM,YAAA,GAAe,qBAAA,CAAsB,GAAA,CAAI,IAAA,EAAM,kBAAkB,CAAA;AAEvE,EAAA,KAAA,MAAW,MAAM,aAAA,EAAe;AAC9B,IAAA,KAAA,MAAW,MAAM,YAAA,EAAc;AAC7B,MAAA,IAAI,EAAA,CAAG,KAAA,KAAU,EAAA,CAAG,KAAA,EAAO;AACzB,QAAA,OAAO,EAAA,CAAG,SAAS,EAAA,CAAG,KAAA;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;AClHO,IAAM,wBAAA,GAA2BA,EAAE,MAAA,CAAO;AAAA,EAC/C,MAAA,EAAQA,EAAE,MAAA,EAAO;AAAA,EACjB,UAAA,EAAYA,EAAE,MAAA,EAAO;AAAA,EACrB,UAAA,EAAYA,CAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAChC,WAAA,EAAaA,CAAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAC1B,CAAC;AAIM,IAAM,wBAAA,GAA2BA,EAAE,MAAA,CAAO;AAAA,EAC/C,MAAA,EAAQA,EAAE,MAAA,EAAO;AAAA,EACjB,QAAA,EAAUA,CAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC9B,SAAA,EAAWA,CAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC/B,WAAA,EAAaA,CAAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAC1B,CAAC;ACcM,SAAS,UAAA,CAAW,KAAU,GAAA,EAAkB;AACrD,EAAA,IAAI,CAAC,GAAA,CAAI,UAAA,CAAW,IAAI,GAAG,OAAO,MAAA;AAClC,EAAA,MAAM,QAAQ,GAAA,CAAI,SAAA,CAAU,CAAC,CAAA,CAAE,MAAM,GAAG,CAAA;AACxC,EAAA,IAAI,OAAA,GAAU,GAAA;AACd,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,OAAA,IAAW,IAAA,IAAQ,OAAO,OAAA,KAAY,UAAU,OAAO,MAAA;AAC3D,IAAA,OAAA,GAAU,QAAQ,IAAI,CAAA;AAAA,EACxB;AACA,EAAA,OAAO,OAAA;AACT;AAGO,SAAS,eAAA,CAAgB,KAAU,KAAA,EAAiB;AACzD,EAAA,IAAI,SAAS,OAAO,KAAA,KAAU,YAAY,OAAO,KAAA,CAAM,SAAS,QAAA,EAAU;AACxE,IAAA,OAAO,UAAA,CAAW,GAAA,EAAK,KAAA,CAAM,IAAI,CAAA;AAAA,EACnC;AACA,EAAA,OAAO,KAAA;AACT;AAGA,SAAS,mBAAA,CAAoB,KAAU,MAAA,EAA8E;AACnH,EAAA,MAAM,QAAQ,GAAA,CAAI,KAAA;AAClB,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,IAAA;AAEhD,EAAA,KAAA,MAAW,CAAC,OAAA,EAAS,QAAQ,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AACvD,IAAA,IAAI,QAAA,IAAY,IAAA,IAAQ,OAAO,QAAA,KAAa,QAAA,EAAU;AACtD,IAAA,MAAM,OAAA,GAAU,CAAC,KAAA,EAAO,MAAA,EAAQ,OAAO,QAAA,EAAU,OAAA,EAAS,WAAW,MAAM,CAAA;AAC3E,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAE5B,MAAA,MAAM,EAAA,GAAM,SAAiB,MAAM,CAAA;AACnC,MAAA,IAAI,CAAC,EAAA,EAAI;AACT,MAAA,IAAI,EAAA,CAAG,gBAAgB,MAAA,EAAQ,OAAO,EAAE,OAAA,EAAS,SAAA,EAAW,IAAI,MAAA,EAAO;AACvE,MAAA,IAAI,EAAA,CAAG,WAAW,CAAA,KAAM,MAAA,SAAe,EAAE,OAAA,EAAS,SAAA,EAAW,EAAA,EAAI,MAAA,EAAO;AAAA,IAC1E;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,OAAA,IAAW,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAG;AACxC,IAAA,MAAM,WAAW,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA,CAAE,OAAO,OAAO,CAAA;AAClD,IAAA,MAAM,aAAA,GAAgB,SAAS,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAC,CAAA;AACjE,IAAA,IAAI,cAAc,QAAA,CAAS,MAAM,CAAA,EAAG,OAAO,EAAE,OAAA,EAAQ;AAAA,EACvD;AAEA,EAAA,MAAM,OAAA,GAAU,IAAI,UAAA,EAAY,OAAA;AAChC,EAAA,IAAI,OAAA,IAAW,OAAO,OAAA,KAAY,QAAA,EAAU;AAC1C,IAAA,IAAI,UAAU,OAAA,EAAS,OAAO,EAAE,OAAA,EAAS,CAAA,qBAAA,EAAwB,MAAM,CAAA,CAAA,EAAG;AAAA,EAC5E;AAGA,EAAA,SAAS,cAAc,GAAA,EAAmB;AACxC,IAAA,IAAI,GAAA,IAAO,IAAA,IAAQ,OAAO,GAAA,KAAQ,UAAU,OAAO,KAAA;AACnD,IAAA,IAAI,GAAA,CAAI,WAAW,CAAA,KAAM,MAAA,EAAQ,OAAO,IAAA;AACxC,IAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA,EAAG;AACpC,MAAA,IAAI,aAAA,CAAc,GAAG,CAAA,EAAG,OAAO,IAAA;AAAA,IACjC;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,cAAc,GAAG,CAAA,EAAG,OAAO,EAAE,SAAS,mBAAA,EAAoB;AAE9D,EAAA,OAAO,IAAA;AACT;AAEO,IAAM,cAAA,GAAgC;AAAA,EAC3C,WAAA,CAAY,OAAA,EAAkB,OAAA,EAAmB,QAAA,EAAiC;AAChF,IAAA,MAAM,GAAA,GAAM,OAAA;AACZ,IAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,SAAiB,EAAC;AAE7C,IAAA,MAAM,UAAyB,EAAC;AAChC,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,MAAM,KAAA,GAAQ,mBAAA,CAAoB,GAAA,EAAK,MAAM,CAAA;AAC7C,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,MAAA;AAAA,UACA,QAAA,EAAU,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,MAAM,OAAO,CAAA,CAAA;AAAA,UACtC,OAAA,EAAS,EAAE,GAAA,EAAK,KAAA;AAAM,SACvB,CAAA;AAAA,MACH;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AACF;AAWA,SAAS,kBAAkB,IAAA,EAAsB;AAC/C,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA;AACrC,EAAA,OAAO,YAAY,CAAA,GAAI,IAAA,CAAK,SAAA,CAAU,QAAA,GAAW,CAAC,CAAA,GAAI,IAAA;AACxD;AAEA,SAAS,mBAAmB,OAAA,EAA2C;AACrE,EAAA,MAAM,MAAA,GAAS,IAAI,aAAA,CAAc,MAAA,EAAO;AACxC,EAAA,MAAM,SAA4B,EAAC;AAEnC,EAAA,IAAI;AAEF,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,CAAO,OAAO,CAAA;AACjC,IAAA,MAAM,aAAa,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GAAI,GAAA,GAAM,CAAC,GAAG,CAAA;AAElD,IAAA,KAAA,MAAW,QAAQ,UAAA,EAAY;AAC7B,MAAA,IAAI,IAAA,CAAK,IAAA,KAAS,QAAA,IAAY,IAAA,CAAK,YAAY,OAAA,EAAS;AAExD,MAAA,MAAM,OAAA,GAAkB,OAAO,IAAA,CAAK,KAAA,KAAU,QAAA,GAC1C,IAAA,CAAK,KAAA,GAEJ,IAAA,CAAK,KAAA,GAAkB,CAAC,CAAA,EAAG,KAAA,IAAS,EAAA;AACzC,MAAA,MAAM,SAAA,GAAY,kBAAkB,OAAO,CAAA;AAE3C,MAAA,MAAM,OAAA,GAAA,CAAkD,IAAA,CAAK,kBAAA,IAAsB,IAEhF,MAAA,CAAO,CAAC,GAAA,KAAa,GAAA,CAAI,QAAA,KAAa,QAAQ,CAAA,CAE9C,GAAA,CAAI,CAAC,GAAA,KAAa;AACjB,QAAA,MAAM,OAAA,GAAU,GAAA,CAAI,MAAA,EAAQ,MAAA,IAAU,EAAA;AACtC,QAAA,IAAI,OAAA,GAAU,GAAA,CAAI,UAAA,EAAY,QAAA,IAAY,EAAA;AAC1C,QAAA,IAAI,GAAA,CAAI,YAAY,MAAA,EAAQ;AAC1B,UAAA,OAAA,IAAW,CAAA,CAAA,EAAI,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,CAAA,CAAA;AAAA,QACtC;AACA,QAAA,IAAI,GAAA,CAAI,YAAY,KAAA,EAAO;AACzB,UAAA,OAAA,GAAU,QAAQ,OAAA,CAAQ,KAAA,EAAO,IAAI,GAAA,CAAI,UAAA,CAAW,KAAK,CAAA,CAAA,CAAG,CAAA;AAAA,QAC9D;AACA,QAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,OAAA,EAAQ;AAAA,MACxC,CAAC,CAAA;AAEH,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,CAAA;AAAA,MAC1C;AAAA,IACF;AAEA,IAAA,OAAO,MAAA,CAAO,MAAA,GAAS,CAAA,GAAI,MAAA,GAAS,IAAA;AAAA,EACtC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,SAAS,kBAAkB,OAAA,EAAoC;AAC7D,EAAA,MAAM,SAA4B,EAAC;AACnC,EAAA,MAAM,UAAA,GAAa,iHAAA;AAEnB,EAAA,IAAI,KAAA;AACJ,EAAA,OAAA,CAAQ,KAAA,GAAQ,UAAA,CAAW,IAAA,CAAK,OAAO,OAAO,IAAA,EAAM;AAClD,IAAA,MAAM,SAAA,GAAY,MAAM,CAAC,CAAA;AACzB,IAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,IAAA,MAAM,UAAiD,EAAC;AAExD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA;AAC/D,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI,kEAAA,CAAmE,IAAA,CAAK,IAAI,CAAA,EAAG;AAEnF,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,mDAAmD,CAAA;AAC/E,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,QAAA,CAAS,CAAC,GAAG,IAAA,EAAM,QAAA,CAAS,CAAC,CAAA,EAAG,CAAA;AAAA,MACvD;AAAA,IACF;AAEA,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,CAAA;AAAA,IAC1C;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEO,IAAM,UAAA,GAA4B;AAAA,EACvC,WAAA,CAAY,OAAA,EAAkB,OAAA,EAAmB,QAAA,EAAiC;AAChF,IAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,EAAC;AAEzC,IAAA,IAAI,MAAA,GAAS,mBAAmB,OAAO,CAAA;AACvC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAA,GAAS,kBAAkB,OAAO,CAAA;AAAA,IACpC;AAEA,IAAA,MAAM,UAAyB,EAAC;AAChC,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,MAAM,QAAQ,MAAA,CAAO,IAAA;AAAA,QACnB,CAAC,CAAA,KAAM,CAAA,CAAE,KAAK,WAAA,EAAY,KAAM,OAAO,WAAA;AAAY,OACrD;AACA,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,MAAA;AAAA,UACA,QAAA,EAAU,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,MAAM,IAAI,CAAA,CAAA;AAAA,UACnC,OAAA,EAAS,EAAE,KAAA;AAAM,SAClB,CAAA;AAAA,MACH;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AACF;AAMA,SAASC,gBAAe,QAAA,EAA4B;AAClD,EAAA,OAAO,QAAA,CAAS,KAAA,CAAM,QAAQ,CAAA,CAAE,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA;AACnE;AAEO,IAAM,iBAAA,GAAmC;AAAA,EAC9C,WAAA,CAAY,OAAA,EAAkB,OAAA,EAAmB,QAAA,EAAiC;AAChF,IAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,EAAC;AAEzC,IAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,OAAO,CAAA;AACjC,IAAA,MAAM,UAAyB,EAAC;AAChC,IAAA,MAAM,cAAA,GAAiB,8DAAA;AAEvB,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AAChC,IAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,KAAA,CAAM,QAAQ,OAAA,EAAA,EAAW;AACxD,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,OAAA,GAAU,CAAC,CAAA;AAC9B,MAAA,MAAM,OAAO,IAAI,MAAA,CAAO,cAAA,CAAe,MAAA,EAAQ,eAAe,KAAK,CAAA;AACnE,MAAA,IAAI,CAAA;AACJ,MAAA,OAAA,CAAQ,CAAA,GAAI,IAAA,CAAK,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AACrC,QAAA,MAAM,GAAA,GAAMA,eAAAA,CAAe,CAAA,CAAE,CAAC,KAAK,EAAE,CAAA;AACrC,QAAA,KAAA,MAAW,MAAM,GAAA,EAAK;AACpB,UAAA,IAAI,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA,EAAG;AACrB,YAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,cACX,MAAA,EAAQ,EAAA;AAAA,cACR,QAAA,EAAU,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AAAA,cAChC,OAAA,EAAS,EAAE,QAAA,EAAU,IAAA,EAAM,OAAA;AAAQ,aACpC,CAAA;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AACF;AAKO,SAAS,wBAAwB,eAAA,EAA0C;AAChF,EAAA,OAAO;AAAA,IACL,WAAA,CAAY,OAAA,EAAkB,OAAA,EAAmB,QAAA,EAAiC;AAChF,MAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,EAAC;AAEzC,MAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,OAAO,CAAA;AACjC,MAAA,MAAM,UAAyB,EAAC;AAEhC,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AAChC,MAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,KAAA,CAAM,QAAQ,OAAA,EAAA,EAAW;AACxD,QAAA,MAAM,IAAA,GAAO,KAAA,CAAM,OAAA,GAAU,CAAC,CAAA;AAC9B,QAAA,KAAA,MAAW,MAAM,eAAA,EAAiB;AAChC,UAAA,MAAM,OAAO,IAAI,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,GAAG,KAAK,CAAA;AAC3C,UAAA,IAAI,CAAA;AACJ,UAAA,OAAA,CAAQ,CAAA,GAAI,IAAA,CAAK,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AACrC,YAAA,MAAM,GAAA,GAAMA,eAAAA,CAAe,CAAA,CAAE,CAAC,KAAK,EAAE,CAAA;AACrC,YAAA,KAAA,MAAW,MAAM,GAAA,EAAK;AACpB,cAAA,IAAI,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA,EAAG;AACrB,gBAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,kBACX,MAAA,EAAQ,EAAA;AAAA,kBACR,QAAA,EAAU,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AAAA,kBAChC,OAAA,EAAS,EAAE,QAAA,EAAU,IAAA,EAAM,OAAA;AAAQ,iBACpC,CAAA;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,MAAA,OAAO,OAAA;AAAA,IACT;AAAA,GACF;AACF;AAMA,IAAM,iBAAA,GAAmD;AAAA,EACvD,OAAA,EAAS,cAAA;AAAA,EACT,GAAA,EAAK,UAAA;AAAA,EACL,UAAA,EAAY;AACd,CAAA;AAEA,SAAS,oBAAoB,MAAA,EAA4C;AACvE,EAAA,IAAI,MAAA,CAAO,OAAA,EAAS,OAAO,MAAA,CAAO,OAAA;AAClC,EAAA,IAAI,MAAA,CAAO,SAAS,YAAA,IAAgB,MAAA,CAAO,mBAAmB,MAAA,CAAO,eAAA,CAAgB,SAAS,CAAA,EAAG;AAC/F,IAAA,OAAO,uBAAA,CAAwB,OAAO,eAAe,CAAA;AAAA,EACvD;AACA,EAAA,OAAO,iBAAA,CAAkB,MAAA,CAAO,IAAI,CAAA,IAAK,IAAA;AAC3C;AAMA,SAAS,eAAA,CAAgB,UAAkB,UAAA,EAA6B;AACtE,EAAA,MAAM,OAAA,GAAUC,YAAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAC9C,EAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,MAAA,KAAW,GAAG,OAAO,IAAA;AAE7C,EAAA,IAAI,eAAe,SAAA,EAAW;AAC5B,IAAA,IAAI,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA,EAAG;AAC9B,MAAA,OAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,IAC3B;AACA,IAAA,OAAOC,MAAU,OAAO,CAAA;AAAA,EAC1B;AAEA,EAAA,OAAO,OAAA;AACT;AAqBO,SAAS,aAAA,CACd,OAAA,EACA,OAAA,EACA,QAAA,EACkB;AAClB,EAAA,MAAM,GAAA,GAAM,QAAA,IAAY,OAAA,CAAQ,GAAA,EAAI;AACpC,EAAA,MAAM,MAAA,uBAA+B,GAAA,EAAI;AACzC,EAAA,MAAM,WAA0B,EAAC;AAEjC,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,MAAM,OAAA,GAAU,oBAAoB,MAAM,CAAA;AAC1C,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,CAAA,kCAAA,EAAqC,MAAA,CAAO,IAAI,CAAA,4BAAA,CAAA;AAAA,QACzD,YAAY,MAAA,CAAO;AAAA,OACpB,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AACjC,IAAA,KAAA,MAAW,OAAA,IAAW,OAAO,KAAA,EAAO;AAClC,MAAA,MAAM,KAAA,GAAQC,IAAAA,CAAK,IAAA,CAAK,OAAA,EAAS;AAAA,QAC/B,GAAA;AAAA,QACA,MAAA,EAAQ,MAAA,CAAO,OAAA,IAAW;AAAC,OAC5B,CAAA;AACD,MAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,QAAA,QAAA,CAAS,IAAI,CAAC,CAAA;AAAA,MAChB;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,MAAA,MAAM,WAAW,UAAA,CAAW,OAAO,IAAI,OAAA,GAAUC,IAAAA,CAAK,KAAK,OAAO,CAAA;AAClE,MAAA,IAAI,CAAC,UAAA,CAAW,QAAQ,CAAA,EAAG;AAE3B,MAAA,IAAI,OAAA;AACJ,MAAA,IAAI;AACF,QAAA,OAAA,GAAU,eAAA,CAAgB,QAAA,EAAU,MAAA,CAAO,IAAI,CAAA;AAAA,MACjD,SAAS,CAAA,EAAG;AACV,QAAA,MAAM,MAAM,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AACrD,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,CAAA,eAAA,EAAkB,OAAO,CAAA,EAAA,EAAK,GAAG,CAAA,CAAA;AAAA,UAC1C,YAAY,MAAA,CAAO,IAAA;AAAA,UACnB,QAAA,EAAU;AAAA,SACX,CAAA;AACD,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,WAAW,IAAA,EAAM;AAErB,MAAA,IAAI,OAAA;AACJ,MAAA,IAAI;AACF,QAAA,OAAA,GAAU,OAAA,CAAQ,WAAA,CAAY,OAAA,EAAS,OAAA,EAAS,OAAO,CAAA;AAAA,MACzD,SAAS,CAAA,EAAG;AACV,QAAA,MAAM,MAAM,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AACrD,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,CAAA,kBAAA,EAAqB,OAAO,CAAA,EAAA,EAAK,GAAG,CAAA,CAAA;AAAA,UAC7C,YAAY,MAAA,CAAO,IAAA;AAAA,UACnB,QAAA,EAAU;AAAA,SACX,CAAA;AACD,QAAA;AAAA,MACF;AAEA,MAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,QAAA,MAAM,WAAA,GAA+B;AAAA,UACnC,GAAG,KAAA;AAAA,UACH,YAAY,MAAA,CAAO,IAAA;AAAA,UACnB,UAAU,MAAA,CAAO,QAAA;AAAA,UACjB,QAAA,EAAU;AAAA,SACZ;AAEA,QAAA,MAAM,QAAA,GAAW,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,MAAM,CAAA;AACxC,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,QAAA,CAAS,KAAK,WAAW,CAAA;AAAA,QAC3B,CAAA,MAAO;AACL,UAAA,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,MAAA,EAAQ,CAAC,WAAW,CAAC,CAAA;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,QAAA,EAAS;AACrC;AAUO,SAAS,iBAAA,CACd,MAAA,EACA,OAAA,EAEA,cAAA,EACA,IAAA,EACa;AACb,EAAA,MAAM,SAAgC,EAAC;AACvC,EAAA,MAAM,WAAoC,EAAC;AAE3C,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,IAAA,GAAO,cAAA,CAAe,KAAA,CAAM,UAAU,CAAA;AAC5C,IAAA,IAAI,CAAC,IAAA,EAAM;AAEX,IAAA,IAAI,KAAA,CAAM,eAAe,SAAA,EAAW;AAClC,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA;AAChC,MAAA,MAAM,MAAM,KAAA,CAAM,OAAA;AAClB,MAAA,IAAI,CAAC,GAAA,EAAK,KAAA,EAAO,SAAA,EAAW;AAE5B,MAAA,mBAAA,CAAoB,QAAQ,OAAA,EAAS,GAAA,CAAI,GAAA,EAAK,GAAA,CAAI,OAAO,QAAQ,CAAA;AAAA,IACnE,CAAA,MAAA,IAAW,KAAA,CAAM,UAAA,KAAe,KAAA,EAAO;AACrC,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA;AAChC,MAAA,MAAM,MAAM,KAAA,CAAM,OAAA;AAClB,MAAA,IAAI,CAAC,KAAK,KAAA,EAAO;AAEjB,MAAA,eAAA,CAAgB,MAAA,EAAQ,OAAA,EAAS,GAAA,CAAI,KAAA,EAAO,QAAQ,CAAA;AAAA,IACtD;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,OAAO,MAAA,KAAW,CAAA;AAAA,IAC3B,MAAA;AAAA,IACA;AAAA,GACF;AACF;AAEA,SAAS,mBAAA,CACP,MAAA,EACA,OAAA,EAEA,GAAA,EAEA,OACA,QAAA,EACM;AACN,EAAA,IAAI,OAAA,CAAQ,MAAA,IAAU,KAAA,CAAM,SAAA,EAAW;AACrC,IAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,MAAA,CAAO,WAAA,EAAY;AAClD,IAAA,MAAM,YAAA,GAAe,KAAA,CAAM,MAAA,EAAQ,WAAA,EAAY;AAC/C,IAAA,IAAI,YAAA,IAAgB,iBAAiB,cAAA,EAAgB;AACnD,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,CAAA,qBAAA,EAAwB,MAAM,CAAA,YAAA,EAAe,cAAA,CAAe,aAAa,CAAA,QAAA,EAAW,YAAA,CAAa,WAAA,EAAa,CAAA,CAAA;AAAA,QACvH;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,IAAI,KAAA,CAAM,SAAA,IAAa,OAAA,CAAQ,UAAA,EAAY;AACzC,IAAA,MAAM,QAAA,GAAA,CACH,KAAA,CAAM,SAAA,CAAU,UAAA,IAAc,EAAC,EAAG,GAAA;AAAA;AAAA,MAEjC,CAAC,CAAA,KAAW,eAAA,CAAgB,GAAA,EAAK,CAAC;AAAA,KACpC;AAEF,IAAA,KAAA,MAAW,aAAA,IAAiB,QAAQ,UAAA,EAAY;AAC9C,MAAA,MAAM,QAAQ,QAAA,CAAS,IAAA;AAAA,QACrB,CAAC,CAAA,KAAM,CAAA,EAAG,IAAA,KAAS,aAAA,CAAc,IAAA,KAAS,CAAC,aAAA,CAAc,EAAA,IAAM,CAAA,EAAG,EAAA,KAAO,aAAA,CAAc,EAAA;AAAA,OACzF;AACA,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,CAAA,WAAA,EAAc,aAAA,CAAc,IAAI,6BAA6B,MAAM,CAAA,CAAA,CAAA;AAAA,UAC5E,MAAA;AAAA,UACA,OAAO,aAAA,CAAc;AAAA,SACtB,CAAA;AAAA,MACH,CAAA,MAAA,IAAW,aAAA,CAAc,IAAA,IAAQ,KAAA,CAAM,QAAQ,IAAA,EAAM;AACnD,QAAA,IAAI,CAAC,iBAAA,CAAkB,aAAA,CAAc,MAAM,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA,EAAG;AAC7D,UAAA,QAAA,CAAS,IAAA,CAAK;AAAA,YACZ,OAAA,EAAS,CAAA,WAAA,EAAc,aAAA,CAAc,IAAI,CAAA,0BAAA,EAA6B,cAAc,IAAI,CAAA,QAAA,EAAW,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA,CAAA;AAAA,YACpH,MAAA;AAAA,YACA,OAAO,aAAA,CAAc;AAAA,WACtB,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,KAAA,CAAM,SAAA,IAAa,OAAA,CAAQ,kBAAA,EAAoB;AACjD,IAAA,MAAM,eAAA,GAAkB,MAAM,SAAA,CAAU,SAAA,GAAY,KAAK,CAAA,IAAK,KAAA,CAAM,SAAA,CAAU,SAAA,GAAY,KAAK,CAAA;AAE/F,IAAA,IAAI,cAAA,GAAsB,eAAA,EAAiB,OAAA,GAAU,kBAAkB,CAAA,EAAG,MAAA;AAC1E,IAAA,cAAA,GAAiB,eAAA,CAAgB,KAAK,cAAc,CAAA;AAEpD,IAAA,IAAI,cAAA,EAAgB,SAAS,OAAA,EAAS;AACpC,MAAA,cAAA,GAAiB,eAAA,CAAgB,GAAA,EAAK,cAAA,CAAe,KAAK,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,aAAA,GAAgB,cAAA,EAAgB,UAAA,IAAc,EAAC;AAErD,IAAA,KAAA,MAAW,YAAA,IAAgB,QAAQ,kBAAA,EAAoB;AACrD,MAAA,MAAM,SAAA,GAAY,aAAA,CAAc,YAAA,CAAa,IAAI,CAAA;AACjD,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,CAAA,mBAAA,EAAsB,YAAA,CAAa,IAAI,6BAA6B,MAAM,CAAA,CAAA,CAAA;AAAA,UACnF,MAAA;AAAA,UACA,OAAO,YAAA,CAAa;AAAA,SACrB,CAAA;AAAA,MACH,CAAA,MAAA,IAAW,YAAA,CAAa,IAAA,IAAQ,SAAA,CAAU,IAAA,EAAM;AAC9C,QAAA,IAAI,CAAC,iBAAA,CAAkB,YAAA,CAAa,IAAA,EAAM,SAAA,CAAU,IAAI,CAAA,EAAG;AACzD,UAAA,QAAA,CAAS,IAAA,CAAK;AAAA,YACZ,OAAA,EAAS,sBAAsB,YAAA,CAAa,IAAI,6BAA6B,YAAA,CAAa,IAAI,CAAA,QAAA,EAAW,SAAA,CAAU,IAAI,CAAA,CAAA;AAAA,YACvH,MAAA;AAAA,YACA,OAAO,YAAA,CAAa;AAAA,WACrB,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,eAAA,CACP,MAAA,EACA,OAAA,EACA,KAAA,EACA,QAAA,EACM;AACN,EAAA,IAAI,CAAC,QAAQ,OAAA,EAAS;AAEtB,EAAA,KAAA,MAAW,WAAA,IAAe,QAAQ,OAAA,EAAS;AACzC,IAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,IAAA;AAAA,MAC7B,CAAC,MAAM,CAAA,CAAE,IAAA,CAAK,aAAY,KAAM,WAAA,CAAY,KAAK,WAAA;AAAY,KAC/D;AAEA,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,SAAS,CAAA,QAAA,EAAW,WAAA,CAAY,IAAI,CAAA,sBAAA,EAAyB,QAAQ,SAAS,CAAA,CAAA,CAAA;AAAA,QAC9E,MAAA;AAAA,QACA,OAAO,WAAA,CAAY;AAAA,OACpB,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,OAAA,CAAQ,UAAA,IAAc,WAAA,CAAY,IAAA,IAAQ,SAAS,IAAA,EAAM;AAC3D,MAAA,IAAI,CAAC,iBAAA,CAAkB,WAAA,CAAY,IAAA,EAAM,QAAA,CAAS,IAAI,CAAA,EAAG;AACvD,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,CAAA,QAAA,EAAW,WAAA,CAAY,IAAI,CAAA,0BAAA,EAA6B,OAAA,CAAQ,SAAS,CAAA,YAAA,EAAe,WAAA,CAAY,IAAI,CAAA,QAAA,EAAW,QAAA,CAAS,IAAI,CAAA,CAAA;AAAA,UACzI,MAAA;AAAA,UACA,OAAO,WAAA,CAAY;AAAA,SACpB,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF","file":"index.js","sourcesContent":["/**\n * Definition and validation of model relations\n */\nimport { z } from 'zod';\n\n// ============================================================================\n// Model Levels\n// ============================================================================\n\n/**\n * Model abstraction level\n * \n * - L0: Business + Domain Analysis (Why / Problem space)\n * Desired outcomes/value, business flows, actors, terminology, business rules\n * - L1: Requirements (What)\n * Functional/non-functional requirements, constraints, acceptance criteria\n * - L2: Design (How / Direction)\n * Architecture, component breakdown, domain model, key sequences\n * - L3: Detailed Design/Implementation (How to build / Concrete artifacts)\n * Screen/API/DB definitions, external SSOT references\n */\nexport type ModelLevel = 'L0' | 'L1' | 'L2' | 'L3';\n\n/**\n * Get numeric index of level\n */\nexport function getLevelIndex(level: ModelLevel): number {\n return ['L0', 'L1', 'L2', 'L3'].indexOf(level);\n}\n\n// ============================================================================\n// Relation Types\n// ============================================================================\n\n/**\n * Relation types\n */\nexport const RELATION_TYPES = [\n 'dependsOn',\n 'uses',\n 'includes',\n 'implements',\n 'refines',\n 'verifies',\n 'verifiedBy',\n 'satisfies',\n 'traces',\n 'relatedTo',\n] as const;\n\nexport type RelationType = typeof RELATION_TYPES[number];\n\n/**\n * Relation schema\n */\nexport const RelationSchema = z.object({\n /** Relation type */\n type: z.enum(RELATION_TYPES),\n /** Target ID */\n target: z.string(),\n /** Description (optional) */\n description: z.string().optional(),\n});\n\n/**\n * Relation field to add to model schemas\n * Usage: schema.extend({ relations: RelationsFieldSchema })\n */\nexport const RelationsFieldSchema = z.array(RelationSchema).optional();\n\nexport type Relation = z.infer<typeof RelationSchema>;\n\n// ============================================================================\n// Relation Constraints\n// ============================================================================\n\n/**\n * Definition of relation constraints\n */\nexport interface RelationConstraint {\n /** Allowed target levels (all levels allowed if not specified) */\n allowedTargetLevels?: ModelLevel[];\n /** Level constraint rule */\n levelRule: 'source>target' | 'source>=target' | 'same' | 'any';\n /** Direction of impact propagation */\n propagation: 'forward' | 'backward' | 'both';\n}\n\n/**\n * Constraint definitions per relation type\n * \n * Level hierarchy:\n * L0 (Business) → L1 (Requirements) → L2 (Design) → L3 (Implementation)\n * Abstract ───────────────────────────→ Concrete\n */\nexport const RELATION_CONSTRAINTS: Record<RelationType, RelationConstraint> = {\n // Concrete→Abstract (implementation/design fulfills requirements)\n 'implements': {\n allowedTargetLevels: ['L1'], // Implements requirements\n levelRule: 'source>target',\n propagation: 'forward', // A changes → B needs review\n },\n // Concrete→Abstract (design/implementation satisfies business/requirements)\n 'satisfies': {\n allowedTargetLevels: ['L0', 'L1'], // Satisfies business/requirements\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A needs update\n },\n // Concrete→Abstract (refinement: requirements refine business, design refines requirements)\n 'refines': {\n allowedTargetLevels: ['L0', 'L1'], // Refines business/requirements\n levelRule: 'source>target',\n propagation: 'backward', // B changes → A needs update\n },\n // Test→Requirements/Business (verification relationship)\n 'verifies': {\n allowedTargetLevels: ['L0', 'L1'], // Verifies business/requirements\n levelRule: 'any',\n propagation: 'backward', // B changes → A needs update\n },\n // Dependencies (same level or concrete→abstract)\n 'dependsOn': {\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A affected\n },\n // Usage relationship (no level constraint)\n 'uses': {\n levelRule: 'any',\n propagation: 'backward', // B changes → A affected\n },\n // Inclusion relationship (same level only)\n 'includes': {\n levelRule: 'same',\n propagation: 'backward', // B changes → A affected\n },\n // Bidirectional tracing\n 'traces': {\n levelRule: 'any',\n propagation: 'both',\n },\n // Spec→Test (verification relationship: spec is verified by test code)\n 'verifiedBy': {\n allowedTargetLevels: ['L2', 'L3'],\n levelRule: 'any',\n propagation: 'backward',\n },\n // General relation\n 'relatedTo': {\n levelRule: 'any',\n propagation: 'both',\n },\n};\n\n// ============================================================================\n// Relation Validation\n// ============================================================================\n\n/**\n * Relation validation result\n */\nexport interface RelationValidationResult {\n valid: boolean;\n errors: RelationValidationError[];\n}\n\n/**\n * Relation validation error\n */\nexport interface RelationValidationError {\n type: 'level_violation' | 'target_level_violation' | 'self_reference' | 'cycle_detected';\n message: string;\n relation: Relation;\n sourceId: string;\n}\n\n/**\n * Validate level constraint for single relation\n * \n * @param sourceLevel - Source model level (set in _models/)\n * @param sourceSpecId - Source spec ID\n * @param relation - Relation\n * @param targetLevel - Target model level\n */\nexport function validateRelationLevel(\n sourceLevel: ModelLevel | undefined,\n sourceSpecId: string,\n relation: Relation,\n targetLevel: ModelLevel | undefined,\n): RelationValidationError | null {\n // Self-reference check\n if (sourceSpecId === relation.target) {\n return {\n type: 'self_reference',\n message: `Self-reference is not allowed: ${sourceSpecId} → ${relation.target}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n\n // Skip if level is undefined\n if (!sourceLevel || !targetLevel) {\n return null;\n }\n \n const constraint = RELATION_CONSTRAINTS[relation.type];\n \n // Target level constraint check\n if (constraint.allowedTargetLevels && \n !constraint.allowedTargetLevels.includes(targetLevel)) {\n return {\n type: 'target_level_violation',\n message: `'${relation.type}' relation target must be ${constraint.allowedTargetLevels.join(' or ')}, but target is ${targetLevel}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n \n // Level direction constraint check\n const srcIdx = getLevelIndex(sourceLevel);\n const tgtIdx = getLevelIndex(targetLevel);\n \n switch (constraint.levelRule) {\n case 'source>target':\n if (srcIdx <= tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'source>=target':\n if (srcIdx < tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be same or more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'same':\n if (srcIdx !== tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) and target (${targetLevel}) to be same level`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n }\n \n return null;\n}\n\n/**\n * Detect circular references\n */\nexport function detectCycles(\n relations: Array<{ sourceId: string; targetId: string; type: RelationType }>,\n): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const graph = new Map<string, Set<string>>();\n const relationMap = new Map<string, Relation>();\n \n // Build graph\n for (const rel of relations) {\n if (!graph.has(rel.sourceId)) {\n graph.set(rel.sourceId, new Set());\n }\n graph.get(rel.sourceId)!.add(rel.targetId);\n relationMap.set(`${rel.sourceId}→${rel.targetId}`, { type: rel.type, target: rel.targetId });\n }\n \n // Detect cycles using DFS\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const cyclePath: string[] = [];\n \n function dfs(node: string): boolean {\n visited.add(node);\n recursionStack.add(node);\n cyclePath.push(node);\n \n const neighbors = graph.get(node);\n if (neighbors) {\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor)) {\n return true;\n }\n } else if (recursionStack.has(neighbor)) {\n // Cycle detected\n const cycleStart = cyclePath.indexOf(neighbor);\n const cycle = cyclePath.slice(cycleStart);\n cycle.push(neighbor); // Close the cycle\n \n errors.push({\n type: 'cycle_detected',\n message: `Circular reference detected: ${cycle.join(' → ')}`,\n relation: relationMap.get(`${node}→${neighbor}`)!,\n sourceId: node,\n });\n return true;\n }\n }\n }\n \n cyclePath.pop();\n recursionStack.delete(node);\n return false;\n }\n \n for (const node of graph.keys()) {\n if (!visited.has(node)) {\n dfs(node);\n }\n }\n \n return errors;\n}\n\n/**\n * Infer model ID from spec ID (prefix-based)\n */\nexport function inferModelIdFromSpecId(specId: string): string | undefined {\n const prefixMap: Record<string, string> = {\n 'REQ': 'requirement',\n 'CR': 'constraint',\n 'UC': 'usecase',\n 'ACTOR': 'actor',\n 'TERM': 'term',\n 'COMP': 'component',\n 'ENT': 'entity',\n 'FLOW': 'process-flow',\n 'LAYER': 'layer',\n 'BND': 'boundary',\n 'SCR': 'screen',\n 'API': 'api-ref',\n 'TBL': 'table-ref',\n 'IAC': 'iac-ref',\n 'BATCH': 'batch-ref',\n };\n \n for (const [prefix, modelId] of Object.entries(prefixMap)) {\n if (specId.startsWith(prefix + '-')) {\n return modelId;\n }\n }\n \n return undefined;\n}\n","/**\n * Core DSL — Base spec schema\n *\n * Common schema fields shared by all models: id, name, description, relations.\n * Models extend this with domain-specific fields via `.extend()`.\n */\nimport { z } from 'zod';\nimport { RelationSchema } from '../relation.js';\n\nexport const baseSpecSchema = z.object({\n id: z.string(),\n name: z.string().min(1),\n description: z.string(),\n relations: z.array(RelationSchema).optional(),\n});\n\nexport type BaseSpec = z.infer<typeof baseSpecSchema>;\n","/**\n * Core DSL — Lint rule factories\n *\n * Factory functions that produce LintRule<T> objects for common patterns.\n * Users compose these in their model's `lintRules` array.\n */\nimport type { LintRule } from '../model.js';\n\n/**\n * Require a string field to be non-empty.\n */\nexport function requireField<T>(\n field: keyof T & string,\n severity: 'error' | 'warning' | 'info' = 'warning',\n): LintRule<T> {\n return {\n id: `has-${field}`,\n severity,\n message: `${field} must not be empty`,\n check: (spec) => {\n const value = (spec as Record<string, unknown>)[field];\n return !value || (typeof value === 'string' && value.trim() === '');\n },\n };\n}\n\n/**\n * Require an array field to have at least `min` elements.\n */\nexport function arrayMinLength<T>(\n field: keyof T & string,\n min: number,\n severity: 'error' | 'warning' = 'error',\n): LintRule<T> {\n return {\n id: `${field}-min-${min}`,\n severity,\n message: `${field} must have at least ${min} item(s)`,\n check: (spec) => {\n const value = (spec as Record<string, unknown>)[field];\n return !Array.isArray(value) || value.length < min;\n },\n };\n}\n\n/**\n * Require the `id` field to match a prefix-based format.\n *\n * Default pattern: `{prefix}-{NNN}` (e.g. `FR-001`).\n * Override with `opts.pattern` for custom formats.\n */\nexport function idFormat<T>(\n prefix: string,\n opts?: { digits?: number; pattern?: RegExp },\n): LintRule<T> {\n const pattern = opts?.pattern\n ?? new RegExp(`^${prefix}-\\\\d{${opts?.digits ?? 3}}$`);\n\n return {\n id: 'id-format',\n severity: 'warning',\n message: `ID should match format ${pattern}`,\n check: (spec) => {\n const id = (spec as Record<string, unknown>)['id'];\n return typeof id !== 'string' || !pattern.test(id);\n },\n };\n}\n\n/**\n * Require child element IDs to follow parent ID (e.g. `FR-001-01`).\n */\nexport function childIdFormat<T>(\n arrayField: keyof T & string,\n idField: string,\n): LintRule<T> {\n return {\n id: `${arrayField}-id-format`,\n severity: 'warning',\n message: `${arrayField} IDs should follow parent ID pattern`,\n check: (spec) => {\n const parentId = (spec as Record<string, unknown>)['id'] as string;\n const children = (spec as Record<string, unknown>)[arrayField];\n if (!Array.isArray(children) || !parentId) return false;\n return children.some((child: Record<string, unknown>) => {\n const childId = child[idField];\n return typeof childId === 'string' && !childId.startsWith(parentId + '-');\n });\n },\n };\n}\n","/**\n * Core DSL — Exporter factories\n *\n * Factory functions that produce Exporter<T> objects from declarative config.\n */\nimport type { Exporter } from '../model.js';\n\ninterface MetaField<T> {\n key: keyof T & string;\n label?: string;\n}\n\ninterface SectionConfig<T> {\n heading: string;\n field?: keyof T & string;\n render?: (spec: T) => string;\n optional?: boolean;\n}\n\ninterface ColumnConfig<T> {\n key: keyof T & string;\n label?: string;\n render?: (value: unknown, spec: T) => string;\n}\n\nexport interface MarkdownExporterConfig<T> {\n outputDir: string;\n single?: {\n title: keyof T & string | ((spec: T) => string);\n meta?: Array<keyof T & string | MetaField<T>>;\n sections?: SectionConfig<T>[];\n };\n index?: {\n title?: string;\n columns: Array<keyof T & string | ColumnConfig<T>>;\n };\n}\n\n/**\n * Create a markdown exporter from declarative configuration.\n */\nexport function markdownExporter<T extends { id: string }>(\n config: MarkdownExporterConfig<T>,\n): Exporter<T> {\n const exporter: Exporter<T> = {\n format: 'markdown',\n outputDir: config.outputDir,\n filename: (spec) => spec.id,\n };\n\n if (config.single) {\n const singleCfg = config.single;\n exporter.single = (spec) => {\n const lines: string[] = [];\n\n const title = typeof singleCfg.title === 'function'\n ? singleCfg.title(spec)\n : String((spec as Record<string, unknown>)[singleCfg.title] ?? '');\n lines.push(`# ${title}`, '');\n\n if (singleCfg.meta) {\n for (const m of singleCfg.meta) {\n const key = typeof m === 'string' ? m : m.key;\n const label = typeof m === 'string' ? key : (m.label ?? m.key);\n const value = (spec as Record<string, unknown>)[key];\n if (value !== undefined && value !== null) {\n lines.push(`**${label}**: ${String(value)}`);\n }\n }\n lines.push('');\n }\n\n if (singleCfg.sections) {\n for (const section of singleCfg.sections) {\n let content: string | undefined;\n if (section.render) {\n content = section.render(spec);\n } else if (section.field) {\n const value = (spec as Record<string, unknown>)[section.field];\n if (typeof value === 'string') content = value;\n }\n if (section.optional && !content) continue;\n lines.push(`## ${section.heading}`, '');\n if (content) lines.push(content, '');\n }\n }\n\n return lines.join('\\n');\n };\n }\n\n if (config.index) {\n const indexCfg = config.index;\n exporter.index = (specs) => {\n const lines: string[] = [];\n const title = indexCfg.title ?? 'Index';\n lines.push(`# ${title}`, '');\n\n const columns = indexCfg.columns.map(c =>\n typeof c === 'string' ? { key: c, label: c } : { key: c.key, label: c.label ?? c.key, render: c.render },\n );\n\n lines.push('| ' + columns.map(c => c.label).join(' | ') + ' |');\n lines.push('| ' + columns.map(() => '---').join(' | ') + ' |');\n\n for (const spec of specs) {\n const cells = columns.map(col => {\n const value = (spec as Record<string, unknown>)[col.key];\n if ('render' in col && col.render) return col.render(value, spec);\n if (col.key === 'id') return `[${value}](./${value}.md)`;\n return String(value ?? '-');\n });\n lines.push('| ' + cells.join(' | ') + ' |');\n }\n\n return lines.join('\\n');\n };\n }\n\n return exporter;\n}\n","/**\n * Core DSL — Coverage checkers and annotation scan utilities\n *\n * Per-model checker factory functions (testChecker, externalOpenAPIChecker, etc.)\n * have been replaced by the global scanner (src/core/global-scanner.ts).\n * This module retains coverage checkers and shared annotation scan utilities.\n */\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { glob } from 'glob';\nimport type { CoverageChecker, CoverageResult } from '../model.js';\nimport type { ArtifactConfig } from '../config-api.js';\n\n// ---------------------------------------------------------------------------\n// Annotation scan utilities (shared by coverage checkers)\n// ---------------------------------------------------------------------------\n\nexport type AnnotationRelationType = 'verifiedBy' | 'implements' | 'traces';\n\nfunction relationTypeToAnnotation(relationType: AnnotationRelationType): string {\n return relationType === 'verifiedBy' ? 'verifies' : relationType;\n}\n\nfunction getDefaultPatternForRelation(relationType: AnnotationRelationType): RegExp {\n const ann = relationTypeToAnnotation(relationType);\n return new RegExp(`@${ann}\\\\s+([\\\\w-]+(?:[,\\\\s]+[\\\\w-]+)*)`, 'g');\n}\n\nfunction extractSpecIds(captured: string): string[] {\n return captured.split(/[,\\s]+/).map(s => s.trim()).filter(Boolean);\n}\n\nlet _artifactsConfig: Record<string, ArtifactConfig> | undefined;\n\nexport function setArtifactsConfig(config: Record<string, ArtifactConfig>): void {\n _artifactsConfig = config;\n}\n\nexport function getArtifactsConfig(): Record<string, ArtifactConfig> | undefined {\n return _artifactsConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Annotation coverage checker\n// ---------------------------------------------------------------------------\n\nexport interface AnnotationCoverageConfig {\n artifact: string;\n relationType: AnnotationRelationType;\n description: string;\n contentPatterns?: RegExp[];\n}\n\nexport function annotationCoverage<T extends { id: string }>(\n config: AnnotationCoverageConfig,\n): CoverageChecker<T> {\n return {\n targetModel: 'annotation',\n description: config.description,\n check: (specs, _registry): CoverageResult => {\n const basePath = process.cwd();\n const allSpecIds = new Set(specs.map((s) => s.id));\n const coveredIds = new Set<string>();\n\n const artifactsConfig = getArtifactsConfig();\n const artifactConfig = artifactsConfig?.[config.artifact];\n if (!artifactConfig) {\n return {\n total: allSpecIds.size,\n covered: 0,\n uncovered: allSpecIds.size,\n coveragePercent: 0,\n coveredItems: [],\n uncoveredItems: Array.from(allSpecIds).map((id) => ({ id })),\n };\n }\n\n const allFiles = new Set<string>();\n for (const pattern of artifactConfig.globs) {\n const found = glob.sync(pattern, {\n cwd: basePath,\n ignore: artifactConfig.exclude ?? [],\n });\n for (const f of found) {\n allFiles.add(f);\n }\n }\n\n const patterns =\n config.contentPatterns ??\n artifactConfig.contentPatterns ??\n [getDefaultPatternForRelation(config.relationType)];\n\n const patternList = Array.isArray(patterns) ? patterns : [patterns];\n\n for (const filePath of allFiles) {\n const fullPath = join(basePath, filePath);\n let content: string;\n try {\n content = readFileSync(fullPath, 'utf-8');\n } catch {\n continue;\n }\n\n const lines = content.split('\\n');\n for (const line of lines) {\n for (const re of patternList) {\n const copy = new RegExp(re.source, re.flags);\n let m: RegExpExecArray | null;\n while ((m = copy.exec(line)) !== null) {\n const ids = extractSpecIds(m[1] ?? '');\n for (const id of ids) {\n if (allSpecIds.has(id)) {\n coveredIds.add(id);\n }\n }\n }\n }\n }\n }\n\n const coveredItems = Array.from(coveredIds).map((id) => ({ id }));\n const uncoveredItems = Array.from(allSpecIds)\n .filter((id) => !coveredIds.has(id))\n .map((id) => ({ id }));\n\n const total = allSpecIds.size;\n const covered = coveredItems.length;\n const coveragePercent = total > 0 ? Math.round((covered / total) * 100) : 100;\n\n return {\n total,\n covered,\n uncovered: total - covered,\n coveragePercent,\n coveredItems,\n uncoveredItems,\n };\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Relation-based coverage checker\n// ---------------------------------------------------------------------------\n\nexport interface RelationCoverageConfig {\n targetModel: string;\n description: string;\n relationType?: string;\n targetPrefix?: string;\n}\n\nexport function relationCoverage<T extends { id: string; relations?: Array<{ type: string; target: string }> }>(\n config: RelationCoverageConfig,\n): CoverageChecker<T> {\n return {\n targetModel: config.targetModel,\n description: config.description,\n check: (specs, registry): CoverageResult => {\n const targets = registry[config.targetModel];\n if (!targets) {\n return { total: 0, covered: 0, uncovered: 0, coveragePercent: 100, coveredItems: [], uncoveredItems: [] };\n }\n\n const allTargetIds = new Set<string>();\n const targetDescriptions = new Map<string, string>();\n for (const t of targets.values() as IterableIterator<{ id: string; name?: string; description?: string }>) {\n if (config.targetPrefix && !t.id.startsWith(config.targetPrefix)) continue;\n allTargetIds.add(t.id);\n targetDescriptions.set(t.id, t.name ?? t.description ?? t.id);\n }\n\n const coveredIds = new Set<string>();\n for (const spec of specs) {\n if (!spec.relations) continue;\n for (const rel of spec.relations) {\n if (config.relationType && rel.type !== config.relationType) continue;\n if (allTargetIds.has(rel.target)) coveredIds.add(rel.target);\n }\n }\n\n const coveredItems: CoverageResult['coveredItems'] = [];\n const uncoveredItems: CoverageResult['uncoveredItems'] = [];\n for (const id of allTargetIds) {\n const desc = targetDescriptions.get(id);\n if (coveredIds.has(id)) {\n coveredItems.push({ id, description: desc });\n } else {\n uncoveredItems.push({ id, description: desc });\n }\n }\n\n const total = allTargetIds.size;\n const covered = coveredItems.length;\n const coveragePercent = total > 0 ? Math.round((covered / total) * 100) : 100;\n\n return { total, covered, uncovered: total - covered, coveragePercent, coveredItems, uncoveredItems };\n },\n };\n}\n","/**\n * Type Compatibility — Containment-based type comparison\n *\n * The spec defines the minimum required type. The DDL/OpenAPI satisfies the\n * requirement if its type can hold all values of the spec type (equal or wider).\n */\n\ninterface ParsedType {\n base: string;\n length?: number;\n precision?: number;\n scale?: number;\n}\n\nconst ALIASES: Record<string, string> = {\n INTEGER: 'INT',\n BOOL: 'BOOLEAN',\n REAL: 'FLOAT',\n 'DOUBLE PRECISION': 'DOUBLE',\n SERIAL: 'INT',\n BIGSERIAL: 'BIGINT',\n SMALLSERIAL: 'SMALLINT',\n TIMESTAMPTZ: 'TIMESTAMP',\n 'TIMESTAMP WITH TIME ZONE': 'TIMESTAMP',\n 'TIMESTAMP WITHOUT TIME ZONE': 'TIMESTAMP',\n 'CHARACTER VARYING': 'VARCHAR',\n CHARACTER: 'CHAR',\n INT2: 'SMALLINT',\n INT4: 'INT',\n INT8: 'BIGINT',\n FLOAT4: 'FLOAT',\n FLOAT8: 'DOUBLE',\n};\n\nconst CONTAINMENT_CHAINS: string[][] = [\n ['SMALLINT', 'INT', 'BIGINT'],\n ['FLOAT', 'DOUBLE'],\n ['CHAR', 'VARCHAR', 'TEXT'],\n ['INTEGER', 'NUMBER'],\n];\n\nfunction parseType(raw: string): ParsedType {\n const trimmed = raw.trim().toUpperCase();\n\n const match = trimmed.match(/^([A-Z\\s]+?)(?:\\(\\s*(\\d+)(?:\\s*,\\s*(\\d+))?\\s*\\))?$/);\n if (!match) {\n return { base: trimmed };\n }\n\n const base = match[1].trim();\n\n return {\n base,\n length: match[2] !== undefined ? Number(match[2]) : undefined,\n precision: match[2] !== undefined ? Number(match[2]) : undefined,\n scale: match[3] !== undefined ? Number(match[3]) : undefined,\n };\n}\n\nfunction normalize(base: string): string {\n return ALIASES[base] ?? base;\n}\n\nfunction findAllChainPositions(\n base: string,\n chains: string[][],\n): Array<{ chain: string[]; index: number }> {\n const results: Array<{ chain: string[]; index: number }> = [];\n const resolved = normalize(base);\n for (const chain of chains) {\n let idx = chain.indexOf(base);\n if (idx === -1) idx = chain.indexOf(resolved);\n if (idx !== -1) results.push({ chain, index: idx });\n }\n return results;\n}\n\n/**\n * Returns true if ddlType can hold all values representable by specType.\n *\n * Containment rules:\n * - Numeric: SMALLINT ⊂ INT ⊂ BIGINT, FLOAT ⊂ DOUBLE\n * - String: CHAR(n) ⊂ VARCHAR(n) ⊂ TEXT (with length comparison)\n * - DECIMAL: precision/scale must be >= spec\n * - OpenAPI: integer ⊂ number\n */\nexport function isTypeContainedBy(specType: string, ddlType: string): boolean {\n const spec = parseType(specType);\n const ddl = parseType(ddlType);\n\n const specNorm = normalize(spec.base);\n const ddlNorm = normalize(ddl.base);\n\n if (specNorm === ddlNorm) {\n if (specNorm === 'DECIMAL' || specNorm === 'NUMERIC') {\n if (spec.precision !== undefined && ddl.precision !== undefined) {\n if (ddl.precision < spec.precision) return false;\n }\n if (spec.scale !== undefined && ddl.scale !== undefined) {\n if (ddl.scale < spec.scale) return false;\n }\n return true;\n }\n\n if (spec.length !== undefined && ddl.length !== undefined) {\n return ddl.length >= spec.length;\n }\n return true;\n }\n\n const specPositions = findAllChainPositions(spec.base, CONTAINMENT_CHAINS);\n const ddlPositions = findAllChainPositions(ddl.base, CONTAINMENT_CHAINS);\n\n for (const sp of specPositions) {\n for (const dp of ddlPositions) {\n if (sp.chain === dp.chain) {\n return dp.index >= sp.index;\n }\n }\n }\n\n return false;\n}\n","/**\n * Core DSL — Edge-typed relation schemas\n *\n * Specialized relation schemas for `implements` and `verifiedBy` edges.\n * These carry additional properties beyond the generic RelationSchema.\n */\nimport { z } from 'zod';\n\nexport const ImplementsRelationSchema = z.object({\n target: z.string(),\n targetType: z.string(),\n sourcePath: z.string().optional(),\n description: z.string().optional(),\n});\n\nexport type ImplementsRelation = z.infer<typeof ImplementsRelationSchema>;\n\nexport const VerifiedByRelationSchema = z.object({\n target: z.string(),\n testPath: z.string().optional(),\n framework: z.string().optional(),\n description: z.string().optional(),\n});\n\nexport type VerifiedByRelation = z.infer<typeof VerifiedByRelationSchema>;\n","/**\n * Global Scanner — Scans all configured sources for spec IDs\n *\n * Replaces per-model externalChecker with a single global scan pass.\n * Built-in scanners: openapi, ddl, annotation.\n * Custom scanners can be plugged in via SourceConfig.scanner.\n */\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join, isAbsolute } from 'node:path';\nimport { glob } from 'glob';\nimport { parse as parseYaml } from 'yaml';\nimport nodeSqlParser from 'node-sql-parser';\nimport type { SourceConfig, SourceMatch, SourceScanner } from './config-api.js';\nimport type { CheckResult, DeepValidationConfig, OpenAPIValidationMapping, DDLValidationMapping } from './model.js';\nimport { isTypeContainedBy } from './dsl/type-compat.js';\n\n// ============================================================================\n// Scan Result Types\n// ============================================================================\n\nexport interface GlobalScanMatch extends SourceMatch {\n /** Which source config produced this match */\n sourceType: string;\n /** Relation type from the source config */\n relation: 'implements' | 'verifiedBy';\n /** File path where the match was found */\n filePath: string;\n}\n\nexport type GlobalScanResult = Map<string, GlobalScanMatch[]>;\n\n// ============================================================================\n// Built-in: OpenAPI Scanner\n// ============================================================================\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function resolveRef(doc: any, ref: string): any {\n if (!ref.startsWith('#/')) return undefined;\n const parts = ref.substring(2).split('/');\n let current = doc;\n for (const part of parts) {\n if (current == null || typeof current !== 'object') return undefined;\n current = current[part];\n }\n return current;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function maybeResolveRef(doc: any, value: any): any {\n if (value && typeof value === 'object' && typeof value.$ref === 'string') {\n return resolveRef(doc, value.$ref);\n }\n return value;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction findSpecIdInOpenAPI(doc: any, specId: string): { pathKey: string; operation?: any; method?: string } | null {\n const paths = doc.paths;\n if (!paths || typeof paths !== 'object') return null;\n\n for (const [pathKey, pathItem] of Object.entries(paths)) {\n if (pathItem == null || typeof pathItem !== 'object') continue;\n const methods = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head'];\n for (const method of methods) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const op = (pathItem as any)[method];\n if (!op) continue;\n if (op.operationId === specId) return { pathKey, operation: op, method };\n if (op['x-spec-id'] === specId) return { pathKey, operation: op, method };\n }\n }\n\n for (const pathKey of Object.keys(paths)) {\n const segments = pathKey.split('/').filter(Boolean);\n const cleanSegments = segments.map(s => s.replace(/^\\{|\\}$/g, ''));\n if (cleanSegments.includes(specId)) return { pathKey };\n }\n\n const schemas = doc.components?.schemas;\n if (schemas && typeof schemas === 'object') {\n if (specId in schemas) return { pathKey: `#/components/schemas/${specId}` };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function searchXSpecId(obj: any): boolean {\n if (obj == null || typeof obj !== 'object') return false;\n if (obj['x-spec-id'] === specId) return true;\n for (const val of Object.values(obj)) {\n if (searchXSpecId(val)) return true;\n }\n return false;\n }\n if (searchXSpecId(doc)) return { pathKey: '(x-spec-id match)' };\n\n return null;\n}\n\nexport const openapiScanner: SourceScanner = {\n findSpecIds(content: unknown, specIds: string[], filePath: string): SourceMatch[] {\n const doc = content;\n if (!doc || typeof doc !== 'object') return [];\n\n const matches: SourceMatch[] = [];\n for (const specId of specIds) {\n const match = findSpecIdInOpenAPI(doc, specId);\n if (match) {\n matches.push({\n specId,\n location: `${filePath}:${match.pathKey}`,\n context: { doc, match },\n });\n }\n }\n return matches;\n },\n};\n\n// ============================================================================\n// Built-in: DDL Scanner\n// ============================================================================\n\ninterface TableDefinition {\n name: string;\n columns: Array<{ name: string; type: string }>;\n}\n\nfunction stripSchemaPrefix(name: string): string {\n const dotIndex = name.lastIndexOf('.');\n return dotIndex >= 0 ? name.substring(dotIndex + 1) : name;\n}\n\nfunction parseDDLWithParser(content: string): TableDefinition[] | null {\n const parser = new nodeSqlParser.Parser();\n const tables: TableDefinition[] = [];\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ast = parser.astify(content) as any;\n const statements = Array.isArray(ast) ? ast : [ast];\n\n for (const stmt of statements) {\n if (stmt.type !== 'create' || stmt.keyword !== 'table') continue;\n\n const rawName: string = typeof stmt.table === 'string'\n ? stmt.table\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n : (stmt.table as any[])?.[0]?.table ?? '';\n const tableName = stripSchemaPrefix(rawName);\n\n const columns: Array<{ name: string; type: string }> = (stmt.create_definitions || [])\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .filter((def: any) => def.resource === 'column')\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map((def: any) => {\n const colName = def.column?.column ?? '';\n let colType = def.definition?.dataType ?? '';\n if (def.definition?.length) {\n colType += `(${def.definition.length})`;\n }\n if (def.definition?.scale) {\n colType = colType.replace(/\\)$/, `,${def.definition.scale})`);\n }\n return { name: colName, type: colType };\n });\n\n if (tableName) {\n tables.push({ name: tableName, columns });\n }\n }\n\n return tables.length > 0 ? tables : null;\n } catch {\n return null;\n }\n}\n\nfunction parseDDLWithRegex(content: string): TableDefinition[] {\n const tables: TableDefinition[] = [];\n const tableRegex = /CREATE\\s+TABLE\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(?:(?:[`\"']?\\w+[`\"']?\\s*\\.\\s*)?)[`\"']?(\\w+)[`\"']?\\s*\\(([\\s\\S]*?)\\);/gi;\n\n let match;\n while ((match = tableRegex.exec(content)) !== null) {\n const tableName = match[1];\n const body = match[2];\n const columns: Array<{ name: string; type: string }> = [];\n\n const lines = body.split(',').map(l => l.trim()).filter(Boolean);\n for (const line of lines) {\n if (/^\\s*(PRIMARY\\s+KEY|UNIQUE|CHECK|CONSTRAINT|INDEX|FOREIGN\\s+KEY)/i.test(line)) continue;\n\n const colMatch = line.match(/^(?:`|\"|')?(\\w+)(?:`|\"|')?\\s+(\\w+(?:\\([^)]*\\))?)/i);\n if (colMatch) {\n columns.push({ name: colMatch[1], type: colMatch[2] });\n }\n }\n\n if (tableName) {\n tables.push({ name: tableName, columns });\n }\n }\n\n return tables;\n}\n\nexport const ddlScanner: SourceScanner = {\n findSpecIds(content: unknown, specIds: string[], filePath: string): SourceMatch[] {\n if (typeof content !== 'string') return [];\n\n let tables = parseDDLWithParser(content);\n if (!tables) {\n tables = parseDDLWithRegex(content);\n }\n\n const matches: SourceMatch[] = [];\n for (const specId of specIds) {\n const table = tables.find(\n (t) => t.name.toLowerCase() === specId.toLowerCase(),\n );\n if (table) {\n matches.push({\n specId,\n location: `${filePath}:${table.name}`,\n context: { table },\n });\n }\n }\n return matches;\n },\n};\n\n// ============================================================================\n// Built-in: Annotation Scanner\n// ============================================================================\n\nfunction extractSpecIds(captured: string): string[] {\n return captured.split(/[,\\s]+/).map(s => s.trim()).filter(Boolean);\n}\n\nexport const annotationScanner: SourceScanner = {\n findSpecIds(content: unknown, specIds: string[], filePath: string): SourceMatch[] {\n if (typeof content !== 'string') return [];\n\n const specIdSet = new Set(specIds);\n const matches: SourceMatch[] = [];\n const defaultPattern = /@(?:verifies|implements|traces)\\s+([\\w-]+(?:[,\\s]+[\\w-]+)*)/g;\n\n const lines = content.split('\\n');\n for (let lineNum = 1; lineNum <= lines.length; lineNum++) {\n const line = lines[lineNum - 1];\n const copy = new RegExp(defaultPattern.source, defaultPattern.flags);\n let m: RegExpExecArray | null;\n while ((m = copy.exec(line)) !== null) {\n const ids = extractSpecIds(m[1] ?? '');\n for (const id of ids) {\n if (specIdSet.has(id)) {\n matches.push({\n specId: id,\n location: `${filePath}:${lineNum}`,\n context: { filePath, line: lineNum },\n });\n }\n }\n }\n }\n return matches;\n },\n};\n\n/**\n * Create an annotation scanner with custom content patterns.\n */\nexport function createAnnotationScanner(contentPatterns: RegExp[]): SourceScanner {\n return {\n findSpecIds(content: unknown, specIds: string[], filePath: string): SourceMatch[] {\n if (typeof content !== 'string') return [];\n\n const specIdSet = new Set(specIds);\n const matches: SourceMatch[] = [];\n\n const lines = content.split('\\n');\n for (let lineNum = 1; lineNum <= lines.length; lineNum++) {\n const line = lines[lineNum - 1];\n for (const re of contentPatterns) {\n const copy = new RegExp(re.source, re.flags);\n let m: RegExpExecArray | null;\n while ((m = copy.exec(line)) !== null) {\n const ids = extractSpecIds(m[1] ?? '');\n for (const id of ids) {\n if (specIdSet.has(id)) {\n matches.push({\n specId: id,\n location: `${filePath}:${lineNum}`,\n context: { filePath, line: lineNum },\n });\n }\n }\n }\n }\n }\n return matches;\n },\n };\n}\n\n// ============================================================================\n// Scanner Registry\n// ============================================================================\n\nconst BUILT_IN_SCANNERS: Record<string, SourceScanner> = {\n openapi: openapiScanner,\n ddl: ddlScanner,\n annotation: annotationScanner,\n};\n\nfunction getScannerForSource(source: SourceConfig): SourceScanner | null {\n if (source.scanner) return source.scanner;\n if (source.type === 'annotation' && source.contentPatterns && source.contentPatterns.length > 0) {\n return createAnnotationScanner(source.contentPatterns);\n }\n return BUILT_IN_SCANNERS[source.type] ?? null;\n}\n\n// ============================================================================\n// File Loading\n// ============================================================================\n\nfunction loadFileContent(filePath: string, sourceType: string): unknown {\n const content = readFileSync(filePath, 'utf-8');\n if (!content || content.length === 0) return null;\n\n if (sourceType === 'openapi') {\n if (filePath.endsWith('.json')) {\n return JSON.parse(content);\n }\n return parseYaml(content);\n }\n\n return content;\n}\n\n// ============================================================================\n// Global Scan Orchestrator\n// ============================================================================\n\nexport interface ScanWarning {\n message: string;\n sourceType: string;\n filePath?: string;\n}\n\nexport interface GlobalScanOutput {\n matches: GlobalScanResult;\n warnings: ScanWarning[];\n}\n\n/**\n * Run global scan across all configured sources.\n * Returns a map of specId -> matches for all spec IDs found.\n */\nexport function runGlobalScan(\n sources: SourceConfig[],\n specIds: string[],\n basePath?: string,\n): GlobalScanOutput {\n const cwd = basePath ?? process.cwd();\n const result: GlobalScanResult = new Map();\n const warnings: ScanWarning[] = [];\n\n for (const source of sources) {\n const scanner = getScannerForSource(source);\n if (!scanner) {\n warnings.push({\n message: `No scanner found for source type \"${source.type}\". Provide a custom scanner.`,\n sourceType: source.type,\n });\n continue;\n }\n\n const allFiles = new Set<string>();\n for (const pattern of source.paths) {\n const found = glob.sync(pattern, {\n cwd,\n ignore: source.exclude ?? [],\n });\n for (const f of found) {\n allFiles.add(f);\n }\n }\n\n for (const relPath of allFiles) {\n const fullPath = isAbsolute(relPath) ? relPath : join(cwd, relPath);\n if (!existsSync(fullPath)) continue;\n\n let content: unknown;\n try {\n content = loadFileContent(fullPath, source.type);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push({\n message: `Failed to load ${relPath}: ${msg}`,\n sourceType: source.type,\n filePath: relPath,\n });\n continue;\n }\n\n if (content == null) continue;\n\n let matches: SourceMatch[];\n try {\n matches = scanner.findSpecIds(content, specIds, relPath);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push({\n message: `Scanner error for ${relPath}: ${msg}`,\n sourceType: source.type,\n filePath: relPath,\n });\n continue;\n }\n\n for (const match of matches) {\n const globalMatch: GlobalScanMatch = {\n ...match,\n sourceType: source.type,\n relation: source.relation,\n filePath: relPath,\n };\n\n const existing = result.get(match.specId);\n if (existing) {\n existing.push(globalMatch);\n } else {\n result.set(match.specId, [globalMatch]);\n }\n }\n }\n }\n\n return { matches: result, warnings };\n}\n\n// ============================================================================\n// Deep Validation\n// ============================================================================\n\n/**\n * Run deep validation for a spec against its matched sources.\n * Uses the model's deepValidation config to perform Level 2/3 checks.\n */\nexport function runDeepValidation(\n specId: string,\n matches: GlobalScanMatch[],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n deepValidation: DeepValidationConfig<any>,\n spec: unknown,\n): CheckResult {\n const errors: CheckResult['errors'] = [];\n const warnings: CheckResult['warnings'] = [];\n\n for (const match of matches) {\n const rule = deepValidation[match.sourceType];\n if (!rule) continue;\n\n if (match.sourceType === 'openapi') {\n const mapping = rule.mapper(spec) as OpenAPIValidationMapping;\n const ctx = match.context as { doc: unknown; match: { pathKey: string; operation?: unknown; method?: string } } | undefined;\n if (!ctx?.match?.operation) continue;\n\n validateOpenAPIDeep(specId, mapping, ctx.doc, ctx.match, warnings);\n } else if (match.sourceType === 'ddl') {\n const mapping = rule.mapper(spec) as DDLValidationMapping;\n const ctx = match.context as { table: { name: string; columns: Array<{ name: string; type: string }> } } | undefined;\n if (!ctx?.table) continue;\n\n validateDDLDeep(specId, mapping, ctx.table, warnings);\n }\n }\n\n return {\n success: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nfunction validateOpenAPIDeep(\n specId: string,\n mapping: OpenAPIValidationMapping,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n doc: any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n match: { pathKey: string; operation?: any; method?: string },\n warnings: CheckResult['warnings'],\n): void {\n if (mapping.method && match.operation) {\n const expectedMethod = mapping.method.toLowerCase();\n const actualMethod = match.method?.toLowerCase();\n if (actualMethod && actualMethod !== expectedMethod) {\n warnings.push({\n message: `Method mismatch for \"${specId}\": expected ${expectedMethod.toUpperCase()}, found ${actualMethod.toUpperCase()}`,\n specId,\n });\n }\n }\n\n if (match.operation && mapping.parameters) {\n const opParams: Array<{ name: string; in?: string; schema?: { type?: string } }> =\n (match.operation.parameters || []).map(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (p: any) => maybeResolveRef(doc, p),\n );\n\n for (const expectedParam of mapping.parameters) {\n const found = opParams.find(\n (p) => p?.name === expectedParam.name && (!expectedParam.in || p?.in === expectedParam.in),\n );\n if (!found) {\n warnings.push({\n message: `Parameter \"${expectedParam.name}\" not found in operation \"${specId}\"`,\n specId,\n field: expectedParam.name,\n });\n } else if (expectedParam.type && found.schema?.type) {\n if (!isTypeContainedBy(expectedParam.type, found.schema.type)) {\n warnings.push({\n message: `Parameter \"${expectedParam.name}\" type mismatch: expected ${expectedParam.type}, found ${found.schema.type}`,\n specId,\n field: expectedParam.name,\n });\n }\n }\n }\n }\n\n if (match.operation && mapping.responseProperties) {\n const successResponse = match.operation.responses?.['200'] || match.operation.responses?.['201'];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let responseSchema: any = successResponse?.content?.['application/json']?.schema;\n responseSchema = maybeResolveRef(doc, responseSchema);\n\n if (responseSchema?.type === 'array') {\n responseSchema = maybeResolveRef(doc, responseSchema.items);\n }\n\n const responseProps = responseSchema?.properties || {};\n\n for (const expectedProp of mapping.responseProperties) {\n const foundProp = responseProps[expectedProp.name];\n if (!foundProp) {\n warnings.push({\n message: `Response property \"${expectedProp.name}\" not found in operation \"${specId}\"`,\n specId,\n field: expectedProp.name,\n });\n } else if (expectedProp.type && foundProp.type) {\n if (!isTypeContainedBy(expectedProp.type, foundProp.type)) {\n warnings.push({\n message: `Response property \"${expectedProp.name}\" type mismatch: expected ${expectedProp.type}, found ${foundProp.type}`,\n specId,\n field: expectedProp.name,\n });\n }\n }\n }\n }\n}\n\nfunction validateDDLDeep(\n specId: string,\n mapping: DDLValidationMapping,\n table: { name: string; columns: Array<{ name: string; type: string }> },\n warnings: CheckResult['warnings'],\n): void {\n if (!mapping.columns) return;\n\n for (const expectedCol of mapping.columns) {\n const foundCol = table.columns.find(\n (c) => c.name.toLowerCase() === expectedCol.name.toLowerCase(),\n );\n\n if (!foundCol) {\n warnings.push({\n message: `Column \"${expectedCol.name}\" not found in table \"${mapping.tableName}\"`,\n specId,\n field: expectedCol.name,\n });\n continue;\n }\n\n if (mapping.checkTypes && expectedCol.type && foundCol.type) {\n if (!isTypeContainedBy(expectedCol.type, foundCol.type)) {\n warnings.push({\n message: `Column \"${expectedCol.name}\" type mismatch in table \"${mapping.tableName}\": expected ${expectedCol.type}, found ${foundCol.type}`,\n specId,\n field: expectedCol.name,\n });\n }\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/core/relation.ts","../../src/core/dsl/schema.ts","../../src/core/dsl/lint-rules.ts","../../src/core/dsl/exporters.ts","../../src/core/dsl/checkers.ts","../../src/core/dsl/type-compat.ts","../../src/core/dsl/relation-schemas.ts","../../src/core/global-scanner.ts"],"names":["z","extractSpecIds","readFileSync","parseYaml","glob","join"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Definition and validation of model relations\n */\nimport { z } from 'zod';\n\n// ============================================================================\n// Model Levels\n// ============================================================================\n\n/**\n * Model abstraction level\n * \n * - L0: Business + Domain Analysis (Why / Problem space)\n * Desired outcomes/value, business flows, actors, terminology, business rules\n * - L1: Requirements (What)\n * Functional/non-functional requirements, constraints, acceptance criteria\n * - L2: Design (How / Direction)\n * Architecture, component breakdown, domain model, key sequences\n * - L3: Detailed Design/Implementation (How to build / Concrete artifacts)\n * Screen/API/DB definitions, external SSOT references\n */\nexport type ModelLevel = 'L0' | 'L1' | 'L2' | 'L3';\n\n/**\n * Get numeric index of level\n */\nexport function getLevelIndex(level: ModelLevel): number {\n return ['L0', 'L1', 'L2', 'L3'].indexOf(level);\n}\n\n// ============================================================================\n// Relation Types\n// ============================================================================\n\n/**\n * Relation types\n */\nexport const RELATION_TYPES = [\n 'dependsOn',\n 'uses',\n 'includes',\n 'implements',\n 'refines',\n 'verifies',\n 'verifiedBy',\n 'satisfies',\n 'traces',\n 'relatedTo',\n] as const;\n\nexport type RelationType = typeof RELATION_TYPES[number];\n\n/**\n * Relation schema\n */\nexport const RelationSchema = z.object({\n /** Relation type */\n type: z.enum(RELATION_TYPES),\n /** Target ID */\n target: z.string(),\n /** Description (optional) */\n description: z.string().optional(),\n});\n\n/**\n * Relation field to add to model schemas\n * Usage: schema.extend({ relations: RelationsFieldSchema })\n */\nexport const RelationsFieldSchema = z.array(RelationSchema).optional();\n\nexport type Relation = z.infer<typeof RelationSchema>;\n\n// ============================================================================\n// Relation Constraints\n// ============================================================================\n\n/**\n * Definition of relation constraints\n */\nexport interface RelationConstraint {\n /** Allowed target levels (all levels allowed if not specified) */\n allowedTargetLevels?: ModelLevel[];\n /** Level constraint rule */\n levelRule: 'source>target' | 'source>=target' | 'same' | 'any';\n /** Direction of impact propagation */\n propagation: 'forward' | 'backward' | 'both';\n}\n\n/**\n * Constraint definitions per relation type\n * \n * Level hierarchy:\n * L0 (Business) → L1 (Requirements) → L2 (Design) → L3 (Implementation)\n * Abstract ───────────────────────────→ Concrete\n */\nexport const RELATION_CONSTRAINTS: Record<RelationType, RelationConstraint> = {\n // Concrete→Abstract (implementation/design fulfills requirements)\n 'implements': {\n allowedTargetLevels: ['L1'], // Implements requirements\n levelRule: 'source>target',\n propagation: 'forward', // A changes → B needs review\n },\n // Concrete→Abstract (design/implementation satisfies business/requirements)\n 'satisfies': {\n allowedTargetLevels: ['L0', 'L1'], // Satisfies business/requirements\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A needs update\n },\n // Concrete→Abstract (refinement: requirements refine business, design refines requirements)\n 'refines': {\n allowedTargetLevels: ['L0', 'L1'], // Refines business/requirements\n levelRule: 'source>target',\n propagation: 'backward', // B changes → A needs update\n },\n // Test→Requirements/Business (verification relationship)\n 'verifies': {\n allowedTargetLevels: ['L0', 'L1'], // Verifies business/requirements\n levelRule: 'any',\n propagation: 'backward', // B changes → A needs update\n },\n // Dependencies (same level or concrete→abstract)\n 'dependsOn': {\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A affected\n },\n // Usage relationship (no level constraint)\n 'uses': {\n levelRule: 'any',\n propagation: 'backward', // B changes → A affected\n },\n // Inclusion relationship (same level only)\n 'includes': {\n levelRule: 'same',\n propagation: 'backward', // B changes → A affected\n },\n // Bidirectional tracing\n 'traces': {\n levelRule: 'any',\n propagation: 'both',\n },\n // Spec→Test (verification relationship: spec is verified by test code)\n 'verifiedBy': {\n allowedTargetLevels: ['L2', 'L3'],\n levelRule: 'any',\n propagation: 'backward',\n },\n // General relation\n 'relatedTo': {\n levelRule: 'any',\n propagation: 'both',\n },\n};\n\n// ============================================================================\n// Relation Validation\n// ============================================================================\n\n/**\n * Relation validation result\n */\nexport interface RelationValidationResult {\n valid: boolean;\n errors: RelationValidationError[];\n}\n\n/**\n * Relation validation error\n */\nexport interface RelationValidationError {\n type: 'level_violation' | 'target_level_violation' | 'self_reference' | 'cycle_detected';\n message: string;\n relation: Relation;\n sourceId: string;\n}\n\n/**\n * Validate level constraint for single relation\n * \n * @param sourceLevel - Source model level (set in _models/)\n * @param sourceSpecId - Source spec ID\n * @param relation - Relation\n * @param targetLevel - Target model level\n */\nexport function validateRelationLevel(\n sourceLevel: ModelLevel | undefined,\n sourceSpecId: string,\n relation: Relation,\n targetLevel: ModelLevel | undefined,\n): RelationValidationError | null {\n // Self-reference check\n if (sourceSpecId === relation.target) {\n return {\n type: 'self_reference',\n message: `Self-reference is not allowed: ${sourceSpecId} → ${relation.target}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n\n // Skip if level is undefined\n if (!sourceLevel || !targetLevel) {\n return null;\n }\n \n const constraint = RELATION_CONSTRAINTS[relation.type];\n \n // Target level constraint check\n if (constraint.allowedTargetLevels && \n !constraint.allowedTargetLevels.includes(targetLevel)) {\n return {\n type: 'target_level_violation',\n message: `'${relation.type}' relation target must be ${constraint.allowedTargetLevels.join(' or ')}, but target is ${targetLevel}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n \n // Level direction constraint check\n const srcIdx = getLevelIndex(sourceLevel);\n const tgtIdx = getLevelIndex(targetLevel);\n \n switch (constraint.levelRule) {\n case 'source>target':\n if (srcIdx <= tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'source>=target':\n if (srcIdx < tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be same or more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'same':\n if (srcIdx !== tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) and target (${targetLevel}) to be same level`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n }\n \n return null;\n}\n\n/**\n * Detect circular references\n */\nexport function detectCycles(\n relations: Array<{ sourceId: string; targetId: string; type: RelationType }>,\n): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const graph = new Map<string, Set<string>>();\n const relationMap = new Map<string, Relation>();\n \n // Build graph\n for (const rel of relations) {\n if (!graph.has(rel.sourceId)) {\n graph.set(rel.sourceId, new Set());\n }\n graph.get(rel.sourceId)!.add(rel.targetId);\n relationMap.set(`${rel.sourceId}→${rel.targetId}`, { type: rel.type, target: rel.targetId });\n }\n \n // Detect cycles using DFS\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const cyclePath: string[] = [];\n \n function dfs(node: string): boolean {\n visited.add(node);\n recursionStack.add(node);\n cyclePath.push(node);\n \n const neighbors = graph.get(node);\n if (neighbors) {\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor)) {\n return true;\n }\n } else if (recursionStack.has(neighbor)) {\n // Cycle detected\n const cycleStart = cyclePath.indexOf(neighbor);\n const cycle = cyclePath.slice(cycleStart);\n cycle.push(neighbor); // Close the cycle\n \n errors.push({\n type: 'cycle_detected',\n message: `Circular reference detected: ${cycle.join(' → ')}`,\n relation: relationMap.get(`${node}→${neighbor}`)!,\n sourceId: node,\n });\n return true;\n }\n }\n }\n \n cyclePath.pop();\n recursionStack.delete(node);\n return false;\n }\n \n for (const node of graph.keys()) {\n if (!visited.has(node)) {\n dfs(node);\n }\n }\n \n return errors;\n}\n\n/**\n * Infer model ID from spec ID (prefix-based)\n */\nexport function inferModelIdFromSpecId(specId: string): string | undefined {\n const prefixMap: Record<string, string> = {\n 'REQ': 'requirement',\n 'CR': 'constraint',\n 'UC': 'usecase',\n 'ACTOR': 'actor',\n 'TERM': 'term',\n 'COMP': 'component',\n 'ENT': 'entity',\n 'FLOW': 'process-flow',\n 'LAYER': 'layer',\n 'BND': 'boundary',\n 'SCR': 'screen',\n 'API': 'api-ref',\n 'TBL': 'table-ref',\n 'IAC': 'iac-ref',\n 'BATCH': 'batch-ref',\n };\n \n for (const [prefix, modelId] of Object.entries(prefixMap)) {\n if (specId.startsWith(prefix + '-')) {\n return modelId;\n }\n }\n \n return undefined;\n}\n","/**\n * Core DSL — Base spec schema\n *\n * Common schema fields shared by all models: id, name, description, relations.\n * Models extend this with domain-specific fields via `.extend()`.\n */\nimport { z } from 'zod';\nimport { RelationSchema } from '../relation.js';\n\nexport const baseSpecSchema = z.object({\n id: z.string(),\n name: z.string().min(1),\n description: z.string(),\n relations: z.array(RelationSchema).optional(),\n});\n\nexport type BaseSpec = z.infer<typeof baseSpecSchema>;\n","/**\n * Core DSL — Lint rule factories\n *\n * Factory functions that produce LintRule<T> objects for common patterns.\n * Users compose these in their model's `lintRules` array.\n */\nimport type { LintRule } from '../model.js';\n\n/**\n * Require a string field to be non-empty.\n */\nexport function requireField<T>(\n field: keyof T & string,\n severity: 'error' | 'warning' | 'info' = 'warning',\n): LintRule<T> {\n return {\n id: `has-${field}`,\n severity,\n message: `${field} must not be empty`,\n check: (spec) => {\n const value = (spec as Record<string, unknown>)[field];\n return !value || (typeof value === 'string' && value.trim() === '');\n },\n };\n}\n\n/**\n * Require an array field to have at least `min` elements.\n */\nexport function arrayMinLength<T>(\n field: keyof T & string,\n min: number,\n severity: 'error' | 'warning' = 'error',\n): LintRule<T> {\n return {\n id: `${field}-min-${min}`,\n severity,\n message: `${field} must have at least ${min} item(s)`,\n check: (spec) => {\n const value = (spec as Record<string, unknown>)[field];\n return !Array.isArray(value) || value.length < min;\n },\n };\n}\n\n/**\n * Require the `id` field to match a prefix-based format.\n *\n * Default pattern: `{prefix}-{NNN}` (e.g. `FR-001`).\n * Override with `opts.pattern` for custom formats.\n */\nexport function idFormat<T>(\n prefix: string,\n opts?: { digits?: number; pattern?: RegExp },\n): LintRule<T> {\n const pattern = opts?.pattern\n ?? new RegExp(`^${prefix}-\\\\d{${opts?.digits ?? 3}}$`);\n\n return {\n id: 'id-format',\n severity: 'warning',\n message: `ID should match format ${pattern}`,\n check: (spec) => {\n const id = (spec as Record<string, unknown>)['id'];\n return typeof id !== 'string' || !pattern.test(id);\n },\n };\n}\n\n/**\n * Require child element IDs to follow parent ID (e.g. `FR-001-01`).\n */\nexport function childIdFormat<T>(\n arrayField: keyof T & string,\n idField: string,\n): LintRule<T> {\n return {\n id: `${arrayField}-id-format`,\n severity: 'warning',\n message: `${arrayField} IDs should follow parent ID pattern`,\n check: (spec) => {\n const parentId = (spec as Record<string, unknown>)['id'] as string;\n const children = (spec as Record<string, unknown>)[arrayField];\n if (!Array.isArray(children) || !parentId) return false;\n return children.some((child: Record<string, unknown>) => {\n const childId = child[idField];\n return typeof childId === 'string' && !childId.startsWith(parentId + '-');\n });\n },\n };\n}\n","/**\n * Core DSL — Exporter factories\n *\n * Factory functions that produce Exporter<T> objects from declarative config.\n */\nimport type { Exporter } from '../model.js';\n\ninterface MetaField<T> {\n key: keyof T & string;\n label?: string;\n}\n\ninterface SectionConfig<T> {\n heading: string;\n field?: keyof T & string;\n render?: (spec: T) => string;\n optional?: boolean;\n}\n\ninterface ColumnConfig<T> {\n key: keyof T & string;\n label?: string;\n render?: (value: unknown, spec: T) => string;\n}\n\nexport interface MarkdownExporterConfig<T> {\n outputDir: string;\n single?: {\n title: keyof T & string | ((spec: T) => string);\n meta?: Array<keyof T & string | MetaField<T>>;\n sections?: SectionConfig<T>[];\n };\n index?: {\n title?: string;\n columns: Array<keyof T & string | ColumnConfig<T>>;\n };\n}\n\n/**\n * Create a markdown exporter from declarative configuration.\n */\nexport function markdownExporter<T extends { id: string }>(\n config: MarkdownExporterConfig<T>,\n): Exporter<T> {\n const exporter: Exporter<T> = {\n format: 'markdown',\n outputDir: config.outputDir,\n filename: (spec) => spec.id,\n };\n\n if (config.single) {\n const singleCfg = config.single;\n exporter.single = (spec) => {\n const lines: string[] = [];\n\n const title = typeof singleCfg.title === 'function'\n ? singleCfg.title(spec)\n : String((spec as Record<string, unknown>)[singleCfg.title] ?? '');\n lines.push(`# ${title}`, '');\n\n if (singleCfg.meta) {\n for (const m of singleCfg.meta) {\n const key = typeof m === 'string' ? m : m.key;\n const label = typeof m === 'string' ? key : (m.label ?? m.key);\n const value = (spec as Record<string, unknown>)[key];\n if (value !== undefined && value !== null) {\n lines.push(`**${label}**: ${String(value)}`);\n }\n }\n lines.push('');\n }\n\n if (singleCfg.sections) {\n for (const section of singleCfg.sections) {\n let content: string | undefined;\n if (section.render) {\n content = section.render(spec);\n } else if (section.field) {\n const value = (spec as Record<string, unknown>)[section.field];\n if (typeof value === 'string') content = value;\n }\n if (section.optional && !content) continue;\n lines.push(`## ${section.heading}`, '');\n if (content) lines.push(content, '');\n }\n }\n\n return lines.join('\\n');\n };\n }\n\n if (config.index) {\n const indexCfg = config.index;\n exporter.index = (specs) => {\n const lines: string[] = [];\n const title = indexCfg.title ?? 'Index';\n lines.push(`# ${title}`, '');\n\n const columns = indexCfg.columns.map(c =>\n typeof c === 'string' ? { key: c, label: c } : { key: c.key, label: c.label ?? c.key, render: c.render },\n );\n\n lines.push('| ' + columns.map(c => c.label).join(' | ') + ' |');\n lines.push('| ' + columns.map(() => '---').join(' | ') + ' |');\n\n for (const spec of specs) {\n const cells = columns.map(col => {\n const value = (spec as Record<string, unknown>)[col.key];\n if ('render' in col && col.render) return col.render(value, spec);\n if (col.key === 'id') return `[${value}](./${value}.md)`;\n return String(value ?? '-');\n });\n lines.push('| ' + cells.join(' | ') + ' |');\n }\n\n return lines.join('\\n');\n };\n }\n\n return exporter;\n}\n","/**\n * Core DSL — Coverage checkers and annotation scan utilities\n *\n * Per-model checker factory functions (testChecker, externalOpenAPIChecker, etc.)\n * have been replaced by the global scanner (src/core/global-scanner.ts).\n * This module retains coverage checkers and shared annotation scan utilities.\n */\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { glob } from 'glob';\nimport type { CoverageChecker, CoverageResult } from '../model.js';\nimport type { ArtifactConfig } from '../config-api.js';\n\n// ---------------------------------------------------------------------------\n// Annotation scan utilities (shared by coverage checkers)\n// ---------------------------------------------------------------------------\n\nexport type AnnotationRelationType = 'verifiedBy' | 'implements' | 'traces';\n\nfunction relationTypeToAnnotation(relationType: AnnotationRelationType): string {\n return relationType === 'verifiedBy' ? 'verifies' : relationType;\n}\n\nfunction getDefaultPatternForRelation(relationType: AnnotationRelationType): RegExp {\n const ann = relationTypeToAnnotation(relationType);\n return new RegExp(`@${ann}\\\\s+([\\\\w-]+(?:[,\\\\s]+[\\\\w-]+)*)`, 'g');\n}\n\nfunction extractSpecIds(captured: string): string[] {\n return captured.split(/[,\\s]+/).map(s => s.trim()).filter(Boolean);\n}\n\nlet _artifactsConfig: Record<string, ArtifactConfig> | undefined;\n\nexport function setArtifactsConfig(config: Record<string, ArtifactConfig>): void {\n _artifactsConfig = config;\n}\n\nexport function getArtifactsConfig(): Record<string, ArtifactConfig> | undefined {\n return _artifactsConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Annotation coverage checker\n// ---------------------------------------------------------------------------\n\nexport interface AnnotationCoverageConfig {\n artifact: string;\n relationType: AnnotationRelationType;\n description: string;\n contentPatterns?: RegExp[];\n}\n\nexport function annotationCoverage<T extends { id: string }>(\n config: AnnotationCoverageConfig,\n): CoverageChecker<T> {\n return {\n targetModel: 'annotation',\n description: config.description,\n check: (specs, _registry): CoverageResult => {\n const basePath = process.cwd();\n const allSpecIds = new Set(specs.map((s) => s.id));\n const coveredIds = new Set<string>();\n\n const artifactsConfig = getArtifactsConfig();\n const artifactConfig = artifactsConfig?.[config.artifact];\n if (!artifactConfig) {\n return {\n total: allSpecIds.size,\n covered: 0,\n uncovered: allSpecIds.size,\n coveragePercent: 0,\n coveredItems: [],\n uncoveredItems: Array.from(allSpecIds).map((id) => ({ id })),\n };\n }\n\n const allFiles = new Set<string>();\n for (const pattern of artifactConfig.globs) {\n const found = glob.sync(pattern, {\n cwd: basePath,\n ignore: artifactConfig.exclude ?? [],\n });\n for (const f of found) {\n allFiles.add(f);\n }\n }\n\n const patterns =\n config.contentPatterns ??\n artifactConfig.contentPatterns ??\n [getDefaultPatternForRelation(config.relationType)];\n\n const patternList = Array.isArray(patterns) ? patterns : [patterns];\n\n for (const filePath of allFiles) {\n const fullPath = join(basePath, filePath);\n let content: string;\n try {\n content = readFileSync(fullPath, 'utf-8');\n } catch {\n continue;\n }\n\n const lines = content.split('\\n');\n for (const line of lines) {\n for (const re of patternList) {\n const copy = new RegExp(re.source, re.flags);\n let m: RegExpExecArray | null;\n while ((m = copy.exec(line)) !== null) {\n const ids = extractSpecIds(m[1] ?? '');\n for (const id of ids) {\n if (allSpecIds.has(id)) {\n coveredIds.add(id);\n }\n }\n }\n }\n }\n }\n\n const coveredItems = Array.from(coveredIds).map((id) => ({ id }));\n const uncoveredItems = Array.from(allSpecIds)\n .filter((id) => !coveredIds.has(id))\n .map((id) => ({ id }));\n\n const total = allSpecIds.size;\n const covered = coveredItems.length;\n const coveragePercent = total > 0 ? Math.round((covered / total) * 100) : 100;\n\n return {\n total,\n covered,\n uncovered: total - covered,\n coveragePercent,\n coveredItems,\n uncoveredItems,\n };\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Relation-based coverage checker\n// ---------------------------------------------------------------------------\n\nexport interface RelationCoverageConfig {\n targetModel: string;\n description: string;\n relationType?: string;\n targetPrefix?: string;\n}\n\nexport function relationCoverage<T extends { id: string; relations?: Array<{ type: string; target: string }> }>(\n config: RelationCoverageConfig,\n): CoverageChecker<T> {\n return {\n targetModel: config.targetModel,\n description: config.description,\n check: (specs, registry): CoverageResult => {\n const targets = registry[config.targetModel];\n if (!targets) {\n return { total: 0, covered: 0, uncovered: 0, coveragePercent: 100, coveredItems: [], uncoveredItems: [] };\n }\n\n const allTargetIds = new Set<string>();\n const targetDescriptions = new Map<string, string>();\n for (const t of targets.values() as IterableIterator<{ id: string; name?: string; description?: string }>) {\n if (config.targetPrefix && !t.id.startsWith(config.targetPrefix)) continue;\n allTargetIds.add(t.id);\n targetDescriptions.set(t.id, t.name ?? t.description ?? t.id);\n }\n\n const coveredIds = new Set<string>();\n for (const spec of specs) {\n if (!spec.relations) continue;\n for (const rel of spec.relations) {\n if (config.relationType && rel.type !== config.relationType) continue;\n if (allTargetIds.has(rel.target)) coveredIds.add(rel.target);\n }\n }\n\n const coveredItems: CoverageResult['coveredItems'] = [];\n const uncoveredItems: CoverageResult['uncoveredItems'] = [];\n for (const id of allTargetIds) {\n const desc = targetDescriptions.get(id);\n if (coveredIds.has(id)) {\n coveredItems.push({ id, description: desc });\n } else {\n uncoveredItems.push({ id, description: desc });\n }\n }\n\n const total = allTargetIds.size;\n const covered = coveredItems.length;\n const coveragePercent = total > 0 ? Math.round((covered / total) * 100) : 100;\n\n return { total, covered, uncovered: total - covered, coveragePercent, coveredItems, uncoveredItems };\n },\n };\n}\n","/**\n * Type Compatibility — Containment-based type comparison\n *\n * The spec defines the minimum required type. The DDL/OpenAPI satisfies the\n * requirement if its type can hold all values of the spec type (equal or wider).\n */\n\ninterface ParsedType {\n base: string;\n length?: number;\n precision?: number;\n scale?: number;\n}\n\nconst ALIASES: Record<string, string> = {\n INTEGER: 'INT',\n BOOL: 'BOOLEAN',\n REAL: 'FLOAT',\n 'DOUBLE PRECISION': 'DOUBLE',\n SERIAL: 'INT',\n BIGSERIAL: 'BIGINT',\n SMALLSERIAL: 'SMALLINT',\n TIMESTAMPTZ: 'TIMESTAMP',\n 'TIMESTAMP WITH TIME ZONE': 'TIMESTAMP',\n 'TIMESTAMP WITHOUT TIME ZONE': 'TIMESTAMP',\n 'CHARACTER VARYING': 'VARCHAR',\n CHARACTER: 'CHAR',\n INT2: 'SMALLINT',\n INT4: 'INT',\n INT8: 'BIGINT',\n FLOAT4: 'FLOAT',\n FLOAT8: 'DOUBLE',\n};\n\nconst CONTAINMENT_CHAINS: string[][] = [\n ['SMALLINT', 'INT', 'BIGINT'],\n ['FLOAT', 'DOUBLE'],\n ['CHAR', 'VARCHAR', 'TEXT'],\n ['INTEGER', 'NUMBER'],\n];\n\nfunction parseType(raw: string): ParsedType {\n const trimmed = raw.trim().toUpperCase();\n\n const match = trimmed.match(/^([A-Z\\s]+?)(?:\\(\\s*(\\d+)(?:\\s*,\\s*(\\d+))?\\s*\\))?$/);\n if (!match) {\n return { base: trimmed };\n }\n\n const base = match[1].trim();\n\n return {\n base,\n length: match[2] !== undefined ? Number(match[2]) : undefined,\n precision: match[2] !== undefined ? Number(match[2]) : undefined,\n scale: match[3] !== undefined ? Number(match[3]) : undefined,\n };\n}\n\nfunction normalize(base: string): string {\n return ALIASES[base] ?? base;\n}\n\nfunction findAllChainPositions(\n base: string,\n chains: string[][],\n): Array<{ chain: string[]; index: number }> {\n const results: Array<{ chain: string[]; index: number }> = [];\n const resolved = normalize(base);\n for (const chain of chains) {\n let idx = chain.indexOf(base);\n if (idx === -1) idx = chain.indexOf(resolved);\n if (idx !== -1) results.push({ chain, index: idx });\n }\n return results;\n}\n\n/**\n * Returns true if ddlType can hold all values representable by specType.\n *\n * Containment rules:\n * - Numeric: SMALLINT ⊂ INT ⊂ BIGINT, FLOAT ⊂ DOUBLE\n * - String: CHAR(n) ⊂ VARCHAR(n) ⊂ TEXT (with length comparison)\n * - DECIMAL: precision/scale must be >= spec\n * - OpenAPI: integer ⊂ number\n */\nexport function isTypeContainedBy(specType: string, ddlType: string): boolean {\n const spec = parseType(specType);\n const ddl = parseType(ddlType);\n\n const specNorm = normalize(spec.base);\n const ddlNorm = normalize(ddl.base);\n\n if (specNorm === ddlNorm) {\n if (specNorm === 'DECIMAL' || specNorm === 'NUMERIC') {\n if (spec.precision !== undefined && ddl.precision !== undefined) {\n if (ddl.precision < spec.precision) return false;\n }\n if (spec.scale !== undefined && ddl.scale !== undefined) {\n if (ddl.scale < spec.scale) return false;\n }\n return true;\n }\n\n if (spec.length !== undefined && ddl.length !== undefined) {\n return ddl.length >= spec.length;\n }\n return true;\n }\n\n const specPositions = findAllChainPositions(spec.base, CONTAINMENT_CHAINS);\n const ddlPositions = findAllChainPositions(ddl.base, CONTAINMENT_CHAINS);\n\n for (const sp of specPositions) {\n for (const dp of ddlPositions) {\n if (sp.chain === dp.chain) {\n return dp.index >= sp.index;\n }\n }\n }\n\n return false;\n}\n","/**\n * Core DSL — Edge-typed relation schemas\n *\n * Specialized relation schemas for `implements` and `verifiedBy` edges.\n * These carry additional properties beyond the generic RelationSchema.\n */\nimport { z } from 'zod';\n\nexport const ImplementsRelationSchema = z.object({\n target: z.string(),\n targetType: z.string(),\n sourcePath: z.string().optional(),\n description: z.string().optional(),\n});\n\nexport type ImplementsRelation = z.infer<typeof ImplementsRelationSchema>;\n\nexport const VerifiedByRelationSchema = z.object({\n target: z.string(),\n testPath: z.string().optional(),\n framework: z.string().optional(),\n description: z.string().optional(),\n});\n\nexport type VerifiedByRelation = z.infer<typeof VerifiedByRelationSchema>;\n","/**\n * Global Scanner — Scans all configured sources for spec IDs\n *\n * Replaces per-model externalChecker with a single global scan pass.\n * Built-in scanners: openapi, ddl, annotation.\n * Custom scanners can be plugged in via SourceConfig.scanner.\n */\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join, isAbsolute } from 'node:path';\nimport { glob } from 'glob';\nimport { parse as parseYaml } from 'yaml';\nimport nodeSqlParser from 'node-sql-parser';\nimport type { SourceConfig, SourceMatch, SourceScanner } from './config-api.js';\nimport type { CheckResult, DeepValidationConfig, OpenAPIValidationMapping, DDLValidationMapping } from './model.js';\nimport { isTypeContainedBy } from './dsl/type-compat.js';\n\n// ============================================================================\n// Scan Result Types\n// ============================================================================\n\nexport interface GlobalScanMatch extends SourceMatch {\n /** Which source config produced this match */\n sourceType: string;\n /** Relation type from the source config */\n relation: 'implements' | 'verifiedBy';\n /** File path where the match was found */\n filePath: string;\n}\n\nexport type GlobalScanResult = Map<string, GlobalScanMatch[]>;\n\n// ============================================================================\n// Built-in: OpenAPI Scanner\n// ============================================================================\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function resolveRef(doc: any, ref: string): any {\n if (!ref.startsWith('#/')) return undefined;\n const parts = ref.substring(2).split('/');\n let current = doc;\n for (const part of parts) {\n if (current == null || typeof current !== 'object') return undefined;\n current = current[part];\n }\n return current;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function maybeResolveRef(doc: any, value: any): any {\n if (value && typeof value === 'object' && typeof value.$ref === 'string') {\n return resolveRef(doc, value.$ref);\n }\n return value;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction findSpecIdInOpenAPI(doc: any, specId: string): { pathKey: string; operation?: any; method?: string } | null {\n const paths = doc.paths;\n if (!paths || typeof paths !== 'object') return null;\n\n for (const [pathKey, pathItem] of Object.entries(paths)) {\n if (pathItem == null || typeof pathItem !== 'object') continue;\n const methods = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head'];\n for (const method of methods) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const op = (pathItem as any)[method];\n if (!op) continue;\n if (op.operationId === specId) return { pathKey, operation: op, method };\n if (op['x-spec-id'] === specId) return { pathKey, operation: op, method };\n }\n }\n\n for (const pathKey of Object.keys(paths)) {\n const segments = pathKey.split('/').filter(Boolean);\n const cleanSegments = segments.map(s => s.replace(/^\\{|\\}$/g, ''));\n if (cleanSegments.includes(specId)) return { pathKey };\n }\n\n const schemas = doc.components?.schemas;\n if (schemas && typeof schemas === 'object') {\n if (specId in schemas) return { pathKey: `#/components/schemas/${specId}` };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function searchXSpecId(obj: any): boolean {\n if (obj == null || typeof obj !== 'object') return false;\n if (obj['x-spec-id'] === specId) return true;\n for (const val of Object.values(obj)) {\n if (searchXSpecId(val)) return true;\n }\n return false;\n }\n if (searchXSpecId(doc)) return { pathKey: '(x-spec-id match)' };\n\n return null;\n}\n\nexport const openapiScanner: SourceScanner = {\n findSpecIds(content: unknown, specIds: string[], filePath: string): SourceMatch[] {\n const doc = content;\n if (!doc || typeof doc !== 'object') return [];\n\n const matches: SourceMatch[] = [];\n for (const specId of specIds) {\n const match = findSpecIdInOpenAPI(doc, specId);\n if (match) {\n matches.push({\n specId,\n location: `${filePath}:${match.pathKey}`,\n context: { doc, match },\n });\n }\n }\n return matches;\n },\n};\n\n// ============================================================================\n// Built-in: DDL Scanner\n// ============================================================================\n\ninterface TableDefinition {\n name: string;\n columns: Array<{ name: string; type: string }>;\n}\n\nfunction stripSchemaPrefix(name: string): string {\n const dotIndex = name.lastIndexOf('.');\n return dotIndex >= 0 ? name.substring(dotIndex + 1) : name;\n}\n\nfunction parseDDLWithParser(content: string): TableDefinition[] | null {\n const parser = new nodeSqlParser.Parser();\n const tables: TableDefinition[] = [];\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ast = parser.astify(content) as any;\n const statements = Array.isArray(ast) ? ast : [ast];\n\n for (const stmt of statements) {\n if (stmt.type !== 'create' || stmt.keyword !== 'table') continue;\n\n const rawName: string = typeof stmt.table === 'string'\n ? stmt.table\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n : (stmt.table as any[])?.[0]?.table ?? '';\n const tableName = stripSchemaPrefix(rawName);\n\n const columns: Array<{ name: string; type: string }> = (stmt.create_definitions || [])\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .filter((def: any) => def.resource === 'column')\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map((def: any) => {\n const colName = def.column?.column ?? '';\n let colType = def.definition?.dataType ?? '';\n if (def.definition?.length) {\n colType += `(${def.definition.length})`;\n }\n if (def.definition?.scale) {\n colType = colType.replace(/\\)$/, `,${def.definition.scale})`);\n }\n return { name: colName, type: colType };\n });\n\n if (tableName) {\n tables.push({ name: tableName, columns });\n }\n }\n\n return tables.length > 0 ? tables : null;\n } catch {\n return null;\n }\n}\n\nfunction parseDDLWithRegex(content: string): TableDefinition[] {\n const tables: TableDefinition[] = [];\n const tableRegex = /CREATE\\s+TABLE\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(?:(?:[`\"']?\\w+[`\"']?\\s*\\.\\s*)?)[`\"']?(\\w+)[`\"']?\\s*\\(([\\s\\S]*?)\\);/gi;\n\n let match;\n while ((match = tableRegex.exec(content)) !== null) {\n const tableName = match[1];\n const body = match[2];\n const columns: Array<{ name: string; type: string }> = [];\n\n const lines = body.split(',').map(l => l.trim()).filter(Boolean);\n for (const line of lines) {\n if (/^\\s*(PRIMARY\\s+KEY|UNIQUE|CHECK|CONSTRAINT|INDEX|FOREIGN\\s+KEY)/i.test(line)) continue;\n\n const colMatch = line.match(/^(?:`|\"|')?(\\w+)(?:`|\"|')?\\s+(\\w+(?:\\([^)]*\\))?)/i);\n if (colMatch) {\n columns.push({ name: colMatch[1], type: colMatch[2] });\n }\n }\n\n if (tableName) {\n tables.push({ name: tableName, columns });\n }\n }\n\n return tables;\n}\n\nexport const ddlScanner: SourceScanner = {\n findSpecIds(content: unknown, specIds: string[], filePath: string): SourceMatch[] {\n if (typeof content !== 'string') return [];\n\n let tables = parseDDLWithParser(content);\n if (!tables) {\n tables = parseDDLWithRegex(content);\n }\n\n const matches: SourceMatch[] = [];\n for (const specId of specIds) {\n const table = tables.find(\n (t) => t.name.toLowerCase() === specId.toLowerCase(),\n );\n if (table) {\n matches.push({\n specId,\n location: `${filePath}:${table.name}`,\n context: { table },\n });\n }\n }\n return matches;\n },\n};\n\n// ============================================================================\n// Built-in: Annotation Scanner\n// ============================================================================\n\nfunction extractSpecIds(captured: string): string[] {\n return captured.split(/[,\\s]+/).map(s => s.trim()).filter(Boolean);\n}\n\nexport const annotationScanner: SourceScanner = {\n findSpecIds(content: unknown, specIds: string[], filePath: string): SourceMatch[] {\n if (typeof content !== 'string') return [];\n\n const specIdSet = new Set(specIds);\n const matches: SourceMatch[] = [];\n const defaultPattern = /@(?:verifies|implements|traces)\\s+([\\w-]+(?:[,\\s]+[\\w-]+)*)/g;\n\n const lines = content.split('\\n');\n for (let lineNum = 1; lineNum <= lines.length; lineNum++) {\n const line = lines[lineNum - 1];\n const copy = new RegExp(defaultPattern.source, defaultPattern.flags);\n let m: RegExpExecArray | null;\n while ((m = copy.exec(line)) !== null) {\n const ids = extractSpecIds(m[1] ?? '');\n for (const id of ids) {\n if (specIdSet.has(id)) {\n matches.push({\n specId: id,\n location: `${filePath}:${lineNum}`,\n context: { filePath, line: lineNum },\n });\n }\n }\n }\n }\n return matches;\n },\n};\n\n/**\n * Create an annotation scanner with custom content patterns.\n */\nexport function createAnnotationScanner(contentPatterns: RegExp[]): SourceScanner {\n return {\n findSpecIds(content: unknown, specIds: string[], filePath: string): SourceMatch[] {\n if (typeof content !== 'string') return [];\n\n const specIdSet = new Set(specIds);\n const matches: SourceMatch[] = [];\n\n const lines = content.split('\\n');\n for (let lineNum = 1; lineNum <= lines.length; lineNum++) {\n const line = lines[lineNum - 1];\n for (const re of contentPatterns) {\n const copy = new RegExp(re.source, re.flags);\n let m: RegExpExecArray | null;\n while ((m = copy.exec(line)) !== null) {\n const ids = extractSpecIds(m[1] ?? '');\n for (const id of ids) {\n if (specIdSet.has(id)) {\n matches.push({\n specId: id,\n location: `${filePath}:${lineNum}`,\n context: { filePath, line: lineNum },\n });\n }\n }\n }\n }\n }\n return matches;\n },\n };\n}\n\n// ============================================================================\n// Scanner Registry\n// ============================================================================\n\nconst BUILT_IN_SCANNERS: Record<string, SourceScanner> = {\n openapi: openapiScanner,\n ddl: ddlScanner,\n annotation: annotationScanner,\n};\n\nfunction getScannerForSource(source: SourceConfig): SourceScanner | null {\n if (source.scanner) return source.scanner;\n if (source.type === 'annotation' && source.contentPatterns && source.contentPatterns.length > 0) {\n return createAnnotationScanner(source.contentPatterns);\n }\n return BUILT_IN_SCANNERS[source.type] ?? null;\n}\n\n// ============================================================================\n// File Loading\n// ============================================================================\n\nfunction loadFileContent(filePath: string, sourceType: string): unknown {\n const content = readFileSync(filePath, 'utf-8');\n if (!content || content.length === 0) return null;\n\n if (sourceType === 'openapi') {\n if (filePath.endsWith('.json')) {\n return JSON.parse(content);\n }\n return parseYaml(content);\n }\n\n return content;\n}\n\n// ============================================================================\n// Global Scan Orchestrator\n// ============================================================================\n\nexport interface ScanWarning {\n message: string;\n sourceType: string;\n filePath?: string;\n}\n\nexport interface GlobalScanOutput {\n matches: GlobalScanResult;\n warnings: ScanWarning[];\n}\n\n/**\n * Lookup key map: specId -> Record<sourceType, lookupKey>.\n * When a model's spec ID differs from the external identifier\n * (e.g. entity \"user\" vs DDL table \"users\"), the check command\n * builds this map so the scanner searches for the correct key.\n */\nexport type LookupKeyMap = Map<string, Record<string, string>>;\n\n/**\n * Run global scan across all configured sources.\n * Returns a map of specId -> matches for all spec IDs found.\n *\n * @param sources - Source configurations to scan\n * @param specIds - All known spec IDs\n * @param basePath - Base directory for resolving file paths\n * @param lookupKeyMap - Optional per-spec, per-source-type key overrides\n */\nexport function runGlobalScan(\n sources: SourceConfig[],\n specIds: string[],\n basePath?: string,\n lookupKeyMap?: LookupKeyMap,\n): GlobalScanOutput {\n const cwd = basePath ?? process.cwd();\n const result: GlobalScanResult = new Map();\n const warnings: ScanWarning[] = [];\n\n for (const source of sources) {\n const scanner = getScannerForSource(source);\n if (!scanner) {\n warnings.push({\n message: `No scanner found for source type \"${source.type}\". Provide a custom scanner.`,\n sourceType: source.type,\n });\n continue;\n }\n\n // Build lookup key -> original specId mapping for this source type\n const keyToSpecId = new Map<string, string>();\n for (const specId of specIds) {\n const overrides = lookupKeyMap?.get(specId);\n const key = overrides?.[source.type] ?? specId;\n keyToSpecId.set(key, specId);\n }\n const keysToSearch = Array.from(keyToSpecId.keys());\n\n const allFiles = new Set<string>();\n for (const pattern of source.paths) {\n const found = glob.sync(pattern, {\n cwd,\n ignore: source.exclude ?? [],\n });\n for (const f of found) {\n allFiles.add(f);\n }\n }\n\n for (const relPath of allFiles) {\n const fullPath = isAbsolute(relPath) ? relPath : join(cwd, relPath);\n if (!existsSync(fullPath)) continue;\n\n let content: unknown;\n try {\n content = loadFileContent(fullPath, source.type);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push({\n message: `Failed to load ${relPath}: ${msg}`,\n sourceType: source.type,\n filePath: relPath,\n });\n continue;\n }\n\n if (content == null) continue;\n\n let matches: SourceMatch[];\n try {\n matches = scanner.findSpecIds(content, keysToSearch, relPath);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push({\n message: `Scanner error for ${relPath}: ${msg}`,\n sourceType: source.type,\n filePath: relPath,\n });\n continue;\n }\n\n for (const match of matches) {\n // Map the lookup key back to the original specId\n const originalSpecId = keyToSpecId.get(match.specId) ?? match.specId;\n const globalMatch: GlobalScanMatch = {\n ...match,\n specId: originalSpecId,\n sourceType: source.type,\n relation: source.relation,\n filePath: relPath,\n };\n\n const existing = result.get(originalSpecId);\n if (existing) {\n existing.push(globalMatch);\n } else {\n result.set(originalSpecId, [globalMatch]);\n }\n }\n }\n }\n\n return { matches: result, warnings };\n}\n\n// ============================================================================\n// Deep Validation\n// ============================================================================\n\n/**\n * Run deep validation for a spec against its matched sources.\n * Uses the model's deepValidation config to perform Level 2/3 checks.\n */\nexport function runDeepValidation(\n specId: string,\n matches: GlobalScanMatch[],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n deepValidation: DeepValidationConfig<any>,\n spec: unknown,\n): CheckResult {\n const errors: CheckResult['errors'] = [];\n const warnings: CheckResult['warnings'] = [];\n\n for (const match of matches) {\n const rule = deepValidation[match.sourceType];\n if (!rule) continue;\n\n if (match.sourceType === 'openapi') {\n const mapping = rule.mapper(spec) as OpenAPIValidationMapping;\n const ctx = match.context as { doc: unknown; match: { pathKey: string; operation?: unknown; method?: string } } | undefined;\n if (!ctx?.match?.operation) continue;\n\n validateOpenAPIDeep(specId, mapping, ctx.doc, ctx.match, warnings);\n } else if (match.sourceType === 'ddl') {\n const mapping = rule.mapper(spec) as DDLValidationMapping;\n const ctx = match.context as { table: { name: string; columns: Array<{ name: string; type: string }> } } | undefined;\n if (!ctx?.table) continue;\n\n validateDDLDeep(specId, mapping, ctx.table, warnings);\n }\n }\n\n return {\n success: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nfunction validateOpenAPIDeep(\n specId: string,\n mapping: OpenAPIValidationMapping,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n doc: any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n match: { pathKey: string; operation?: any; method?: string },\n warnings: CheckResult['warnings'],\n): void {\n if (mapping.method && match.operation) {\n const expectedMethod = mapping.method.toLowerCase();\n const actualMethod = match.method?.toLowerCase();\n if (actualMethod && actualMethod !== expectedMethod) {\n warnings.push({\n message: `Method mismatch for \"${specId}\": expected ${expectedMethod.toUpperCase()}, found ${actualMethod.toUpperCase()}`,\n specId,\n });\n }\n }\n\n if (match.operation && mapping.parameters) {\n const opParams: Array<{ name: string; in?: string; schema?: { type?: string } }> =\n (match.operation.parameters || []).map(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (p: any) => maybeResolveRef(doc, p),\n );\n\n for (const expectedParam of mapping.parameters) {\n const found = opParams.find(\n (p) => p?.name === expectedParam.name && (!expectedParam.in || p?.in === expectedParam.in),\n );\n if (!found) {\n warnings.push({\n message: `Parameter \"${expectedParam.name}\" not found in operation \"${specId}\"`,\n specId,\n field: expectedParam.name,\n });\n } else if (expectedParam.type && found.schema?.type) {\n if (!isTypeContainedBy(expectedParam.type, found.schema.type)) {\n warnings.push({\n message: `Parameter \"${expectedParam.name}\" type mismatch: expected ${expectedParam.type}, found ${found.schema.type}`,\n specId,\n field: expectedParam.name,\n });\n }\n }\n }\n }\n\n if (match.operation && mapping.responseProperties) {\n const successResponse = match.operation.responses?.['200'] || match.operation.responses?.['201'];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let responseSchema: any = successResponse?.content?.['application/json']?.schema;\n responseSchema = maybeResolveRef(doc, responseSchema);\n\n if (responseSchema?.type === 'array') {\n responseSchema = maybeResolveRef(doc, responseSchema.items);\n }\n\n const responseProps = responseSchema?.properties || {};\n\n for (const expectedProp of mapping.responseProperties) {\n const foundProp = responseProps[expectedProp.name];\n if (!foundProp) {\n warnings.push({\n message: `Response property \"${expectedProp.name}\" not found in operation \"${specId}\"`,\n specId,\n field: expectedProp.name,\n });\n } else if (expectedProp.type && foundProp.type) {\n if (!isTypeContainedBy(expectedProp.type, foundProp.type)) {\n warnings.push({\n message: `Response property \"${expectedProp.name}\" type mismatch: expected ${expectedProp.type}, found ${foundProp.type}`,\n specId,\n field: expectedProp.name,\n });\n }\n }\n }\n }\n}\n\nfunction validateDDLDeep(\n specId: string,\n mapping: DDLValidationMapping,\n table: { name: string; columns: Array<{ name: string; type: string }> },\n warnings: CheckResult['warnings'],\n): void {\n if (!mapping.columns) return;\n\n for (const expectedCol of mapping.columns) {\n const foundCol = table.columns.find(\n (c) => c.name.toLowerCase() === expectedCol.name.toLowerCase(),\n );\n\n if (!foundCol) {\n warnings.push({\n message: `Column \"${expectedCol.name}\" not found in table \"${mapping.tableName}\"`,\n specId,\n field: expectedCol.name,\n });\n continue;\n }\n\n if (mapping.checkTypes && expectedCol.type && foundCol.type) {\n if (!isTypeContainedBy(expectedCol.type, foundCol.type)) {\n warnings.push({\n message: `Column \"${expectedCol.name}\" type mismatch in table \"${mapping.tableName}\": expected ${expectedCol.type}, found ${foundCol.type}`,\n specId,\n field: expectedCol.name,\n });\n }\n }\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
- import { C as CheckContext, a as CheckResult, E as ExportContext, M as ModelDefinition, b as MetaModelRegistry, L as LintContext, c as LintRule, d as LintIssue, S as SourceConfig, e as SpecEntry } from './config-api-BDl4otlv.js';
3
- export { A as ArtifactConfig, B as BaseModelInstance, f as CheckError, g as CheckErrorSchema, h as CheckResult, i as CheckResultSchema, j as CheckWarning, k as CheckWarningSchema, l as CoverageChecker, m as CoverageResult, n as Exporter, o as ExternalChecker, I as InferModelType, J as JsonSchemaExporter, p as LintIssueSchema, q as LintResult, r as LintRule, s as MarkdownExporter, t as MergedDesign, u as MermaidExporter, v as MetaModelConfig, w as Model, x as ModelDefinitionInput, y as ModelLevel, R as RELATION_CONSTRAINTS, z as RELATION_TYPES, D as ReferenceDefinition, F as ReferenceDefinitionSchema, G as Relation, H as RelationSchema, K as RelationValidationError, N as RelationsFieldSchema, O as RenderContext, P as Renderer, Q as ResolvedSpeckeeperConfig, T as SourceMatch, U as SourceScanner, V as SpecModule, W as SpeckeeperConfigInput, X as buildRegistryFromConfig, Y as createLintRule, Z as createMarkdownExporter, _ as createMermaidExporter, $ as defineConfig, a0 as defineModel, a1 as defineSpecs, a2 as detectCycles, a3 as findModelTypeFromConfig, a4 as getLevelIndex, a5 as getSpecsFromConfig, a6 as inferModelIdFromSpecId, a7 as loadSpeckeeperConfig, a8 as mergeSpecs, a9 as validateRelationLevel } from './config-api-BDl4otlv.js';
2
+ import { C as CheckContext, a as CheckResult, E as ExportContext, M as ModelDefinition, b as MetaModelRegistry, L as LintContext, c as LintRule, d as LintIssue, S as SourceConfig, e as SpecEntry } from './config-api-CfxXt9Zt.js';
3
+ export { A as ArtifactConfig, B as BaseModelInstance, f as CheckError, g as CheckErrorSchema, h as CheckResult, i as CheckResultSchema, j as CheckWarning, k as CheckWarningSchema, l as CoverageChecker, m as CoverageResult, D as DDLValidationMapping, n as DeepValidationConfig, o as DeepValidationRule, p as Exporter, q as ExternalChecker, I as InferModelType, J as JsonSchemaExporter, r as LintIssueSchema, s as LintResult, t as LintRule, u as LookupKeyConfig, v as MarkdownExporter, w as MergedDesign, x as MermaidExporter, y as MetaModelConfig, z as Model, F as ModelDefinitionInput, G as ModelLevel, O as OpenAPIValidationMapping, R as RELATION_CONSTRAINTS, H as RELATION_TYPES, K as ReferenceDefinition, N as ReferenceDefinitionSchema, P as Relation, Q as RelationSchema, T as RelationValidationError, U as RelationsFieldSchema, V as RenderContext, W as Renderer, X as ResolvedSpeckeeperConfig, Y as SourceMatch, Z as SourceScanner, _ as SpecModule, $ as SpeckeeperConfigInput, a0 as buildRegistryFromConfig, a1 as createLintRule, a2 as createMarkdownExporter, a3 as createMermaidExporter, a4 as defineConfig, a5 as defineModel, a6 as defineSpecs, a7 as detectCycles, a8 as findModelTypeFromConfig, a9 as getLevelIndex, aa as getSpecsFromConfig, ab as inferModelIdFromSpecId, ac as loadSpeckeeperConfig, ad as mergeSpecs, ae as validateRelationLevel } from './config-api-CfxXt9Zt.js';
4
4
 
5
5
  declare const PhaseSchema: z.ZodEnum<["REQ", "HLD", "LLD", "IMPL", "OPS", "CI"]>;
6
6
  type Phase = z.infer<typeof PhaseSchema>;
package/dist/index.js CHANGED
@@ -349,6 +349,8 @@ var Model = class {
349
349
  externalChecker;
350
350
  /** Deep validation rules keyed by source type (replaces externalChecker) */
351
351
  deepValidation;
352
+ /** Lookup key overrides per source type (when spec ID differs from external identifier) */
353
+ lookupKeys;
352
354
  /** Coverage checker (optional) */
353
355
  coverageChecker;
354
356
  /** Model level (set in _models/) */
@@ -516,6 +518,21 @@ var Model = class {
516
518
  getDeepValidation() {
517
519
  return this.deepValidation;
518
520
  }
521
+ /**
522
+ * Get lookup key config
523
+ */
524
+ getLookupKeys() {
525
+ return this.lookupKeys;
526
+ }
527
+ /**
528
+ * Resolve the lookup key for a spec and source type.
529
+ * Returns the lookup key if an override is defined, otherwise spec.id.
530
+ */
531
+ resolveLookupKey(spec, sourceType) {
532
+ const mapper = this.lookupKeys?.[sourceType];
533
+ if (mapper) return mapper(spec);
534
+ return spec.id;
535
+ }
519
536
  /**
520
537
  * Get lint rules
521
538
  */