@archpilotlabs/archpilot 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/archpilot-cli.js +1036 -341
- package/dist/cli/src/archpilot-cli.js +5523 -0
- package/dist/cli/src/archpilot-cli.js.map +1 -0
- package/dist/core/src/adr/adrLoader.js +97 -0
- package/dist/core/src/adr/adrLoader.js.map +1 -0
- package/dist/core/src/adr/adrParser.js +77 -0
- package/dist/core/src/adr/adrParser.js.map +1 -0
- package/dist/core/src/adr/adrTemplate.js +45 -0
- package/dist/core/src/adr/adrTemplate.js.map +1 -0
- package/dist/core/src/adr/adrTypes.js +3 -0
- package/dist/core/src/adr/adrTypes.js.map +1 -0
- package/dist/core/src/adr/adrValidation.js +160 -0
- package/dist/core/src/adr/adrValidation.js.map +1 -0
- package/dist/core/src/adr/index.js +9 -0
- package/dist/core/src/adr/index.js.map +1 -0
- package/dist/core/src/adrManagement.js +174 -0
- package/dist/core/src/adrManagement.js.map +1 -0
- package/dist/core/src/adrRequirementStatus.js +62 -0
- package/dist/core/src/adrRequirementStatus.js.map +1 -0
- package/dist/core/src/adrScaffoldGeneration.js +325 -0
- package/dist/core/src/adrScaffoldGeneration.js.map +1 -0
- package/dist/core/src/apiDesignAnalysis.js +869 -0
- package/dist/core/src/apiDesignAnalysis.js.map +1 -0
- package/dist/core/src/applicationLayeringAnalysis.js +920 -0
- package/dist/core/src/applicationLayeringAnalysis.js.map +1 -0
- package/dist/core/src/applyRulePack.js +117 -0
- package/dist/core/src/applyRulePack.js.map +1 -0
- package/dist/core/src/architectureBaseline.js +271 -0
- package/dist/core/src/architectureBaseline.js.map +1 -0
- package/dist/core/src/architectureComponentDiscoveryDefaults.js +139 -0
- package/dist/core/src/architectureComponentDiscoveryDefaults.js.map +1 -0
- package/dist/core/src/architectureDependencyContext.js +316 -0
- package/dist/core/src/architectureDependencyContext.js.map +1 -0
- package/dist/core/src/architectureDriftDetection.js +96 -0
- package/dist/core/src/architectureDriftDetection.js.map +1 -0
- package/dist/core/src/architectureDriftTimeline.js +221 -0
- package/dist/core/src/architectureDriftTimeline.js.map +1 -0
- package/dist/core/src/architectureGovernanceBaseline.js +469 -0
- package/dist/core/src/architectureGovernanceBaseline.js.map +1 -0
- package/dist/core/src/architectureHealthHistory.js +208 -0
- package/dist/core/src/architectureHealthHistory.js.map +1 -0
- package/dist/core/src/architectureHealthScore.js +657 -0
- package/dist/core/src/architectureHealthScore.js.map +1 -0
- package/dist/core/src/architectureInit.js +826 -0
- package/dist/core/src/architectureInit.js.map +1 -0
- package/dist/core/src/architectureMap.js +727 -0
- package/dist/core/src/architectureMap.js.map +1 -0
- package/dist/core/src/architectureMigrationPreview.js +467 -0
- package/dist/core/src/architectureMigrationPreview.js.map +1 -0
- package/dist/core/src/architectureModelRefresh.js +209 -0
- package/dist/core/src/architectureModelRefresh.js.map +1 -0
- package/dist/core/src/architectureReportWorkflow.js +139 -0
- package/dist/core/src/architectureReportWorkflow.js.map +1 -0
- package/dist/core/src/architectureValidation.js +3879 -0
- package/dist/core/src/architectureValidation.js.map +1 -0
- package/dist/core/src/architectureWorkspaceModel.js +166 -0
- package/dist/core/src/architectureWorkspaceModel.js.map +1 -0
- package/dist/core/src/authorizationTenantAnalysis.js +652 -0
- package/dist/core/src/authorizationTenantAnalysis.js.map +1 -0
- package/dist/core/src/bootstrapArchitectureConfig.js +150 -0
- package/dist/core/src/bootstrapArchitectureConfig.js.map +1 -0
- package/dist/core/src/changeRisk/changeRiskAssessment.js +251 -0
- package/dist/core/src/changeRisk/changeRiskAssessment.js.map +1 -0
- package/dist/core/src/changeRisk/changeRiskTypes.js +3 -0
- package/dist/core/src/changeRisk/changeRiskTypes.js.map +1 -0
- package/dist/core/src/changeRisk/index.js +6 -0
- package/dist/core/src/changeRisk/index.js.map +1 -0
- package/dist/core/src/ci/githubInlineAnnotations.js +245 -0
- package/dist/core/src/ci/githubInlineAnnotations.js.map +1 -0
- package/dist/core/src/ci/githubPrCommentAdapter.js +232 -0
- package/dist/core/src/ci/githubPrCommentAdapter.js.map +1 -0
- package/dist/core/src/ciWorkflowTemplates.js +1042 -0
- package/dist/core/src/ciWorkflowTemplates.js.map +1 -0
- package/dist/core/src/compliance/complianceExportBuilder.js +122 -0
- package/dist/core/src/compliance/complianceExportBuilder.js.map +1 -0
- package/dist/core/src/compliance/complianceExportTypes.js +3 -0
- package/dist/core/src/compliance/complianceExportTypes.js.map +1 -0
- package/dist/core/src/compliance/complianceExportWriter.js +48 -0
- package/dist/core/src/compliance/complianceExportWriter.js.map +1 -0
- package/dist/core/src/compliance/complianceRulePackResolver.js +62 -0
- package/dist/core/src/compliance/complianceRulePackResolver.js.map +1 -0
- package/dist/core/src/config/index.js +17 -0
- package/dist/core/src/config/index.js.map +1 -0
- package/dist/core/src/config/projectConfig.js +224 -0
- package/dist/core/src/config/projectConfig.js.map +1 -0
- package/dist/core/src/config/projectIdentity.js +160 -0
- package/dist/core/src/config/projectIdentity.js.map +1 -0
- package/dist/core/src/dataQueryRiskDetection.js +1203 -0
- package/dist/core/src/dataQueryRiskDetection.js.map +1 -0
- package/dist/core/src/dependencyValidation.js +2557 -0
- package/dist/core/src/dependencyValidation.js.map +1 -0
- package/dist/core/src/discoverAdrs.js +15 -0
- package/dist/core/src/discoverAdrs.js.map +1 -0
- package/dist/core/src/drift/driftComparator.js +49 -0
- package/dist/core/src/drift/driftComparator.js.map +1 -0
- package/dist/core/src/drift/driftSnapshotLoader.js +136 -0
- package/dist/core/src/drift/driftSnapshotLoader.js.map +1 -0
- package/dist/core/src/drift/driftSnapshotTypes.js +3 -0
- package/dist/core/src/drift/driftSnapshotTypes.js.map +1 -0
- package/dist/core/src/drift/driftSnapshotWriter.js +48 -0
- package/dist/core/src/drift/driftSnapshotWriter.js.map +1 -0
- package/dist/core/src/drift/index.js +6 -0
- package/dist/core/src/drift/index.js.map +1 -0
- package/dist/core/src/eventArchitectureAnalysis.js +925 -0
- package/dist/core/src/eventArchitectureAnalysis.js.map +1 -0
- package/dist/core/src/findingTargetResolution.js +117 -0
- package/dist/core/src/findingTargetResolution.js.map +1 -0
- package/dist/core/src/generateArchitectureDiagrams.js +57 -0
- package/dist/core/src/generateArchitectureDiagrams.js.map +1 -0
- package/dist/core/src/generateImpactAnalysis.js +366 -0
- package/dist/core/src/generateImpactAnalysis.js.map +1 -0
- package/dist/core/src/generateOnboardingDocs.js +262 -0
- package/dist/core/src/generateOnboardingDocs.js.map +1 -0
- package/dist/core/src/governance/cloudConnection.js +203 -0
- package/dist/core/src/governance/cloudConnection.js.map +1 -0
- package/dist/core/src/governance/governanceContracts.js +129 -0
- package/dist/core/src/governance/governanceContracts.js.map +1 -0
- package/dist/core/src/governance/governanceGitMetadata.js +78 -0
- package/dist/core/src/governance/governanceGitMetadata.js.map +1 -0
- package/dist/core/src/governance/governanceUploadClient.js +119 -0
- package/dist/core/src/governance/governanceUploadClient.js.map +1 -0
- package/dist/core/src/governance/governanceUploadLimitErrorFormatting.js +155 -0
- package/dist/core/src/governance/governanceUploadLimitErrorFormatting.js.map +1 -0
- package/dist/core/src/governance/governanceUploadPayload.js +439 -0
- package/dist/core/src/governance/governanceUploadPayload.js.map +1 -0
- package/dist/core/src/governance/runGovernanceUpload.js +103 -0
- package/dist/core/src/governance/runGovernanceUpload.js.map +1 -0
- package/dist/core/src/impactAnalysisEngine.js +376 -0
- package/dist/core/src/impactAnalysisEngine.js.map +1 -0
- package/dist/core/src/initializationState.js +99 -0
- package/dist/core/src/initializationState.js.map +1 -0
- package/dist/core/src/managedArtifacts.js +151 -0
- package/dist/core/src/managedArtifacts.js.map +1 -0
- package/dist/core/src/moduleContractValidation.js +266 -0
- package/dist/core/src/moduleContractValidation.js.map +1 -0
- package/dist/core/src/moduleContractsGenerator.js +337 -0
- package/dist/core/src/moduleContractsGenerator.js.map +1 -0
- package/dist/core/src/moduleDiscovery.js +416 -0
- package/dist/core/src/moduleDiscovery.js.map +1 -0
- package/dist/core/src/moduleScope.js +426 -0
- package/dist/core/src/moduleScope.js.map +1 -0
- package/dist/core/src/onboardingGuidance.js +74 -0
- package/dist/core/src/onboardingGuidance.js.map +1 -0
- package/dist/core/src/operationalLogging.js +7 -0
- package/dist/core/src/operationalLogging.js.map +1 -0
- package/dist/core/src/packageVersion.js +52 -0
- package/dist/core/src/packageVersion.js.map +1 -0
- package/dist/core/src/policy/effectivePolicyResolver.js +91 -0
- package/dist/core/src/policy/effectivePolicyResolver.js.map +1 -0
- package/dist/core/src/policy/exceptionLoader.js +285 -0
- package/dist/core/src/policy/exceptionLoader.js.map +1 -0
- package/dist/core/src/policy/remotePolicyLoader.js +227 -0
- package/dist/core/src/policy/remotePolicyLoader.js.map +1 -0
- package/dist/core/src/policy/remotePolicyTypes.js +3 -0
- package/dist/core/src/policy/remotePolicyTypes.js.map +1 -0
- package/dist/core/src/policy/riskPolicyConfig.js +206 -0
- package/dist/core/src/policy/riskPolicyConfig.js.map +1 -0
- package/dist/core/src/policy/riskPolicyEnforcement.js +203 -0
- package/dist/core/src/policy/riskPolicyEnforcement.js.map +1 -0
- package/dist/core/src/policy/riskPolicyExitCode.js +16 -0
- package/dist/core/src/policy/riskPolicyExitCode.js.map +1 -0
- package/dist/core/src/policy/riskPolicyInitializer.js +90 -0
- package/dist/core/src/policy/riskPolicyInitializer.js.map +1 -0
- package/dist/core/src/quickFix/quickFixEngine.js +132 -0
- package/dist/core/src/quickFix/quickFixEngine.js.map +1 -0
- package/dist/core/src/quickFix/quickFixMessaging.js +15 -0
- package/dist/core/src/quickFix/quickFixMessaging.js.map +1 -0
- package/dist/core/src/quickFix/quickFixProviders.js +87 -0
- package/dist/core/src/quickFix/quickFixProviders.js.map +1 -0
- package/dist/core/src/quickFix/quickFixTypes.js +3 -0
- package/dist/core/src/quickFix/quickFixTypes.js.map +1 -0
- package/dist/core/src/remediation/fileHelpers.js +86 -0
- package/dist/core/src/remediation/fileHelpers.js.map +1 -0
- package/dist/core/src/remediation/fixRegistry.js +645 -0
- package/dist/core/src/remediation/fixRegistry.js.map +1 -0
- package/dist/core/src/remediation/index.js +8 -0
- package/dist/core/src/remediation/index.js.map +1 -0
- package/dist/core/src/remediation/remediationEngine.js +207 -0
- package/dist/core/src/remediation/remediationEngine.js.map +1 -0
- package/dist/core/src/reporting/adrReporter.js +59 -0
- package/dist/core/src/reporting/adrReporter.js.map +1 -0
- package/dist/core/src/reporting/architectureBaselineReporter.js +64 -0
- package/dist/core/src/reporting/architectureBaselineReporter.js.map +1 -0
- package/dist/core/src/reporting/architectureDiagramReporter.js +148 -0
- package/dist/core/src/reporting/architectureDiagramReporter.js.map +1 -0
- package/dist/core/src/reporting/architectureDriftTimelineReporter.js +44 -0
- package/dist/core/src/reporting/architectureDriftTimelineReporter.js.map +1 -0
- package/dist/core/src/reporting/architectureHealthHistoryReporter.js +51 -0
- package/dist/core/src/reporting/architectureHealthHistoryReporter.js.map +1 -0
- package/dist/core/src/reporting/architectureMapReporter.js +228 -0
- package/dist/core/src/reporting/architectureMapReporter.js.map +1 -0
- package/dist/core/src/reporting/architecturePrCommentReporter.js +324 -0
- package/dist/core/src/reporting/architecturePrCommentReporter.js.map +1 -0
- package/dist/core/src/reporting/architecturePrReviewReporter.js +389 -0
- package/dist/core/src/reporting/architecturePrReviewReporter.js.map +1 -0
- package/dist/core/src/reporting/architectureReportArtifacts.js +166 -0
- package/dist/core/src/reporting/architectureReportArtifacts.js.map +1 -0
- package/dist/core/src/reporting/architectureReviewReportGenerator.js +382 -0
- package/dist/core/src/reporting/architectureReviewReportGenerator.js.map +1 -0
- package/dist/core/src/reporting/architectureReviewReporter.js +1633 -0
- package/dist/core/src/reporting/architectureReviewReporter.js.map +1 -0
- package/dist/core/src/reporting/architectureRiskAssessment.js +101 -0
- package/dist/core/src/reporting/architectureRiskAssessment.js.map +1 -0
- package/dist/core/src/reporting/architectureScoreBadge.js +177 -0
- package/dist/core/src/reporting/architectureScoreBadge.js.map +1 -0
- package/dist/core/src/reporting/architectureSupplementalReporters.js +124 -0
- package/dist/core/src/reporting/architectureSupplementalReporters.js.map +1 -0
- package/dist/core/src/reporting/changeRiskAssessment.js +6 -0
- package/dist/core/src/reporting/changeRiskAssessment.js.map +1 -0
- package/dist/core/src/reporting/changeRiskTypes.js +3 -0
- package/dist/core/src/reporting/changeRiskTypes.js.map +1 -0
- package/dist/core/src/reporting/impactAnalysisReporter.js +111 -0
- package/dist/core/src/reporting/impactAnalysisReporter.js.map +1 -0
- package/dist/core/src/reporting/onboardingDocsReporter.js +113 -0
- package/dist/core/src/reporting/onboardingDocsReporter.js.map +1 -0
- package/dist/core/src/reporting/rulePackReporter.js +61 -0
- package/dist/core/src/reporting/rulePackReporter.js.map +1 -0
- package/dist/core/src/reporting/safetyControlsDetection.js +343 -0
- package/dist/core/src/reporting/safetyControlsDetection.js.map +1 -0
- package/dist/core/src/resolveRuleAdrs.js +31 -0
- package/dist/core/src/resolveRuleAdrs.js.map +1 -0
- package/dist/core/src/reviewGenerationWorkflow.js +220 -0
- package/dist/core/src/reviewGenerationWorkflow.js.map +1 -0
- package/dist/core/src/rulePacks/index.js +17 -0
- package/dist/core/src/rulePacks/index.js.map +1 -0
- package/dist/core/src/rulePacks/layeredMonolithRulePack.js +45 -0
- package/dist/core/src/rulePacks/layeredMonolithRulePack.js.map +1 -0
- package/dist/core/src/rulePacks/modularMonolithRulePack.js +41 -0
- package/dist/core/src/rulePacks/modularMonolithRulePack.js.map +1 -0
- package/dist/core/src/rulePacks/types.js +3 -0
- package/dist/core/src/rulePacks/types.js.map +1 -0
- package/dist/core/src/setupNextSteps.js +939 -0
- package/dist/core/src/setupNextSteps.js.map +1 -0
- package/dist/core/src/setupRefresh.js +152 -0
- package/dist/core/src/setupRefresh.js.map +1 -0
- package/dist/core/src/smartInit/apiDbHintDetection.js +836 -0
- package/dist/core/src/smartInit/apiDbHintDetection.js.map +1 -0
- package/dist/core/src/smartInit/architectureProposalBuilder.js +1215 -0
- package/dist/core/src/smartInit/architectureProposalBuilder.js.map +1 -0
- package/dist/core/src/smartInit/architectureStyleDetection.js +472 -0
- package/dist/core/src/smartInit/architectureStyleDetection.js.map +1 -0
- package/dist/core/src/smartInit/archpilotIgnore.js +139 -0
- package/dist/core/src/smartInit/archpilotIgnore.js.map +1 -0
- package/dist/core/src/smartInit/componentDetection.js +1084 -0
- package/dist/core/src/smartInit/componentDetection.js.map +1 -0
- package/dist/core/src/smartInit/implementationProfileResolution.js +53 -0
- package/dist/core/src/smartInit/implementationProfileResolution.js.map +1 -0
- package/dist/core/src/smartInit/index.js +31 -0
- package/dist/core/src/smartInit/index.js.map +1 -0
- package/dist/core/src/smartInit/moduleDetection.js +982 -0
- package/dist/core/src/smartInit/moduleDetection.js.map +1 -0
- package/dist/core/src/smartInit/projectKindDetection.js +437 -0
- package/dist/core/src/smartInit/projectKindDetection.js.map +1 -0
- package/dist/core/src/smartInit/repoTopologyDetection.js +470 -0
- package/dist/core/src/smartInit/repoTopologyDetection.js.map +1 -0
- package/dist/core/src/smartInit/runContext.js +112 -0
- package/dist/core/src/smartInit/runContext.js.map +1 -0
- package/dist/core/src/smartInit/smartInitEngine.js +94 -0
- package/dist/core/src/smartInit/smartInitEngine.js.map +1 -0
- package/dist/core/src/smartInit/stackDetection.js +503 -0
- package/dist/core/src/smartInit/stackDetection.js.map +1 -0
- package/dist/core/src/smartInit/toolingHintDetection.js +345 -0
- package/dist/core/src/smartInit/toolingHintDetection.js.map +1 -0
- package/dist/core/src/sourceScopeClassification.js +83 -0
- package/dist/core/src/sourceScopeClassification.js.map +1 -0
- package/dist/core/src/stackAdapters.js +2475 -0
- package/dist/core/src/stackAdapters.js.map +1 -0
- package/dist/core/src/stackMetadata.js +157 -0
- package/dist/core/src/stackMetadata.js.map +1 -0
- package/dist/core/src/suppressions/index.js +3 -0
- package/dist/core/src/suppressions/index.js.map +1 -0
- package/dist/core/src/suppressions/suppressionReporter.js +38 -0
- package/dist/core/src/suppressions/suppressionReporter.js.map +1 -0
- package/dist/core/src/suppressions/suppressionTypes.js +3 -0
- package/dist/core/src/suppressions/suppressionTypes.js.map +1 -0
- package/dist/core/src/suppressions/suppressionValidator.js +119 -0
- package/dist/core/src/suppressions/suppressionValidator.js.map +1 -0
- package/dist/core/src/transactionDomainAnalysis.js +1416 -0
- package/dist/core/src/transactionDomainAnalysis.js.map +1 -0
- package/dist/core/src/validation/changedFilesResolver.js +165 -0
- package/dist/core/src/validation/changedFilesResolver.js.map +1 -0
- package/dist/core/src/validationProfiling.js +33 -0
- package/dist/core/src/validationProfiling.js.map +1 -0
- package/dist/core/src/validationRuleExplanations.js +69 -0
- package/dist/core/src/validationRuleExplanations.js.map +1 -0
- package/dist/core/src/validationSourceInventory.js +200 -0
- package/dist/core/src/validationSourceInventory.js.map +1 -0
- package/dist/core/src/validationSuppressions.js +231 -0
- package/dist/core/src/validationSuppressions.js.map +1 -0
- package/dist/core/src/validationTypeScriptAstCache.js +82 -0
- package/dist/core/src/validationTypeScriptAstCache.js.map +1 -0
- package/dist/core/src/validationWorkflow.js +222 -0
- package/dist/core/src/validationWorkflow.js.map +1 -0
- package/dist/core/src/workspaceRoot.js +68 -0
- package/dist/core/src/workspaceRoot.js.map +1 -0
- package/package.json +1 -1
package/dist/archpilot-cli.js
CHANGED
|
@@ -140818,9 +140818,9 @@ ${lanes.join("\n")}
|
|
|
140818
140818
|
/*ignoreCase*/
|
|
140819
140819
|
false
|
|
140820
140820
|
)) {
|
|
140821
|
-
const
|
|
140822
|
-
if (
|
|
140823
|
-
const name = removeSuffix(removePrefix(
|
|
140821
|
+
const basename9 = getBaseFileName(a.fileName);
|
|
140822
|
+
if (basename9 === "lib.d.ts" || basename9 === "lib.es6.d.ts") return 0;
|
|
140823
|
+
const name = removeSuffix(removePrefix(basename9, "lib."), ".d.ts");
|
|
140824
140824
|
const index = libs.indexOf(name);
|
|
140825
140825
|
if (index !== -1) return index + 1;
|
|
140826
140826
|
}
|
|
@@ -204566,8 +204566,8 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
204566
204566
|
}
|
|
204567
204567
|
};
|
|
204568
204568
|
for (const file of files) {
|
|
204569
|
-
const
|
|
204570
|
-
if (
|
|
204569
|
+
const basename9 = getBaseFileName(file);
|
|
204570
|
+
if (basename9 === "package.json" || basename9 === "bower.json") {
|
|
204571
204571
|
createProjectWatcher(
|
|
204572
204572
|
file,
|
|
204573
204573
|
"FileWatcher"
|
|
@@ -208239,8 +208239,8 @@ All files are: ${JSON.stringify(names)}`,
|
|
|
208239
208239
|
var _a;
|
|
208240
208240
|
const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
|
|
208241
208241
|
if (!fileOrDirectoryPath) return;
|
|
208242
|
-
const
|
|
208243
|
-
if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (
|
|
208242
|
+
const basename9 = getBaseFileName(fileOrDirectoryPath);
|
|
208243
|
+
if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (basename9 === "package.json" || basename9 === "node_modules")) {
|
|
208244
208244
|
result.affectedModuleSpecifierCacheProjects.forEach((project) => {
|
|
208245
208245
|
var _a2;
|
|
208246
208246
|
(_a2 = project.getModuleSpecifierCache()) == null ? void 0 : _a2.clear();
|
|
@@ -215175,9 +215175,9 @@ function pathHasFileExtension(value) {
|
|
|
215175
215175
|
function isRelativeImport(importSpecifier) {
|
|
215176
215176
|
return importSpecifier === "." || importSpecifier === ".." || importSpecifier.startsWith("./") || importSpecifier.startsWith("../");
|
|
215177
215177
|
}
|
|
215178
|
-
function
|
|
215179
|
-
const child =
|
|
215180
|
-
const parent =
|
|
215178
|
+
function isNormalizedPathInsideOrEqual(normalizedChildPath, normalizedParentPath) {
|
|
215179
|
+
const child = normalizedChildPath.toLowerCase();
|
|
215180
|
+
const parent = normalizedParentPath.toLowerCase();
|
|
215181
215181
|
return child === parent || child.startsWith(`${parent}/`);
|
|
215182
215182
|
}
|
|
215183
215183
|
function toEndpoint(candidate) {
|
|
@@ -215196,38 +215196,43 @@ function compareCandidates(left, right) {
|
|
|
215196
215196
|
}
|
|
215197
215197
|
return left.component.id.localeCompare(right.component.id);
|
|
215198
215198
|
}
|
|
215199
|
-
function
|
|
215200
|
-
const normalizedModulePath = normalizePath2(modulePath);
|
|
215199
|
+
function normalizedModulePathMatchScore(normalizedInputPath, normalizedModulePath) {
|
|
215201
215200
|
if (pathHasFileExtension(normalizedModulePath)) {
|
|
215202
|
-
return
|
|
215201
|
+
return isNormalizedPathInsideOrEqual(normalizedInputPath, normalizedModulePath) || isNormalizedPathInsideOrEqual(normalizedModulePath, normalizedInputPath) ? normalizedModulePath.length + 1e3 : void 0;
|
|
215203
215202
|
}
|
|
215204
|
-
return
|
|
215203
|
+
return isNormalizedPathInsideOrEqual(normalizedInputPath, normalizedModulePath) ? normalizedModulePath.length + 1e3 : void 0;
|
|
215204
|
+
}
|
|
215205
|
+
function modulePathMatchScore(inputPath, modulePath) {
|
|
215206
|
+
return normalizedModulePathMatchScore(normalizePath2(inputPath), normalizePath2(modulePath));
|
|
215205
215207
|
}
|
|
215206
215208
|
function findComponentForPath(components, inputPath) {
|
|
215207
215209
|
const normalizedInputPath = normalizePath2(inputPath);
|
|
215208
215210
|
const candidates = [];
|
|
215209
215211
|
for (const component of components) {
|
|
215210
|
-
for (const
|
|
215211
|
-
if (!moduleReference.
|
|
215212
|
+
for (const moduleReference of component.modules) {
|
|
215213
|
+
if (!moduleReference.normalizedPath) {
|
|
215212
215214
|
continue;
|
|
215213
215215
|
}
|
|
215214
|
-
const score =
|
|
215216
|
+
const score = normalizedModulePathMatchScore(
|
|
215217
|
+
normalizedInputPath,
|
|
215218
|
+
moduleReference.normalizedPath
|
|
215219
|
+
);
|
|
215215
215220
|
if (score !== void 0) {
|
|
215216
215221
|
candidates.push({
|
|
215217
|
-
component,
|
|
215218
|
-
moduleId,
|
|
215222
|
+
component: component.component,
|
|
215223
|
+
moduleId: moduleReference.moduleId,
|
|
215219
215224
|
path: moduleReference.path,
|
|
215220
215225
|
ownership: "module-path",
|
|
215221
215226
|
score
|
|
215222
215227
|
});
|
|
215223
215228
|
}
|
|
215224
215229
|
}
|
|
215225
|
-
if (component.
|
|
215230
|
+
if (component.normalizedPath && isNormalizedPathInsideOrEqual(normalizedInputPath, component.normalizedPath)) {
|
|
215226
215231
|
candidates.push({
|
|
215227
|
-
component,
|
|
215228
|
-
path: component.path,
|
|
215232
|
+
component: component.component,
|
|
215233
|
+
path: component.component.path,
|
|
215229
215234
|
ownership: "component-path",
|
|
215230
|
-
score:
|
|
215235
|
+
score: component.normalizedPath.length
|
|
215231
215236
|
});
|
|
215232
215237
|
}
|
|
215233
215238
|
}
|
|
@@ -215238,19 +215243,20 @@ function findComponentForModuleSpecifier(components, importSpecifier) {
|
|
|
215238
215243
|
const normalizedSegments = normalizedImport.split("/").filter((segment) => segment.length > 0);
|
|
215239
215244
|
const candidates = [];
|
|
215240
215245
|
for (const component of components) {
|
|
215241
|
-
for (const
|
|
215246
|
+
for (const moduleReference of component.modules) {
|
|
215247
|
+
const moduleId = moduleReference.moduleId;
|
|
215242
215248
|
if (normalizedImport === moduleId || normalizedImport.startsWith(`${moduleId}/`)) {
|
|
215243
215249
|
candidates.push({
|
|
215244
|
-
component,
|
|
215250
|
+
component: component.component,
|
|
215245
215251
|
moduleId,
|
|
215246
215252
|
...moduleReference.path ? { path: moduleReference.path } : {},
|
|
215247
215253
|
ownership: moduleReference.path ? "module-path" : "component-path",
|
|
215248
215254
|
score: moduleId.length + 500
|
|
215249
215255
|
});
|
|
215250
215256
|
}
|
|
215251
|
-
if (component.id === VIRTUAL_WORKSPACE_COMPONENT_ID && normalizedSegments.includes(moduleId)) {
|
|
215257
|
+
if (component.component.id === VIRTUAL_WORKSPACE_COMPONENT_ID && normalizedSegments.includes(moduleId)) {
|
|
215252
215258
|
candidates.push({
|
|
215253
|
-
component,
|
|
215259
|
+
component: component.component,
|
|
215254
215260
|
moduleId,
|
|
215255
215261
|
...moduleReference.path ? { path: moduleReference.path } : {},
|
|
215256
215262
|
ownership: "virtual-workspace",
|
|
@@ -215258,20 +215264,20 @@ function findComponentForModuleSpecifier(components, importSpecifier) {
|
|
|
215258
215264
|
});
|
|
215259
215265
|
}
|
|
215260
215266
|
}
|
|
215261
|
-
if (component.
|
|
215267
|
+
if (component.normalizedPath && isNormalizedPathInsideOrEqual(normalizedImport, component.normalizedPath)) {
|
|
215262
215268
|
candidates.push({
|
|
215263
|
-
component,
|
|
215264
|
-
path: component.path,
|
|
215269
|
+
component: component.component,
|
|
215270
|
+
path: component.component.path,
|
|
215265
215271
|
ownership: "component-path",
|
|
215266
|
-
score:
|
|
215272
|
+
score: component.normalizedPath.length
|
|
215267
215273
|
});
|
|
215268
215274
|
}
|
|
215269
|
-
if (normalizedImport === component.id || normalizedImport.startsWith(`${component.id}/`)) {
|
|
215275
|
+
if (normalizedImport === component.component.id || normalizedImport.startsWith(`${component.component.id}/`)) {
|
|
215270
215276
|
candidates.push({
|
|
215271
|
-
component,
|
|
215272
|
-
...component.path ? { path: component.path } : {},
|
|
215273
|
-
ownership: component.path ? "component-path" : "virtual-workspace",
|
|
215274
|
-
score: component.id.length
|
|
215277
|
+
component: component.component,
|
|
215278
|
+
...component.component.path ? { path: component.component.path } : {},
|
|
215279
|
+
ownership: component.component.path ? "component-path" : "virtual-workspace",
|
|
215280
|
+
score: component.component.id.length
|
|
215275
215281
|
});
|
|
215276
215282
|
}
|
|
215277
215283
|
}
|
|
@@ -215315,12 +215321,12 @@ function resolveSourceCandidate(contract, components, sourceFile) {
|
|
|
215315
215321
|
return directMatch;
|
|
215316
215322
|
}
|
|
215317
215323
|
const virtualComponent = components.find(
|
|
215318
|
-
(component) => component.id === VIRTUAL_WORKSPACE_COMPONENT_ID
|
|
215319
|
-
);
|
|
215324
|
+
(component) => component.component.id === VIRTUAL_WORKSPACE_COMPONENT_ID
|
|
215325
|
+
)?.component;
|
|
215320
215326
|
if (virtualComponent) {
|
|
215321
215327
|
return resolveLegacyVirtualSource(contract, sourceFile, virtualComponent);
|
|
215322
215328
|
}
|
|
215323
|
-
const fallback = [...components].sort((left, right) => left.id.localeCompare(right.id))[0];
|
|
215329
|
+
const fallback = [...components].map((component) => component.component).sort((left, right) => left.id.localeCompare(right.id))[0];
|
|
215324
215330
|
if (fallback) {
|
|
215325
215331
|
return {
|
|
215326
215332
|
component: fallback,
|
|
@@ -215331,7 +215337,7 @@ function resolveSourceCandidate(contract, components, sourceFile) {
|
|
|
215331
215337
|
}
|
|
215332
215338
|
throw new Error("Architecture dependency context requires at least one normalized component.");
|
|
215333
215339
|
}
|
|
215334
|
-
function resolveTargetCandidate(components, sourceFile, importSpecifier) {
|
|
215340
|
+
function resolveTargetCandidate(contract, components, sourceFile, importSpecifier) {
|
|
215335
215341
|
if (isRelativeImport(importSpecifier)) {
|
|
215336
215342
|
const resolvedTargetPath = resolveRelativeImportPath(sourceFile, importSpecifier);
|
|
215337
215343
|
return {
|
|
@@ -215340,7 +215346,8 @@ function resolveTargetCandidate(components, sourceFile, importSpecifier) {
|
|
|
215340
215346
|
};
|
|
215341
215347
|
}
|
|
215342
215348
|
const normalizedImport = normalizeImportPath(importSpecifier);
|
|
215343
|
-
|
|
215349
|
+
const normalizedModulesRoot = normalizePath2(resolveModulesRootFromContract(contract));
|
|
215350
|
+
if (normalizedModulesRoot.length > 0 && normalizedImport.startsWith(`${normalizedModulesRoot}/`) || normalizedImport.startsWith("src/") || normalizedImport.startsWith("app/") || normalizedImport.startsWith("apps/") || normalizedImport.startsWith("services/") || normalizedImport.startsWith("packages/") || normalizedImport.startsWith("libs/") || normalizedImport.startsWith("libraries/") || normalizedImport.startsWith("workers/")) {
|
|
215344
215351
|
return {
|
|
215345
215352
|
candidate: findComponentForPath(components, normalizedImport),
|
|
215346
215353
|
resolvedTargetPath: normalizedImport
|
|
@@ -215352,20 +215359,28 @@ function resolveTargetCandidate(components, sourceFile, importSpecifier) {
|
|
|
215352
215359
|
}
|
|
215353
215360
|
return {};
|
|
215354
215361
|
}
|
|
215355
|
-
function
|
|
215356
|
-
|
|
215357
|
-
|
|
215362
|
+
function prepareComponentReferences(components) {
|
|
215363
|
+
return components.map((component) => ({
|
|
215364
|
+
component,
|
|
215365
|
+
...component.path ? { normalizedPath: normalizePath2(component.path) } : {},
|
|
215366
|
+
modules: Object.entries(component.modules).map(([moduleId, moduleReference]) => ({
|
|
215367
|
+
moduleId,
|
|
215368
|
+
...moduleReference.path ? {
|
|
215369
|
+
path: moduleReference.path,
|
|
215370
|
+
normalizedPath: normalizePath2(moduleReference.path)
|
|
215371
|
+
} : {}
|
|
215372
|
+
}))
|
|
215373
|
+
}));
|
|
215374
|
+
}
|
|
215375
|
+
function resolveDependencyContextWithPreparedComponents(contract, components, input2) {
|
|
215376
|
+
const sourceCandidate = resolveSourceCandidate(contract, components, input2.sourceFile);
|
|
215358
215377
|
const { candidate: resolvedTargetCandidate, resolvedTargetPath } = resolveTargetCandidate(
|
|
215359
|
-
|
|
215378
|
+
contract,
|
|
215379
|
+
components,
|
|
215360
215380
|
input2.sourceFile,
|
|
215361
215381
|
input2.importSpecifier
|
|
215362
215382
|
);
|
|
215363
|
-
const targetCandidate = resolvedTargetCandidate ?? (resolvedTargetPath ?
|
|
215364
|
-
...sourceCandidate,
|
|
215365
|
-
path: resolvedTargetPath,
|
|
215366
|
-
ownership: sourceCandidate.ownership,
|
|
215367
|
-
score: 0
|
|
215368
|
-
} : void 0);
|
|
215383
|
+
const targetCandidate = resolvedTargetCandidate ?? (resolvedTargetPath ? resolveSourceCandidate(contract, components, resolvedTargetPath) : void 0);
|
|
215369
215384
|
if (!targetCandidate) {
|
|
215370
215385
|
return {
|
|
215371
215386
|
dependencyType: "external",
|
|
@@ -215386,6 +215401,19 @@ function resolveDependencyContext(contract, input2) {
|
|
|
215386
215401
|
isExternal: false
|
|
215387
215402
|
};
|
|
215388
215403
|
}
|
|
215404
|
+
function createArchitectureDependencyContextResolver(contract) {
|
|
215405
|
+
const model = normalizeArchitectureWorkspaceModel(contract);
|
|
215406
|
+
const components = prepareComponentReferences(model.components);
|
|
215407
|
+
return {
|
|
215408
|
+
contract,
|
|
215409
|
+
model,
|
|
215410
|
+
resolve: (input2) => resolveDependencyContextWithPreparedComponents(
|
|
215411
|
+
contract,
|
|
215412
|
+
components,
|
|
215413
|
+
input2
|
|
215414
|
+
)
|
|
215415
|
+
};
|
|
215416
|
+
}
|
|
215389
215417
|
var path6;
|
|
215390
215418
|
var init_architectureDependencyContext = __esm({
|
|
215391
215419
|
"../core/src/architectureDependencyContext.ts"() {
|
|
@@ -215396,17 +215424,85 @@ var init_architectureDependencyContext = __esm({
|
|
|
215396
215424
|
}
|
|
215397
215425
|
});
|
|
215398
215426
|
|
|
215427
|
+
// ../core/src/sourceScopeClassification.ts
|
|
215428
|
+
function normalizePath3(value) {
|
|
215429
|
+
return value.replace(/\\/g, "/").toLowerCase();
|
|
215430
|
+
}
|
|
215431
|
+
function hasPathSegment(pathValue, pattern) {
|
|
215432
|
+
return pathValue.split("/").some((segment) => pattern.test(segment));
|
|
215433
|
+
}
|
|
215434
|
+
function hasTopLevelPathSegment(pathValue, pattern) {
|
|
215435
|
+
const [firstSegment] = pathValue.split("/");
|
|
215436
|
+
return !!firstSegment && pattern.test(firstSegment);
|
|
215437
|
+
}
|
|
215438
|
+
function classifyValidationSourceScope(relativePath) {
|
|
215439
|
+
const normalized = normalizePath3(relativePath);
|
|
215440
|
+
const fileName = normalized.split("/").at(-1) ?? normalized;
|
|
215441
|
+
const extension = fileName.includes(".") ? fileName.slice(fileName.lastIndexOf(".")) : "";
|
|
215442
|
+
const isTestFile = /\.(?:spec|test|e2e-spec|integration-test)\.(?:ts|tsx|js|jsx|mjs|cjs|java|cs|py|php|go)$/u.test(fileName);
|
|
215443
|
+
const isE2e = isTestFile && /(?:^|[./_-])e2e(?:[./_-]|$)/u.test(fileName) || hasPathSegment(normalized, /^e2e$/u);
|
|
215444
|
+
const isFixture = hasPathSegment(normalized, /^(?:fixtures?|__fixtures__)$/u);
|
|
215445
|
+
const isTestPlugin = hasPathSegment(normalized, /^(?:test-plugins?|testing-plugins?)$/u);
|
|
215446
|
+
const isExamplePlugin = hasPathSegment(normalized, /^example-plugins?$/u) || hasTopLevelPathSegment(normalized, /^examples?$/u);
|
|
215447
|
+
const isGenerated = hasPathSegment(normalized, /^(?:generated|__generated__|gen|templates?)$/u) || /\.(?:generated|gen|g)\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/u.test(fileName) || /\.d\.ts$/u.test(fileName);
|
|
215448
|
+
const isMigration = hasPathSegment(normalized, /^(?:migrations?|schema-migrations?|data-migrations|migration-utils?)$/u);
|
|
215449
|
+
const isCliTooling = hasPathSegment(normalized, /^(?:cli|bin|scripts?|tools?|scaffold|scaffolding|generators?)$/u) || /(?:^|[./_-])(?:cli|script|tool|generator|scaffold)(?:[./_-]|$)/u.test(fileName);
|
|
215450
|
+
const isFrontend = extension === ".tsx" || extension === ".jsx" || hasPathSegment(normalized, /^(?:frontend|client|browser|ui|admin-ui|dashboard|web-app)$/u) || /\b(?:react|angular|vue|svelte)\b/u.test(normalized);
|
|
215451
|
+
const isInfrastructure = hasPathSegment(normalized, /^(?:infrastructure|infra|framework|adapters?|persistence|providers?)$/u) || /(?:transactional-connection|transaction-wrapper|transaction-subscriber|transaction-manager|query-runner|query-builder|event-bus|telemetry|interceptor)\.(?:ts|js|java|cs|py|php|go)$/u.test(fileName);
|
|
215452
|
+
let category = "production-backend";
|
|
215453
|
+
if (isGenerated) {
|
|
215454
|
+
category = "generated";
|
|
215455
|
+
} else if (isE2e) {
|
|
215456
|
+
category = "e2e";
|
|
215457
|
+
} else if (isTestFile || hasPathSegment(normalized, /^(?:test|tests|__tests__|spec|specs|__mocks__|cypress|cypress-tests)$/u)) {
|
|
215458
|
+
category = "test";
|
|
215459
|
+
} else if (isTestPlugin) {
|
|
215460
|
+
category = "test-plugin";
|
|
215461
|
+
} else if (isExamplePlugin) {
|
|
215462
|
+
category = "example-plugin";
|
|
215463
|
+
} else if (isFixture) {
|
|
215464
|
+
category = "fixture";
|
|
215465
|
+
} else if (isMigration) {
|
|
215466
|
+
category = "migration";
|
|
215467
|
+
} else if (isCliTooling) {
|
|
215468
|
+
category = "cli-tooling";
|
|
215469
|
+
} else if (isFrontend) {
|
|
215470
|
+
category = "production-frontend";
|
|
215471
|
+
} else if (isInfrastructure) {
|
|
215472
|
+
category = "infrastructure";
|
|
215473
|
+
}
|
|
215474
|
+
const isTestLike = category === "test" || category === "e2e" || category === "fixture" || category === "test-plugin" || category === "example-plugin";
|
|
215475
|
+
return {
|
|
215476
|
+
category,
|
|
215477
|
+
isProduction: category === "production-backend" || category === "production-frontend" || category === "infrastructure",
|
|
215478
|
+
isFrontend: category === "production-frontend",
|
|
215479
|
+
isTestLike,
|
|
215480
|
+
isGenerated: category === "generated",
|
|
215481
|
+
isMigration: category === "migration",
|
|
215482
|
+
isCliTooling: category === "cli-tooling",
|
|
215483
|
+
isInfrastructure: category === "infrastructure"
|
|
215484
|
+
};
|
|
215485
|
+
}
|
|
215486
|
+
function isProductionBackendGovernanceScope(scope) {
|
|
215487
|
+
return scope.category === "production-backend";
|
|
215488
|
+
}
|
|
215489
|
+
var init_sourceScopeClassification = __esm({
|
|
215490
|
+
"../core/src/sourceScopeClassification.ts"() {
|
|
215491
|
+
"use strict";
|
|
215492
|
+
}
|
|
215493
|
+
});
|
|
215494
|
+
|
|
215399
215495
|
// ../core/src/dependencyValidation.ts
|
|
215400
|
-
function
|
|
215496
|
+
function normalizePath4(filePath) {
|
|
215401
215497
|
return filePath.replace(/\\/g, "/");
|
|
215402
215498
|
}
|
|
215403
215499
|
function toSafeContractModuleFileStem(moduleName) {
|
|
215404
|
-
return
|
|
215500
|
+
return normalizePath4(moduleName).split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0).join(".");
|
|
215405
215501
|
}
|
|
215406
215502
|
function normalizeAbsolutePath(filePath) {
|
|
215407
|
-
return
|
|
215503
|
+
return normalizePath4(path7.resolve(filePath)).toLowerCase();
|
|
215408
215504
|
}
|
|
215409
|
-
function
|
|
215505
|
+
function isPathInsideOrEqual(childPath, parentPath) {
|
|
215410
215506
|
const child = normalizeAbsolutePath(childPath);
|
|
215411
215507
|
const parent = normalizeAbsolutePath(parentPath);
|
|
215412
215508
|
return child === parent || child.startsWith(`${parent}/`);
|
|
@@ -215442,7 +215538,7 @@ function getComponentModuleRoots(workspaceRoot, architectureContract) {
|
|
|
215442
215538
|
}
|
|
215443
215539
|
const typed = value;
|
|
215444
215540
|
const componentId = typeof typed.id === "string" && typed.id.trim().length > 0 ? typed.id.trim() : typeof key === "string" && key.trim().length > 0 ? key.trim() : void 0;
|
|
215445
|
-
const componentPath = typeof typed.path === "string" && typed.path.trim().length > 0 ?
|
|
215541
|
+
const componentPath = typeof typed.path === "string" && typed.path.trim().length > 0 ? normalizePath4(typed.path.trim()) : void 0;
|
|
215446
215542
|
if (!componentId || !componentPath || componentPath === ".") {
|
|
215447
215543
|
continue;
|
|
215448
215544
|
}
|
|
@@ -215487,6 +215583,9 @@ function buildChildModulesByParent(hierarchyEdges) {
|
|
|
215487
215583
|
])
|
|
215488
215584
|
);
|
|
215489
215585
|
}
|
|
215586
|
+
function isIsolatedContractlessHierarchyModule(input2) {
|
|
215587
|
+
return !input2.hasContract && input2.parentModule !== void 0 && input2.declaredDependencies.length === 0 && input2.actualDependencies.length === 0 && input2.inboundDeclaredFrom.length === 0 && input2.inboundActualFrom.length === 0 && input2.unusedDeclaredDependencies.length === 0 && input2.undeclaredActualDependencies.length === 0;
|
|
215588
|
+
}
|
|
215490
215589
|
function getScriptKind(filePath) {
|
|
215491
215590
|
const extension = path7.extname(filePath).toLowerCase();
|
|
215492
215591
|
switch (extension) {
|
|
@@ -215642,9 +215741,9 @@ async function buildTsConfigPathAliasMap(workspaceRoot, moduleRoots) {
|
|
|
215642
215741
|
continue;
|
|
215643
215742
|
}
|
|
215644
215743
|
const isWildcard = /\/\*$/u.test(aliasPattern) && /\/\*$/u.test(targetPattern);
|
|
215645
|
-
const normalizedTarget =
|
|
215744
|
+
const normalizedTarget = normalizePath4(targetPattern).replace(/\/\*$/u, "");
|
|
215646
215745
|
const absoluteTarget = path7.join(workspaceRoot, ...normalizedTarget.split("/"));
|
|
215647
|
-
const moduleEntry = [...moduleRoots.entries()].filter(([, moduleRoot2]) =>
|
|
215746
|
+
const moduleEntry = [...moduleRoots.entries()].filter(([, moduleRoot2]) => isPathInsideOrEqual(absoluteTarget, moduleRoot2)).sort((left, right) => right[1].length - left[1].length || left[0].localeCompare(right[0]))[0];
|
|
215648
215747
|
if (!moduleEntry) {
|
|
215649
215748
|
continue;
|
|
215650
215749
|
}
|
|
@@ -215745,7 +215844,7 @@ async function findModuleRoots(workspaceRoot, modulesRootRelativePath = "src/mod
|
|
|
215745
215844
|
if (!configuredPath || typeof configuredPath !== "string") {
|
|
215746
215845
|
continue;
|
|
215747
215846
|
}
|
|
215748
|
-
const normalizedConfiguredPath =
|
|
215847
|
+
const normalizedConfiguredPath = normalizePath4(configuredPath);
|
|
215749
215848
|
if (/\.[a-z0-9]+$/iu.test(normalizedConfiguredPath)) {
|
|
215750
215849
|
continue;
|
|
215751
215850
|
}
|
|
@@ -215853,7 +215952,7 @@ async function buildExplicitStandaloneModulePathMap(workspaceRoot, architectureC
|
|
|
215853
215952
|
if (!configuredPath || typeof configuredPath !== "string") {
|
|
215854
215953
|
continue;
|
|
215855
215954
|
}
|
|
215856
|
-
const normalizedConfiguredPath =
|
|
215955
|
+
const normalizedConfiguredPath = normalizePath4(configuredPath);
|
|
215857
215956
|
if (!/\.[a-z0-9]+$/iu.test(normalizedConfiguredPath)) {
|
|
215858
215957
|
continue;
|
|
215859
215958
|
}
|
|
@@ -215869,11 +215968,7 @@ async function buildExplicitStandaloneModulePathMap(workspaceRoot, architectureC
|
|
|
215869
215968
|
return map;
|
|
215870
215969
|
}
|
|
215871
215970
|
function isTestSourcePath(relativePath) {
|
|
215872
|
-
|
|
215873
|
-
if (normalized.includes("/__tests__/") || normalized.includes("/test/") || normalized.includes("/tests/") || normalized.includes("/__mocks__/")) {
|
|
215874
|
-
return true;
|
|
215875
|
-
}
|
|
215876
|
-
return /(^|\/)[^/]+\.(test|spec)\.[cm]?[jt]sx?$/u.test(normalized);
|
|
215971
|
+
return classifyValidationSourceScope(relativePath).isTestLike;
|
|
215877
215972
|
}
|
|
215878
215973
|
async function collectSourceFiles(directoryPath, adapter, scanRootPath = directoryPath, excludedDirectoryRoots = []) {
|
|
215879
215974
|
const entries = await import_node_fs6.promises.readdir(directoryPath, { withFileTypes: true });
|
|
@@ -215883,11 +215978,11 @@ async function collectSourceFiles(directoryPath, adapter, scanRootPath = directo
|
|
|
215883
215978
|
const fullPath = path7.join(directoryPath, entry.name);
|
|
215884
215979
|
if (entry.isDirectory()) {
|
|
215885
215980
|
if (excludedDirectoryRoots.some(
|
|
215886
|
-
(excludedRoot) =>
|
|
215981
|
+
(excludedRoot) => isPathInsideOrEqual(fullPath, excludedRoot)
|
|
215887
215982
|
)) {
|
|
215888
215983
|
continue;
|
|
215889
215984
|
}
|
|
215890
|
-
const normalizedRelativeDirectory =
|
|
215985
|
+
const normalizedRelativeDirectory = normalizePath4(
|
|
215891
215986
|
path7.relative(scanRootPath, fullPath)
|
|
215892
215987
|
);
|
|
215893
215988
|
if (adapter.ignoreDirectoryNames.includes(entry.name) || adapter.ignoreDirectoryNames.includes(normalizedRelativeDirectory)) {
|
|
@@ -216098,6 +216193,80 @@ function extractGoImportSpecifiers(sourceText) {
|
|
|
216098
216193
|
return left.specifier.localeCompare(right.specifier);
|
|
216099
216194
|
});
|
|
216100
216195
|
}
|
|
216196
|
+
function extractJavaPackageName(sourceText) {
|
|
216197
|
+
const match = /^\s*package\s+([a-zA-Z_][\w.]*)\s*;/mu.exec(sourceText);
|
|
216198
|
+
return match?.[1];
|
|
216199
|
+
}
|
|
216200
|
+
async function buildJavaImportIndex(workspaceRoot, moduleRoots, adapter) {
|
|
216201
|
+
const classes = /* @__PURE__ */ new Map();
|
|
216202
|
+
const packageCandidates = /* @__PURE__ */ new Map();
|
|
216203
|
+
for (const [moduleId, moduleRoot] of [...moduleRoots.entries()].sort(
|
|
216204
|
+
([left], [right]) => left.localeCompare(right)
|
|
216205
|
+
)) {
|
|
216206
|
+
const childModuleRoots = [...moduleRoots.entries()].filter(([childModuleName, childModuleRoot]) => childModuleName !== moduleId && isPathInsideOrEqual(childModuleRoot, moduleRoot)).map(([, childModuleRoot]) => childModuleRoot);
|
|
216207
|
+
const sourceFiles = await collectSourceFiles(moduleRoot, adapter, moduleRoot, childModuleRoots);
|
|
216208
|
+
for (const sourceFilePath of sourceFiles) {
|
|
216209
|
+
const relativePath = normalizePath4(path7.relative(workspaceRoot, sourceFilePath));
|
|
216210
|
+
if (isTestSourcePath(relativePath)) {
|
|
216211
|
+
continue;
|
|
216212
|
+
}
|
|
216213
|
+
const sourceText = await readTextFileIfExists2(sourceFilePath);
|
|
216214
|
+
if (!sourceText) {
|
|
216215
|
+
continue;
|
|
216216
|
+
}
|
|
216217
|
+
const packageName = extractJavaPackageName(sourceText);
|
|
216218
|
+
if (!packageName) {
|
|
216219
|
+
continue;
|
|
216220
|
+
}
|
|
216221
|
+
const className = path7.basename(sourceFilePath, path7.extname(sourceFilePath));
|
|
216222
|
+
const entry = { moduleId, resolvedPath: sourceFilePath };
|
|
216223
|
+
classes.set(`${packageName}.${className}`, entry);
|
|
216224
|
+
const existing = packageCandidates.get(packageName) ?? [];
|
|
216225
|
+
existing.push(entry);
|
|
216226
|
+
packageCandidates.set(packageName, existing);
|
|
216227
|
+
}
|
|
216228
|
+
}
|
|
216229
|
+
const packages = /* @__PURE__ */ new Map();
|
|
216230
|
+
for (const [packageName, entries] of packageCandidates) {
|
|
216231
|
+
const moduleIds = new Set(entries.map((entry) => entry.moduleId));
|
|
216232
|
+
packages.set(packageName, moduleIds.size === 1 ? entries[0] : "ambiguous");
|
|
216233
|
+
}
|
|
216234
|
+
return { classes, packages };
|
|
216235
|
+
}
|
|
216236
|
+
function resolveJavaImportFromIndex(importSpecifier, index, workspaceRoot) {
|
|
216237
|
+
if (!index) {
|
|
216238
|
+
return void 0;
|
|
216239
|
+
}
|
|
216240
|
+
if (importSpecifier.endsWith(".*")) {
|
|
216241
|
+
const packageName = importSpecifier.slice(0, -2);
|
|
216242
|
+
const entry = index.packages.get(packageName);
|
|
216243
|
+
if (!entry || entry === "ambiguous") {
|
|
216244
|
+
return void 0;
|
|
216245
|
+
}
|
|
216246
|
+
return {
|
|
216247
|
+
targetModule: entry.moduleId,
|
|
216248
|
+
resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, entry.resolvedPath)),
|
|
216249
|
+
isPublicImport: false
|
|
216250
|
+
};
|
|
216251
|
+
}
|
|
216252
|
+
const exactEntry = index.classes.get(importSpecifier);
|
|
216253
|
+
if (exactEntry) {
|
|
216254
|
+
return {
|
|
216255
|
+
targetModule: exactEntry.moduleId,
|
|
216256
|
+
resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, exactEntry.resolvedPath)),
|
|
216257
|
+
isPublicImport: false
|
|
216258
|
+
};
|
|
216259
|
+
}
|
|
216260
|
+
const ownerCandidate = [...index.classes.entries()].filter(([classImport]) => importSpecifier.startsWith(`${classImport}.`)).sort((left, right) => right[0].length - left[0].length || left[0].localeCompare(right[0]))[0];
|
|
216261
|
+
if (!ownerCandidate) {
|
|
216262
|
+
return void 0;
|
|
216263
|
+
}
|
|
216264
|
+
return {
|
|
216265
|
+
targetModule: ownerCandidate[1].moduleId,
|
|
216266
|
+
resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, ownerCandidate[1].resolvedPath)),
|
|
216267
|
+
isPublicImport: false
|
|
216268
|
+
};
|
|
216269
|
+
}
|
|
216101
216270
|
function extractPythonImportSpecifiers(sourceText) {
|
|
216102
216271
|
const imports = [];
|
|
216103
216272
|
const lines = sourceText.split(/\r?\n/u);
|
|
@@ -216200,7 +216369,7 @@ function resolveJavaModuleImport(modulesRootRelativePath, moduleRoots, importSpe
|
|
|
216200
216369
|
const lastSegment = segments[segments.length - 1];
|
|
216201
216370
|
const defaultEntrypointFileName = adapter.scaffoldingDefaults?.moduleIndexFileName ?? "Application.java";
|
|
216202
216371
|
const resolvedFileName = lastSegment === "*" ? defaultEntrypointFileName : lastSegment.endsWith(".java") ? lastSegment : `${lastSegment}.java`;
|
|
216203
|
-
const resolvedRelativePath =
|
|
216372
|
+
const resolvedRelativePath = normalizePath4(
|
|
216204
216373
|
`${modulesRootRelativePath}/${targetModule}/${resolvedFileName}`
|
|
216205
216374
|
);
|
|
216206
216375
|
return {
|
|
@@ -216538,13 +216707,17 @@ async function resolveWorkspacePackageImportTarget(importSpecifier, workspacePac
|
|
|
216538
216707
|
}
|
|
216539
216708
|
return void 0;
|
|
216540
216709
|
}
|
|
216541
|
-
async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath, moduleRoots, explicitStandaloneModuleByPath, workspacePackageAliases, sourceFilePath, importSpecifier, adapter, resolutionContext) {
|
|
216710
|
+
async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath, moduleRoots, explicitStandaloneModuleByPath, workspacePackageAliases, sourceFilePath, importSpecifier, adapter, javaImportIndex, resolutionContext) {
|
|
216542
216711
|
const candidateBasePaths = [];
|
|
216543
216712
|
let packageAliasTargetModule;
|
|
216544
216713
|
let packageAliasTargetModuleRoot;
|
|
216545
216714
|
let isPublicPackageAliasImport = false;
|
|
216546
|
-
const normalizedModulesRoot =
|
|
216715
|
+
const normalizedModulesRoot = normalizePath4(modulesRootRelativePath).replace(/^\/+/, "");
|
|
216547
216716
|
if (usesJavaImportParser(adapter) && !importSpecifier.startsWith(".")) {
|
|
216717
|
+
const indexedJava = resolveJavaImportFromIndex(importSpecifier, javaImportIndex, workspaceRoot);
|
|
216718
|
+
if (indexedJava) {
|
|
216719
|
+
return indexedJava;
|
|
216720
|
+
}
|
|
216548
216721
|
const resolvedJava = resolveJavaModuleImport(
|
|
216549
216722
|
normalizedModulesRoot,
|
|
216550
216723
|
moduleRoots,
|
|
@@ -216638,22 +216811,22 @@ async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath,
|
|
|
216638
216811
|
if (!resolvedPath) {
|
|
216639
216812
|
return void 0;
|
|
216640
216813
|
}
|
|
216641
|
-
const targetModuleEntry = packageAliasTargetModule && packageAliasTargetModuleRoot ? [packageAliasTargetModule, packageAliasTargetModuleRoot] : [...moduleRoots.entries()].filter(([, moduleRoot]) =>
|
|
216814
|
+
const targetModuleEntry = packageAliasTargetModule && packageAliasTargetModuleRoot ? [packageAliasTargetModule, packageAliasTargetModuleRoot] : [...moduleRoots.entries()].filter(([, moduleRoot]) => isPathInsideOrEqual(resolvedPath, moduleRoot)).sort((left, right) => right[1].length - left[1].length || left[0].localeCompare(right[0]))[0];
|
|
216642
216815
|
if (!targetModuleEntry) {
|
|
216643
216816
|
const standaloneTargetModule = explicitStandaloneModuleByPath.get(
|
|
216644
|
-
|
|
216817
|
+
normalizePath4(path7.relative(workspaceRoot, resolvedPath))
|
|
216645
216818
|
);
|
|
216646
216819
|
if (!standaloneTargetModule) {
|
|
216647
216820
|
return void 0;
|
|
216648
216821
|
}
|
|
216649
216822
|
return {
|
|
216650
216823
|
targetModule: standaloneTargetModule,
|
|
216651
|
-
resolvedRelativePath:
|
|
216824
|
+
resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, resolvedPath)),
|
|
216652
216825
|
isPublicImport: true
|
|
216653
216826
|
};
|
|
216654
216827
|
}
|
|
216655
216828
|
const [targetModule, targetModuleRoot] = targetModuleEntry;
|
|
216656
|
-
const targetSubPath =
|
|
216829
|
+
const targetSubPath = normalizePath4(path7.relative(targetModuleRoot, resolvedPath));
|
|
216657
216830
|
if (targetSubPath === "" || targetSubPath.startsWith("../") || targetSubPath.startsWith("..\\")) {
|
|
216658
216831
|
return void 0;
|
|
216659
216832
|
}
|
|
@@ -216669,7 +216842,7 @@ async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath,
|
|
|
216669
216842
|
);
|
|
216670
216843
|
return {
|
|
216671
216844
|
targetModule,
|
|
216672
|
-
resolvedRelativePath:
|
|
216845
|
+
resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, resolvedPath)),
|
|
216673
216846
|
isPublicImport,
|
|
216674
216847
|
...isPublicPackageAliasImport ? { isPackagePublicImport: true } : {}
|
|
216675
216848
|
};
|
|
@@ -216680,10 +216853,11 @@ async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath,
|
|
|
216680
216853
|
if (!supportsDependencyImportParsing(adapter)) {
|
|
216681
216854
|
return imports;
|
|
216682
216855
|
}
|
|
216856
|
+
const javaImportIndex = usesJavaImportParser(adapter) ? await buildJavaImportIndex(workspaceRoot, moduleRoots, adapter) : void 0;
|
|
216683
216857
|
for (const [moduleName, moduleRoot] of [...moduleRoots.entries()].sort(
|
|
216684
216858
|
([left], [right]) => left.localeCompare(right)
|
|
216685
216859
|
)) {
|
|
216686
|
-
const childModuleRoots = [...moduleRoots.entries()].filter(([childModuleName, childModuleRoot]) => childModuleName !== moduleName &&
|
|
216860
|
+
const childModuleRoots = [...moduleRoots.entries()].filter(([childModuleName, childModuleRoot]) => childModuleName !== moduleName && isPathInsideOrEqual(childModuleRoot, moduleRoot)).map(([, childModuleRoot]) => childModuleRoot);
|
|
216687
216861
|
const sourceFiles = await collectSourceFiles(
|
|
216688
216862
|
moduleRoot,
|
|
216689
216863
|
adapter,
|
|
@@ -216691,7 +216865,7 @@ async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath,
|
|
|
216691
216865
|
childModuleRoots
|
|
216692
216866
|
);
|
|
216693
216867
|
for (const sourceFilePath of sourceFiles) {
|
|
216694
|
-
const sourceFileRelativePath =
|
|
216868
|
+
const sourceFileRelativePath = normalizePath4(
|
|
216695
216869
|
path7.relative(workspaceRoot, sourceFilePath)
|
|
216696
216870
|
);
|
|
216697
216871
|
if (!includeTestFiles && isTestSourcePath(sourceFileRelativePath)) {
|
|
@@ -216716,6 +216890,7 @@ async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath,
|
|
|
216716
216890
|
sourceFilePath,
|
|
216717
216891
|
importReference.specifier,
|
|
216718
216892
|
adapter,
|
|
216893
|
+
javaImportIndex,
|
|
216719
216894
|
options?.resolutionContext
|
|
216720
216895
|
);
|
|
216721
216896
|
if (!resolved || resolved.targetModule === moduleName) {
|
|
@@ -216818,15 +216993,15 @@ function toDependencyContextMetadata(context) {
|
|
|
216818
216993
|
isExternal: context.isExternal
|
|
216819
216994
|
};
|
|
216820
216995
|
}
|
|
216821
|
-
function resolveImportDependencyContextMetadata(architectureContract, dependencyImport) {
|
|
216822
|
-
const directContext =
|
|
216996
|
+
function resolveImportDependencyContextMetadata(architectureContract, dependencyImport, resolver = createArchitectureDependencyContextResolver(architectureContract)) {
|
|
216997
|
+
const directContext = resolver.resolve({
|
|
216823
216998
|
sourceFile: dependencyImport.sourceFileRelativePath,
|
|
216824
216999
|
importSpecifier: dependencyImport.importSpecifier
|
|
216825
217000
|
});
|
|
216826
217001
|
if (!directContext.isExternal) {
|
|
216827
217002
|
return toDependencyContextMetadata(directContext);
|
|
216828
217003
|
}
|
|
216829
|
-
const moduleTargetContext =
|
|
217004
|
+
const moduleTargetContext = resolver.resolve({
|
|
216830
217005
|
sourceFile: dependencyImport.sourceFileRelativePath,
|
|
216831
217006
|
importSpecifier: dependencyImport.targetModule
|
|
216832
217007
|
});
|
|
@@ -216837,7 +217012,7 @@ function resolveImportDependencyContextMetadata(architectureContract, dependency
|
|
|
216837
217012
|
resolvedTargetPath: dependencyImport.resolvedTargetRelativePath
|
|
216838
217013
|
});
|
|
216839
217014
|
}
|
|
216840
|
-
const resolvedPathContext =
|
|
217015
|
+
const resolvedPathContext = resolver.resolve({
|
|
216841
217016
|
sourceFile: dependencyImport.sourceFileRelativePath,
|
|
216842
217017
|
importSpecifier: dependencyImport.resolvedTargetRelativePath
|
|
216843
217018
|
});
|
|
@@ -216875,11 +217050,15 @@ function validateComponentDependencyPolicies(architectureContract, imports) {
|
|
|
216875
217050
|
if (!architectureContract || policies.size === 0) {
|
|
216876
217051
|
return [];
|
|
216877
217052
|
}
|
|
217053
|
+
const dependencyContextResolver = createArchitectureDependencyContextResolver(
|
|
217054
|
+
architectureContract
|
|
217055
|
+
);
|
|
216878
217056
|
const findings = [];
|
|
216879
217057
|
for (const dependencyImport of imports) {
|
|
216880
217058
|
const dependencyMetadata = resolveImportDependencyContextMetadata(
|
|
216881
217059
|
architectureContract,
|
|
216882
|
-
dependencyImport
|
|
217060
|
+
dependencyImport,
|
|
217061
|
+
dependencyContextResolver
|
|
216883
217062
|
);
|
|
216884
217063
|
if (dependencyMetadata.dependencyType !== "cross-component" || dependencyMetadata.isExternal || !dependencyMetadata.sourceComponentId || !dependencyMetadata.targetComponentId) {
|
|
216885
217064
|
continue;
|
|
@@ -216915,7 +217094,7 @@ function validateComponentDependencyPolicies(architectureContract, imports) {
|
|
|
216915
217094
|
}
|
|
216916
217095
|
return findings;
|
|
216917
217096
|
}
|
|
216918
|
-
function isModuleScopedDependencyImport(architectureContract, dependencyImport) {
|
|
217097
|
+
function isModuleScopedDependencyImport(architectureContract, dependencyImport, resolver) {
|
|
216919
217098
|
if (dependencyImport.sourceModule === dependencyImport.targetModule || isParentChildModuleRelationship(
|
|
216920
217099
|
dependencyImport.sourceModule,
|
|
216921
217100
|
dependencyImport.targetModule
|
|
@@ -216927,7 +217106,8 @@ function isModuleScopedDependencyImport(architectureContract, dependencyImport)
|
|
|
216927
217106
|
}
|
|
216928
217107
|
const dependencyMetadata = resolveImportDependencyContextMetadata(
|
|
216929
217108
|
architectureContract,
|
|
216930
|
-
dependencyImport
|
|
217109
|
+
dependencyImport,
|
|
217110
|
+
resolver
|
|
216931
217111
|
);
|
|
216932
217112
|
return !dependencyMetadata.isExternal;
|
|
216933
217113
|
}
|
|
@@ -216956,7 +217136,7 @@ function buildDependencyConfigSkippedFindings(reason, options) {
|
|
|
216956
217136
|
return findings;
|
|
216957
217137
|
}
|
|
216958
217138
|
function normalizePathList(values) {
|
|
216959
|
-
return values.map((value) =>
|
|
217139
|
+
return values.map((value) => normalizePath4(value)).sort((left, right) => left.localeCompare(right));
|
|
216960
217140
|
}
|
|
216961
217141
|
function normalizeModuleContract(contractLike) {
|
|
216962
217142
|
if (typeof contractLike.module !== "string") {
|
|
@@ -217059,7 +217239,7 @@ function buildContractSkipMessage(ruleId, sourceModule, targetModule, sourceCont
|
|
|
217059
217239
|
)}.`;
|
|
217060
217240
|
}
|
|
217061
217241
|
function isImportWithinPublicEntrypoints(resolvedTargetRelativePath, publicEntrypoints) {
|
|
217062
|
-
const normalizedTargetPath =
|
|
217242
|
+
const normalizedTargetPath = normalizePath4(resolvedTargetRelativePath);
|
|
217063
217243
|
for (const publicEntrypoint of normalizePathList(publicEntrypoints)) {
|
|
217064
217244
|
const isFileEntrypoint = /\.[a-z0-9]+$/iu.test(publicEntrypoint);
|
|
217065
217245
|
if (isFileEntrypoint && normalizedTargetPath === publicEntrypoint) {
|
|
@@ -217106,17 +217286,18 @@ async function inferExistingPublicEntrypointsFromModuleRoot(workspaceRoot, modul
|
|
|
217106
217286
|
const candidatePath = path7.join(moduleRoot, ...candidateSubpath.split("/"));
|
|
217107
217287
|
if (await pathExists4(candidatePath)) {
|
|
217108
217288
|
existingEntrypoints.push(
|
|
217109
|
-
|
|
217289
|
+
normalizePath4(path7.relative(workspaceRoot, candidatePath))
|
|
217110
217290
|
);
|
|
217111
217291
|
}
|
|
217112
217292
|
}
|
|
217113
217293
|
return existingEntrypoints.sort((left, right) => left.localeCompare(right));
|
|
217114
217294
|
}
|
|
217115
|
-
async function
|
|
217116
|
-
const registryPublicEntrypoints = architectureContract
|
|
217295
|
+
async function resolveKnownModulePublicEntrypoints(workspaceRoot, architectureContract, moduleName, targetContract, moduleRoots, adapter) {
|
|
217296
|
+
const registryPublicEntrypoints = architectureContract?.modules[moduleName]?.publicEntrypoints ?? [];
|
|
217297
|
+
const contractPublicEntrypoints = targetContract?.publicEntrypoints ?? [];
|
|
217117
217298
|
const explicitPublicEntrypoints = sortUnique2([
|
|
217118
217299
|
...registryPublicEntrypoints,
|
|
217119
|
-
...
|
|
217300
|
+
...contractPublicEntrypoints
|
|
217120
217301
|
]);
|
|
217121
217302
|
const existingExplicitEntrypoints = await filterExistingPublicEntrypoints(
|
|
217122
217303
|
workspaceRoot,
|
|
@@ -217125,13 +217306,16 @@ async function resolveModulePublicEntrypoints(workspaceRoot, architectureContrac
|
|
|
217125
217306
|
if (existingExplicitEntrypoints.length > 0) {
|
|
217126
217307
|
return existingExplicitEntrypoints;
|
|
217127
217308
|
}
|
|
217309
|
+
if (usesJavaImportParser(adapter)) {
|
|
217310
|
+
return [];
|
|
217311
|
+
}
|
|
217128
217312
|
return inferExistingPublicEntrypointsFromModuleRoot(
|
|
217129
217313
|
workspaceRoot,
|
|
217130
217314
|
moduleRoots.get(moduleName)
|
|
217131
217315
|
);
|
|
217132
217316
|
}
|
|
217133
217317
|
function labelPublicEntrypoint(publicEntrypoint) {
|
|
217134
|
-
const normalizedEntrypoint =
|
|
217318
|
+
const normalizedEntrypoint = normalizePath4(publicEntrypoint);
|
|
217135
217319
|
const fileName = normalizedEntrypoint.split("/").at(-1) ?? "";
|
|
217136
217320
|
return /^index\.[cm]?[jt]sx?$/iu.test(fileName) ? `${fileName} public entrypoint` : "public entrypoint";
|
|
217137
217321
|
}
|
|
@@ -217151,7 +217335,7 @@ async function describeModulePublicImportGuidance(workspaceRoot, moduleName, mod
|
|
|
217151
217335
|
return `Use the public entrypoint at ${describePublicEntrypointTargets(inferredEntrypoints)} instead.`;
|
|
217152
217336
|
}
|
|
217153
217337
|
if (moduleRoot) {
|
|
217154
|
-
return `Use an existing public entrypoint under ${
|
|
217338
|
+
return `Use an existing public entrypoint under ${normalizePath4(path7.relative(workspaceRoot, moduleRoot))} instead.`;
|
|
217155
217339
|
}
|
|
217156
217340
|
return "Use an existing target module public entrypoint instead.";
|
|
217157
217341
|
}
|
|
@@ -217273,34 +217457,42 @@ async function buildDependencyGraphSummary(workspaceRoot, architectureContract,
|
|
|
217273
217457
|
const inboundDeclared = buildInboundDependencyMap(declaredBySource, moduleIds);
|
|
217274
217458
|
const inboundActual = buildInboundDependencyMap(actualBySource, moduleIds);
|
|
217275
217459
|
const hierarchyEdges = buildModuleHierarchyEdges(moduleIds);
|
|
217276
|
-
const childModulesByParent = buildChildModulesByParent(hierarchyEdges);
|
|
217277
217460
|
const parentModuleByChild = new Map(
|
|
217278
217461
|
hierarchyEdges.map((edge) => [edge.childModule, edge.parentModule])
|
|
217279
217462
|
);
|
|
217463
|
+
const moduleSummaries = moduleIds.map((moduleId) => {
|
|
217464
|
+
const declaredDependencies = sortUnique2(declaredBySource.get(moduleId) ?? []);
|
|
217465
|
+
const actualDependencies = sortUnique2(actualBySource.get(moduleId) ?? []);
|
|
217466
|
+
const unusedDeclaredDependencies = declaredDependencies.filter(
|
|
217467
|
+
(declaredDependency) => !actualDependencies.includes(declaredDependency)
|
|
217468
|
+
);
|
|
217469
|
+
const undeclaredActualDependencies = actualDependencies.filter(
|
|
217470
|
+
(actualDependency) => !declaredDependencies.includes(actualDependency)
|
|
217471
|
+
);
|
|
217472
|
+
return {
|
|
217473
|
+
module: moduleId,
|
|
217474
|
+
hasContract: hasContractByModule.get(moduleId) ?? false,
|
|
217475
|
+
...parentModuleByChild.has(moduleId) ? { parentModule: parentModuleByChild.get(moduleId) } : {},
|
|
217476
|
+
childModules: [],
|
|
217477
|
+
declaredDependencies,
|
|
217478
|
+
actualDependencies,
|
|
217479
|
+
inboundDeclaredFrom: inboundDeclared.get(moduleId) ?? [],
|
|
217480
|
+
inboundActualFrom: inboundActual.get(moduleId) ?? [],
|
|
217481
|
+
unusedDeclaredDependencies,
|
|
217482
|
+
undeclaredActualDependencies
|
|
217483
|
+
};
|
|
217484
|
+
}).filter((moduleSummary) => !isIsolatedContractlessHierarchyModule(moduleSummary));
|
|
217485
|
+
const retainedModuleIds = new Set(moduleSummaries.map((moduleSummary) => moduleSummary.module));
|
|
217486
|
+
const retainedHierarchyEdges = hierarchyEdges.filter(
|
|
217487
|
+
(edge) => retainedModuleIds.has(edge.parentModule) && retainedModuleIds.has(edge.childModule)
|
|
217488
|
+
);
|
|
217489
|
+
const childModulesByParent = buildChildModulesByParent(retainedHierarchyEdges);
|
|
217280
217490
|
return {
|
|
217281
|
-
modules:
|
|
217282
|
-
|
|
217283
|
-
|
|
217284
|
-
|
|
217285
|
-
|
|
217286
|
-
);
|
|
217287
|
-
const undeclaredActualDependencies = actualDependencies.filter(
|
|
217288
|
-
(actualDependency) => !declaredDependencies.includes(actualDependency)
|
|
217289
|
-
);
|
|
217290
|
-
return {
|
|
217291
|
-
module: moduleId,
|
|
217292
|
-
hasContract: hasContractByModule.get(moduleId) ?? false,
|
|
217293
|
-
...parentModuleByChild.has(moduleId) ? { parentModule: parentModuleByChild.get(moduleId) } : {},
|
|
217294
|
-
childModules: childModulesByParent.get(moduleId) ?? [],
|
|
217295
|
-
declaredDependencies,
|
|
217296
|
-
actualDependencies,
|
|
217297
|
-
inboundDeclaredFrom: inboundDeclared.get(moduleId) ?? [],
|
|
217298
|
-
inboundActualFrom: inboundActual.get(moduleId) ?? [],
|
|
217299
|
-
unusedDeclaredDependencies,
|
|
217300
|
-
undeclaredActualDependencies
|
|
217301
|
-
};
|
|
217302
|
-
}),
|
|
217303
|
-
hierarchyEdges
|
|
217491
|
+
modules: moduleSummaries.map((moduleSummary) => ({
|
|
217492
|
+
...moduleSummary,
|
|
217493
|
+
childModules: childModulesByParent.get(moduleSummary.module) ?? []
|
|
217494
|
+
})),
|
|
217495
|
+
hierarchyEdges: retainedHierarchyEdges
|
|
217304
217496
|
};
|
|
217305
217497
|
}
|
|
217306
217498
|
async function validateDependencyContractBoundaries(workspaceRoot, architectureContract, options) {
|
|
@@ -217330,9 +217522,16 @@ async function validateDependencyContractBoundaries(workspaceRoot, architectureC
|
|
|
217330
217522
|
workspacePackageAliases,
|
|
217331
217523
|
adapter
|
|
217332
217524
|
);
|
|
217525
|
+
const dependencyContextResolver = createArchitectureDependencyContextResolver(
|
|
217526
|
+
architectureContract
|
|
217527
|
+
);
|
|
217333
217528
|
const peerImports = filterPeerModuleImports(imports);
|
|
217334
217529
|
const moduleScopedPeerImports = peerImports.filter(
|
|
217335
|
-
(dependencyImport) => isModuleScopedDependencyImport(
|
|
217530
|
+
(dependencyImport) => isModuleScopedDependencyImport(
|
|
217531
|
+
architectureContract,
|
|
217532
|
+
dependencyImport,
|
|
217533
|
+
dependencyContextResolver
|
|
217534
|
+
)
|
|
217336
217535
|
);
|
|
217337
217536
|
const findings = [];
|
|
217338
217537
|
const moduleContractCache = /* @__PURE__ */ new Map();
|
|
@@ -217342,7 +217541,8 @@ async function validateDependencyContractBoundaries(workspaceRoot, architectureC
|
|
|
217342
217541
|
for (const dependencyImport of moduleScopedPeerImports) {
|
|
217343
217542
|
const dependencyMetadata = resolveImportDependencyContextMetadata(
|
|
217344
217543
|
architectureContract,
|
|
217345
|
-
dependencyImport
|
|
217544
|
+
dependencyImport,
|
|
217545
|
+
dependencyContextResolver
|
|
217346
217546
|
);
|
|
217347
217547
|
if (dependencyMetadata.isExternal) {
|
|
217348
217548
|
continue;
|
|
@@ -217474,7 +217674,8 @@ async function validateDependencyContractBoundaries(workspaceRoot, architectureC
|
|
|
217474
217674
|
for (const dependencyImport of moduleScopedPeerImports) {
|
|
217475
217675
|
const dependencyMetadata = resolveImportDependencyContextMetadata(
|
|
217476
217676
|
architectureContract,
|
|
217477
|
-
dependencyImport
|
|
217677
|
+
dependencyImport,
|
|
217678
|
+
dependencyContextResolver
|
|
217478
217679
|
);
|
|
217479
217680
|
if (dependencyMetadata.isExternal) {
|
|
217480
217681
|
continue;
|
|
@@ -217548,12 +217749,13 @@ async function validateDependencyContractBoundaries(workspaceRoot, architectureC
|
|
|
217548
217749
|
}
|
|
217549
217750
|
continue;
|
|
217550
217751
|
}
|
|
217551
|
-
const publicEntrypoints = await
|
|
217752
|
+
const publicEntrypoints = await resolveKnownModulePublicEntrypoints(
|
|
217552
217753
|
workspaceRoot,
|
|
217553
217754
|
architectureContract,
|
|
217554
217755
|
dependencyImport.targetModule,
|
|
217555
217756
|
targetContract.contract,
|
|
217556
|
-
moduleRoots
|
|
217757
|
+
moduleRoots,
|
|
217758
|
+
adapter
|
|
217557
217759
|
);
|
|
217558
217760
|
if (publicEntrypoints.length === 0) {
|
|
217559
217761
|
continue;
|
|
@@ -217732,11 +217934,17 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
|
|
|
217732
217934
|
workspacePackageAliases,
|
|
217733
217935
|
adapter
|
|
217734
217936
|
);
|
|
217937
|
+
const dependencyContextResolver = parsedArchitectureContract ? createArchitectureDependencyContextResolver(parsedArchitectureContract) : void 0;
|
|
217735
217938
|
const peerImports = filterPeerModuleImports(imports);
|
|
217736
217939
|
const moduleScopedPeerImports = peerImports.filter(
|
|
217737
|
-
(dependencyImport) => isModuleScopedDependencyImport(
|
|
217940
|
+
(dependencyImport) => isModuleScopedDependencyImport(
|
|
217941
|
+
parsedArchitectureContract,
|
|
217942
|
+
dependencyImport,
|
|
217943
|
+
dependencyContextResolver
|
|
217944
|
+
)
|
|
217738
217945
|
);
|
|
217739
217946
|
const findings = [];
|
|
217947
|
+
const moduleContractCache = /* @__PURE__ */ new Map();
|
|
217740
217948
|
let dependencyRules;
|
|
217741
217949
|
let dependencyRulesSkipReason;
|
|
217742
217950
|
if (options.dependencyRulesConfigOverride) {
|
|
@@ -217792,7 +218000,8 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
|
|
|
217792
218000
|
if (parsedArchitectureContract) {
|
|
217793
218001
|
const dependencyMetadata = resolveImportDependencyContextMetadata(
|
|
217794
218002
|
parsedArchitectureContract,
|
|
217795
|
-
dependencyImport
|
|
218003
|
+
dependencyImport,
|
|
218004
|
+
dependencyContextResolver
|
|
217796
218005
|
);
|
|
217797
218006
|
if (dependencyMetadata.isExternal) {
|
|
217798
218007
|
return false;
|
|
@@ -217816,7 +218025,11 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
|
|
|
217816
218025
|
});
|
|
217817
218026
|
} else {
|
|
217818
218027
|
for (const violation of violations) {
|
|
217819
|
-
const dependencyMetadata = parsedArchitectureContract ? resolveImportDependencyContextMetadata(
|
|
218028
|
+
const dependencyMetadata = parsedArchitectureContract ? resolveImportDependencyContextMetadata(
|
|
218029
|
+
parsedArchitectureContract,
|
|
218030
|
+
violation,
|
|
218031
|
+
dependencyContextResolver
|
|
218032
|
+
) : void 0;
|
|
217820
218033
|
const allowedDependencies = dependencyRules.modules[violation.sourceModule]?.allowedDependencies ?? [];
|
|
217821
218034
|
const allowedDescription = allowedDependencies.length === 0 ? "may not depend on any other modules" : `may only depend on: ${allowedDependencies.join(", ")}`;
|
|
217822
218035
|
findings.push({
|
|
@@ -217853,19 +218066,50 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
|
|
|
217853
218066
|
})
|
|
217854
218067
|
);
|
|
217855
218068
|
} else {
|
|
217856
|
-
const violations =
|
|
218069
|
+
const violations = [];
|
|
218070
|
+
for (const dependencyImport of moduleScopedPeerImports) {
|
|
217857
218071
|
if (parsedArchitectureContract) {
|
|
217858
218072
|
const dependencyMetadata = resolveImportDependencyContextMetadata(
|
|
217859
218073
|
parsedArchitectureContract,
|
|
217860
|
-
dependencyImport
|
|
218074
|
+
dependencyImport,
|
|
218075
|
+
dependencyContextResolver
|
|
217861
218076
|
);
|
|
217862
218077
|
if (dependencyMetadata.isExternal) {
|
|
217863
|
-
|
|
218078
|
+
continue;
|
|
217864
218079
|
}
|
|
217865
218080
|
}
|
|
217866
218081
|
const moduleRules = dependencyRules.modules[dependencyImport.sourceModule];
|
|
217867
|
-
|
|
217868
|
-
|
|
218082
|
+
if (moduleRules?.publicEntrypointsOnly !== true || dependencyImport.isPublicImport) {
|
|
218083
|
+
continue;
|
|
218084
|
+
}
|
|
218085
|
+
if (dependencyImport.isPackagePublicImport === true) {
|
|
218086
|
+
continue;
|
|
218087
|
+
}
|
|
218088
|
+
const targetContract = parsedArchitectureContract ? await loadModuleArchitectureContract(
|
|
218089
|
+
workspaceRoot,
|
|
218090
|
+
parsedArchitectureContract,
|
|
218091
|
+
dependencyImport.targetModule,
|
|
218092
|
+
moduleContractCache
|
|
218093
|
+
) : void 0;
|
|
218094
|
+
const publicEntrypoints = await resolveKnownModulePublicEntrypoints(
|
|
218095
|
+
workspaceRoot,
|
|
218096
|
+
parsedArchitectureContract,
|
|
218097
|
+
dependencyImport.targetModule,
|
|
218098
|
+
targetContract?.contract,
|
|
218099
|
+
moduleRoots,
|
|
218100
|
+
adapter
|
|
218101
|
+
);
|
|
218102
|
+
if (publicEntrypoints.length === 0) {
|
|
218103
|
+
continue;
|
|
218104
|
+
}
|
|
218105
|
+
if (isImportWithinPublicEntrypoints(
|
|
218106
|
+
dependencyImport.resolvedTargetRelativePath,
|
|
218107
|
+
publicEntrypoints
|
|
218108
|
+
)) {
|
|
218109
|
+
continue;
|
|
218110
|
+
}
|
|
218111
|
+
violations.push(dependencyImport);
|
|
218112
|
+
}
|
|
217869
218113
|
if (violations.length === 0) {
|
|
217870
218114
|
findings.push({
|
|
217871
218115
|
result: makeValidationResult(
|
|
@@ -217877,7 +218121,11 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
|
|
|
217877
218121
|
});
|
|
217878
218122
|
} else {
|
|
217879
218123
|
for (const violation of violations) {
|
|
217880
|
-
const dependencyMetadata = parsedArchitectureContract ? resolveImportDependencyContextMetadata(
|
|
218124
|
+
const dependencyMetadata = parsedArchitectureContract ? resolveImportDependencyContextMetadata(
|
|
218125
|
+
parsedArchitectureContract,
|
|
218126
|
+
violation,
|
|
218127
|
+
dependencyContextResolver
|
|
218128
|
+
) : void 0;
|
|
217881
218129
|
const publicImportGuidance = await describeModulePublicImportGuidance(
|
|
217882
218130
|
workspaceRoot,
|
|
217883
218131
|
violation.targetModule,
|
|
@@ -218014,6 +218262,7 @@ var init_dependencyValidation = __esm({
|
|
|
218014
218262
|
init_architectureDependencyContext();
|
|
218015
218263
|
init_moduleDiscovery();
|
|
218016
218264
|
init_stackAdapters();
|
|
218265
|
+
init_sourceScopeClassification();
|
|
218017
218266
|
dependencyRulesConfigFile = ".archpilot/dependency-rules.json";
|
|
218018
218267
|
DependencyRulesConfigError = class extends Error {
|
|
218019
218268
|
};
|
|
@@ -218021,7 +218270,7 @@ var init_dependencyValidation = __esm({
|
|
|
218021
218270
|
});
|
|
218022
218271
|
|
|
218023
218272
|
// ../core/src/moduleScope.ts
|
|
218024
|
-
function
|
|
218273
|
+
function normalizePath5(value) {
|
|
218025
218274
|
return value.replace(/\\/g, "/").replace(/^\.\/+/u, "").replace(/\/+$/u, "").toLowerCase();
|
|
218026
218275
|
}
|
|
218027
218276
|
function pathExists5(targetPath) {
|
|
@@ -218074,7 +218323,7 @@ function hasJsxEnabled(configPath) {
|
|
|
218074
218323
|
return typeof jsx === "string" && jsx.trim().length > 0;
|
|
218075
218324
|
}
|
|
218076
218325
|
function listPathSegments(modulePath) {
|
|
218077
|
-
return
|
|
218326
|
+
return normalizePath5(modulePath).split("/").filter((entry) => entry.length > 0);
|
|
218078
218327
|
}
|
|
218079
218328
|
function getCandidateRoots(workspaceRoot, modulePath) {
|
|
218080
218329
|
const resolvedWorkspaceRoot = path8.resolve(workspaceRoot);
|
|
@@ -218406,9 +218655,12 @@ var init_moduleScope = __esm({
|
|
|
218406
218655
|
});
|
|
218407
218656
|
|
|
218408
218657
|
// ../core/src/smartInit/moduleDetection.ts
|
|
218409
|
-
function
|
|
218658
|
+
function normalizePath6(value) {
|
|
218410
218659
|
return value.replaceAll("\\", "/");
|
|
218411
218660
|
}
|
|
218661
|
+
function isUnderJvmResourceRoot(relativePath) {
|
|
218662
|
+
return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizePath6(relativePath).toLowerCase());
|
|
218663
|
+
}
|
|
218412
218664
|
function safeReadDirEntries(directoryPath) {
|
|
218413
218665
|
try {
|
|
218414
218666
|
return fs8.readdirSync(directoryPath, { withFileTypes: true });
|
|
@@ -218425,7 +218677,7 @@ function pathExists6(pathValue) {
|
|
|
218425
218677
|
}
|
|
218426
218678
|
}
|
|
218427
218679
|
function isIgnoredPath(context, relativePath) {
|
|
218428
|
-
return context?.ignoreMatcher?.isIgnored(
|
|
218680
|
+
return context?.ignoreMatcher?.isIgnored(normalizePath6(relativePath)) ?? false;
|
|
218429
218681
|
}
|
|
218430
218682
|
function uniqueSorted(values) {
|
|
218431
218683
|
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
@@ -218440,15 +218692,15 @@ function normalizeIdentity(value) {
|
|
|
218440
218692
|
return value.toLowerCase().replace(/[^a-z0-9]+/gu, "");
|
|
218441
218693
|
}
|
|
218442
218694
|
function pathLeafIdentity(value) {
|
|
218443
|
-
const normalized =
|
|
218695
|
+
const normalized = normalizePath6(value).replace(/\/+$/gu, "");
|
|
218444
218696
|
const leaf = normalized.split("/").filter((segment) => segment.length > 0).at(-1) ?? normalized;
|
|
218445
218697
|
return normalizeIdentity(leaf);
|
|
218446
218698
|
}
|
|
218447
218699
|
function getComponentAlignedEvidence(input2) {
|
|
218448
|
-
const modulePath =
|
|
218700
|
+
const modulePath = normalizePath6(input2.modulePath).replace(/\/+$/gu, "");
|
|
218449
218701
|
const moduleNameIdentity = normalizeIdentity(input2.moduleName);
|
|
218450
218702
|
const modulePathLeaf = pathLeafIdentity(modulePath);
|
|
218451
|
-
const matchingPath = input2.context?.componentPaths?.map((entry) =>
|
|
218703
|
+
const matchingPath = input2.context?.componentPaths?.map((entry) => normalizePath6(entry).replace(/\/+$/gu, "")).find(
|
|
218452
218704
|
(componentPath) => componentPath.length > 0 && componentPath !== "." && (componentPath === modulePath || componentPath.startsWith(`${modulePath}/`))
|
|
218453
218705
|
);
|
|
218454
218706
|
if (matchingPath) {
|
|
@@ -218458,7 +218710,7 @@ function getComponentAlignedEvidence(input2) {
|
|
|
218458
218710
|
if (matchingName) {
|
|
218459
218711
|
return `Matches detected component/service/app identity ${input2.moduleName}`;
|
|
218460
218712
|
}
|
|
218461
|
-
const matchingResourcePath = input2.context?.resourcePaths?.map((entry) =>
|
|
218713
|
+
const matchingResourcePath = input2.context?.resourcePaths?.map((entry) => normalizePath6(entry).replace(/\/+$/gu, "")).find(
|
|
218462
218714
|
(resourcePath) => resourcePath.length > 0 && resourcePath !== "." && (resourcePath === modulePath || resourcePath.startsWith(`${modulePath}/`))
|
|
218463
218715
|
);
|
|
218464
218716
|
if (matchingResourcePath) {
|
|
@@ -218638,6 +218890,9 @@ function containsAppRouteFiles(absolutePath) {
|
|
|
218638
218890
|
return false;
|
|
218639
218891
|
}
|
|
218640
218892
|
function makeDetectedModule(workspaceRoot, moduleName, modulePath, rootPath, hasSourceFiles, hasRoleFiles, sourceFileCount, context) {
|
|
218893
|
+
if (isUnderJvmResourceRoot(modulePath)) {
|
|
218894
|
+
return void 0;
|
|
218895
|
+
}
|
|
218641
218896
|
const evidence = [];
|
|
218642
218897
|
if (hasSourceFiles) {
|
|
218643
218898
|
evidence.push("Contains source files");
|
|
@@ -218696,11 +218951,14 @@ function collectModuleCandidatesFromRoot(workspaceRoot, modulesRootRelative, def
|
|
|
218696
218951
|
const rootLower = modulesRootRelative.toLowerCase();
|
|
218697
218952
|
const skipFrontendUtilities = rootLower === "src/features" || rootLower.endsWith("/src/features") || rootLower === "app" || rootLower === "src/app" || rootLower.endsWith("/app") || rootLower.endsWith("/src/app");
|
|
218698
218953
|
const entries = safeReadDirEntries(absoluteRoot).filter(
|
|
218699
|
-
(entry) => entry.isDirectory() && !ignoredDirectoryNames.has(entry.name) && !isIgnoredPath(context,
|
|
218954
|
+
(entry) => entry.isDirectory() && !ignoredDirectoryNames.has(entry.name) && !isIgnoredPath(context, normalizePath6(`${modulesRootRelative}/${entry.name}`))
|
|
218700
218955
|
).sort((left, right) => left.name.localeCompare(right.name));
|
|
218701
218956
|
const modules = [];
|
|
218702
218957
|
for (const entry of entries) {
|
|
218703
|
-
const candidateProjectRoot =
|
|
218958
|
+
const candidateProjectRoot = normalizePath6(`${modulesRootRelative}/${entry.name}`);
|
|
218959
|
+
if (isUnderJvmResourceRoot(candidateProjectRoot)) {
|
|
218960
|
+
continue;
|
|
218961
|
+
}
|
|
218704
218962
|
if (["apps", "packages", "services", "libs"].includes(rootLower) && (context?.projectRoots?.length ?? 0) > 0 && !context?.projectRoots?.includes(candidateProjectRoot)) {
|
|
218705
218963
|
continue;
|
|
218706
218964
|
}
|
|
@@ -218717,7 +218975,7 @@ function collectModuleCandidatesFromRoot(workspaceRoot, modulesRootRelative, def
|
|
|
218717
218975
|
const detected = makeDetectedModule(
|
|
218718
218976
|
workspaceRoot,
|
|
218719
218977
|
moduleName,
|
|
218720
|
-
|
|
218978
|
+
normalizePath6(`${modulesRootRelative}/${entry.name}`),
|
|
218721
218979
|
modulesRootRelative,
|
|
218722
218980
|
inspected.hasSourceFiles,
|
|
218723
218981
|
inspected.hasRoleFiles,
|
|
@@ -218740,7 +218998,7 @@ function collectAppRouteModules(workspaceRoot, appRootRelative, context) {
|
|
|
218740
218998
|
return [];
|
|
218741
218999
|
}
|
|
218742
219000
|
const entries = safeReadDirEntries(absoluteRoot).filter(
|
|
218743
|
-
(entry) => entry.isDirectory() && !ignoredDirectoryNames.has(entry.name) && !isIgnoredPath(context,
|
|
219001
|
+
(entry) => entry.isDirectory() && !ignoredDirectoryNames.has(entry.name) && !isIgnoredPath(context, normalizePath6(`${appRootRelative}/${entry.name}`))
|
|
218744
219002
|
).sort((left, right) => left.name.localeCompare(right.name));
|
|
218745
219003
|
const modules = [];
|
|
218746
219004
|
for (const entry of entries) {
|
|
@@ -218754,7 +219012,7 @@ function collectAppRouteModules(workspaceRoot, appRootRelative, context) {
|
|
|
218754
219012
|
if (!moduleName || frontendUtilityDirectoryNames.has(moduleName.toLowerCase())) {
|
|
218755
219013
|
continue;
|
|
218756
219014
|
}
|
|
218757
|
-
const moduleRelativePath =
|
|
219015
|
+
const moduleRelativePath = normalizePath6(`${appRootRelative}/${rawName}`);
|
|
218758
219016
|
const moduleAbsolutePath = path9.join(absoluteRoot, rawName);
|
|
218759
219017
|
if (!containsAppRouteFiles(moduleAbsolutePath)) {
|
|
218760
219018
|
continue;
|
|
@@ -218881,14 +219139,14 @@ function collectJavaPackageRoots(workspaceRoot, context) {
|
|
|
218881
219139
|
continue;
|
|
218882
219140
|
}
|
|
218883
219141
|
for (const entry of safeReadDirEntries(current.absolutePath)) {
|
|
218884
|
-
const childRelativePath =
|
|
219142
|
+
const childRelativePath = normalizePath6(`${current.relativePath}/${entry.name}`);
|
|
218885
219143
|
if (!entry.isDirectory() || ignoredDirectoryNames.has(entry.name) || isIgnoredPath(context, childRelativePath)) {
|
|
218886
219144
|
continue;
|
|
218887
219145
|
}
|
|
218888
219146
|
const lowerName = entry.name.toLowerCase();
|
|
218889
219147
|
if (lowerName === "modules" || lowerName === "features") {
|
|
218890
219148
|
const childCount = safeReadDirEntries(path9.join(current.absolutePath, entry.name)).filter(
|
|
218891
|
-
(child) => child.isDirectory() && !ignoredDirectoryNames.has(child.name) && !isIgnoredPath(context,
|
|
219149
|
+
(child) => child.isDirectory() && !ignoredDirectoryNames.has(child.name) && !isIgnoredPath(context, normalizePath6(`${childRelativePath}/${child.name}`))
|
|
218892
219150
|
).length;
|
|
218893
219151
|
if (childCount >= 2) {
|
|
218894
219152
|
roots.push(childRelativePath);
|
|
@@ -218947,10 +219205,10 @@ function detectModules(workspaceRoot, options) {
|
|
|
218947
219205
|
projectKinds: options?.projectKinds,
|
|
218948
219206
|
stacks: options?.stacks,
|
|
218949
219207
|
ignoreMatcher: options?.ignoreMatcher,
|
|
218950
|
-
projectRoots: options?.projectRoots?.map(
|
|
218951
|
-
componentPaths: options?.componentPaths?.map(
|
|
219208
|
+
projectRoots: options?.projectRoots?.map(normalizePath6),
|
|
219209
|
+
componentPaths: options?.componentPaths?.map(normalizePath6),
|
|
218952
219210
|
componentNames: options?.componentNames,
|
|
218953
|
-
resourcePaths: options?.resourcePaths?.map(
|
|
219211
|
+
resourcePaths: options?.resourcePaths?.map(normalizePath6),
|
|
218954
219212
|
resourceNames: options?.resourceNames
|
|
218955
219213
|
};
|
|
218956
219214
|
const explicitRoots = collectExplicitRoots(workspaceRoot, context);
|
|
@@ -219028,7 +219286,7 @@ function detectModules(workspaceRoot, options) {
|
|
|
219028
219286
|
};
|
|
219029
219287
|
}
|
|
219030
219288
|
function detectModuleCandidatesForRoot(workspaceRoot, modulesRootRelative, options) {
|
|
219031
|
-
const normalizedRoot =
|
|
219289
|
+
const normalizedRoot = normalizePath6(modulesRootRelative.trim()).replace(/^\/+|\/+$/gu, "");
|
|
219032
219290
|
if (normalizedRoot.length === 0) {
|
|
219033
219291
|
return [];
|
|
219034
219292
|
}
|
|
@@ -219040,10 +219298,10 @@ function detectModuleCandidatesForRoot(workspaceRoot, modulesRootRelative, optio
|
|
|
219040
219298
|
projectKinds: options?.projectKinds,
|
|
219041
219299
|
stacks: options?.stacks,
|
|
219042
219300
|
ignoreMatcher: options?.ignoreMatcher,
|
|
219043
|
-
projectRoots: options?.projectRoots?.map(
|
|
219044
|
-
componentPaths: options?.componentPaths?.map(
|
|
219301
|
+
projectRoots: options?.projectRoots?.map(normalizePath6),
|
|
219302
|
+
componentPaths: options?.componentPaths?.map(normalizePath6),
|
|
219045
219303
|
componentNames: options?.componentNames,
|
|
219046
|
-
resourcePaths: options?.resourcePaths?.map(
|
|
219304
|
+
resourcePaths: options?.resourcePaths?.map(normalizePath6),
|
|
219047
219305
|
resourceNames: options?.resourceNames
|
|
219048
219306
|
}
|
|
219049
219307
|
);
|
|
@@ -219084,6 +219342,7 @@ var init_moduleDetection = __esm({
|
|
|
219084
219342
|
"scripts",
|
|
219085
219343
|
"test",
|
|
219086
219344
|
"tests",
|
|
219345
|
+
"cypress-tests",
|
|
219087
219346
|
"__tests__",
|
|
219088
219347
|
"fixtures",
|
|
219089
219348
|
"docs",
|
|
@@ -219307,7 +219566,7 @@ var init_moduleDetection = __esm({
|
|
|
219307
219566
|
});
|
|
219308
219567
|
|
|
219309
219568
|
// ../core/src/architectureMap.ts
|
|
219310
|
-
function
|
|
219569
|
+
function normalizePath7(value) {
|
|
219311
219570
|
return value.replace(/\\/g, "/");
|
|
219312
219571
|
}
|
|
219313
219572
|
async function pathExists7(targetPath) {
|
|
@@ -219329,7 +219588,7 @@ function sortUnique3(values) {
|
|
|
219329
219588
|
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
219330
219589
|
}
|
|
219331
219590
|
function toSafeContractModuleFileStem2(moduleName) {
|
|
219332
|
-
return
|
|
219591
|
+
return normalizePath7(moduleName).split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0).join(".");
|
|
219333
219592
|
}
|
|
219334
219593
|
function getModuleRegistry(contract) {
|
|
219335
219594
|
const modules = contract?.modules;
|
|
@@ -219374,7 +219633,7 @@ function hasExplicitModuleRegistry(config) {
|
|
|
219374
219633
|
);
|
|
219375
219634
|
}
|
|
219376
219635
|
function normalizePublicEntrypointList(entries) {
|
|
219377
|
-
return sortUnique3(entries.map((entry) =>
|
|
219636
|
+
return sortUnique3(entries.map((entry) => normalizePath7(entry.trim())).filter((entry) => entry.length > 0));
|
|
219378
219637
|
}
|
|
219379
219638
|
function hasConfiguredPublicEntrypoint(registryEntry) {
|
|
219380
219639
|
return Array.isArray(registryEntry?.publicEntrypoints) && registryEntry.publicEntrypoints.some(
|
|
@@ -219484,10 +219743,10 @@ function parseCycleString(cycle) {
|
|
|
219484
219743
|
}
|
|
219485
219744
|
async function discoverModulesFromArchitectureContract(workspaceRoot, contract, modulesRoot) {
|
|
219486
219745
|
const moduleRegistry = getModuleRegistry(contract);
|
|
219487
|
-
const normalizedModulesRoot =
|
|
219488
|
-
const contractsRoot =
|
|
219746
|
+
const normalizedModulesRoot = normalizePath7(modulesRoot);
|
|
219747
|
+
const contractsRoot = normalizePath7(contract.structure.contractsRoot ?? ".archpilot/contracts");
|
|
219489
219748
|
const discovered = [];
|
|
219490
|
-
const toContractPath = (moduleName, registryEntry) =>
|
|
219749
|
+
const toContractPath = (moduleName, registryEntry) => normalizePath7(
|
|
219491
219750
|
typeof registryEntry?.contract === "string" ? registryEntry.contract : `${contractsRoot}/${toSafeContractModuleFileStem2(moduleName)}.contract.json`
|
|
219492
219751
|
);
|
|
219493
219752
|
const resolveMissingPublicEntrypointAlignment = async (registryEntry, contractPath) => {
|
|
@@ -219515,7 +219774,7 @@ async function discoverModulesFromArchitectureContract(workspaceRoot, contract,
|
|
|
219515
219774
|
if (!registryEntry.path || typeof registryEntry.path !== "string") {
|
|
219516
219775
|
continue;
|
|
219517
219776
|
}
|
|
219518
|
-
const normalizedSourcePath =
|
|
219777
|
+
const normalizedSourcePath = normalizePath7(registryEntry.path);
|
|
219519
219778
|
const absoluteSourcePath = path10.join(workspaceRoot, ...normalizedSourcePath.split("/"));
|
|
219520
219779
|
let sourcePathExists = false;
|
|
219521
219780
|
let sourceIsDirectory = false;
|
|
@@ -219531,7 +219790,7 @@ async function discoverModulesFromArchitectureContract(workspaceRoot, contract,
|
|
|
219531
219790
|
if (!sourceIsDirectory && !sourceIsFile) {
|
|
219532
219791
|
continue;
|
|
219533
219792
|
}
|
|
219534
|
-
const contractPath =
|
|
219793
|
+
const contractPath = normalizePath7(
|
|
219535
219794
|
typeof registryEntry.contract === "string" ? registryEntry.contract : `${contractsRoot}/${toSafeContractModuleFileStem2(moduleName)}.contract.json`
|
|
219536
219795
|
);
|
|
219537
219796
|
const contractExists = await pathExists7(path10.join(workspaceRoot, ...contractPath.split("/")));
|
|
@@ -219615,7 +219874,7 @@ function getComponentEntries(contract) {
|
|
|
219615
219874
|
}
|
|
219616
219875
|
const typed = value;
|
|
219617
219876
|
const componentId = typeof typed.id === "string" && typed.id.trim().length > 0 ? typed.id.trim() : typeof key === "string" && key.trim().length > 0 ? key.trim() : void 0;
|
|
219618
|
-
const sourcePath = typeof typed.path === "string" && typed.path.trim().length > 0 ?
|
|
219877
|
+
const sourcePath = typeof typed.path === "string" && typed.path.trim().length > 0 ? normalizePath7(typed.path.trim()) : void 0;
|
|
219619
219878
|
if (!componentId || !sourcePath || sourcePath === ".") {
|
|
219620
219879
|
continue;
|
|
219621
219880
|
}
|
|
@@ -219740,7 +219999,7 @@ async function generateArchitectureMap(workspaceRoot, options) {
|
|
|
219740
219999
|
const shouldUseConfiguredRootInference = hasArchitectureJson && !contractHasConfiguredModules && !hasExplicitEmptyModuleRegistry && hasExplicitModuleRootConfig(rawArchitectureConfig);
|
|
219741
220000
|
const shouldUseTopLevelWorkspaceInference = hasArchitectureJson && !contractHasConfiguredModules && !hasExplicitEmptyModuleRegistry && !shouldUseConfiguredRootInference;
|
|
219742
220001
|
const discoveryMode = hasArchitectureJson ? "architecture-json" : "inferred-src-modules";
|
|
219743
|
-
const modulesRoot =
|
|
220002
|
+
const modulesRoot = normalizePath7(
|
|
219744
220003
|
await resolveConfiguredModulesRoot(
|
|
219745
220004
|
workspaceRoot,
|
|
219746
220005
|
resolveModulesRootFromContract(contract)
|
|
@@ -220638,7 +220897,7 @@ var init_archpilotIgnore = __esm({
|
|
|
220638
220897
|
});
|
|
220639
220898
|
|
|
220640
220899
|
// ../core/src/moduleContractsGenerator.ts
|
|
220641
|
-
function
|
|
220900
|
+
function normalizePath8(value) {
|
|
220642
220901
|
return value.replace(/\\/g, "/");
|
|
220643
220902
|
}
|
|
220644
220903
|
function toAbsolutePath(workspaceRoot, relativePath) {
|
|
@@ -220656,7 +220915,7 @@ function sortUnique4(values) {
|
|
|
220656
220915
|
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
220657
220916
|
}
|
|
220658
220917
|
function toSafeContractModuleFileStem3(moduleName) {
|
|
220659
|
-
return
|
|
220918
|
+
return normalizePath8(moduleName).split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0).join(".");
|
|
220660
220919
|
}
|
|
220661
220920
|
function wildcardToRegex(pattern) {
|
|
220662
220921
|
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -220670,14 +220929,14 @@ function getModuleRegistry2(contract) {
|
|
|
220670
220929
|
return modules;
|
|
220671
220930
|
}
|
|
220672
220931
|
async function inferModulePublicEntrypoints(workspaceRoot, moduleSourcePath, adapter) {
|
|
220673
|
-
const normalizedSourcePath =
|
|
220932
|
+
const normalizedSourcePath = normalizePath8(moduleSourcePath);
|
|
220674
220933
|
if (/\.[a-z0-9]+$/iu.test(normalizedSourcePath)) {
|
|
220675
220934
|
const absoluteSourcePath = toAbsolutePath(workspaceRoot, normalizedSourcePath);
|
|
220676
220935
|
if (await pathExists8(absoluteSourcePath)) {
|
|
220677
220936
|
return [normalizedSourcePath];
|
|
220678
220937
|
}
|
|
220679
220938
|
}
|
|
220680
|
-
const candidateFiles = adapter.defaultEntrypointHints.map((hint) =>
|
|
220939
|
+
const candidateFiles = adapter.defaultEntrypointHints.map((hint) => normalizePath8(hint)).filter((hint) => !hint.includes("/"));
|
|
220681
220940
|
const exactCandidates = candidateFiles.filter((hint) => !hint.includes("*"));
|
|
220682
220941
|
const wildcardCandidates = candidateFiles.filter((hint) => hint.includes("*"));
|
|
220683
220942
|
const resolvedWildcardCandidates = [];
|
|
@@ -220712,10 +220971,6 @@ async function inferModulePublicEntrypoints(workspaceRoot, moduleSourcePath, ada
|
|
|
220712
220971
|
break;
|
|
220713
220972
|
}
|
|
220714
220973
|
}
|
|
220715
|
-
if (inferred.length === 0) {
|
|
220716
|
-
const fallbackName = adapter.scaffoldingDefaults?.moduleIndexFileName ?? orderedCandidates.find((entry) => entry.startsWith("index.")) ?? "index.ts";
|
|
220717
|
-
inferred.push(`${normalizedSourcePath}/${fallbackName}`);
|
|
220718
|
-
}
|
|
220719
220974
|
return sortUnique4(inferred);
|
|
220720
220975
|
}
|
|
220721
220976
|
function buildDependsOnBySource(edges) {
|
|
@@ -220736,9 +220991,9 @@ function resolveContractPath(contract, moduleName) {
|
|
|
220736
220991
|
const moduleRegistry = getModuleRegistry2(contract);
|
|
220737
220992
|
const configured = moduleRegistry[moduleName]?.contract;
|
|
220738
220993
|
if (configured && configured.trim().length > 0) {
|
|
220739
|
-
return
|
|
220994
|
+
return normalizePath8(configured);
|
|
220740
220995
|
}
|
|
220741
|
-
return
|
|
220996
|
+
return normalizePath8(
|
|
220742
220997
|
path15.posix.join(
|
|
220743
220998
|
resolveContractsRootFromContract(contract),
|
|
220744
220999
|
`${toSafeContractModuleFileStem3(moduleName)}.contract.json`
|
|
@@ -220769,7 +221024,7 @@ async function readExistingModuleContractPublicEntrypoints(workspaceRoot, contra
|
|
|
220769
221024
|
if (parsed.publicEntrypoints.some((entry) => typeof entry !== "string")) {
|
|
220770
221025
|
return void 0;
|
|
220771
221026
|
}
|
|
220772
|
-
return sortUnique4(parsed.publicEntrypoints.map((entry) =>
|
|
221027
|
+
return sortUnique4(parsed.publicEntrypoints.map((entry) => normalizePath8(entry)));
|
|
220773
221028
|
} catch {
|
|
220774
221029
|
return void 0;
|
|
220775
221030
|
}
|
|
@@ -220832,14 +221087,14 @@ async function generateMissingModuleContracts(workspaceRoot) {
|
|
|
220832
221087
|
(left, right) => left.moduleName.localeCompare(right.moduleName)
|
|
220833
221088
|
)) {
|
|
220834
221089
|
const contractPath = resolveContractPath(contract, moduleEntry.moduleName);
|
|
220835
|
-
const sourcePath =
|
|
221090
|
+
const sourcePath = normalizePath8(moduleEntry.sourcePath);
|
|
220836
221091
|
const absoluteContractPath = toAbsolutePath(workspaceRoot, contractPath);
|
|
220837
221092
|
const contractExists = await pathExists8(absoluteContractPath);
|
|
220838
221093
|
const existingContract = contractExists ? await readExistingModuleContract(workspaceRoot, contractPath) : void 0;
|
|
220839
221094
|
const existingContractPublicEntrypoints = contractExists ? await readExistingModuleContractPublicEntrypoints(workspaceRoot, contractPath) : void 0;
|
|
220840
221095
|
const configuredPublicEntrypoints = !contractExists && Array.isArray(getModuleRegistry2(contract)[moduleEntry.moduleName]?.publicEntrypoints) ? sortUnique4(
|
|
220841
221096
|
getModuleRegistry2(contract)[moduleEntry.moduleName]?.publicEntrypoints?.map(
|
|
220842
|
-
(entry) =>
|
|
221097
|
+
(entry) => normalizePath8(entry)
|
|
220843
221098
|
) ?? []
|
|
220844
221099
|
) : void 0;
|
|
220845
221100
|
const publicEntrypoints = existingContractPublicEntrypoints ?? configuredPublicEntrypoints ?? await inferModulePublicEntrypoints(
|
|
@@ -220892,7 +221147,7 @@ async function generateMissingModuleContracts(workspaceRoot) {
|
|
|
220892
221147
|
});
|
|
220893
221148
|
createdContracts.push(contractPath);
|
|
220894
221149
|
}
|
|
220895
|
-
if (isRegistryEntryDifferent({
|
|
221150
|
+
if (moduleEntry.discoverySource === "architecture.json" && isRegistryEntryDifferent({
|
|
220896
221151
|
contract,
|
|
220897
221152
|
moduleName: moduleEntry.moduleName,
|
|
220898
221153
|
sourcePath,
|
|
@@ -220941,7 +221196,7 @@ var bootstrapArchitectureConfig_exports = {};
|
|
|
220941
221196
|
__export(bootstrapArchitectureConfig_exports, {
|
|
220942
221197
|
bootstrapArchitectureConfig: () => bootstrapArchitectureConfig
|
|
220943
221198
|
});
|
|
220944
|
-
function
|
|
221199
|
+
function normalizePath9(value) {
|
|
220945
221200
|
return value.replace(/\\/g, "/");
|
|
220946
221201
|
}
|
|
220947
221202
|
function toAbsolutePath2(workspaceRoot, relativePath) {
|
|
@@ -221044,9 +221299,9 @@ async function bootstrapArchitectureConfig(workspaceRoot, options) {
|
|
|
221044
221299
|
}
|
|
221045
221300
|
}
|
|
221046
221301
|
return {
|
|
221047
|
-
createdFiles: sortUnique5(createdFiles.map((entry) =>
|
|
221048
|
-
ensuredDirectories: sortUnique5(ensuredDirectories.map((entry) =>
|
|
221049
|
-
skippedExistingFiles: sortUnique5(skippedExistingFiles.map((entry) =>
|
|
221302
|
+
createdFiles: sortUnique5(createdFiles.map((entry) => normalizePath9(entry))),
|
|
221303
|
+
ensuredDirectories: sortUnique5(ensuredDirectories.map((entry) => normalizePath9(entry))),
|
|
221304
|
+
skippedExistingFiles: sortUnique5(skippedExistingFiles.map((entry) => normalizePath9(entry))),
|
|
221050
221305
|
moduleCount: modules.length,
|
|
221051
221306
|
...contractGeneration ? { contractGeneration } : {},
|
|
221052
221307
|
...contractGenerationSkippedReason ? { contractGenerationSkippedReason } : {}
|
|
@@ -221871,7 +222126,15 @@ function formatArchitectureDriftSummaryMessage(areas) {
|
|
|
221871
222126
|
}
|
|
221872
222127
|
return `Architecture drift detected in ${labels.slice(0, -1).join(", ")}, and ${labels.at(-1)}.`;
|
|
221873
222128
|
}
|
|
221874
|
-
function buildArchitectureDriftSummary(results, _suppressedResults = []) {
|
|
222129
|
+
function buildArchitectureDriftSummary(results, _suppressedResults = [], options = {}) {
|
|
222130
|
+
if (options.baselineAvailable !== true) {
|
|
222131
|
+
return {
|
|
222132
|
+
detected: false,
|
|
222133
|
+
areas: [],
|
|
222134
|
+
message: "No comparison baseline available; architecture drift was not evaluated.",
|
|
222135
|
+
baselineAvailable: false
|
|
222136
|
+
};
|
|
222137
|
+
}
|
|
221875
222138
|
const activeFailedResults = results.filter(
|
|
221876
222139
|
(result) => !result.passed && result.severity !== "info"
|
|
221877
222140
|
);
|
|
@@ -221879,7 +222142,8 @@ function buildArchitectureDriftSummary(results, _suppressedResults = []) {
|
|
|
221879
222142
|
return {
|
|
221880
222143
|
detected: areas.length > 0,
|
|
221881
222144
|
areas,
|
|
221882
|
-
message: formatArchitectureDriftSummaryMessage(areas)
|
|
222145
|
+
message: formatArchitectureDriftSummaryMessage(areas),
|
|
222146
|
+
baselineAvailable: true
|
|
221883
222147
|
};
|
|
221884
222148
|
}
|
|
221885
222149
|
|
|
@@ -222179,7 +222443,7 @@ async function validateModuleContractIntegrity(workspaceRoot, contract, options)
|
|
|
222179
222443
|
var path19 = __toESM(require("node:path"));
|
|
222180
222444
|
var import_node_fs15 = require("node:fs");
|
|
222181
222445
|
var suppressionsRelativePath = ".archpilot/suppressions.json";
|
|
222182
|
-
function
|
|
222446
|
+
function normalizePath10(value) {
|
|
222183
222447
|
let normalized = value.replace(/\\/g, "/").trim();
|
|
222184
222448
|
while (normalized.startsWith("./")) {
|
|
222185
222449
|
normalized = normalized.slice(2);
|
|
@@ -222217,8 +222481,8 @@ function globToRegex(pattern) {
|
|
|
222217
222481
|
return new RegExp(expression, "u");
|
|
222218
222482
|
}
|
|
222219
222483
|
function isSuppressionPathMatch(pattern, findingPath) {
|
|
222220
|
-
const normalizedPattern =
|
|
222221
|
-
const normalizedFindingPath =
|
|
222484
|
+
const normalizedPattern = normalizePath10(pattern);
|
|
222485
|
+
const normalizedFindingPath = normalizePath10(findingPath);
|
|
222222
222486
|
if (!normalizedPattern || !normalizedFindingPath) {
|
|
222223
222487
|
return false;
|
|
222224
222488
|
}
|
|
@@ -222321,7 +222585,7 @@ async function readValidationSuppressions(workspaceRoot, knownRuleIds) {
|
|
|
222321
222585
|
ignored.push({
|
|
222322
222586
|
index,
|
|
222323
222587
|
ruleId,
|
|
222324
|
-
...entryScopeValue ? { scope:
|
|
222588
|
+
...entryScopeValue ? { scope: normalizePath10(entryScopeValue) } : {},
|
|
222325
222589
|
reason: "Unknown rule ID. Entry was ignored.",
|
|
222326
222590
|
...expiresOn ? { expiresOn } : {}
|
|
222327
222591
|
});
|
|
@@ -222330,7 +222594,7 @@ async function readValidationSuppressions(workspaceRoot, knownRuleIds) {
|
|
|
222330
222594
|
suppressions.push({
|
|
222331
222595
|
index,
|
|
222332
222596
|
ruleId,
|
|
222333
|
-
...entryScopeValue ? { scope:
|
|
222597
|
+
...entryScopeValue ? { scope: normalizePath10(entryScopeValue) } : {},
|
|
222334
222598
|
...reason ? { reason } : {},
|
|
222335
222599
|
...expiresOn ? { expiresOn } : {}
|
|
222336
222600
|
});
|
|
@@ -225107,66 +225371,8 @@ async function profileValidationPhase(label, run, details) {
|
|
|
225107
225371
|
}
|
|
225108
225372
|
}
|
|
225109
225373
|
|
|
225110
|
-
// ../core/src/sourceScopeClassification.ts
|
|
225111
|
-
function normalizePath10(value) {
|
|
225112
|
-
return value.replace(/\\/g, "/").toLowerCase();
|
|
225113
|
-
}
|
|
225114
|
-
function hasPathSegment(pathValue, pattern) {
|
|
225115
|
-
return pathValue.split("/").some((segment) => pattern.test(segment));
|
|
225116
|
-
}
|
|
225117
|
-
function classifyValidationSourceScope(relativePath) {
|
|
225118
|
-
const normalized = normalizePath10(relativePath);
|
|
225119
|
-
const fileName = normalized.split("/").at(-1) ?? normalized;
|
|
225120
|
-
const extension = fileName.includes(".") ? fileName.slice(fileName.lastIndexOf(".")) : "";
|
|
225121
|
-
const isTestFile = /\.(?:spec|test|e2e-spec)\.(?:ts|tsx|js|jsx|mjs|cjs|java|cs|py|php|go)$/u.test(fileName);
|
|
225122
|
-
const isE2e = isTestFile && /(?:^|[./_-])e2e(?:[./_-]|$)/u.test(fileName) || hasPathSegment(normalized, /^e2e$/u);
|
|
225123
|
-
const isFixture = hasPathSegment(normalized, /^(?:fixtures?|__fixtures__)$/u);
|
|
225124
|
-
const isTestPlugin = hasPathSegment(normalized, /^(?:test-plugins?|testing-plugins?)$/u);
|
|
225125
|
-
const isExamplePlugin = hasPathSegment(normalized, /^(?:example-plugins?|examples?)$/u);
|
|
225126
|
-
const isGenerated = hasPathSegment(normalized, /^(?:generated|__generated__|gen|templates?)$/u) || /\.(?:generated|gen|g)\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/u.test(fileName) || /\.d\.ts$/u.test(fileName);
|
|
225127
|
-
const isMigration = hasPathSegment(normalized, /^(?:migrations?|schema-migrations?|migration-utils?)$/u) || /(?:^|[./_-])migration(?:[./_-]|$)/u.test(fileName);
|
|
225128
|
-
const isCliTooling = hasPathSegment(normalized, /^(?:cli|bin|scripts?|tools?|scaffold|scaffolding|generators?)$/u) || /(?:^|[./_-])(?:cli|script|tool|generator|scaffold)(?:[./_-]|$)/u.test(fileName);
|
|
225129
|
-
const isFrontend = extension === ".tsx" || extension === ".jsx" || hasPathSegment(normalized, /^(?:frontend|client|browser|ui|admin-ui|dashboard|web-app)$/u) || /\b(?:react|angular|vue|svelte)\b/u.test(normalized);
|
|
225130
|
-
const isInfrastructure = hasPathSegment(normalized, /^(?:infrastructure|infra|framework|adapters?|persistence|providers?)$/u) || /(?:transactional-connection|transaction-wrapper|transaction-subscriber|transaction-manager|query-runner|query-builder|event-bus|telemetry|interceptor)\.(?:ts|js|java|cs|py|php|go)$/u.test(fileName);
|
|
225131
|
-
let category = "production-backend";
|
|
225132
|
-
if (isGenerated) {
|
|
225133
|
-
category = "generated";
|
|
225134
|
-
} else if (isE2e) {
|
|
225135
|
-
category = "e2e";
|
|
225136
|
-
} else if (isTestFile || hasPathSegment(normalized, /^(?:test|tests|__tests__|spec|specs)$/u)) {
|
|
225137
|
-
category = "test";
|
|
225138
|
-
} else if (isTestPlugin) {
|
|
225139
|
-
category = "test-plugin";
|
|
225140
|
-
} else if (isExamplePlugin) {
|
|
225141
|
-
category = "example-plugin";
|
|
225142
|
-
} else if (isFixture) {
|
|
225143
|
-
category = "fixture";
|
|
225144
|
-
} else if (isMigration) {
|
|
225145
|
-
category = "migration";
|
|
225146
|
-
} else if (isCliTooling) {
|
|
225147
|
-
category = "cli-tooling";
|
|
225148
|
-
} else if (isFrontend) {
|
|
225149
|
-
category = "production-frontend";
|
|
225150
|
-
} else if (isInfrastructure) {
|
|
225151
|
-
category = "infrastructure";
|
|
225152
|
-
}
|
|
225153
|
-
const isTestLike = category === "test" || category === "e2e" || category === "fixture" || category === "test-plugin" || category === "example-plugin";
|
|
225154
|
-
return {
|
|
225155
|
-
category,
|
|
225156
|
-
isProduction: category === "production-backend" || category === "production-frontend" || category === "infrastructure",
|
|
225157
|
-
isFrontend: category === "production-frontend",
|
|
225158
|
-
isTestLike,
|
|
225159
|
-
isGenerated: category === "generated",
|
|
225160
|
-
isMigration: category === "migration",
|
|
225161
|
-
isCliTooling: category === "cli-tooling",
|
|
225162
|
-
isInfrastructure: category === "infrastructure"
|
|
225163
|
-
};
|
|
225164
|
-
}
|
|
225165
|
-
function isProductionBackendGovernanceScope(scope) {
|
|
225166
|
-
return scope.category === "production-backend";
|
|
225167
|
-
}
|
|
225168
|
-
|
|
225169
225374
|
// ../core/src/dataQueryRiskDetection.ts
|
|
225375
|
+
init_sourceScopeClassification();
|
|
225170
225376
|
var maxFileSizeBytes = 256 * 1024;
|
|
225171
225377
|
var supplementalRiskScanExtensions = [".json", ".yaml", ".yml", ".sql"];
|
|
225172
225378
|
var backendCodeExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".java", ".cs", ".py", ".php", ".go"];
|
|
@@ -225174,7 +225380,7 @@ var supplementalIgnoredDirectoryNames = [".vscode-test", ".tmp"];
|
|
|
225174
225380
|
var batchingEvidencePattern = /\b(?:DataLoader|Promise\.all|findMany\s*\([\s\S]{0,300}\bin\b|where\s*:\s*\{[\s\S]{0,300}\bin\s*:|include\s*:|join\s*\(|leftJoin|innerJoin|JOIN\b)\b/iu;
|
|
225175
225381
|
var queryReadPattern = /\b((?:this\.)?(?:prisma\.(\w+)|([A-Za-z_$][\w$]*Repository|repository))\.(find\w*|count|aggregate|groupBy)\s*\()/giu;
|
|
225176
225382
|
var unboundedLoadPattern = /\b(?:const|let|var)\s+(\w+)\s*=\s*await\s+((?:this\.)?(?:prisma\.\w+|\w*Repository|repository)\.(?:findMany|findAll|find))\s*\(([\s\S]{0,700}?)\)\s*;?[\s\S]{0,1000}\b\1\.(?:filter|map|reduce)\s*\(/iu;
|
|
225177
|
-
var boundEvidencePattern = /\b(?:take|limit|page|cursor|skip|offset|PageRequest|Pageable)\b/iu;
|
|
225383
|
+
var boundEvidencePattern = /\b(?:take|limit|page|cursor|skip|offset|PageRequest|Pageable|findOne|findOneOrFail|findOneBy|findOneByOrFail|findUnique|findFirst|getOne|getRawOne|first)\b/iu;
|
|
225178
225384
|
var repeatedQueryPattern = /\b((?:this\.)?(?:prisma\.(\w+)|(\w*Repository|repository))\.(find\w*|count|aggregate|groupBy)\s*\(\s*(?:\{[\s\S]{0,300}?\}|\w+)\s*\))/giu;
|
|
225179
225385
|
var tenantPredicatePattern = /\b(?:tenantId|tenant_id|organizationId|organization_id|orgId|org_id|accountId|account_id|workspaceId|workspace_id|companyId|company_id|customerId|customer_id)\b/u;
|
|
225180
225386
|
var codePaginationEvidencePattern = /\b(?:take|skip|limit|offset|page|perPage|pageSize|cursor|Pageable|PageRequest|paginate|simplePaginate|Limit|Offset|Take|Skip|TOP\s+\d+)\b/iu;
|
|
@@ -225985,7 +226191,7 @@ function detectRepeatedQueryPattern(method) {
|
|
|
225985
226191
|
function extractSqlQueryLiterals(content) {
|
|
225986
226192
|
const queries = [];
|
|
225987
226193
|
const patterns = [
|
|
225988
|
-
/(?:\b(?:query|execute|executeQuery|createNativeQuery|createQuery|FromSqlRaw|FromSqlInterpolated|Query|QueryContext|QueryRow|QueryRowContext|Exec|ExecContext|Raw|text)|\$queryRaw|\$executeRaw)\s*\([^'"`)]{0,180}?(['"`])([\s\S]{0,900}?)\1/giu,
|
|
226194
|
+
/(?:\b(?:[\w$]+\.)?(?:query|execute|executeQuery|createNativeQuery|createQuery|FromSqlRaw|FromSqlInterpolated|Query|QueryContext|QueryRow|QueryRowContext|Exec|ExecContext|Raw|text)|\$queryRaw|\$executeRaw)\s*\([^'"`)]{0,180}?(['"`])([\s\S]{0,900}?)\1/giu,
|
|
225989
226195
|
/\b(?:DB::select|DB::statement|DB::raw|DB::table)\s*\([^'"`)]{0,180}?(['"`])([\s\S]{0,900}?)\1/gu,
|
|
225990
226196
|
/@Query\s*\(\s*(['"`])([\s\S]{0,900}?)\1/gu
|
|
225991
226197
|
];
|
|
@@ -226072,7 +226278,7 @@ function collectOrmReadEvidence(method) {
|
|
|
226072
226278
|
return evidence;
|
|
226073
226279
|
}
|
|
226074
226280
|
function getOrmTerminalOperation(snippet) {
|
|
226075
|
-
const match = /\.(getMany|getRawMany|getOne|getRawOne|getCount|getExists|execute|findOne|findOneBy|findUnique|findFirst|count|exists|update|delete|remove|save|insert)\s*\(/iu.exec(snippet);
|
|
226281
|
+
const match = /\.(getMany|getRawMany|loadMany|getOne|getRawOne|loadOne|getCount|getExists|execute|findOne|findOneOrFail|findOneBy|findOneByOrFail|findUnique|findFirst|count|exists|update|delete|remove|save|insert)\s*\(/iu.exec(snippet);
|
|
226076
226282
|
return match?.[1];
|
|
226077
226283
|
}
|
|
226078
226284
|
function isOperationalOrBatchQueryContext(file, methodName) {
|
|
@@ -226081,12 +226287,20 @@ function isOperationalOrBatchQueryContext(file, methodName) {
|
|
|
226081
226287
|
const method = methodName?.toLowerCase() ?? "";
|
|
226082
226288
|
return segments.some((segment) => /\b(?:health|cache|job|queue|scheduler|indexer|telemetry|metrics)\b/u.test(segment.replace(/-/g, " "))) || /(^|\/)(?:health-check|healthchecks?|cache|job-queue|scheduler|search|indexer|telemetry|metrics)(?:\/|-)/u.test(pathValue) || /(?:health-check|healthcheck|cache|job-queue|scheduler|search|indexer|telemetry|metrics)\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/u.test(pathValue) || /\b(?:health|cache|job|queue|schedule|scheduler|index|telemetry|metrics|buffer|worker|batch)\b/u.test(method) || method.includes("batch") || /^on(?:moduleinit|applicationbootstrap|applicationstart|init)$/u.test(method);
|
|
226083
226289
|
}
|
|
226084
|
-
function
|
|
226085
|
-
return
|
|
226290
|
+
function isScopedRelationLoad(snippet) {
|
|
226291
|
+
return /\.relation\s*\(/iu.test(snippet) && /\.of\s*\(\s*[^)]{1,180}\)\s*\.loadMany\s*\(/iu.test(snippet);
|
|
226086
226292
|
}
|
|
226087
|
-
function
|
|
226293
|
+
function hasAssignedBuilderBoundedTerminal(methodBody, snippet) {
|
|
226294
|
+
const variableMatch = /\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:[\s\S]{0,240}?)createQueryBuilder\s*\(/iu.exec(snippet);
|
|
226295
|
+
const variableName = variableMatch?.[1];
|
|
226296
|
+
if (!variableName) {
|
|
226297
|
+
return false;
|
|
226298
|
+
}
|
|
226299
|
+
return new RegExp(`\\b${variableName}\\s*\\.\\s*(?:getOne|getRawOne|loadOne|getCount|getExists)\\s*\\(`, "iu").test(methodBody);
|
|
226300
|
+
}
|
|
226301
|
+
function isNonCollectionOrmRead(label, snippet, methodBody = snippet) {
|
|
226088
226302
|
const terminal = getOrmTerminalOperation(snippet);
|
|
226089
|
-
return /\b(?:findOne|findOneBy|findUnique|findFirst|count|exists|aggregate)\b/iu.test(label) || !!terminal && /^(?:getOne|getRawOne|getCount|getExists|findOne|findOneBy|findUnique|findFirst|count|exists|update|delete|remove|save|insert|execute)$/iu.test(terminal);
|
|
226303
|
+
return /\b(?:findOne|findOneOrFail|findOneBy|findOneByOrFail|findUnique|findFirst|count|exists|aggregate)\b/iu.test(label) || !!terminal && /^(?:getOne|getRawOne|loadOne|getCount|getExists|findOne|findOneOrFail|findOneBy|findOneByOrFail|findUnique|findFirst|count|exists|update|delete|remove|save|insert|execute)$/iu.test(terminal) || isScopedRelationLoad(snippet) || hasAssignedBuilderBoundedTerminal(methodBody, snippet);
|
|
226090
226304
|
}
|
|
226091
226305
|
function hasOrmBoundEvidence(snippet) {
|
|
226092
226306
|
return codePaginationEvidencePattern.test(snippet) || /\.(?:take|limit|offset|skip)\s*\(/iu.test(snippet) || /\b(?:maxResults|setMaxResults|firstResult|setFirstResult)\s*\(/iu.test(snippet) || /\b(?:pageSize|perPage|limit|take)\s*[:=]\s*\d+\b/iu.test(snippet);
|
|
@@ -226121,7 +226335,7 @@ function detectOrmQueryShapeFindings(method, config) {
|
|
|
226121
226335
|
target: evidence.label
|
|
226122
226336
|
}));
|
|
226123
226337
|
}
|
|
226124
|
-
if (!isOperationalOrBatchQueryContext(method.file, method.name) && !
|
|
226338
|
+
if (!isOperationalOrBatchQueryContext(method.file, method.name) && !isNonCollectionOrmRead(evidence.label, evidence.snippet, method.body) && !hasOrmBoundEvidence(evidence.snippet)) {
|
|
226125
226339
|
const target = getOrmQueryTarget(method, evidence.label, evidence.snippet);
|
|
226126
226340
|
const label = getOrmQueryLabel(method, evidence.label, evidence.snippet);
|
|
226127
226341
|
findings.push(createCodeFinding({
|
|
@@ -226146,9 +226360,12 @@ function detectCodeQueryRiskFindings(files, config, astCache) {
|
|
|
226146
226360
|
findings.push(...detectCodeSqlQueryShapeFindings(file, config));
|
|
226147
226361
|
}
|
|
226148
226362
|
for (const method of extractMethodBodies(file, astCache)) {
|
|
226363
|
+
if (!isProductionBackend) {
|
|
226364
|
+
continue;
|
|
226365
|
+
}
|
|
226149
226366
|
nPlusOneEvidence.push(...detectNPlusOneQueryRisk(method));
|
|
226150
226367
|
findings.push(
|
|
226151
|
-
...
|
|
226368
|
+
...detectOrmQueryShapeFindings(method, config),
|
|
226152
226369
|
...detectLargeCollectionLoading(method),
|
|
226153
226370
|
...detectMissingProjection(method),
|
|
226154
226371
|
...detectRepeatedQueryPattern(method)
|
|
@@ -226241,6 +226458,7 @@ var import_node_fs25 = require("node:fs");
|
|
|
226241
226458
|
var ts3 = __toESM(require_typescript());
|
|
226242
226459
|
init_moduleDiscovery();
|
|
226243
226460
|
init_archpilotIgnore();
|
|
226461
|
+
init_sourceScopeClassification();
|
|
226244
226462
|
var ApplicationLayeringRuleIds = {
|
|
226245
226463
|
CONTROLLER_BUSINESS_LOGIC: "AP-APP-001",
|
|
226246
226464
|
REPOSITORY_BUSINESS_LOGIC: "AP-APP-002",
|
|
@@ -226577,17 +226795,40 @@ function getModulePathForName(contract, moduleName) {
|
|
|
226577
226795
|
const reference = contract.modules?.[moduleName];
|
|
226578
226796
|
return normalizePath11(reference?.path ?? `${modulesRoot}/${moduleName}`);
|
|
226579
226797
|
}
|
|
226580
|
-
function
|
|
226798
|
+
function getComponentEntries2(contract) {
|
|
226799
|
+
const components = contract.components;
|
|
226800
|
+
if (!components) {
|
|
226801
|
+
return [];
|
|
226802
|
+
}
|
|
226803
|
+
return Array.isArray(components) ? components.map((component, index) => [
|
|
226804
|
+
typeof component.id === "string" && component.id.trim().length > 0 ? component.id.trim() : `component-${index}`,
|
|
226805
|
+
component
|
|
226806
|
+
]) : Object.entries(components);
|
|
226807
|
+
}
|
|
226808
|
+
function getComponentPathForFile(contract, relativePath) {
|
|
226581
226809
|
const normalized = normalizePath11(relativePath).toLowerCase();
|
|
226582
|
-
|
|
226810
|
+
const candidates = getComponentEntries2(contract).map(([, component]) => component.path).filter(
|
|
226811
|
+
(componentPath) => typeof componentPath === "string" && componentPath.trim().length > 0
|
|
226812
|
+
).map((componentPath) => normalizePath11(componentPath)).filter((componentPath) => {
|
|
226813
|
+
const normalizedComponentPath = componentPath.toLowerCase();
|
|
226814
|
+
return normalized === normalizedComponentPath || normalized.startsWith(`${normalizedComponentPath}/`);
|
|
226815
|
+
}).sort((left, right) => right.length - left.length || left.localeCompare(right));
|
|
226816
|
+
return candidates[0];
|
|
226817
|
+
}
|
|
226818
|
+
function getOwnershipPathForFile(contract, relativePath, moduleName) {
|
|
226819
|
+
return getModulePathForName(contract, moduleName) ?? getComponentPathForFile(contract, relativePath);
|
|
226820
|
+
}
|
|
226821
|
+
function getPathSegmentsInsideModule(relativePath, ownershipPath) {
|
|
226822
|
+
const normalized = normalizePath11(relativePath).toLowerCase();
|
|
226823
|
+
if (!ownershipPath) {
|
|
226583
226824
|
return normalized.split("/");
|
|
226584
226825
|
}
|
|
226585
|
-
const
|
|
226586
|
-
if (normalized ===
|
|
226826
|
+
const normalizedOwnershipPath = normalizePath11(ownershipPath).toLowerCase();
|
|
226827
|
+
if (normalized === normalizedOwnershipPath) {
|
|
226587
226828
|
return [];
|
|
226588
226829
|
}
|
|
226589
|
-
if (normalized.startsWith(`${
|
|
226590
|
-
return normalized.slice(
|
|
226830
|
+
if (normalized.startsWith(`${normalizedOwnershipPath}/`)) {
|
|
226831
|
+
return normalized.slice(normalizedOwnershipPath.length + 1).split("/");
|
|
226591
226832
|
}
|
|
226592
226833
|
return normalized.split("/");
|
|
226593
226834
|
}
|
|
@@ -226723,7 +226964,10 @@ function createFinding(input2) {
|
|
|
226723
226964
|
function hasRepositoryLayer(files, contract) {
|
|
226724
226965
|
return files.some((file) => {
|
|
226725
226966
|
const moduleName = inferModuleForPath2(contract, file.relativePath);
|
|
226726
|
-
return classifySourceFile(
|
|
226967
|
+
return classifySourceFile(
|
|
226968
|
+
file,
|
|
226969
|
+
getOwnershipPathForFile(contract, file.relativePath, moduleName)
|
|
226970
|
+
).isRepository;
|
|
226727
226971
|
});
|
|
226728
226972
|
}
|
|
226729
226973
|
function hasServiceLayer(files) {
|
|
@@ -226912,35 +227156,30 @@ function isDbModelEvidenceToken(value) {
|
|
|
226912
227156
|
const lower = normalized.toLowerCase();
|
|
226913
227157
|
const excluded = /* @__PURE__ */ new Set([
|
|
226914
227158
|
"a",
|
|
227159
|
+
"all",
|
|
226915
227160
|
"an",
|
|
226916
|
-
"
|
|
226917
|
-
"
|
|
226918
|
-
"
|
|
226919
|
-
"
|
|
226920
|
-
"into",
|
|
226921
|
-
"join",
|
|
226922
|
-
"openapi",
|
|
226923
|
-
"or",
|
|
226924
|
-
"paddle",
|
|
226925
|
-
"provider",
|
|
227161
|
+
"doing",
|
|
227162
|
+
"first",
|
|
227163
|
+
"is",
|
|
227164
|
+
"outside",
|
|
226926
227165
|
"resend",
|
|
226927
|
-
"
|
|
226928
|
-
"select",
|
|
226929
|
-
"stripe",
|
|
227166
|
+
"scratch",
|
|
226930
227167
|
"swagger",
|
|
226931
|
-
"
|
|
226932
|
-
"the",
|
|
226933
|
-
"this",
|
|
226934
|
-
"to",
|
|
226935
|
-
"update",
|
|
226936
|
-
"where",
|
|
226937
|
-
"with"
|
|
227168
|
+
"the"
|
|
226938
227169
|
]);
|
|
226939
227170
|
if (excluded.has(lower)) {
|
|
226940
227171
|
return false;
|
|
226941
227172
|
}
|
|
226942
227173
|
return !/(?:client|provider|service|controller|guard|swagger|openapi)$/iu.test(normalized);
|
|
226943
227174
|
}
|
|
227175
|
+
function isStructuredSqlTableEvidence(value, keyword, quote, following = "") {
|
|
227176
|
+
const normalized = value.trim();
|
|
227177
|
+
const hasStructuralEvidence = /^(?:from|update|into)$/iu.test(keyword) || quote !== void 0 && quote.length > 0 || /[_.]/u.test(normalized) || /^join$/iu.test(keyword) && /\bon\b/iu.test(following);
|
|
227178
|
+
return hasStructuralEvidence && isDbModelEvidenceToken(normalized);
|
|
227179
|
+
}
|
|
227180
|
+
function extractSqlLikeLiterals(content) {
|
|
227181
|
+
return [...content.matchAll(/(['"`])([\s\S]{0,1200}?)\1/gu)].map((match) => match[2] ?? "").filter((literal) => /\b(?:select|update|delete|insert)\b[\s\S]{0,400}\b(?:from|join|into|update)\b/iu.test(literal));
|
|
227182
|
+
}
|
|
226944
227183
|
function extractDbModelsTouched(content) {
|
|
226945
227184
|
const models = /* @__PURE__ */ new Set();
|
|
226946
227185
|
for (const match of content.matchAll(/\b(?:this\.)?prisma\.([a-z]\w*)\./giu)) {
|
|
@@ -226948,9 +227187,13 @@ function extractDbModelsTouched(content) {
|
|
|
226948
227187
|
models.add(match[1]);
|
|
226949
227188
|
}
|
|
226950
227189
|
}
|
|
226951
|
-
for (const
|
|
226952
|
-
|
|
226953
|
-
|
|
227190
|
+
for (const sqlLiteral of extractSqlLikeLiterals(content)) {
|
|
227191
|
+
for (const match of sqlLiteral.matchAll(/\b(?:from|join|update|into)\s+(["`]?)([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)?)\1/giu)) {
|
|
227192
|
+
const keyword = /\b(from|join|update|into)\b/iu.exec(match[0])?.[1] ?? "";
|
|
227193
|
+
const following = sqlLiteral.slice((match.index ?? 0) + match[0].length, (match.index ?? 0) + match[0].length + 120);
|
|
227194
|
+
if (match[2] && isStructuredSqlTableEvidence(match[2], keyword, match[1], following)) {
|
|
227195
|
+
models.add(match[2]);
|
|
227196
|
+
}
|
|
226954
227197
|
}
|
|
226955
227198
|
}
|
|
226956
227199
|
return sortUnique6(models).slice(0, 6);
|
|
@@ -227046,7 +227289,7 @@ async function detectApplicationLayeringFindings(input2) {
|
|
|
227046
227289
|
const moduleName = inferModuleForPath2(input2.contract, file.relativePath);
|
|
227047
227290
|
const classification = classifySourceFile(
|
|
227048
227291
|
file,
|
|
227049
|
-
|
|
227292
|
+
getOwnershipPathForFile(input2.contract, file.relativePath, moduleName),
|
|
227050
227293
|
input2.astCache
|
|
227051
227294
|
);
|
|
227052
227295
|
const candidates = [
|
|
@@ -227694,6 +227937,7 @@ var import_node_fs27 = require("node:fs");
|
|
|
227694
227937
|
var ts5 = __toESM(require_typescript());
|
|
227695
227938
|
init_moduleDiscovery();
|
|
227696
227939
|
init_archpilotIgnore();
|
|
227940
|
+
init_sourceScopeClassification();
|
|
227697
227941
|
var RuleIds2 = {
|
|
227698
227942
|
TXN_BOUNDARY_TOO_BROAD: "AP-TXN-001",
|
|
227699
227943
|
TXN_IN_CONTROLLER: "AP-TXN-002",
|
|
@@ -228737,35 +228981,30 @@ function isDbModelEvidenceToken2(value) {
|
|
|
228737
228981
|
const lower = normalized.toLowerCase();
|
|
228738
228982
|
const excluded = /* @__PURE__ */ new Set([
|
|
228739
228983
|
"a",
|
|
228984
|
+
"all",
|
|
228740
228985
|
"an",
|
|
228741
|
-
"
|
|
228742
|
-
"
|
|
228743
|
-
"
|
|
228744
|
-
"
|
|
228745
|
-
"into",
|
|
228746
|
-
"join",
|
|
228747
|
-
"openapi",
|
|
228748
|
-
"or",
|
|
228749
|
-
"paddle",
|
|
228750
|
-
"provider",
|
|
228986
|
+
"doing",
|
|
228987
|
+
"first",
|
|
228988
|
+
"is",
|
|
228989
|
+
"outside",
|
|
228751
228990
|
"resend",
|
|
228752
|
-
"
|
|
228753
|
-
"select",
|
|
228754
|
-
"stripe",
|
|
228991
|
+
"scratch",
|
|
228755
228992
|
"swagger",
|
|
228756
|
-
"
|
|
228757
|
-
"the",
|
|
228758
|
-
"this",
|
|
228759
|
-
"to",
|
|
228760
|
-
"update",
|
|
228761
|
-
"where",
|
|
228762
|
-
"with"
|
|
228993
|
+
"the"
|
|
228763
228994
|
]);
|
|
228764
228995
|
if (excluded.has(lower)) {
|
|
228765
228996
|
return false;
|
|
228766
228997
|
}
|
|
228767
228998
|
return !/(?:client|provider|service|controller|guard|swagger|openapi)$/iu.test(normalized);
|
|
228768
228999
|
}
|
|
229000
|
+
function isStructuredSqlTableEvidence2(value, keyword, quote, following = "") {
|
|
229001
|
+
const normalized = value.trim();
|
|
229002
|
+
const hasStructuralEvidence = /^(?:from|update|into)$/iu.test(keyword) || quote !== void 0 && quote.length > 0 || /[_.]/u.test(normalized) || /^join$/iu.test(keyword) && /\bon\b/iu.test(following);
|
|
229003
|
+
return hasStructuralEvidence && isDbModelEvidenceToken2(normalized);
|
|
229004
|
+
}
|
|
229005
|
+
function extractSqlLikeLiterals2(content) {
|
|
229006
|
+
return [...content.matchAll(/(['"`])([\s\S]{0,1200}?)\1/gu)].map((match) => match[2] ?? "").filter((literal) => /\b(?:select|update|delete|insert)\b[\s\S]{0,400}\b(?:from|join|into|update)\b/iu.test(literal));
|
|
229007
|
+
}
|
|
228769
229008
|
function extractDbModelsTouched2(content) {
|
|
228770
229009
|
const models = /* @__PURE__ */ new Set();
|
|
228771
229010
|
for (const match of content.matchAll(/\b(?:this\.)?prisma\.([a-z]\w*)\./giu)) {
|
|
@@ -228773,9 +229012,13 @@ function extractDbModelsTouched2(content) {
|
|
|
228773
229012
|
models.add(match[1]);
|
|
228774
229013
|
}
|
|
228775
229014
|
}
|
|
228776
|
-
for (const
|
|
228777
|
-
|
|
228778
|
-
|
|
229015
|
+
for (const sqlLiteral of extractSqlLikeLiterals2(content)) {
|
|
229016
|
+
for (const match of sqlLiteral.matchAll(/\b(?:from|join|update|into)\s+(["`]?)([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)?)\1/giu)) {
|
|
229017
|
+
const keyword = /\b(from|join|update|into)\b/iu.exec(match[0])?.[1] ?? "";
|
|
229018
|
+
const following = sqlLiteral.slice((match.index ?? 0) + match[0].length, (match.index ?? 0) + match[0].length + 120);
|
|
229019
|
+
if (match[2] && isStructuredSqlTableEvidence2(match[2], keyword, match[1], following)) {
|
|
229020
|
+
models.add(match[2]);
|
|
229021
|
+
}
|
|
228779
229022
|
}
|
|
228780
229023
|
}
|
|
228781
229024
|
return sortUnique7(models).slice(0, 6);
|
|
@@ -229025,6 +229268,7 @@ var path33 = __toESM(require("node:path"));
|
|
|
229025
229268
|
var import_node_fs28 = require("node:fs");
|
|
229026
229269
|
init_moduleDiscovery();
|
|
229027
229270
|
init_archpilotIgnore();
|
|
229271
|
+
init_sourceScopeClassification();
|
|
229028
229272
|
var RuleIds3 = {
|
|
229029
229273
|
MISSING_PAGINATION: "AP-API-010",
|
|
229030
229274
|
BULK_OPERATION_RISK: "AP-API-011",
|
|
@@ -229541,8 +229785,34 @@ function hasPaginationEvidence2(endpoint, contractEndpoints) {
|
|
|
229541
229785
|
${endpoint.signature}
|
|
229542
229786
|
${endpoint.body}`);
|
|
229543
229787
|
}
|
|
229788
|
+
function stripStaticLiteralNoise(value) {
|
|
229789
|
+
return value.replace(/\/\*[\s\S]*?\*\//gu, " ").replace(/\/\/.*$/gmu, " ").replace(/(['"`])(?:\\.|(?!\1)[\s\S])*\1/gu, '""');
|
|
229790
|
+
}
|
|
229791
|
+
function isStaticCollectionExpression(expression) {
|
|
229792
|
+
const normalized = expression.trim().replace(/;$/u, "").trim();
|
|
229793
|
+
return /^(?:Object\.)?(?:freeze|values|entries|keys)\s*\(/u.test(normalized) || /^(?:\[[\s\S]*\]|\{[\s\S]*\})$/u.test(normalized) || /^(?:[A-Z][A-Za-z0-9_]*|[a-z][A-Za-z0-9_]*(?:Config|Configs|Catalog|Catalogs|Metadata|Definitions|Types|Widgets|Constants))$/u.test(normalized);
|
|
229794
|
+
}
|
|
229795
|
+
function hasStaticDeclarationEvidence(fileContent, identifier) {
|
|
229796
|
+
const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
229797
|
+
return new RegExp(`\\bimport\\s+(?:\\{[^}]*\\b${escaped}\\b[^}]*\\}|${escaped}\\b)`, "u").test(fileContent) || new RegExp(`\\b(?:const|readonly)\\s+${escaped}\\s*=\\s*(?:Object\\.freeze\\s*\\(|\\[|\\{)`, "u").test(fileContent) || new RegExp(`\\benum\\s+${escaped}\\b`, "u").test(fileContent);
|
|
229798
|
+
}
|
|
229799
|
+
function isStaticCollectionBackedEndpoint(endpoint) {
|
|
229800
|
+
const body = endpoint.body.trim();
|
|
229801
|
+
if (/\b(?:await|repository|Repository|createQueryBuilder|findMany|findAll|find\s*\(|query\s*\(|execute\s*\(|service\.)\b/iu.test(body)) {
|
|
229802
|
+
return false;
|
|
229803
|
+
}
|
|
229804
|
+
const returnMatch = /\breturn\s+([\s\S]{0,500}?);/u.exec(body) ?? /\bres\.(?:json|send)\s*\(\s*([\s\S]{0,500}?)\s*\)\s*;?/u.exec(body) ?? /\bOk\s*\(\s*([\s\S]{0,500}?)\s*\)\s*;?/u.exec(body);
|
|
229805
|
+
if (!returnMatch?.[1]) {
|
|
229806
|
+
return false;
|
|
229807
|
+
}
|
|
229808
|
+
const expression = returnMatch[1].trim();
|
|
229809
|
+
if (/^[A-Za-z_$][\w$]*$/u.test(expression)) {
|
|
229810
|
+
return hasStaticDeclarationEvidence(endpoint.file.content, expression);
|
|
229811
|
+
}
|
|
229812
|
+
return isStaticCollectionExpression(stripStaticLiteralNoise(expression));
|
|
229813
|
+
}
|
|
229544
229814
|
function detectPaginationFindings(endpoints, contractEndpoints) {
|
|
229545
|
-
return endpoints.filter((endpoint) => isCollectionGet(endpoint) && !hasPaginationEvidence2(endpoint, contractEndpoints)).map((endpoint) => createFinding4({
|
|
229815
|
+
return endpoints.filter((endpoint) => isCollectionGet(endpoint) && !hasPaginationEvidence2(endpoint, contractEndpoints) && !isStaticCollectionBackedEndpoint(endpoint)).map((endpoint) => createFinding4({
|
|
229546
229816
|
id: RuleIds3.MISSING_PAGINATION,
|
|
229547
229817
|
message: `Collection endpoint ${endpoint.httpMethod.toUpperCase()} ${endpoint.path} lacks visible pagination evidence.`,
|
|
229548
229818
|
endpoint
|
|
@@ -231200,7 +231470,7 @@ src/
|
|
|
231200
231470
|
architectureScope: "module",
|
|
231201
231471
|
applicability: { requiresArchitectureModules: true },
|
|
231202
231472
|
description: "Checks whether cross-module imports target another module through its public entrypoints rather than internal implementation files.",
|
|
231203
|
-
recommendedFix: "Import
|
|
231473
|
+
recommendedFix: "Import through the target module or package public entrypoint declared in its contract rather than reaching into internal implementation files."
|
|
231204
231474
|
},
|
|
231205
231475
|
DEP_CROSS_MODULE_DEPENDENCY_DECLARED_IN_CONTRACT: {
|
|
231206
231476
|
id: ValidationRuleIds.DEP_CROSS_MODULE_DEPENDENCY_DECLARED_IN_CONTRACT,
|
|
@@ -242593,6 +242863,9 @@ var ignoredRootPathPrefixes = [
|
|
|
242593
242863
|
function normalizeRelativePath5(value) {
|
|
242594
242864
|
return value.replaceAll("\\", "/");
|
|
242595
242865
|
}
|
|
242866
|
+
function isUnderJvmResourceRoot2(relativePath) {
|
|
242867
|
+
return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizeRelativePath5(relativePath).toLowerCase());
|
|
242868
|
+
}
|
|
242596
242869
|
function sortUnique16(values) {
|
|
242597
242870
|
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
242598
242871
|
}
|
|
@@ -242730,7 +243003,7 @@ function collectDetectedRoots(scan) {
|
|
|
242730
243003
|
const roots = /* @__PURE__ */ new Set();
|
|
242731
243004
|
for (const manifestName of manifestFileNames) {
|
|
242732
243005
|
for (const manifestPath of scan.manifestPathsByName[manifestName]) {
|
|
242733
|
-
if (isIgnoredRelativePath(manifestPath)) {
|
|
243006
|
+
if (isIgnoredRelativePath(manifestPath) || isUnderJvmResourceRoot2(manifestPath)) {
|
|
242734
243007
|
continue;
|
|
242735
243008
|
}
|
|
242736
243009
|
const containingDirectory = normalizeRelativePath5(path58.dirname(manifestPath));
|
|
@@ -242745,11 +243018,11 @@ function buildResultFromScan(scan) {
|
|
|
242745
243018
|
const evidence = [];
|
|
242746
243019
|
const detectedRoots = collectDetectedRoots(scan);
|
|
242747
243020
|
const filteredManifestPathsByName = {
|
|
242748
|
-
"package.json": scan.manifestPathsByName["package.json"].filter((entry) => !isIgnoredRelativePath(entry)),
|
|
242749
|
-
"pom.xml": scan.manifestPathsByName["pom.xml"].filter((entry) => !isIgnoredRelativePath(entry)),
|
|
242750
|
-
"requirements.txt": scan.manifestPathsByName["requirements.txt"].filter((entry) => !isIgnoredRelativePath(entry)),
|
|
242751
|
-
"go.mod": scan.manifestPathsByName["go.mod"].filter((entry) => !isIgnoredRelativePath(entry)),
|
|
242752
|
-
"composer.json": scan.manifestPathsByName["composer.json"].filter((entry) => !isIgnoredRelativePath(entry))
|
|
243021
|
+
"package.json": scan.manifestPathsByName["package.json"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry)),
|
|
243022
|
+
"pom.xml": scan.manifestPathsByName["pom.xml"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry)),
|
|
243023
|
+
"requirements.txt": scan.manifestPathsByName["requirements.txt"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry)),
|
|
243024
|
+
"go.mod": scan.manifestPathsByName["go.mod"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry)),
|
|
243025
|
+
"composer.json": scan.manifestPathsByName["composer.json"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry))
|
|
242753
243026
|
};
|
|
242754
243027
|
let monorepoStrongSignals = 0;
|
|
242755
243028
|
let monorepoWeakSignals = 0;
|
|
@@ -243049,6 +243322,12 @@ function confidenceWeight(confidence) {
|
|
|
243049
243322
|
return 1;
|
|
243050
243323
|
}
|
|
243051
243324
|
function compareCandidates2(left, right) {
|
|
243325
|
+
if (left.result.confidence === "high" && right.result.confidence === "high" && left.adapter.category === "framework" && right.adapter.category === "generic-language" && left.adapter.ecosystem === right.adapter.ecosystem) {
|
|
243326
|
+
return -1;
|
|
243327
|
+
}
|
|
243328
|
+
if (left.result.confidence === "high" && right.result.confidence === "high" && left.adapter.category === "generic-language" && right.adapter.category === "framework" && left.adapter.ecosystem === right.adapter.ecosystem) {
|
|
243329
|
+
return 1;
|
|
243330
|
+
}
|
|
243052
243331
|
const confidenceDiff = confidenceWeight(right.result.confidence) - confidenceWeight(left.result.confidence);
|
|
243053
243332
|
if (confidenceDiff !== 0) {
|
|
243054
243333
|
return confidenceDiff;
|
|
@@ -244794,6 +245073,9 @@ var ignoredDirectoryNames12 = /* @__PURE__ */ new Set([
|
|
|
244794
245073
|
function normalizePath24(value) {
|
|
244795
245074
|
return value.replaceAll("\\", "/");
|
|
244796
245075
|
}
|
|
245076
|
+
function isUnderJvmResourceRoot3(relativePath) {
|
|
245077
|
+
return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizePath24(relativePath).toLowerCase());
|
|
245078
|
+
}
|
|
244797
245079
|
function unique(values) {
|
|
244798
245080
|
return [...new Set(values)];
|
|
244799
245081
|
}
|
|
@@ -244942,7 +245224,7 @@ function hasAnyDependency2(summary, dependencyNames) {
|
|
|
244942
245224
|
function collectCandidateRoots(workspaceRoot, topology, ignoreMatcher) {
|
|
244943
245225
|
const roots = /* @__PURE__ */ new Set();
|
|
244944
245226
|
for (const root of topology.detectedRoots ?? []) {
|
|
244945
|
-
if (root && root !== "." && !isIgnoredPath6(ignoreMatcher, root) && !isSupportingAssetRoot(root)) {
|
|
245227
|
+
if (root && root !== "." && !isIgnoredPath6(ignoreMatcher, root) && !isSupportingAssetRoot(root) && !isUnderJvmResourceRoot3(root)) {
|
|
244946
245228
|
roots.add(normalizePath24(root));
|
|
244947
245229
|
}
|
|
244948
245230
|
}
|
|
@@ -244950,7 +245232,7 @@ function collectCandidateRoots(workspaceRoot, topology, ignoreMatcher) {
|
|
|
244950
245232
|
const absoluteBase = path63.join(workspaceRoot, base);
|
|
244951
245233
|
for (const entry of safeReadDirEntries4(absoluteBase)) {
|
|
244952
245234
|
const relativePath = `${base}/${entry.name}`;
|
|
244953
|
-
if (!entry.isDirectory() || ignoredDirectoryNames12.has(entry.name) || isIgnoredPath6(ignoreMatcher, relativePath) || isSupportingAssetRoot(relativePath) || (topology.detectedRoots?.length ?? 0) > 0 && !topology.detectedRoots?.includes(relativePath) && !hasManifest(workspaceRoot, relativePath)) {
|
|
245235
|
+
if (!entry.isDirectory() || ignoredDirectoryNames12.has(entry.name) || isIgnoredPath6(ignoreMatcher, relativePath) || isSupportingAssetRoot(relativePath) || isUnderJvmResourceRoot3(relativePath) || (topology.detectedRoots?.length ?? 0) > 0 && !topology.detectedRoots?.includes(relativePath) && !hasManifest(workspaceRoot, relativePath)) {
|
|
244954
245236
|
continue;
|
|
244955
245237
|
}
|
|
244956
245238
|
roots.add(relativePath);
|
|
@@ -245034,9 +245316,10 @@ function inspectRoot(workspaceRoot, root, ignoreMatcher) {
|
|
|
245034
245316
|
addEvidence5(evidence, "Detected modules root");
|
|
245035
245317
|
}
|
|
245036
245318
|
const hasFrontendSignals = fileExists5(scan.files, "next.config.js") || fileExists5(scan.files, "next.config.ts") || fileExists5(scan.files, "angular.json") || fileExists5(scan.files, "vite.config.ts") || fileExists5(scan.files, "vite.config.js") || hasDirectory(scan.directories, "pages") || hasDirectory(scan.directories, "public") || hasAnyDependency2(packageJson, ["next", "react", "vue", "@angular/core"]);
|
|
245319
|
+
const hasRunnableFrontendSignals = fileExists5(scan.files, "next.config.js") || fileExists5(scan.files, "next.config.ts") || fileExists5(scan.files, "angular.json") || fileExists5(scan.files, "vite.config.ts") || fileExists5(scan.files, "vite.config.js") || fileExists5(scan.files, "index.html") || hasDirectory(scan.directories, "pages") || hasDirectory(scan.directories, "src/app");
|
|
245037
245320
|
const hasBackendSignals = hasApiBoundary || hasDatabaseAccess || fileExists5(scan.files, "pom.xml") || fileExists5(scan.files, "requirements.txt") || fileExists5(scan.files, "go.mod") || hasDirectory(scan.directories, "src/main/java");
|
|
245038
245321
|
let classification = "unknown";
|
|
245039
|
-
if ((root.startsWith("packages/") || root.startsWith("libs/")) && !hasApiBoundary) {
|
|
245322
|
+
if ((root.startsWith("packages/") || root.startsWith("libs/")) && !hasRunnableFrontendSignals && !hasApiBoundary) {
|
|
245040
245323
|
classification = "shared_package";
|
|
245041
245324
|
} else if (hasBackendSignals && !hasFrontendSignals) {
|
|
245042
245325
|
classification = "backend_app";
|
|
@@ -245147,6 +245430,8 @@ function isIgnoredComponentCandidatePath(componentPath) {
|
|
|
245147
245430
|
const ignoredRootSegments = [
|
|
245148
245431
|
"tests",
|
|
245149
245432
|
"test",
|
|
245433
|
+
"cypress",
|
|
245434
|
+
"cypress-tests",
|
|
245150
245435
|
"__tests__",
|
|
245151
245436
|
"fixtures",
|
|
245152
245437
|
"smoke",
|
|
@@ -245214,8 +245499,14 @@ function recordKeys(value) {
|
|
|
245214
245499
|
function hasObject(value) {
|
|
245215
245500
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
245216
245501
|
}
|
|
245502
|
+
function hasPackagePublishSurface(packageJson) {
|
|
245503
|
+
return hasObject(packageJson?.exports) || typeof packageJson?.main === "string" || typeof packageJson?.module === "string" || typeof packageJson?.types === "string" || hasObject(packageJson?.publishConfig) || Array.isArray(packageJson?.files);
|
|
245504
|
+
}
|
|
245505
|
+
function absoluteComponentRoot(workspaceRoot, componentPath) {
|
|
245506
|
+
return componentPath === "." ? workspaceRoot : path64.join(workspaceRoot, ...componentPath.split("/"));
|
|
245507
|
+
}
|
|
245217
245508
|
function readPackageJson(workspaceRoot, componentPath) {
|
|
245218
|
-
const absoluteRoot =
|
|
245509
|
+
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
245219
245510
|
return safeReadJson(path64.join(absoluteRoot, "package.json"));
|
|
245220
245511
|
}
|
|
245221
245512
|
function readTextFileSafe(filePath) {
|
|
@@ -245233,7 +245524,10 @@ function readFirstXmlTag(value, tagName) {
|
|
|
245233
245524
|
return match?.[1]?.trim().replace(/\s+/gu, " ");
|
|
245234
245525
|
}
|
|
245235
245526
|
function readMavenMetadata(workspaceRoot, componentPath) {
|
|
245236
|
-
|
|
245527
|
+
if (isUnderJvmResourceRoot4(componentPath)) {
|
|
245528
|
+
return void 0;
|
|
245529
|
+
}
|
|
245530
|
+
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
245237
245531
|
const pomXml = readTextFileSafe(path64.join(absoluteRoot, "pom.xml"));
|
|
245238
245532
|
if (!pomXml) {
|
|
245239
245533
|
return void 0;
|
|
@@ -245246,7 +245540,15 @@ function readMavenMetadata(workspaceRoot, componentPath) {
|
|
|
245246
245540
|
artifactId: readFirstXmlTag(normalizedPom, "artifactId"),
|
|
245247
245541
|
name: readFirstXmlTag(normalizedPom, "name"),
|
|
245248
245542
|
hasPom: true,
|
|
245543
|
+
hasModules: /<modules\b/iu.test(normalizedPom),
|
|
245249
245544
|
hasDependencyManagement: /<dependencyManagement\b/iu.test(normalizedPom),
|
|
245545
|
+
hasSpringBootPlugin: /\bspring-boot-maven-plugin\b/iu.test(normalizedPom),
|
|
245546
|
+
hasSpringBootRepackageGoal: /<goal>\s*repackage\s*<\/goal>/iu.test(normalizedPom),
|
|
245547
|
+
configuredMainClass: readFirstXmlTag(normalizedPom, "mainClass") ?? readFirstXmlTag(normalizedPom, "start-class"),
|
|
245548
|
+
hasSpringBootStarterDependency: dependencyBlocks.some((block) => /<artifactId>\s*spring-boot-starter(?:-[^<]+)?\s*<\/artifactId>/iu.test(block)),
|
|
245549
|
+
hasSpringBootAutoconfigureDependency: dependencyBlocks.some((block) => /<artifactId>\s*spring-boot-autoconfigure\s*<\/artifactId>/iu.test(block)),
|
|
245550
|
+
hasSpringBootAutoconfigureProcessor: /spring-boot-autoconfigure-processor|spring-boot-configuration-processor/iu.test(normalizedPom),
|
|
245551
|
+
hasDocumentationTooling: /asciidoctor-maven-plugin|maven-site-plugin|doxia|antora|javadoc|<goal>\s*site\s*<\/goal>/iu.test(normalizedPom),
|
|
245250
245552
|
testScopedDependencyCount: dependencyBlocks.filter((block) => /<scope>\s*test\s*<\/scope>/iu.test(block)).length,
|
|
245251
245553
|
totalDependencyCount: dependencyBlocks.length,
|
|
245252
245554
|
hasMavenPluginConfiguration: packaging === "maven-plugin" || /maven-plugin-plugin|<goalPrefix>|<mojo/iu.test(normalizedPom),
|
|
@@ -245329,21 +245631,384 @@ function resolveId(componentPath, usedIds) {
|
|
|
245329
245631
|
usedIds.add(id);
|
|
245330
245632
|
return id;
|
|
245331
245633
|
}
|
|
245332
|
-
function
|
|
245634
|
+
function hasRunnableFrontendComponentEvidence(workspaceRoot, componentPath) {
|
|
245635
|
+
const absoluteRoot = componentPath === "." ? workspaceRoot : path64.join(workspaceRoot, ...componentPath.split("/"));
|
|
245636
|
+
const packageJson = readPackageJson(workspaceRoot, componentPath);
|
|
245637
|
+
const dependencies = [
|
|
245638
|
+
...recordKeys(packageJson?.dependencies),
|
|
245639
|
+
...recordKeys(packageJson?.devDependencies)
|
|
245640
|
+
];
|
|
245641
|
+
const scripts = recordKeys(packageJson?.scripts);
|
|
245642
|
+
const hasFrontendFramework = dependencies.some(
|
|
245643
|
+
(dependency) => /^(?:react|next|vue|@angular\/core|@sveltejs\/kit)$/u.test(dependency)
|
|
245644
|
+
);
|
|
245645
|
+
const hasInteractiveRunnableScript = scripts.some(
|
|
245646
|
+
(script) => /^(?:dev|start|serve|preview)(?::|$)/u.test(script)
|
|
245647
|
+
);
|
|
245648
|
+
const hasBundlerConfig = [
|
|
245649
|
+
"next.config.js",
|
|
245650
|
+
"next.config.ts",
|
|
245651
|
+
"vite.config.js",
|
|
245652
|
+
"vite.config.ts",
|
|
245653
|
+
"angular.json"
|
|
245654
|
+
].some((relativePath) => pathExists19(path64.join(absoluteRoot, ...relativePath.split("/"))));
|
|
245655
|
+
const hasApplicationEntry = [
|
|
245656
|
+
"index.html",
|
|
245657
|
+
"src/main.tsx",
|
|
245658
|
+
"src/main.ts",
|
|
245659
|
+
"src/App.tsx",
|
|
245660
|
+
"src/app",
|
|
245661
|
+
"pages"
|
|
245662
|
+
].some((relativePath) => pathExists19(path64.join(absoluteRoot, ...relativePath.split("/"))));
|
|
245663
|
+
return hasFrontendFramework && (hasApplicationEntry || hasInteractiveRunnableScript && hasBundlerConfig);
|
|
245664
|
+
}
|
|
245665
|
+
function isUnderJvmResourceRoot4(componentPath) {
|
|
245666
|
+
return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizePath25(componentPath).toLowerCase());
|
|
245667
|
+
}
|
|
245668
|
+
function hasFileUnderRoot(root, pattern) {
|
|
245669
|
+
if (!pathExists19(root)) {
|
|
245670
|
+
return false;
|
|
245671
|
+
}
|
|
245672
|
+
const entries = fs58.readdirSync(root, { recursive: true, withFileTypes: true });
|
|
245673
|
+
return entries.some((entry) => entry.isFile() && pattern.test(entry.name));
|
|
245674
|
+
}
|
|
245675
|
+
var javaMainMethodPattern = /\bpublic\s+static\s+void\s+main\s*\(\s*String\s*(?:(?:\[\s*\]\s*)|\.\.\.\s*)[A-Za-z_$][\w$]*\s*(?:\[\s*\])?\s*\)/u;
|
|
245676
|
+
function stripJavaLikeCommentsAndStrings(value) {
|
|
245677
|
+
let result = "";
|
|
245678
|
+
let index = 0;
|
|
245679
|
+
let state = "code";
|
|
245680
|
+
while (index < value.length) {
|
|
245681
|
+
const current = value[index] ?? "";
|
|
245682
|
+
const next = value[index + 1] ?? "";
|
|
245683
|
+
const nextTwo = value.slice(index, index + 3);
|
|
245684
|
+
if (state === "code") {
|
|
245685
|
+
if (current === "/" && next === "/") {
|
|
245686
|
+
result += " ";
|
|
245687
|
+
index += 2;
|
|
245688
|
+
state = "line-comment";
|
|
245689
|
+
continue;
|
|
245690
|
+
}
|
|
245691
|
+
if (current === "/" && next === "*") {
|
|
245692
|
+
result += " ";
|
|
245693
|
+
index += 2;
|
|
245694
|
+
state = "block-comment";
|
|
245695
|
+
continue;
|
|
245696
|
+
}
|
|
245697
|
+
if (nextTwo === '"""') {
|
|
245698
|
+
result += " ";
|
|
245699
|
+
index += 3;
|
|
245700
|
+
state = "text-block";
|
|
245701
|
+
continue;
|
|
245702
|
+
}
|
|
245703
|
+
if (current === '"') {
|
|
245704
|
+
result += " ";
|
|
245705
|
+
index += 1;
|
|
245706
|
+
state = "string";
|
|
245707
|
+
continue;
|
|
245708
|
+
}
|
|
245709
|
+
if (current === "'") {
|
|
245710
|
+
result += " ";
|
|
245711
|
+
index += 1;
|
|
245712
|
+
state = "char";
|
|
245713
|
+
continue;
|
|
245714
|
+
}
|
|
245715
|
+
result += current;
|
|
245716
|
+
index += 1;
|
|
245717
|
+
continue;
|
|
245718
|
+
}
|
|
245719
|
+
if (state === "line-comment") {
|
|
245720
|
+
result += current === "\n" || current === "\r" ? current : " ";
|
|
245721
|
+
index += 1;
|
|
245722
|
+
if (current === "\n") {
|
|
245723
|
+
state = "code";
|
|
245724
|
+
}
|
|
245725
|
+
continue;
|
|
245726
|
+
}
|
|
245727
|
+
if (state === "block-comment") {
|
|
245728
|
+
if (current === "*" && next === "/") {
|
|
245729
|
+
result += " ";
|
|
245730
|
+
index += 2;
|
|
245731
|
+
state = "code";
|
|
245732
|
+
continue;
|
|
245733
|
+
}
|
|
245734
|
+
result += current === "\n" || current === "\r" ? current : " ";
|
|
245735
|
+
index += 1;
|
|
245736
|
+
continue;
|
|
245737
|
+
}
|
|
245738
|
+
if (state === "text-block") {
|
|
245739
|
+
if (nextTwo === '"""') {
|
|
245740
|
+
result += " ";
|
|
245741
|
+
index += 3;
|
|
245742
|
+
state = "code";
|
|
245743
|
+
continue;
|
|
245744
|
+
}
|
|
245745
|
+
result += current === "\n" || current === "\r" ? current : " ";
|
|
245746
|
+
index += 1;
|
|
245747
|
+
continue;
|
|
245748
|
+
}
|
|
245749
|
+
if (state === "string") {
|
|
245750
|
+
if (current === "\\") {
|
|
245751
|
+
result += " ";
|
|
245752
|
+
index += next ? 2 : 1;
|
|
245753
|
+
if (next) {
|
|
245754
|
+
result += " ";
|
|
245755
|
+
}
|
|
245756
|
+
continue;
|
|
245757
|
+
}
|
|
245758
|
+
result += current === "\n" || current === "\r" ? current : " ";
|
|
245759
|
+
index += 1;
|
|
245760
|
+
if (current === '"') {
|
|
245761
|
+
state = "code";
|
|
245762
|
+
}
|
|
245763
|
+
continue;
|
|
245764
|
+
}
|
|
245765
|
+
if (current === "\\") {
|
|
245766
|
+
result += " ";
|
|
245767
|
+
index += next ? 2 : 1;
|
|
245768
|
+
if (next) {
|
|
245769
|
+
result += " ";
|
|
245770
|
+
}
|
|
245771
|
+
continue;
|
|
245772
|
+
}
|
|
245773
|
+
result += current === "\n" || current === "\r" ? current : " ";
|
|
245774
|
+
index += 1;
|
|
245775
|
+
if (current === "'") {
|
|
245776
|
+
state = "code";
|
|
245777
|
+
}
|
|
245778
|
+
}
|
|
245779
|
+
return result;
|
|
245780
|
+
}
|
|
245781
|
+
function readMavenProductionSourceFiles(workspaceRoot, componentPath) {
|
|
245782
|
+
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
245783
|
+
const mainRoots = [
|
|
245784
|
+
path64.join(absoluteRoot, "src", "main", "java"),
|
|
245785
|
+
path64.join(absoluteRoot, "src", "main", "kotlin"),
|
|
245786
|
+
path64.join(absoluteRoot, "src", "main", "scala")
|
|
245787
|
+
];
|
|
245788
|
+
const files = [];
|
|
245789
|
+
for (const sourceRoot of mainRoots) {
|
|
245790
|
+
if (!pathExists19(sourceRoot)) {
|
|
245791
|
+
continue;
|
|
245792
|
+
}
|
|
245793
|
+
const entries = fs58.readdirSync(sourceRoot, { recursive: true, withFileTypes: true });
|
|
245794
|
+
for (const entry of entries) {
|
|
245795
|
+
if (!entry.isFile() || !/\.(?:java|kt|scala)$/iu.test(entry.name)) {
|
|
245796
|
+
continue;
|
|
245797
|
+
}
|
|
245798
|
+
const contents = readTextFileSafe(path64.join(entry.parentPath, entry.name));
|
|
245799
|
+
if (contents) {
|
|
245800
|
+
files.push({ fileName: entry.name, contents });
|
|
245801
|
+
}
|
|
245802
|
+
}
|
|
245803
|
+
}
|
|
245804
|
+
return files;
|
|
245805
|
+
}
|
|
245806
|
+
function findMatchingBrace6(value, openBraceIndex) {
|
|
245807
|
+
let depth = 0;
|
|
245808
|
+
for (let index = openBraceIndex; index < value.length; index += 1) {
|
|
245809
|
+
const current = value[index];
|
|
245810
|
+
if (current === "{") {
|
|
245811
|
+
depth += 1;
|
|
245812
|
+
} else if (current === "}") {
|
|
245813
|
+
depth -= 1;
|
|
245814
|
+
if (depth === 0) {
|
|
245815
|
+
return index;
|
|
245816
|
+
}
|
|
245817
|
+
}
|
|
245818
|
+
}
|
|
245819
|
+
return -1;
|
|
245820
|
+
}
|
|
245821
|
+
function getDeclaredPackageName(value) {
|
|
245822
|
+
return value.match(/\bpackage\s+([a-zA-Z_$][\w$]*(?:\.[a-zA-Z_$][\w$]*)*)\s*;/u)?.[1];
|
|
245823
|
+
}
|
|
245824
|
+
function classNameMatchesConfiguredMainClass(className, packageName, configuredMainClass) {
|
|
245825
|
+
const normalized = configuredMainClass.trim();
|
|
245826
|
+
if (normalized.length === 0) {
|
|
245827
|
+
return false;
|
|
245828
|
+
}
|
|
245829
|
+
return normalized === className || (packageName ? normalized === `${packageName}.${className}` : false);
|
|
245830
|
+
}
|
|
245831
|
+
function normalizeAnnotationName(value) {
|
|
245832
|
+
return value.slice(value.lastIndexOf(".") + 1);
|
|
245833
|
+
}
|
|
245834
|
+
function hasAnnotation(annotations, annotationNames) {
|
|
245835
|
+
return annotations.some((annotation) => annotationNames.has(normalizeAnnotationName(annotation)));
|
|
245836
|
+
}
|
|
245837
|
+
function extractAnnotations(annotationBlock) {
|
|
245838
|
+
return [...annotationBlock.matchAll(/@\s*([A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*)/gu)].map((match) => match[1]).filter((annotation) => Boolean(annotation));
|
|
245839
|
+
}
|
|
245840
|
+
function extractConcreteClassDeclarations(contents) {
|
|
245841
|
+
const sanitized = stripJavaLikeCommentsAndStrings(contents);
|
|
245842
|
+
const packageName = getDeclaredPackageName(sanitized);
|
|
245843
|
+
const classPattern = /((?:@\s*[\w.]+(?:\s*\([^)]*\))?\s*)*)(?:public\s+|protected\s+|private\s+|abstract\s+|final\s+|sealed\s+|non-sealed\s+|static\s+)*class\s+([A-Za-z_$][\w$]*)[^{]*\{/gu;
|
|
245844
|
+
const declarations = [];
|
|
245845
|
+
for (const match of sanitized.matchAll(classPattern)) {
|
|
245846
|
+
const annotationBlock = match[1] ?? "";
|
|
245847
|
+
const className = match[2] ?? "";
|
|
245848
|
+
const openBraceIndex = (match.index ?? 0) + match[0].length - 1;
|
|
245849
|
+
const closeBraceIndex = findMatchingBrace6(sanitized, openBraceIndex);
|
|
245850
|
+
if (closeBraceIndex < 0) {
|
|
245851
|
+
continue;
|
|
245852
|
+
}
|
|
245853
|
+
declarations.push({
|
|
245854
|
+
className,
|
|
245855
|
+
...packageName ? { packageName } : {},
|
|
245856
|
+
annotations: extractAnnotations(annotationBlock),
|
|
245857
|
+
body: sanitized.slice(openBraceIndex + 1, closeBraceIndex)
|
|
245858
|
+
});
|
|
245859
|
+
}
|
|
245860
|
+
return declarations;
|
|
245861
|
+
}
|
|
245862
|
+
function extractApplicationAnnotationNames(sourceFiles) {
|
|
245863
|
+
const applicationAnnotations = /* @__PURE__ */ new Set(["SpringBootApplication"]);
|
|
245864
|
+
let changed = true;
|
|
245865
|
+
while (changed) {
|
|
245866
|
+
changed = false;
|
|
245867
|
+
for (const sourceFile of sourceFiles) {
|
|
245868
|
+
const sanitized = stripJavaLikeCommentsAndStrings(sourceFile.contents);
|
|
245869
|
+
const annotationPattern = /((?:@\s*[\w.]+(?:\s*\([^)]*\))?\s*)*)public\s+@interface\s+([A-Za-z_$][\w$]*)\b/gu;
|
|
245870
|
+
for (const match of sanitized.matchAll(annotationPattern)) {
|
|
245871
|
+
const annotations = extractAnnotations(match[1] ?? "");
|
|
245872
|
+
const annotationName = match[2];
|
|
245873
|
+
if (annotationName && !applicationAnnotations.has(annotationName) && hasAnnotation(annotations, applicationAnnotations)) {
|
|
245874
|
+
applicationAnnotations.add(annotationName);
|
|
245875
|
+
changed = true;
|
|
245876
|
+
}
|
|
245877
|
+
}
|
|
245878
|
+
}
|
|
245879
|
+
}
|
|
245880
|
+
return applicationAnnotations;
|
|
245881
|
+
}
|
|
245882
|
+
function hasSpringApplicationRunForClass(body, className) {
|
|
245883
|
+
return new RegExp(`\\bSpringApplication\\.run\\s*\\(\\s*${className}\\.class\\b`, "u").test(body);
|
|
245884
|
+
}
|
|
245885
|
+
function hasIndirectSpringApplicationRunForClass(body, className) {
|
|
245886
|
+
const helperCalls = [...body.matchAll(/\b([A-Za-z_$][\w$]*)\s*\(\s*([A-Za-z_$][\w$]*)\.class\s*,/gu)].filter((match) => match[2] === className).map((match) => match[1]).filter((methodName) => Boolean(methodName));
|
|
245887
|
+
return helperCalls.some(
|
|
245888
|
+
(methodName) => new RegExp(`\\b${methodName}\\s*\\([^)]*\\)\\s*\\{[\\s\\S]*?\\bSpringApplication\\.run\\s*\\(`, "u").test(body)
|
|
245889
|
+
);
|
|
245890
|
+
}
|
|
245891
|
+
function hasConcreteSpringBootApplicationBootstrap(sourceFiles) {
|
|
245892
|
+
const applicationAnnotations = extractApplicationAnnotationNames(sourceFiles);
|
|
245893
|
+
const declarations = sourceFiles.flatMap((sourceFile) => extractConcreteClassDeclarations(sourceFile.contents));
|
|
245894
|
+
const applicationClassNames = new Set(
|
|
245895
|
+
declarations.filter((declaration) => hasAnnotation(declaration.annotations, applicationAnnotations)).map((declaration) => declaration.className)
|
|
245896
|
+
);
|
|
245897
|
+
if (applicationClassNames.size === 0) {
|
|
245898
|
+
return false;
|
|
245899
|
+
}
|
|
245900
|
+
const hasLauncherForApplicationClass = (declaration) => javaMainMethodPattern.test(declaration.body) && [...applicationClassNames].some(
|
|
245901
|
+
(applicationClassName) => hasSpringApplicationRunForClass(declaration.body, applicationClassName) || applicationClassName === declaration.className && hasIndirectSpringApplicationRunForClass(declaration.body, applicationClassName)
|
|
245902
|
+
);
|
|
245903
|
+
if (declarations.some(hasLauncherForApplicationClass)) {
|
|
245904
|
+
return true;
|
|
245905
|
+
}
|
|
245906
|
+
for (const sourceFile of sourceFiles) {
|
|
245907
|
+
for (const declaration of extractConcreteClassDeclarations(sourceFile.contents)) {
|
|
245908
|
+
if (!hasAnnotation(declaration.annotations, applicationAnnotations)) {
|
|
245909
|
+
continue;
|
|
245910
|
+
}
|
|
245911
|
+
if (javaMainMethodPattern.test(declaration.body) && (hasSpringApplicationRunForClass(declaration.body, declaration.className) || hasIndirectSpringApplicationRunForClass(declaration.body, declaration.className))) {
|
|
245912
|
+
return true;
|
|
245913
|
+
}
|
|
245914
|
+
}
|
|
245915
|
+
}
|
|
245916
|
+
return false;
|
|
245917
|
+
}
|
|
245918
|
+
function hasConfiguredMainClassEntrypoint(contents, configuredMainClass) {
|
|
245919
|
+
for (const declaration of extractConcreteClassDeclarations(contents)) {
|
|
245920
|
+
if (!classNameMatchesConfiguredMainClass(declaration.className, declaration.packageName, configuredMainClass)) {
|
|
245921
|
+
continue;
|
|
245922
|
+
}
|
|
245923
|
+
if (javaMainMethodPattern.test(declaration.body)) {
|
|
245924
|
+
return true;
|
|
245925
|
+
}
|
|
245926
|
+
}
|
|
245927
|
+
return false;
|
|
245928
|
+
}
|
|
245929
|
+
function hasMavenMainEntrypoint(workspaceRoot, componentPath) {
|
|
245930
|
+
return hasConcreteSpringBootApplicationBootstrap(readMavenProductionSourceFiles(workspaceRoot, componentPath));
|
|
245931
|
+
}
|
|
245932
|
+
function hasMavenConfiguredMainClassEntrypoint(workspaceRoot, componentPath, configuredMainClass) {
|
|
245933
|
+
if (!configuredMainClass) {
|
|
245934
|
+
return false;
|
|
245935
|
+
}
|
|
245936
|
+
return readMavenProductionSourceFiles(workspaceRoot, componentPath).some((sourceFile) => hasConfiguredMainClassEntrypoint(sourceFile.contents, configuredMainClass));
|
|
245937
|
+
}
|
|
245938
|
+
function hasMavenAutoConfigurationMetadata(workspaceRoot, componentPath) {
|
|
245939
|
+
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
245940
|
+
return [
|
|
245941
|
+
path64.join(absoluteRoot, "src", "main", "resources", "META-INF", "spring.factories"),
|
|
245942
|
+
path64.join(absoluteRoot, "src", "main", "resources", "META-INF", "spring", "org.springframework.boot.autoconfigure.AutoConfiguration.imports")
|
|
245943
|
+
].some(pathExists19);
|
|
245944
|
+
}
|
|
245945
|
+
function hasMavenMainJvmSource(workspaceRoot, componentPath) {
|
|
245946
|
+
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
245947
|
+
return [
|
|
245948
|
+
path64.join(absoluteRoot, "src", "main", "java"),
|
|
245949
|
+
path64.join(absoluteRoot, "src", "main", "kotlin"),
|
|
245950
|
+
path64.join(absoluteRoot, "src", "main", "scala")
|
|
245951
|
+
].some((root) => hasFileUnderRoot(root, /\.(?:java|kt|scala)$/iu));
|
|
245952
|
+
}
|
|
245953
|
+
function hasRuntimeSourceFiles(workspaceRoot, componentPath) {
|
|
245954
|
+
if (isUnderJvmResourceRoot4(componentPath)) {
|
|
245955
|
+
return false;
|
|
245956
|
+
}
|
|
245957
|
+
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
245958
|
+
const sourceRoots = [
|
|
245959
|
+
path64.join(absoluteRoot, "src", "main", "java"),
|
|
245960
|
+
path64.join(absoluteRoot, "src"),
|
|
245961
|
+
path64.join(absoluteRoot, "app"),
|
|
245962
|
+
path64.join(absoluteRoot, "server")
|
|
245963
|
+
];
|
|
245964
|
+
for (const sourceRoot of sourceRoots) {
|
|
245965
|
+
if (!pathExists19(sourceRoot)) {
|
|
245966
|
+
continue;
|
|
245967
|
+
}
|
|
245968
|
+
const entries = fs58.readdirSync(sourceRoot, { recursive: true, withFileTypes: true });
|
|
245969
|
+
if (entries.some((entry) => entry.isFile() && /\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/iu.test(entry.name))) {
|
|
245970
|
+
return true;
|
|
245971
|
+
}
|
|
245972
|
+
}
|
|
245973
|
+
return false;
|
|
245974
|
+
}
|
|
245975
|
+
function resolveKind(workspaceRoot, candidate, localProjectKinds) {
|
|
245333
245976
|
const lowerPath = candidate.path.toLowerCase();
|
|
245977
|
+
const packageJson = readPackageJson(workspaceRoot, candidate.path);
|
|
245978
|
+
const maven = readMavenMetadata(workspaceRoot, candidate.path);
|
|
245979
|
+
const hasRunnableFrontendEvidence = hasRunnableFrontendComponentEvidence(workspaceRoot, candidate.path);
|
|
245980
|
+
const hasPublishSurface = hasPackagePublishSurface(packageJson);
|
|
245981
|
+
const hasMavenRunnableEvidence = Boolean(
|
|
245982
|
+
maven && (hasMavenMainEntrypoint(workspaceRoot, candidate.path) || hasMavenConfiguredMainClassEntrypoint(workspaceRoot, candidate.path, maven.configuredMainClass) || maven.hasSpringBootPlugin && maven.hasSpringBootRepackageGoal && hasMavenMainEntrypoint(workspaceRoot, candidate.path) || maven.packaging === "war" && hasMavenMainEntrypoint(workspaceRoot, candidate.path))
|
|
245983
|
+
);
|
|
245984
|
+
const hasMavenLibraryEvidence = Boolean(
|
|
245985
|
+
maven && !hasMavenRunnableEvidence && (maven.packaging === "jar" || maven.packaging === "maven-plugin" || maven.packaging === "pom") && (hasMavenMainJvmSource(workspaceRoot, candidate.path) || maven.hasMainResources || maven.hasDependencyManagement || maven.hasSpringBootAutoconfigureDependency || maven.hasSpringBootAutoconfigureProcessor || hasMavenAutoConfigurationMetadata(workspaceRoot, candidate.path) || maven.hasDocumentationTooling || maven.hasTestJava || maven.hasTestResources)
|
|
245986
|
+
);
|
|
245334
245987
|
if (lowerPath.endsWith("/db") || lowerPath.endsWith("/database") || lowerPath.endsWith("/data")) {
|
|
245335
245988
|
return "data";
|
|
245336
245989
|
}
|
|
245990
|
+
if (hasMavenLibraryEvidence) {
|
|
245991
|
+
return "library";
|
|
245992
|
+
}
|
|
245993
|
+
if (maven && !hasMavenRunnableEvidence && localProjectKinds.primaryKind === "backend") {
|
|
245994
|
+
return "library";
|
|
245995
|
+
}
|
|
245337
245996
|
const classification = candidate.architectureRoot?.classification;
|
|
245338
245997
|
if (classification === "frontend_app") {
|
|
245339
|
-
return "frontend";
|
|
245998
|
+
return hasPublishSurface && !hasRunnableFrontendEvidence ? "library" : "frontend";
|
|
245340
245999
|
}
|
|
245341
246000
|
if (classification === "backend_app") {
|
|
245342
246001
|
return "backend";
|
|
245343
246002
|
}
|
|
246003
|
+
if (hasRunnableFrontendEvidence && localProjectKinds.primaryKind !== "backend" && localProjectKinds.primaryKind !== "service" && localProjectKinds.primaryKind !== "cli") {
|
|
246004
|
+
return "frontend";
|
|
246005
|
+
}
|
|
245344
246006
|
if (classification === "shared_package") {
|
|
245345
246007
|
return "library";
|
|
245346
246008
|
}
|
|
246009
|
+
if (hasPublishSurface && !hasRunnableFrontendEvidence) {
|
|
246010
|
+
return "library";
|
|
246011
|
+
}
|
|
245347
246012
|
if (localProjectKinds.primaryKind === "service") {
|
|
245348
246013
|
return "worker";
|
|
245349
246014
|
}
|
|
@@ -245412,15 +246077,21 @@ function classifyGovernanceRole(input2) {
|
|
|
245412
246077
|
const scriptText = scripts.join(" ").toLowerCase();
|
|
245413
246078
|
const dependencyText = [...dependencies, ...devDependencies].join(" ").toLowerCase();
|
|
245414
246079
|
const hasStrongSupportPath = hasAnyToken(pathText, [
|
|
245415
|
-
/(^|\/)(testing|test-plugins|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
|
|
246080
|
+
/(^|\/)(testing|test-plugins|cypress-tests|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
|
|
245416
246081
|
/(^|\/)(dev-server|scaffold|scaffolding|generators?|devkit|tooling|tools)(\/|$)/u
|
|
245417
246082
|
]);
|
|
245418
|
-
const
|
|
246083
|
+
const isPlainResourcesSurface = isUnderJvmResourceRoot4(pathText) && !hasRuntimeSourceFiles(input2.workspaceRoot, input2.candidate.path) && !packageJson && !maven;
|
|
246084
|
+
const hasPublishSurface = hasPackagePublishSurface(packageJson);
|
|
245419
246085
|
const isPrivate = packageJson?.private === true;
|
|
245420
246086
|
const hasBin = hasObject(packageJson?.bin) || typeof packageJson?.bin === "string";
|
|
245421
246087
|
const mavenMetadataText = `${maven?.artifactId ?? ""} ${maven?.name ?? ""}`.toLowerCase();
|
|
245422
246088
|
const hasMavenMainSource = Boolean(maven?.hasMainJava || maven?.hasMainResources);
|
|
245423
246089
|
const hasMavenTestSource = Boolean(maven?.hasTestJava || maven?.hasTestResources);
|
|
246090
|
+
const hasMavenMainEntrypointEvidence = Boolean(maven && hasMavenMainEntrypoint(input2.workspaceRoot, input2.candidate.path));
|
|
246091
|
+
const hasMavenMainJvmSourceEvidence = Boolean(maven && hasMavenMainJvmSource(input2.workspaceRoot, input2.candidate.path));
|
|
246092
|
+
const hasMavenAutoConfigurationEvidence = Boolean(maven && (hasMavenAutoConfigurationMetadata(input2.workspaceRoot, input2.candidate.path) || maven.hasSpringBootAutoconfigureDependency || maven.hasSpringBootAutoconfigureProcessor));
|
|
246093
|
+
const hasMavenExecutableConfiguration = Boolean(maven && (hasMavenConfiguredMainClassEntrypoint(input2.workspaceRoot, input2.candidate.path, maven.configuredMainClass) || maven.hasSpringBootPlugin && maven.hasSpringBootRepackageGoal && hasMavenMainEntrypointEvidence || maven.packaging === "war" && hasMavenMainEntrypointEvidence));
|
|
246094
|
+
const hasMavenRunnableApplicationEvidence = Boolean(hasMavenMainEntrypointEvidence || hasMavenExecutableConfiguration);
|
|
245424
246095
|
const isMavenPomOnly = Boolean(maven?.packaging === "pom" && !hasMavenMainSource && !hasMavenTestSource);
|
|
245425
246096
|
const hasMavenTestContext = hasAnyToken(pathText, [
|
|
245426
246097
|
/(^|\/)(test-framework|testsuite|integration-tests?|test-apps)(\/|$)/u
|
|
@@ -245459,17 +246130,19 @@ function classifyGovernanceRole(input2) {
|
|
|
245459
246130
|
if (maven?.hasPom) {
|
|
245460
246131
|
addEvidence6(evidence, `Maven packaging ${maven.packaging ?? "jar"}`);
|
|
245461
246132
|
}
|
|
245462
|
-
if (maven && (maven.packaging === "jar" || maven.packaging === "war") &&
|
|
246133
|
+
if (maven && (maven.packaging === "jar" || maven.packaging === "war") && hasMavenRunnableApplicationEvidence) {
|
|
245463
246134
|
runtimeScore += 3;
|
|
245464
|
-
addEvidence6(evidence, "Maven
|
|
246135
|
+
addEvidence6(evidence, "Maven executable application evidence");
|
|
245465
246136
|
}
|
|
245466
|
-
if (maven?.packaging === "war" &&
|
|
246137
|
+
if (maven?.packaging === "war" && hasMavenMainJvmSourceEvidence) {
|
|
245467
246138
|
runtimeScore += 1;
|
|
245468
246139
|
addEvidence6(evidence, "Maven deployable WAR artifact");
|
|
245469
246140
|
}
|
|
245470
|
-
if (maven && hasMavenMainSource && !hasMavenTestContext && !hasMavenBomEvidence && maven.packaging !== "maven-plugin") {
|
|
245471
|
-
|
|
245472
|
-
|
|
246141
|
+
if (maven && hasMavenMainSource && !hasMavenRunnableApplicationEvidence && !hasMavenTestContext && !hasMavenBomEvidence && maven.packaging !== "maven-plugin") {
|
|
246142
|
+
addEvidence6(evidence, "Maven library main source/resource surface");
|
|
246143
|
+
}
|
|
246144
|
+
if (hasMavenAutoConfigurationEvidence && !hasMavenRunnableApplicationEvidence) {
|
|
246145
|
+
addEvidence6(evidence, "Maven Spring Boot auto-configuration/starter library evidence");
|
|
245473
246146
|
}
|
|
245474
246147
|
if (hasAnyToken(descriptiveManifestText, [/\b(e2e|end-to-end|testing|test helper|test utilities|fixtures?)\b/u])) {
|
|
245475
246148
|
supportScore += 3;
|
|
@@ -245484,7 +246157,7 @@ function classifyGovernanceRole(input2) {
|
|
|
245484
246157
|
addEvidence6(evidence, "Package metadata describes development/tooling usage");
|
|
245485
246158
|
}
|
|
245486
246159
|
if (hasAnyToken(pathText, [
|
|
245487
|
-
/(^|\/)(test|tests|testing|__tests__|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
|
|
246160
|
+
/(^|\/)(test|tests|testing|__tests__|cypress|cypress-tests|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
|
|
245488
246161
|
/(^|\/)(dev-server|test-plugins|scaffold|scaffolding|generators?|devkit|tooling|tools)(\/|$)/u
|
|
245489
246162
|
])) {
|
|
245490
246163
|
supportScore += 1;
|
|
@@ -245510,6 +246183,10 @@ function classifyGovernanceRole(input2) {
|
|
|
245510
246183
|
supportScore += 5;
|
|
245511
246184
|
addEvidence6(evidence, "Maven plugin/build-tooling module");
|
|
245512
246185
|
}
|
|
246186
|
+
if (maven?.hasDocumentationTooling && !hasMavenMainJvmSourceEvidence) {
|
|
246187
|
+
supportScore += 4;
|
|
246188
|
+
addEvidence6(evidence, "Maven documentation tooling without JVM runtime source");
|
|
246189
|
+
}
|
|
245513
246190
|
if (hasMavenBomEvidence) {
|
|
245514
246191
|
supportScore += 5;
|
|
245515
246192
|
addEvidence6(evidence, "Maven BOM/dependency-management module without runtime source");
|
|
@@ -245534,6 +246211,17 @@ function classifyGovernanceRole(input2) {
|
|
|
245534
246211
|
supportScore += 1;
|
|
245535
246212
|
addEvidence6(evidence, "Maven POM-only aggregator/packaging module");
|
|
245536
246213
|
}
|
|
246214
|
+
if (isPlainResourcesSurface) {
|
|
246215
|
+
supportScore += 4;
|
|
246216
|
+
addEvidence6(evidence, "Resources-only surface without runtime source or manifest evidence");
|
|
246217
|
+
}
|
|
246218
|
+
if (isPlainResourcesSurface && input2.kind !== "infrastructure" && input2.stack !== "terraform" && input2.stack !== "ansible") {
|
|
246219
|
+
return {
|
|
246220
|
+
governanceRole: "support",
|
|
246221
|
+
governanceEvidence: uniqueSorted4(evidence),
|
|
246222
|
+
selectedByDefault: false
|
|
246223
|
+
};
|
|
246224
|
+
}
|
|
245537
246225
|
if (hasMavenDistributionPackagingEvidence && hasAnyToken(mavenMetadataText, [/\b(docs?|documentation|metadata tests?|licenses?|maven plugins?|builds?)\b/u])) {
|
|
245538
246226
|
supportScore += 3;
|
|
245539
246227
|
addEvidence6(evidence, "Maven documentation/build/distribution packaging evidence without runtime source");
|
|
@@ -245547,9 +246235,9 @@ function classifyGovernanceRole(input2) {
|
|
|
245547
246235
|
}
|
|
245548
246236
|
if (maven && (isMavenPomOnly || hasMavenDistributionPackagingEvidence) && supportScore >= 1) {
|
|
245549
246237
|
return {
|
|
245550
|
-
governanceRole: "
|
|
246238
|
+
governanceRole: "support",
|
|
245551
246239
|
governanceEvidence: uniqueSorted4(evidence),
|
|
245552
|
-
selectedByDefault:
|
|
246240
|
+
selectedByDefault: false
|
|
245553
246241
|
};
|
|
245554
246242
|
}
|
|
245555
246243
|
if (runtimeScore >= 2) {
|
|
@@ -245590,8 +246278,10 @@ function maybeAddAttributedApiAndDb(component, workspaceRoot, componentPath, arc
|
|
|
245590
246278
|
}
|
|
245591
246279
|
function detectComponents(input2) {
|
|
245592
246280
|
const ignoreMatcher = input2.ignoreMatcher ?? loadArchpilotIgnoreMatcher(input2.workspaceRoot);
|
|
245593
|
-
const manifestBackedRoots = new Set(
|
|
245594
|
-
|
|
246281
|
+
const manifestBackedRoots = new Set(
|
|
246282
|
+
(input2.topology.detectedRoots ?? []).filter((root) => !isUnderJvmResourceRoot4(root))
|
|
246283
|
+
);
|
|
246284
|
+
const rootCandidates = buildRootCandidates(input2).filter((candidate) => !ignoreMatcher.isIgnored(candidate.path)).filter((candidate) => !isIgnoredComponentCandidatePath(candidate.path)).filter((candidate) => !(isUnderJvmResourceRoot4(candidate.path) && !hasRuntimeSourceFiles(input2.workspaceRoot, candidate.path))).filter((candidate) => {
|
|
245595
246285
|
if (input2.topology.topology !== "monorepo" || manifestBackedRoots.size === 0) {
|
|
245596
246286
|
return true;
|
|
245597
246287
|
}
|
|
@@ -245614,7 +246304,7 @@ function detectComponents(input2) {
|
|
|
245614
246304
|
}
|
|
245615
246305
|
const localProjectKinds = input2.runContext?.detectProjectKinds(absoluteRoot) ?? detectProjectKinds(absoluteRoot);
|
|
245616
246306
|
const stackDetection = input2.runContext?.detectStacks(absoluteRoot) ?? detectStacks(absoluteRoot);
|
|
245617
|
-
const kind = resolveKind(candidate, localProjectKinds);
|
|
246307
|
+
const kind = resolveKind(input2.workspaceRoot, candidate, localProjectKinds);
|
|
245618
246308
|
const stack = resolveStack(kind, stackDetection);
|
|
245619
246309
|
const evidence = [...candidate.evidence];
|
|
245620
246310
|
if (candidate.architectureRoot?.classification && candidate.architectureRoot.classification !== "unknown") {
|
|
@@ -245851,6 +246541,10 @@ function getSelectedCandidate(detection) {
|
|
|
245851
246541
|
function getBackendComponents(detection) {
|
|
245852
246542
|
return (detection.detectedComponents ?? []).filter((component) => component.kind === "backend" || component.kind === "worker");
|
|
245853
246543
|
}
|
|
246544
|
+
function getDefaultGovernedBackendComponents(detection) {
|
|
246545
|
+
const components = detection.detectedComponents ?? [];
|
|
246546
|
+
return components.filter((component) => component.kind === "backend" || component.kind === "worker").filter((component) => isDefaultGovernedComponent(component, components));
|
|
246547
|
+
}
|
|
245854
246548
|
function getFrontendComponents(detection) {
|
|
245855
246549
|
return (detection.detectedComponents ?? []).filter((component) => component.kind === "frontend");
|
|
245856
246550
|
}
|
|
@@ -245885,7 +246579,7 @@ function isCliSupportCandidate(component, allComponents) {
|
|
|
245885
246579
|
}
|
|
245886
246580
|
function hasIndependentRuntimeEvidence(component) {
|
|
245887
246581
|
const text = componentEvidenceText(component);
|
|
245888
|
-
return component.governanceRole === "runtime" && (/Maven
|
|
246582
|
+
return component.governanceRole === "runtime" && (/Maven executable application evidence/iu.test(text) || /Maven deployable WAR artifact/iu.test(text) || /Published package surface signal/iu.test(text) && !/Path contains support\/tooling role tokens/iu.test(text));
|
|
245889
246583
|
}
|
|
245890
246584
|
function hasSupportRoleEvidence(component) {
|
|
245891
246585
|
const text = componentEvidenceText(component);
|
|
@@ -245990,7 +246684,8 @@ function resolveProposalComponents(detection) {
|
|
|
245990
246684
|
return components.length > 0 ? components : void 0;
|
|
245991
246685
|
}
|
|
245992
246686
|
function resolveResourceOwnerComponent(detection) {
|
|
245993
|
-
|
|
246687
|
+
const backendComponents = getDefaultGovernedBackendComponents(detection);
|
|
246688
|
+
return backendComponents.find((component) => component.kind === "backend") ?? backendComponents[0];
|
|
245994
246689
|
}
|
|
245995
246690
|
function resourceIdFor(ownerId, suffix) {
|
|
245996
246691
|
if (suffix === "api" && /(^|-)api$/u.test(ownerId)) {
|
|
@@ -246025,7 +246720,7 @@ function resolveProposalResources(input2) {
|
|
|
246025
246720
|
usedIds.add(resource.id);
|
|
246026
246721
|
resources.push(resource);
|
|
246027
246722
|
};
|
|
246028
|
-
for (const component of
|
|
246723
|
+
for (const component of getDefaultGovernedBackendComponents(input2.detection)) {
|
|
246029
246724
|
if (component.apiStyle && component.apiStyle !== "unknown" && component.apiStyle !== "none") {
|
|
246030
246725
|
addResource({
|
|
246031
246726
|
id: resourceIdFor(component.id, "api"),
|