@xylabs/toolchain 7.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/analyze.mjs +140 -0
- package/dist/actions/analyze.mjs.map +1 -0
- package/dist/actions/build.mjs +173 -0
- package/dist/actions/build.mjs.map +1 -0
- package/dist/actions/claude-check.mjs +199 -0
- package/dist/actions/claude-check.mjs.map +1 -0
- package/dist/actions/claude-clean.mjs +70 -0
- package/dist/actions/claude-clean.mjs.map +1 -0
- package/dist/actions/claude-commands.mjs +126 -0
- package/dist/actions/claude-commands.mjs.map +1 -0
- package/dist/actions/claude-rules.mjs +151 -0
- package/dist/actions/claude-rules.mjs.map +1 -0
- package/dist/actions/claude-settings.mjs +99 -0
- package/dist/actions/claude-settings.mjs.map +1 -0
- package/dist/actions/claude-skills.mjs +131 -0
- package/dist/actions/claude-skills.mjs.map +1 -0
- package/dist/actions/clean-docs.mjs +66 -0
- package/dist/actions/clean-docs.mjs.map +1 -0
- package/dist/actions/clean-eslint.mjs +47 -0
- package/dist/actions/clean-eslint.mjs.map +1 -0
- package/dist/actions/clean.mjs +166 -0
- package/dist/actions/clean.mjs.map +1 -0
- package/dist/actions/compile.mjs +184 -0
- package/dist/actions/compile.mjs.map +1 -0
- package/dist/actions/copy-assets.mjs +81 -0
- package/dist/actions/copy-assets.mjs.map +1 -0
- package/dist/actions/cycle.mjs +275 -0
- package/dist/actions/cycle.mjs.map +1 -0
- package/dist/actions/dead.mjs +119 -0
- package/dist/actions/dead.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/checkPackage.mjs +1556 -0
- package/dist/actions/deplint/checkPackage/checkPackage.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/checkPackageTypes.mjs +1 -0
- package/dist/actions/deplint/checkPackage/checkPackageTypes.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/getMismatchedPeerDevVersions.mjs +77 -0
- package/dist/actions/deplint/checkPackage/getMismatchedPeerDevVersions.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/getUnlistedDependencies.mjs +158 -0
- package/dist/actions/deplint/checkPackage/getUnlistedDependencies.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/getUnlistedDevDependencies.mjs +125 -0
- package/dist/actions/deplint/checkPackage/getUnlistedDevDependencies.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/getUnnecessaryPeerDependencies.mjs +207 -0
- package/dist/actions/deplint/checkPackage/getUnnecessaryPeerDependencies.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/getUnsatisfiedPeerDependencies.mjs +318 -0
- package/dist/actions/deplint/checkPackage/getUnsatisfiedPeerDependencies.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/getUnusedDependencies.mjs +163 -0
- package/dist/actions/deplint/checkPackage/getUnusedDependencies.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/getUnusedDevDependencies.mjs +408 -0
- package/dist/actions/deplint/checkPackage/getUnusedDevDependencies.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/getUnusedPeerDependencies.mjs +75 -0
- package/dist/actions/deplint/checkPackage/getUnusedPeerDependencies.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/getWorkspaceVersionProblems.mjs +128 -0
- package/dist/actions/deplint/checkPackage/getWorkspaceVersionProblems.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/index.mjs +1609 -0
- package/dist/actions/deplint/checkPackage/index.mjs.map +1 -0
- package/dist/actions/deplint/deplint.mjs +1840 -0
- package/dist/actions/deplint/deplint.mjs.map +1 -0
- package/dist/actions/deplint/engine.mjs +1736 -0
- package/dist/actions/deplint/engine.mjs.map +1 -0
- package/dist/actions/deplint/findFiles.mjs +39 -0
- package/dist/actions/deplint/findFiles.mjs.map +1 -0
- package/dist/actions/deplint/findFilesByGlob.mjs +14 -0
- package/dist/actions/deplint/findFilesByGlob.mjs.map +1 -0
- package/dist/actions/deplint/fixer.mjs +103 -0
- package/dist/actions/deplint/fixer.mjs.map +1 -0
- package/dist/actions/deplint/getBasePackageName.mjs +13 -0
- package/dist/actions/deplint/getBasePackageName.mjs.map +1 -0
- package/dist/actions/deplint/getCliReferencedPackagesFromFiles.mjs +140 -0
- package/dist/actions/deplint/getCliReferencedPackagesFromFiles.mjs.map +1 -0
- package/dist/actions/deplint/getDependenciesFromPackageJson.mjs +29 -0
- package/dist/actions/deplint/getDependenciesFromPackageJson.mjs.map +1 -0
- package/dist/actions/deplint/getExtendsFromTsconfigs.mjs +68 -0
- package/dist/actions/deplint/getExtendsFromTsconfigs.mjs.map +1 -0
- package/dist/actions/deplint/getExternalImportsFromFiles.mjs +143 -0
- package/dist/actions/deplint/getExternalImportsFromFiles.mjs.map +1 -0
- package/dist/actions/deplint/getImportsFromFile.mjs +85 -0
- package/dist/actions/deplint/getImportsFromFile.mjs.map +1 -0
- package/dist/actions/deplint/getRequiredPeerDependencies.mjs +37 -0
- package/dist/actions/deplint/getRequiredPeerDependencies.mjs.map +1 -0
- package/dist/actions/deplint/getScriptReferencedPackages.mjs +83 -0
- package/dist/actions/deplint/getScriptReferencedPackages.mjs.map +1 -0
- package/dist/actions/deplint/implicitDevDependencies.mjs +116 -0
- package/dist/actions/deplint/implicitDevDependencies.mjs.map +1 -0
- package/dist/actions/deplint/index.mjs +1848 -0
- package/dist/actions/deplint/index.mjs.map +1 -0
- package/dist/actions/deplint/packageEditor.mjs +82 -0
- package/dist/actions/deplint/packageEditor.mjs.map +1 -0
- package/dist/actions/deplint/packageJsonEditor.mjs +101 -0
- package/dist/actions/deplint/packageJsonEditor.mjs.map +1 -0
- package/dist/actions/deplint/reporters.mjs +36 -0
- package/dist/actions/deplint/reporters.mjs.map +1 -0
- package/dist/actions/deplint/rules.mjs +1223 -0
- package/dist/actions/deplint/rules.mjs.map +1 -0
- package/dist/actions/deplint/snapshot.mjs +372 -0
- package/dist/actions/deplint/snapshot.mjs.map +1 -0
- package/dist/actions/deplint/tsScriptsAliases.mjs +20 -0
- package/dist/actions/deplint/tsScriptsAliases.mjs.map +1 -0
- package/dist/actions/deplint/types.mjs +1 -0
- package/dist/actions/deplint/types.mjs.map +1 -0
- package/dist/actions/deploy.mjs +194 -0
- package/dist/actions/deploy.mjs.map +1 -0
- package/dist/actions/dupdeps.mjs +226 -0
- package/dist/actions/dupdeps.mjs.map +1 -0
- package/dist/actions/eject.mjs +142 -0
- package/dist/actions/eject.mjs.map +1 -0
- package/dist/actions/fix.mjs +359 -0
- package/dist/actions/fix.mjs.map +1 -0
- package/dist/actions/gen-docs.mjs +155 -0
- package/dist/actions/gen-docs.mjs.map +1 -0
- package/dist/actions/gitignore.mjs +159 -0
- package/dist/actions/gitignore.mjs.map +1 -0
- package/dist/actions/gitlint-fix.mjs +27 -0
- package/dist/actions/gitlint-fix.mjs.map +1 -0
- package/dist/actions/gitlint.mjs +48 -0
- package/dist/actions/gitlint.mjs.map +1 -0
- package/dist/actions/index.mjs +8259 -0
- package/dist/actions/index.mjs.map +1 -0
- package/dist/actions/knip.mjs +119 -0
- package/dist/actions/knip.mjs.map +1 -0
- package/dist/actions/license.mjs +92 -0
- package/dist/actions/license.mjs.map +1 -0
- package/dist/actions/lint-init.mjs +275 -0
- package/dist/actions/lint-init.mjs.map +1 -0
- package/dist/actions/lint.mjs +356 -0
- package/dist/actions/lint.mjs.map +1 -0
- package/dist/actions/lintNext.mjs +209 -0
- package/dist/actions/lintNext.mjs.map +1 -0
- package/dist/actions/lintlint.mjs +341 -0
- package/dist/actions/lintlint.mjs.map +1 -0
- package/dist/actions/npmignore-gen.mjs +90 -0
- package/dist/actions/npmignore-gen.mjs.map +1 -0
- package/dist/actions/orphan.mjs +110 -0
- package/dist/actions/orphan.mjs.map +1 -0
- package/dist/actions/package/clean-outputs.mjs +50 -0
- package/dist/actions/package/clean-outputs.mjs.map +1 -0
- package/dist/actions/package/clean-typescript.mjs +50 -0
- package/dist/actions/package/clean-typescript.mjs.map +1 -0
- package/dist/actions/package/clean.mjs +69 -0
- package/dist/actions/package/clean.mjs.map +1 -0
- package/dist/actions/package/compile/XyConfig.mjs +32 -0
- package/dist/actions/package/compile/XyConfig.mjs.map +1 -0
- package/dist/actions/package/compile/buildEntries.mjs +53 -0
- package/dist/actions/package/compile/buildEntries.mjs.map +1 -0
- package/dist/actions/package/compile/compile.mjs +439 -0
- package/dist/actions/package/compile/compile.mjs.map +1 -0
- package/dist/actions/package/compile/copyTypeFiles.mjs +34 -0
- package/dist/actions/package/compile/copyTypeFiles.mjs.map +1 -0
- package/dist/actions/package/compile/deepMerge.mjs +27 -0
- package/dist/actions/package/compile/deepMerge.mjs.map +1 -0
- package/dist/actions/package/compile/getCompilerOptions.mjs +12 -0
- package/dist/actions/package/compile/getCompilerOptions.mjs.map +1 -0
- package/dist/actions/package/compile/index.mjs +472 -0
- package/dist/actions/package/compile/index.mjs.map +1 -0
- package/dist/actions/package/compile/inputs.mjs +22 -0
- package/dist/actions/package/compile/inputs.mjs.map +1 -0
- package/dist/actions/package/compile/packageCompileTsc.mjs +93 -0
- package/dist/actions/package/compile/packageCompileTsc.mjs.map +1 -0
- package/dist/actions/package/compile/packageCompileTscTypes.mjs +92 -0
- package/dist/actions/package/compile/packageCompileTscTypes.mjs.map +1 -0
- package/dist/actions/package/compile/packageCompileTsup.mjs +402 -0
- package/dist/actions/package/compile/packageCompileTsup.mjs.map +1 -0
- package/dist/actions/package/copy-assets.mjs +69 -0
- package/dist/actions/package/copy-assets.mjs.map +1 -0
- package/dist/actions/package/cycle.mjs +62 -0
- package/dist/actions/package/cycle.mjs.map +1 -0
- package/dist/actions/package/gen-docs.mjs +137 -0
- package/dist/actions/package/gen-docs.mjs.map +1 -0
- package/dist/actions/package/index.mjs +1131 -0
- package/dist/actions/package/index.mjs.map +1 -0
- package/dist/actions/package/lint.mjs +87 -0
- package/dist/actions/package/lint.mjs.map +1 -0
- package/dist/actions/package/publint.mjs +336 -0
- package/dist/actions/package/publint.mjs.map +1 -0
- package/dist/actions/package/recompile.mjs +510 -0
- package/dist/actions/package/recompile.mjs.map +1 -0
- package/dist/actions/package-lint-deps.mjs +348 -0
- package/dist/actions/package-lint-deps.mjs.map +1 -0
- package/dist/actions/package-lint.mjs +774 -0
- package/dist/actions/package-lint.mjs.map +1 -0
- package/dist/actions/packman/clean.mjs +144 -0
- package/dist/actions/packman/clean.mjs.map +1 -0
- package/dist/actions/packman/convert.mjs +1331 -0
- package/dist/actions/packman/convert.mjs.map +1 -0
- package/dist/actions/packman/convertToPnpm.mjs +295 -0
- package/dist/actions/packman/convertToPnpm.mjs.map +1 -0
- package/dist/actions/packman/convertToYarn.mjs +307 -0
- package/dist/actions/packman/convertToYarn.mjs.map +1 -0
- package/dist/actions/packman/index.mjs +1493 -0
- package/dist/actions/packman/index.mjs.map +1 -0
- package/dist/actions/packman/lint.mjs +109 -0
- package/dist/actions/packman/lint.mjs.map +1 -0
- package/dist/actions/packman/rewriteScripts.mjs +52 -0
- package/dist/actions/packman/rewriteScripts.mjs.map +1 -0
- package/dist/actions/packman/rewriteSourceImports.mjs +60 -0
- package/dist/actions/packman/rewriteSourceImports.mjs.map +1 -0
- package/dist/actions/packman/swapTsScriptsDependency.mjs +57 -0
- package/dist/actions/packman/swapTsScriptsDependency.mjs.map +1 -0
- package/dist/actions/publint.mjs +748 -0
- package/dist/actions/publint.mjs.map +1 -0
- package/dist/actions/publish.mjs +208 -0
- package/dist/actions/publish.mjs.map +1 -0
- package/dist/actions/reactTest.mjs +142 -0
- package/dist/actions/reactTest.mjs.map +1 -0
- package/dist/actions/readme-gen.mjs +362 -0
- package/dist/actions/readme-gen.mjs.map +1 -0
- package/dist/actions/readme-init.mjs +89 -0
- package/dist/actions/readme-init.mjs.map +1 -0
- package/dist/actions/readme-lint.mjs +147 -0
- package/dist/actions/readme-lint.mjs.map +1 -0
- package/dist/actions/rebuild.mjs +143 -0
- package/dist/actions/rebuild.mjs.map +1 -0
- package/dist/actions/recompile.mjs +196 -0
- package/dist/actions/recompile.mjs.map +1 -0
- package/dist/actions/reinstall.mjs +283 -0
- package/dist/actions/reinstall.mjs.map +1 -0
- package/dist/actions/relint.mjs +355 -0
- package/dist/actions/relint.mjs.map +1 -0
- package/dist/actions/repo-init.mjs +217 -0
- package/dist/actions/repo-init.mjs.map +1 -0
- package/dist/actions/retest.mjs +150 -0
- package/dist/actions/retest.mjs.map +1 -0
- package/dist/actions/sitemap.mjs +121 -0
- package/dist/actions/sitemap.mjs.map +1 -0
- package/dist/actions/sonar.mjs +119 -0
- package/dist/actions/sonar.mjs.map +1 -0
- package/dist/actions/start.mjs +142 -0
- package/dist/actions/start.mjs.map +1 -0
- package/dist/actions/statics.mjs +225 -0
- package/dist/actions/statics.mjs.map +1 -0
- package/dist/actions/test.mjs +144 -0
- package/dist/actions/test.mjs.map +1 -0
- package/dist/actions/up.mjs +140 -0
- package/dist/actions/up.mjs.map +1 -0
- package/dist/actions/updo.mjs +533 -0
- package/dist/actions/updo.mjs.map +1 -0
- package/dist/actions/upplug.mjs +124 -0
- package/dist/actions/upplug.mjs.map +1 -0
- package/dist/actions/upyarn.mjs +119 -0
- package/dist/actions/upyarn.mjs.map +1 -0
- package/dist/actions/yarn3only.mjs +60 -0
- package/dist/actions/yarn3only.mjs.map +1 -0
- package/dist/bin/package/build-only.mjs +451 -0
- package/dist/bin/package/build-only.mjs.map +1 -0
- package/dist/bin/package/build.mjs +451 -0
- package/dist/bin/package/build.mjs.map +1 -0
- package/dist/bin/package/clean-outputs.mjs +50 -0
- package/dist/bin/package/clean-outputs.mjs.map +1 -0
- package/dist/bin/package/clean-typescript.mjs +50 -0
- package/dist/bin/package/clean-typescript.mjs.map +1 -0
- package/dist/bin/package/clean.mjs +75 -0
- package/dist/bin/package/clean.mjs.map +1 -0
- package/dist/bin/package/compile-only.mjs +447 -0
- package/dist/bin/package/compile-only.mjs.map +1 -0
- package/dist/bin/package/compile-tsup.mjs +409 -0
- package/dist/bin/package/compile-tsup.mjs.map +1 -0
- package/dist/bin/package/compile.mjs +451 -0
- package/dist/bin/package/compile.mjs.map +1 -0
- package/dist/bin/package/copy-assets-cjs.mjs +75 -0
- package/dist/bin/package/copy-assets-cjs.mjs.map +1 -0
- package/dist/bin/package/copy-assets-esm.mjs +75 -0
- package/dist/bin/package/copy-assets-esm.mjs.map +1 -0
- package/dist/bin/package/cycle.mjs +72 -0
- package/dist/bin/package/cycle.mjs.map +1 -0
- package/dist/bin/package/fix.mjs +97 -0
- package/dist/bin/package/fix.mjs.map +1 -0
- package/dist/bin/package/gen-docs.mjs +142 -0
- package/dist/bin/package/gen-docs.mjs.map +1 -0
- package/dist/bin/package/lint-verbose.mjs +97 -0
- package/dist/bin/package/lint-verbose.mjs.map +1 -0
- package/dist/bin/package/lint.mjs +97 -0
- package/dist/bin/package/lint.mjs.map +1 -0
- package/dist/bin/package/publint.mjs +423 -0
- package/dist/bin/package/publint.mjs.map +1 -0
- package/dist/bin/package/recompile.mjs +516 -0
- package/dist/bin/package/recompile.mjs.map +1 -0
- package/dist/bin/package/relint.mjs +97 -0
- package/dist/bin/package/relint.mjs.map +1 -0
- package/dist/bin/run-or-exec.mjs +20 -0
- package/dist/bin/run-or-exec.mjs.map +1 -0
- package/dist/bin/xy.mjs +8885 -0
- package/dist/bin/xy.mjs.map +1 -0
- package/dist/index.d.ts +1102 -0
- package/dist/index.mjs +9986 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/checkResult.mjs +16 -0
- package/dist/lib/checkResult.mjs.map +1 -0
- package/dist/lib/claudeMdTemplate.mjs +69 -0
- package/dist/lib/claudeMdTemplate.mjs.map +1 -0
- package/dist/lib/concurrency.mjs +38 -0
- package/dist/lib/concurrency.mjs.map +1 -0
- package/dist/lib/createBuildConfig.mjs +55 -0
- package/dist/lib/createBuildConfig.mjs.map +1 -0
- package/dist/lib/defaultBuildConfig.mjs +23 -0
- package/dist/lib/defaultBuildConfig.mjs.map +1 -0
- package/dist/lib/deleteGlob.mjs +13 -0
- package/dist/lib/deleteGlob.mjs.map +1 -0
- package/dist/lib/dependencies/DuplicateDetector.mjs +99 -0
- package/dist/lib/dependencies/DuplicateDetector.mjs.map +1 -0
- package/dist/lib/dependencies/detectDuplicateDependencies.mjs +203 -0
- package/dist/lib/dependencies/detectDuplicateDependencies.mjs.map +1 -0
- package/dist/lib/dependencies/index.mjs +281 -0
- package/dist/lib/dependencies/index.mjs.map +1 -0
- package/dist/lib/dependencies/workspaceCycles.mjs +79 -0
- package/dist/lib/dependencies/workspaceCycles.mjs.map +1 -0
- package/dist/lib/file/ReadFileSyncOptions.mjs +6 -0
- package/dist/lib/file/ReadFileSyncOptions.mjs.map +1 -0
- package/dist/lib/file/constants.mjs +8 -0
- package/dist/lib/file/constants.mjs.map +1 -0
- package/dist/lib/file/fileLines.mjs +32 -0
- package/dist/lib/file/fileLines.mjs.map +1 -0
- package/dist/lib/file/index.mjs +42 -0
- package/dist/lib/file/index.mjs.map +1 -0
- package/dist/lib/file/tryReadFileSync.mjs +14 -0
- package/dist/lib/file/tryReadFileSync.mjs.map +1 -0
- package/dist/lib/fillTemplate.mjs +8 -0
- package/dist/lib/fillTemplate.mjs.map +1 -0
- package/dist/lib/generateIgnoreFiles.mjs +86 -0
- package/dist/lib/generateIgnoreFiles.mjs.map +1 -0
- package/dist/lib/generateReadmeFiles.mjs +323 -0
- package/dist/lib/generateReadmeFiles.mjs.map +1 -0
- package/dist/lib/gitignoreTemplate.mjs +12 -0
- package/dist/lib/gitignoreTemplate.mjs.map +1 -0
- package/dist/lib/index.mjs +1627 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/initCwd.mjs +8 -0
- package/dist/lib/initCwd.mjs.map +1 -0
- package/dist/lib/jsonFormatters.mjs +11 -0
- package/dist/lib/jsonFormatters.mjs.map +1 -0
- package/dist/lib/latestVersions.mjs +12 -0
- package/dist/lib/latestVersions.mjs.map +1 -0
- package/dist/lib/loadConfig.mjs +72 -0
- package/dist/lib/loadConfig.mjs.map +1 -0
- package/dist/lib/packageName.mjs +26 -0
- package/dist/lib/packageName.mjs.map +1 -0
- package/dist/lib/parsedPackageJSON.mjs +11 -0
- package/dist/lib/parsedPackageJSON.mjs.map +1 -0
- package/dist/lib/processEx.mjs +36 -0
- package/dist/lib/processEx.mjs.map +1 -0
- package/dist/lib/repoTemplates.mjs +34 -0
- package/dist/lib/repoTemplates.mjs.map +1 -0
- package/dist/lib/runInstall.mjs +30 -0
- package/dist/lib/runInstall.mjs.map +1 -0
- package/dist/lib/runSteps.mjs +118 -0
- package/dist/lib/runSteps.mjs.map +1 -0
- package/dist/lib/runStepsAsync.mjs +136 -0
- package/dist/lib/runStepsAsync.mjs.map +1 -0
- package/dist/lib/runXy.mjs +147 -0
- package/dist/lib/runXy.mjs.map +1 -0
- package/dist/lib/runXyWithWarning.mjs +36 -0
- package/dist/lib/runXyWithWarning.mjs.map +1 -0
- package/dist/lib/safeExit.mjs +61 -0
- package/dist/lib/safeExit.mjs.map +1 -0
- package/dist/lib/string/empty.mjs +8 -0
- package/dist/lib/string/empty.mjs.map +1 -0
- package/dist/lib/string/index.mjs +12 -0
- package/dist/lib/string/index.mjs.map +1 -0
- package/dist/lib/string/union.mjs +6 -0
- package/dist/lib/string/union.mjs.map +1 -0
- package/dist/lib/tryRunLocalScript.mjs +57 -0
- package/dist/lib/tryRunLocalScript.mjs.map +1 -0
- package/dist/lib/updo/applyUpdates.mjs +44 -0
- package/dist/lib/updo/applyUpdates.mjs.map +1 -0
- package/dist/lib/updo/collectWorkspaceDeps.mjs +48 -0
- package/dist/lib/updo/collectWorkspaceDeps.mjs.map +1 -0
- package/dist/lib/updo/fetchRegistryInfo.mjs +53 -0
- package/dist/lib/updo/fetchRegistryInfo.mjs.map +1 -0
- package/dist/lib/updo/index.mjs +594 -0
- package/dist/lib/updo/index.mjs.map +1 -0
- package/dist/lib/updo/interactiveSelect.mjs +185 -0
- package/dist/lib/updo/interactiveSelect.mjs.map +1 -0
- package/dist/lib/updo/interfaces.mjs +1 -0
- package/dist/lib/updo/interfaces.mjs.map +1 -0
- package/dist/lib/updo/renderTable.mjs +79 -0
- package/dist/lib/updo/renderTable.mjs.map +1 -0
- package/dist/lib/updo/resolveVersions.mjs +49 -0
- package/dist/lib/updo/resolveVersions.mjs.map +1 -0
- package/dist/lib/updo/runUpdo.mjs +511 -0
- package/dist/lib/updo/runUpdo.mjs.map +1 -0
- package/dist/lib/withErrnoException.mjs +13 -0
- package/dist/lib/withErrnoException.mjs.map +1 -0
- package/dist/lib/withError.mjs +8 -0
- package/dist/lib/withError.mjs.map +1 -0
- package/dist/lib/yarn/index.mjs +39 -0
- package/dist/lib/yarn/index.mjs.map +1 -0
- package/dist/lib/yarn/isYarnVersionOrGreater.mjs +18 -0
- package/dist/lib/yarn/isYarnVersionOrGreater.mjs.map +1 -0
- package/dist/lib/yarn/workspace/Workspace.mjs +1 -0
- package/dist/lib/yarn/workspace/Workspace.mjs.map +1 -0
- package/dist/lib/yarn/workspace/index.mjs +23 -0
- package/dist/lib/yarn/workspace/index.mjs.map +1 -0
- package/dist/lib/yarn/workspace/yarnWorkspace.mjs +22 -0
- package/dist/lib/yarn/workspace/yarnWorkspace.mjs.map +1 -0
- package/dist/lib/yarn/workspace/yarnWorkspaces.mjs +15 -0
- package/dist/lib/yarn/workspace/yarnWorkspaces.mjs.map +1 -0
- package/dist/lib/yarn/yarnInitCwd.mjs +8 -0
- package/dist/lib/yarn/yarnInitCwd.mjs.map +1 -0
- package/dist/loadPackageConfig.mjs +18 -0
- package/dist/loadPackageConfig.mjs.map +1 -0
- package/dist/pm/PackageManager.mjs +1 -0
- package/dist/pm/PackageManager.mjs.map +1 -0
- package/dist/pm/detectPackageManager.mjs +10 -0
- package/dist/pm/detectPackageManager.mjs.map +1 -0
- package/dist/pm/detectReact.mjs +52 -0
- package/dist/pm/detectReact.mjs.map +1 -0
- package/dist/pm/index.mjs +263 -0
- package/dist/pm/index.mjs.map +1 -0
- package/dist/pm/pnpmPackageManager.mjs +97 -0
- package/dist/pm/pnpmPackageManager.mjs.map +1 -0
- package/dist/pm/registry.mjs +27 -0
- package/dist/pm/registry.mjs.map +1 -0
- package/dist/pm/yarnPackageManager.mjs +112 -0
- package/dist/pm/yarnPackageManager.mjs.map +1 -0
- package/dist/types.d.mjs +1 -0
- package/dist/types.d.mjs.map +1 -0
- package/dist/xy/build/buildCommand.mjs +194 -0
- package/dist/xy/build/buildCommand.mjs.map +1 -0
- package/dist/xy/build/compileCommand.mjs +203 -0
- package/dist/xy/build/compileCommand.mjs.map +1 -0
- package/dist/xy/build/compileOnlyCommand.mjs +204 -0
- package/dist/xy/build/compileOnlyCommand.mjs.map +1 -0
- package/dist/xy/build/copyAssetsCommand.mjs +92 -0
- package/dist/xy/build/copyAssetsCommand.mjs.map +1 -0
- package/dist/xy/build/index.mjs +487 -0
- package/dist/xy/build/index.mjs.map +1 -0
- package/dist/xy/build/rebuildCommand.mjs +156 -0
- package/dist/xy/build/rebuildCommand.mjs.map +1 -0
- package/dist/xy/build/recompileCommand.mjs +215 -0
- package/dist/xy/build/recompileCommand.mjs.map +1 -0
- package/dist/xy/common/checkCommand.mjs +1909 -0
- package/dist/xy/common/checkCommand.mjs.map +1 -0
- package/dist/xy/common/claude/checkCommand.mjs +207 -0
- package/dist/xy/common/claude/checkCommand.mjs.map +1 -0
- package/dist/xy/common/claude/cleanCommand.mjs +78 -0
- package/dist/xy/common/claude/cleanCommand.mjs.map +1 -0
- package/dist/xy/common/claude/commandsCommand.mjs +134 -0
- package/dist/xy/common/claude/commandsCommand.mjs.map +1 -0
- package/dist/xy/common/claude/index.mjs +734 -0
- package/dist/xy/common/claude/index.mjs.map +1 -0
- package/dist/xy/common/claude/initCommand.mjs +458 -0
- package/dist/xy/common/claude/initCommand.mjs.map +1 -0
- package/dist/xy/common/claude/rulesCommand.mjs +167 -0
- package/dist/xy/common/claude/rulesCommand.mjs.map +1 -0
- package/dist/xy/common/claude/settingsCommand.mjs +115 -0
- package/dist/xy/common/claude/settingsCommand.mjs.map +1 -0
- package/dist/xy/common/claude/skillsCommand.mjs +140 -0
- package/dist/xy/common/claude/skillsCommand.mjs.map +1 -0
- package/dist/xy/common/cleanDocsCommand.mjs +74 -0
- package/dist/xy/common/cleanDocsCommand.mjs.map +1 -0
- package/dist/xy/common/deadCommand.mjs +137 -0
- package/dist/xy/common/deadCommand.mjs.map +1 -0
- package/dist/xy/common/genDocsCommand.mjs +175 -0
- package/dist/xy/common/genDocsCommand.mjs.map +1 -0
- package/dist/xy/common/gitignoreCommand.mjs +165 -0
- package/dist/xy/common/gitignoreCommand.mjs.map +1 -0
- package/dist/xy/common/gitlintCommand.mjs +89 -0
- package/dist/xy/common/gitlintCommand.mjs.map +1 -0
- package/dist/xy/common/index.mjs +4654 -0
- package/dist/xy/common/index.mjs.map +1 -0
- package/dist/xy/common/licenseCommand.mjs +108 -0
- package/dist/xy/common/licenseCommand.mjs.map +1 -0
- package/dist/xy/common/npmignoreGenCommand.mjs +100 -0
- package/dist/xy/common/npmignoreGenCommand.mjs.map +1 -0
- package/dist/xy/common/orphan/cleanCommand.mjs +102 -0
- package/dist/xy/common/orphan/cleanCommand.mjs.map +1 -0
- package/dist/xy/common/orphan/index.mjs +138 -0
- package/dist/xy/common/orphan/index.mjs.map +1 -0
- package/dist/xy/common/orphan/listCommand.mjs +100 -0
- package/dist/xy/common/orphan/listCommand.mjs.map +1 -0
- package/dist/xy/common/packmanCommand.mjs +1538 -0
- package/dist/xy/common/packmanCommand.mjs.map +1 -0
- package/dist/xy/common/readme/genCommand.mjs +395 -0
- package/dist/xy/common/readme/genCommand.mjs.map +1 -0
- package/dist/xy/common/readme/index.mjs +538 -0
- package/dist/xy/common/readme/index.mjs.map +1 -0
- package/dist/xy/common/readme/initCommand.mjs +109 -0
- package/dist/xy/common/readme/initCommand.mjs.map +1 -0
- package/dist/xy/common/readme/lintCommand.mjs +181 -0
- package/dist/xy/common/readme/lintCommand.mjs.map +1 -0
- package/dist/xy/common/repo/index.mjs +1070 -0
- package/dist/xy/common/repo/index.mjs.map +1 -0
- package/dist/xy/common/repo/initCommand.mjs +273 -0
- package/dist/xy/common/repo/initCommand.mjs.map +1 -0
- package/dist/xy/common/repo/lintCommand.mjs +789 -0
- package/dist/xy/common/repo/lintCommand.mjs.map +1 -0
- package/dist/xy/common/retestCommand.mjs +163 -0
- package/dist/xy/common/retestCommand.mjs.map +1 -0
- package/dist/xy/common/testCommand.mjs +157 -0
- package/dist/xy/common/testCommand.mjs.map +1 -0
- package/dist/xy/deploy/deployCommand.mjs +214 -0
- package/dist/xy/deploy/deployCommand.mjs.map +1 -0
- package/dist/xy/deploy/index.mjs +289 -0
- package/dist/xy/deploy/index.mjs.map +1 -0
- package/dist/xy/deploy/publishCommand.mjs +218 -0
- package/dist/xy/deploy/publishCommand.mjs.map +1 -0
- package/dist/xy/index.mjs +8887 -0
- package/dist/xy/index.mjs.map +1 -0
- package/dist/xy/install/cleanCommand.mjs +182 -0
- package/dist/xy/install/cleanCommand.mjs.map +1 -0
- package/dist/xy/install/dupdepsCommand.mjs +234 -0
- package/dist/xy/install/dupdepsCommand.mjs.map +1 -0
- package/dist/xy/install/index.mjs +1006 -0
- package/dist/xy/install/index.mjs.map +1 -0
- package/dist/xy/install/reinstallCommand.mjs +292 -0
- package/dist/xy/install/reinstallCommand.mjs.map +1 -0
- package/dist/xy/install/staticsCommand.mjs +233 -0
- package/dist/xy/install/staticsCommand.mjs.map +1 -0
- package/dist/xy/install/upCommand.mjs +150 -0
- package/dist/xy/install/upCommand.mjs.map +1 -0
- package/dist/xy/install/updoCommand.mjs +550 -0
- package/dist/xy/install/updoCommand.mjs.map +1 -0
- package/dist/xy/lint/cycleCommand.mjs +289 -0
- package/dist/xy/lint/cycleCommand.mjs.map +1 -0
- package/dist/xy/lint/deplintCommand.mjs +1897 -0
- package/dist/xy/lint/deplintCommand.mjs.map +1 -0
- package/dist/xy/lint/fixCommand.mjs +398 -0
- package/dist/xy/lint/fixCommand.mjs.map +1 -0
- package/dist/xy/lint/index.mjs +3759 -0
- package/dist/xy/lint/index.mjs.map +1 -0
- package/dist/xy/lint/knipCommand.mjs +142 -0
- package/dist/xy/lint/knipCommand.mjs.map +1 -0
- package/dist/xy/lint/lint/index.mjs +695 -0
- package/dist/xy/lint/lint/index.mjs.map +1 -0
- package/dist/xy/lint/lint/initCommand.mjs +282 -0
- package/dist/xy/lint/lint/initCommand.mjs.map +1 -0
- package/dist/xy/lint/lint/runCommand.mjs +405 -0
- package/dist/xy/lint/lint/runCommand.mjs.map +1 -0
- package/dist/xy/lint/lintCommand.mjs +695 -0
- package/dist/xy/lint/lintCommand.mjs.map +1 -0
- package/dist/xy/lint/lintlintCommand.mjs +359 -0
- package/dist/xy/lint/lintlintCommand.mjs.map +1 -0
- package/dist/xy/lint/publintCommand.mjs +778 -0
- package/dist/xy/lint/publintCommand.mjs.map +1 -0
- package/dist/xy/lint/relintCommand.mjs +381 -0
- package/dist/xy/lint/relintCommand.mjs.map +1 -0
- package/dist/xy/lint/sonarCommand.mjs +137 -0
- package/dist/xy/lint/sonarCommand.mjs.map +1 -0
- package/dist/xy/param.mjs +8 -0
- package/dist/xy/param.mjs.map +1 -0
- package/dist/xy/react/analyzeCommand.mjs +150 -0
- package/dist/xy/react/analyzeCommand.mjs.map +1 -0
- package/dist/xy/react/ejectCommand.mjs +150 -0
- package/dist/xy/react/ejectCommand.mjs.map +1 -0
- package/dist/xy/react/index.mjs +202 -0
- package/dist/xy/react/index.mjs.map +1 -0
- package/dist/xy/react/sitemapCommand.mjs +129 -0
- package/dist/xy/react/sitemapCommand.mjs.map +1 -0
- package/dist/xy/react/startCommand.mjs +150 -0
- package/dist/xy/react/startCommand.mjs.map +1 -0
- package/dist/xy/xy.mjs +8879 -0
- package/dist/xy/xy.mjs.map +1 -0
- package/dist/xy/xyParseOptions.mjs +117 -0
- package/dist/xy/xyParseOptions.mjs.map +1 -0
- package/dist/xy/yarn/index.mjs +188 -0
- package/dist/xy/yarn/index.mjs.map +1 -0
- package/dist/xy/yarn/upplugCommand.mjs +134 -0
- package/dist/xy/yarn/upplugCommand.mjs.map +1 -0
- package/dist/xy/yarn/upyarnCommand.mjs +129 -0
- package/dist/xy/yarn/upyarnCommand.mjs.map +1 -0
- package/dist/xy/yarn/yarn3OnlyCommand.mjs +70 -0
- package/dist/xy/yarn/yarn3OnlyCommand.mjs.map +1 -0
- package/package.json +119 -0
- package/templates/claude/CLAUDE-local.md +4 -0
- package/templates/claude/CLAUDE-project.md +4 -0
- package/templates/claude/commands/xy-build.md +7 -0
- package/templates/claude/commands/xy-clean.md +7 -0
- package/templates/claude/commands/xy-compile.md +7 -0
- package/templates/claude/commands/xy-cycle.md +7 -0
- package/templates/claude/commands/xy-dead.md +7 -0
- package/templates/claude/commands/xy-deplint.md +7 -0
- package/templates/claude/commands/xy-deps.md +24 -0
- package/templates/claude/commands/xy-dupdeps.md +7 -0
- package/templates/claude/commands/xy-fix.md +7 -0
- package/templates/claude/commands/xy-gen-docs.md +7 -0
- package/templates/claude/commands/xy-gitignore.md +7 -0
- package/templates/claude/commands/xy-gitlint.md +7 -0
- package/templates/claude/commands/xy-knip.md +7 -0
- package/templates/claude/commands/xy-license.md +7 -0
- package/templates/claude/commands/xy-lint-rules.md +44 -0
- package/templates/claude/commands/xy-lint.md +7 -0
- package/templates/claude/commands/xy-publint.md +7 -0
- package/templates/claude/commands/xy-rebuild.md +7 -0
- package/templates/claude/commands/xy-recompile.md +7 -0
- package/templates/claude/commands/xy-reinstall.md +7 -0
- package/templates/claude/commands/xy-relint.md +7 -0
- package/templates/claude/commands/xy-retest.md +7 -0
- package/templates/claude/commands/xy-sonar.md +7 -0
- package/templates/claude/commands/xy-test.md +7 -0
- package/templates/claude/commands/xy-up.md +9 -0
- package/templates/claude/rules/xylabs-architecture.md +8 -0
- package/templates/claude/rules/xylabs-git-workflow.md +7 -0
- package/templates/claude/rules/xylabs-naming.md +7 -0
- package/templates/claude/rules/xylabs-style.md +17 -0
- package/templates/claude/skills/xylabs-e2e-setup/SKILL.md +223 -0
- package/templates/claude/skills/xylabs-xy-cli/SKILL.md +236 -0
- package/templates/claude/skills/xylabs-xy-deplint-fix/SKILL.md +122 -0
- package/templates/gitignore/gitignore/template.gitignore +51 -0
- package/templates/gitignore/template.gitignore +51 -0
- package/templates/readme/README.body.md +25 -0
- package/templates/readme/README.template.md +22 -0
- package/templates/repo/cli/package/package.json.tmpl +63 -0
- package/templates/repo/cli/package/src/__packageName__.ts.tmpl +21 -0
- package/templates/repo/cli/package/src/actions/index.ts +1 -0
- package/templates/repo/cli/package/src/actions/printVersion.ts.tmpl +8 -0
- package/templates/repo/cli/package/src/bin/__packageName__.ts.tmpl +12 -0
- package/templates/repo/cli/package/src/commands/index.ts +1 -0
- package/templates/repo/cli/package/src/commands/versionCommand.ts.tmpl +11 -0
- package/templates/repo/cli/package/src/index.ts.tmpl +1 -0
- package/templates/repo/cli/package/tsconfig.build.json +25 -0
- package/templates/repo/cli/package/tsconfig.json +4 -0
- package/templates/repo/cli/package/tsup.config.ts +15 -0
- package/templates/repo/cli/package/xy.config.ts +3 -0
- package/templates/repo/cli/root/CLAUDE.md.tmpl +38 -0
- package/templates/repo/cli/root/cspell.json.tmpl +13 -0
- package/templates/repo/cli/root/eslint.config.ts +28 -0
- package/templates/repo/cli/root/github/workflows/build-pnpm.yml.tmpl +34 -0
- package/templates/repo/cli/root/github/workflows/build-yarn.yml.tmpl +32 -0
- package/templates/repo/cli/root/gitignore.tmpl +47 -0
- package/templates/repo/cli/root/knip.config.ts +16 -0
- package/templates/repo/cli/root/package.json.tmpl +54 -0
- package/templates/repo/cli/root/pnpm-workspace.yaml +2 -0
- package/templates/repo/cli/root/tsconfig.json +4 -0
- package/templates/repo/cli/root/vitest.config.ts +31 -0
- package/templates/repo/cli/root/xy.config.ts.tmpl +5 -0
|
@@ -0,0 +1,3759 @@
|
|
|
1
|
+
// src/lib/checkResult.ts
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
var checkResult = (name, result, level = "error", exitOnFail = false) => {
|
|
4
|
+
if (result) {
|
|
5
|
+
const exiting = exitOnFail ? "[Exiting Process]" : "[Continuing]";
|
|
6
|
+
const chalkFunc = level === "error" ? chalk.red : chalk.yellow;
|
|
7
|
+
console[level](chalkFunc(`${name} had ${result} failures ${exiting}`));
|
|
8
|
+
if (exitOnFail) {
|
|
9
|
+
process.exit(result);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// src/lib/concurrency.ts
|
|
15
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
16
|
+
var outputStorage = new AsyncLocalStorage();
|
|
17
|
+
var captureInstalled = false;
|
|
18
|
+
function installOutputCapture() {
|
|
19
|
+
if (captureInstalled) return;
|
|
20
|
+
captureInstalled = true;
|
|
21
|
+
const originalStdoutWrite = process.stdout.write.bind(process.stdout);
|
|
22
|
+
const originalStderrWrite = process.stderr.write.bind(process.stderr);
|
|
23
|
+
function intercept(original) {
|
|
24
|
+
return function(chunk, ...args) {
|
|
25
|
+
const buffer = outputStorage.getStore();
|
|
26
|
+
if (buffer) {
|
|
27
|
+
buffer.push(typeof chunk === "string" ? chunk : new TextDecoder().decode(chunk));
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
return original(chunk, ...args);
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
process.stdout.write = intercept(originalStdoutWrite);
|
|
34
|
+
process.stderr.write = intercept(originalStderrWrite);
|
|
35
|
+
}
|
|
36
|
+
async function runWithConcurrency(items, concurrency, fn) {
|
|
37
|
+
let next = 0;
|
|
38
|
+
async function worker() {
|
|
39
|
+
while (next < items.length) {
|
|
40
|
+
const i = next++;
|
|
41
|
+
await fn(items[i]);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/pm/detectPackageManager.ts
|
|
48
|
+
import { existsSync } from "fs";
|
|
49
|
+
function detectPackageManager() {
|
|
50
|
+
if (existsSync("pnpm-lock.yaml") || existsSync("pnpm-workspace.yaml")) return "pnpm";
|
|
51
|
+
return "yarn";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/pm/registry.ts
|
|
55
|
+
var implementations = /* @__PURE__ */ new Map();
|
|
56
|
+
function getPackageManager(name) {
|
|
57
|
+
const pmName = name ?? detectPackageManager();
|
|
58
|
+
const pm = implementations.get(pmName);
|
|
59
|
+
if (!pm) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
`No package manager implementation registered for "${pmName}". Ensure registerPackageManager() has been called before getPackageManager().`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
return pm;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// src/lib/processEx.ts
|
|
68
|
+
import chalk2 from "chalk";
|
|
69
|
+
|
|
70
|
+
// src/lib/withError.ts
|
|
71
|
+
var withError = (ex, closure, predicate = (ex2) => !!ex2.name && !!ex2.message) => {
|
|
72
|
+
return predicate(ex) ? closure(ex) : void 0;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// src/lib/withErrnoException.ts
|
|
76
|
+
var withErrnoException = (ex, closure) => {
|
|
77
|
+
return withError(ex, closure, (ex2) => ex2.errno !== void 0);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// src/lib/processEx.ts
|
|
81
|
+
var processEx = (ex) => {
|
|
82
|
+
const error = typeof ex === "string" ? new Error(ex) : ex;
|
|
83
|
+
const exitCode = withErrnoException(error, (error2) => {
|
|
84
|
+
if (error2.code === "ENOENT") {
|
|
85
|
+
console.error(chalk2.red(`'${error2.path}' not found.`));
|
|
86
|
+
} else {
|
|
87
|
+
console.error(chalk2.red(`Errno: ${error2.code}`));
|
|
88
|
+
}
|
|
89
|
+
return error2.errno ?? -1;
|
|
90
|
+
}) ?? withError(error, (error2) => {
|
|
91
|
+
console.error(chalk2.red(`${error2.name}: ${error2.message}`));
|
|
92
|
+
return -1;
|
|
93
|
+
}) ?? (() => {
|
|
94
|
+
console.error(chalk2.red(`Unexpected Error: ${JSON.stringify(ex, null, 2)}`));
|
|
95
|
+
return -1;
|
|
96
|
+
})();
|
|
97
|
+
process.exit(process.exitCode ?? exitCode);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// src/lib/safeExit.ts
|
|
101
|
+
var safeExit = (func, exitOnFail = true) => {
|
|
102
|
+
try {
|
|
103
|
+
const result = func();
|
|
104
|
+
if (result && exitOnFail) {
|
|
105
|
+
process.exit(result);
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
} catch (ex) {
|
|
109
|
+
return processEx(ex);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// src/lib/dependencies/workspaceCycles.ts
|
|
114
|
+
import { readFileSync } from "fs";
|
|
115
|
+
import PATH from "path";
|
|
116
|
+
import chalk3 from "chalk";
|
|
117
|
+
function detectWorkspaceCycles(workspaces) {
|
|
118
|
+
const workspaceNames = new Set(workspaces.map((ws) => ws.name));
|
|
119
|
+
const graph = /* @__PURE__ */ new Map();
|
|
120
|
+
for (const ws of workspaces) {
|
|
121
|
+
const pkgPath = PATH.join(ws.location, "package.json");
|
|
122
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
123
|
+
const deps = pkg.dependencies ?? {};
|
|
124
|
+
const devDeps = pkg.devDependencies ?? {};
|
|
125
|
+
const edges = [];
|
|
126
|
+
for (const dep of Object.keys(deps)) {
|
|
127
|
+
if (workspaceNames.has(dep)) edges.push({ name: dep, type: "dep" });
|
|
128
|
+
}
|
|
129
|
+
for (const dep of Object.keys(devDeps)) {
|
|
130
|
+
if (workspaceNames.has(dep)) edges.push({ name: dep, type: "devDep" });
|
|
131
|
+
}
|
|
132
|
+
graph.set(ws.name, edges);
|
|
133
|
+
}
|
|
134
|
+
const WHITE = 0;
|
|
135
|
+
const GRAY = 1;
|
|
136
|
+
const BLACK = 2;
|
|
137
|
+
const color = /* @__PURE__ */ new Map();
|
|
138
|
+
const cycles = [];
|
|
139
|
+
const path9 = [];
|
|
140
|
+
const onPath = /* @__PURE__ */ new Set();
|
|
141
|
+
for (const name of workspaceNames) color.set(name, WHITE);
|
|
142
|
+
function dfs(u, incomingEdgeType) {
|
|
143
|
+
color.set(u, GRAY);
|
|
144
|
+
onPath.add(u);
|
|
145
|
+
path9.push({ name: u, edgeType: incomingEdgeType });
|
|
146
|
+
for (const edge of graph.get(u) ?? []) {
|
|
147
|
+
const v = edge.name;
|
|
148
|
+
if (onPath.has(v)) {
|
|
149
|
+
const cycleEdges = [];
|
|
150
|
+
const startIdx = path9.findIndex((p) => p.name === v);
|
|
151
|
+
for (let i = startIdx; i < path9.length - 1; i++) {
|
|
152
|
+
const nextEdgeType = path9[i + 1].edgeType ?? "dep";
|
|
153
|
+
cycleEdges.push({
|
|
154
|
+
from: path9[i].name,
|
|
155
|
+
to: path9[i + 1].name,
|
|
156
|
+
type: nextEdgeType
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
cycleEdges.push({
|
|
160
|
+
from: u,
|
|
161
|
+
to: v,
|
|
162
|
+
type: edge.type
|
|
163
|
+
});
|
|
164
|
+
cycles.push(cycleEdges);
|
|
165
|
+
} else if (color.get(v) === WHITE) {
|
|
166
|
+
dfs(v, edge.type);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
path9.pop();
|
|
170
|
+
onPath.delete(u);
|
|
171
|
+
color.set(u, BLACK);
|
|
172
|
+
}
|
|
173
|
+
for (const name of workspaceNames) {
|
|
174
|
+
if (color.get(name) === WHITE) dfs(name);
|
|
175
|
+
}
|
|
176
|
+
return cycles;
|
|
177
|
+
}
|
|
178
|
+
function printWorkspaceCycles(cycles) {
|
|
179
|
+
for (const cycle2 of cycles) {
|
|
180
|
+
console.error(chalk3.red(" Workspace dependency cycle:"));
|
|
181
|
+
for (const edge of cycle2) {
|
|
182
|
+
const edgeLabel = edge.type === "devDep" ? chalk3.yellow("devDep") : chalk3.cyan("dep");
|
|
183
|
+
console.error(` ${chalk3.white(edge.from)} --(${edgeLabel})--> ${chalk3.white(edge.to)}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// src/lib/initCwd.ts
|
|
189
|
+
function INIT_CWD() {
|
|
190
|
+
return process.env.INIT_CWD ?? process.cwd();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// src/lib/loadConfig.ts
|
|
194
|
+
import chalk4 from "chalk";
|
|
195
|
+
import { cosmiconfig } from "cosmiconfig";
|
|
196
|
+
import { TypeScriptLoader } from "cosmiconfig-typescript-loader";
|
|
197
|
+
import deepmerge from "deepmerge";
|
|
198
|
+
var config;
|
|
199
|
+
var rootConfigPath;
|
|
200
|
+
var workspaceConfigCache = /* @__PURE__ */ new Map();
|
|
201
|
+
var deprecationWarned = /* @__PURE__ */ new Set();
|
|
202
|
+
function createExplorer() {
|
|
203
|
+
return cosmiconfig("xy", { cache: true, loaders: { ".ts": TypeScriptLoader() } });
|
|
204
|
+
}
|
|
205
|
+
var loadConfig = async (params) => {
|
|
206
|
+
if (config === void 0) {
|
|
207
|
+
const cosmicConfigResult = await createExplorer().search();
|
|
208
|
+
config = cosmicConfigResult?.config ?? {};
|
|
209
|
+
rootConfigPath = cosmicConfigResult?.filepath;
|
|
210
|
+
const configFilePath = cosmicConfigResult?.filepath;
|
|
211
|
+
if (configFilePath !== void 0) {
|
|
212
|
+
console.log(chalk4.green(`Loaded config from ${configFilePath}`));
|
|
213
|
+
if (config.verbose) {
|
|
214
|
+
console.log(chalk4.gray(`${JSON.stringify(config, null, 2)}`));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return deepmerge(config, params ?? {});
|
|
219
|
+
};
|
|
220
|
+
async function loadWorkspaceConfig(workspaceDir) {
|
|
221
|
+
const cached = workspaceConfigCache.get(workspaceDir);
|
|
222
|
+
if (cached !== void 0) return cached;
|
|
223
|
+
const result = await createExplorer().search(workspaceDir);
|
|
224
|
+
if (!result || result.filepath === rootConfigPath) {
|
|
225
|
+
workspaceConfigCache.set(workspaceDir, {});
|
|
226
|
+
return {};
|
|
227
|
+
}
|
|
228
|
+
const wsConfig = result.config ?? {};
|
|
229
|
+
workspaceConfigCache.set(workspaceDir, wsConfig);
|
|
230
|
+
return wsConfig;
|
|
231
|
+
}
|
|
232
|
+
var DEPRECATED_COMMAND_FIELDS = /* @__PURE__ */ new Set(["deplint", "publint"]);
|
|
233
|
+
function resolveCommandField(cfg, commandName, configPath) {
|
|
234
|
+
const commands = cfg.commands;
|
|
235
|
+
const fromCommands = commands?.[commandName];
|
|
236
|
+
const fromTopLevel = cfg[commandName];
|
|
237
|
+
if (fromCommands !== void 0 && typeof fromCommands === "object") {
|
|
238
|
+
return fromCommands;
|
|
239
|
+
}
|
|
240
|
+
if (fromTopLevel !== void 0 && typeof fromTopLevel === "object" && DEPRECATED_COMMAND_FIELDS.has(commandName)) {
|
|
241
|
+
const key = `${configPath ?? "unknown"}:${commandName}`;
|
|
242
|
+
if (!deprecationWarned.has(key)) {
|
|
243
|
+
deprecationWarned.add(key);
|
|
244
|
+
console.warn(chalk4.yellow(
|
|
245
|
+
`[xy] Deprecated: top-level "${commandName}" in ${configPath ?? "xy.config"} \u2014 move to "commands.${commandName}"`
|
|
246
|
+
));
|
|
247
|
+
}
|
|
248
|
+
return fromTopLevel;
|
|
249
|
+
}
|
|
250
|
+
return {};
|
|
251
|
+
}
|
|
252
|
+
async function loadWorkspaceCommandConfig(workspaceDir, commandName) {
|
|
253
|
+
const root = await loadConfig();
|
|
254
|
+
const rootCmd = resolveCommandField(root, commandName, rootConfigPath);
|
|
255
|
+
const wsConfig = await loadWorkspaceConfig(workspaceDir);
|
|
256
|
+
const wsConfigPath = workspaceConfigCache.has(workspaceDir) ? workspaceDir : void 0;
|
|
257
|
+
const wsCmd = resolveCommandField(wsConfig, commandName, wsConfigPath);
|
|
258
|
+
return deepmerge(rootCmd, wsCmd);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// src/lib/packageName.ts
|
|
262
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
263
|
+
import path from "path";
|
|
264
|
+
function packageName() {
|
|
265
|
+
if (process.env.npm_package_name) {
|
|
266
|
+
return process.env.npm_package_name;
|
|
267
|
+
}
|
|
268
|
+
try {
|
|
269
|
+
const pkgPath = path.join(INIT_CWD(), "package.json");
|
|
270
|
+
const pkg = JSON.parse(readFileSync2(pkgPath, "utf8"));
|
|
271
|
+
return pkg.name;
|
|
272
|
+
} catch {
|
|
273
|
+
return void 0;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// src/lib/runInstall.ts
|
|
278
|
+
import { spawnSync } from "child_process";
|
|
279
|
+
import chalk5 from "chalk";
|
|
280
|
+
function runInstall(cwd) {
|
|
281
|
+
const pm = detectPackageManager();
|
|
282
|
+
console.log(chalk5.gray(`Running ${pm} install...`));
|
|
283
|
+
const result = spawnSync(pm, ["install"], {
|
|
284
|
+
cwd,
|
|
285
|
+
stdio: "inherit"
|
|
286
|
+
});
|
|
287
|
+
if (result.status !== 0) {
|
|
288
|
+
console.warn(chalk5.yellow(`${pm} install failed`));
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
console.log(chalk5.green("Dependencies installed"));
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// src/lib/runSteps.ts
|
|
296
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
297
|
+
import { existsSync as existsSync2 } from "fs";
|
|
298
|
+
import chalk6 from "chalk";
|
|
299
|
+
var runSteps = (name, steps, exitOnFail = true, messages) => {
|
|
300
|
+
return safeExit(() => {
|
|
301
|
+
const pkgName = packageName();
|
|
302
|
+
console.log(chalk6.green(`${name} [${pkgName}]`));
|
|
303
|
+
let totalStatus = 0;
|
|
304
|
+
for (const [i, [command, args, config2]] of steps.entries()) {
|
|
305
|
+
if (messages?.[i]) {
|
|
306
|
+
console.log(chalk6.gray(messages?.[i]));
|
|
307
|
+
}
|
|
308
|
+
const argList = Array.isArray(args) ? args : args.split(" ");
|
|
309
|
+
if (command === "node" && !existsSync2(argList[0])) {
|
|
310
|
+
throw new Error(`File not found [${argList[0]}]`);
|
|
311
|
+
}
|
|
312
|
+
const status = spawnSync2(command, Array.isArray(args) ? args : args.split(" "), {
|
|
313
|
+
...config2,
|
|
314
|
+
encoding: "utf8",
|
|
315
|
+
env: { FORCE_COLOR: "3", ...process.env },
|
|
316
|
+
shell: true,
|
|
317
|
+
stdio: "inherit"
|
|
318
|
+
}).status ?? 0;
|
|
319
|
+
checkResult(name, status, "error", exitOnFail);
|
|
320
|
+
totalStatus += status ?? 0;
|
|
321
|
+
}
|
|
322
|
+
return totalStatus;
|
|
323
|
+
}, !!exitOnFail);
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
// src/actions/cycle.ts
|
|
327
|
+
import { cruise } from "dependency-cruiser";
|
|
328
|
+
var cycle = async ({ verbose, pkg }) => {
|
|
329
|
+
return pkg ? cyclePackage({ pkg, verbose }) : await cycleAll({ verbose });
|
|
330
|
+
};
|
|
331
|
+
var cyclePackage = ({ pkg, verbose }) => {
|
|
332
|
+
const pm = getPackageManager();
|
|
333
|
+
const verboseOptions = verbose ? ["--verbose"] : ["--no-verbose"];
|
|
334
|
+
return runSteps(
|
|
335
|
+
`Cycle [${pkg}]`,
|
|
336
|
+
[pm.runInWorkspace(pkg, "package-cycle", verboseOptions)]
|
|
337
|
+
);
|
|
338
|
+
};
|
|
339
|
+
var cycleAll = async ({ verbose = false }) => {
|
|
340
|
+
const pkgName = packageName();
|
|
341
|
+
let exitCode = 0;
|
|
342
|
+
const pm = getPackageManager();
|
|
343
|
+
const workspaces = pm.listWorkspaces();
|
|
344
|
+
const workspaceCycles = detectWorkspaceCycles(workspaces);
|
|
345
|
+
if (workspaceCycles.length > 0) {
|
|
346
|
+
console.error(`${pkgName} workspace dependency graph has ${workspaceCycles.length} cycle(s):`);
|
|
347
|
+
printWorkspaceCycles(workspaceCycles);
|
|
348
|
+
exitCode = 1;
|
|
349
|
+
} else if (verbose) {
|
|
350
|
+
console.log(`${pkgName} workspace dependency graph has no cycles`);
|
|
351
|
+
}
|
|
352
|
+
const cruiseOptions = {
|
|
353
|
+
ruleSet: {
|
|
354
|
+
forbidden: [
|
|
355
|
+
{
|
|
356
|
+
name: "no-circular",
|
|
357
|
+
severity: "error",
|
|
358
|
+
comment: "This dependency creates a circular reference",
|
|
359
|
+
from: {},
|
|
360
|
+
to: { circular: true }
|
|
361
|
+
}
|
|
362
|
+
]
|
|
363
|
+
},
|
|
364
|
+
exclude: "node_modules|packages/.*/packages",
|
|
365
|
+
validate: true,
|
|
366
|
+
doNotFollow: { path: "node_modules|packages/.*/packages" },
|
|
367
|
+
tsPreCompilationDeps: false,
|
|
368
|
+
combinedDependencies: true,
|
|
369
|
+
outputType: verbose ? "text" : "err"
|
|
370
|
+
};
|
|
371
|
+
const target = "**/packages/*/src";
|
|
372
|
+
console.log(`Checking for circular dependencies in ${target}...`);
|
|
373
|
+
const result = await cruise([target], cruiseOptions);
|
|
374
|
+
if (result.output) {
|
|
375
|
+
console.log(result.output);
|
|
376
|
+
}
|
|
377
|
+
if (result.exitCode !== 0) {
|
|
378
|
+
exitCode = result.exitCode;
|
|
379
|
+
}
|
|
380
|
+
if (exitCode === 0) {
|
|
381
|
+
console.log(`${pkgName} \u2705 No dependency violations`);
|
|
382
|
+
} else {
|
|
383
|
+
console.error(`${pkgName} \u274C Dependency violations found`);
|
|
384
|
+
}
|
|
385
|
+
return exitCode;
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
// src/actions/deplint/deplint.ts
|
|
389
|
+
import chalk18 from "chalk";
|
|
390
|
+
|
|
391
|
+
// src/actions/deplint/packageJsonEditor.ts
|
|
392
|
+
import fs2 from "fs";
|
|
393
|
+
import chalk7 from "chalk";
|
|
394
|
+
import sortPackageJson from "sort-package-json";
|
|
395
|
+
|
|
396
|
+
// src/actions/deplint/getRequiredPeerDependencies.ts
|
|
397
|
+
import fs from "fs";
|
|
398
|
+
import path2 from "path";
|
|
399
|
+
function findDepPackageJson(location, dep) {
|
|
400
|
+
let dir = location;
|
|
401
|
+
while (true) {
|
|
402
|
+
const candidate = path2.join(dir, "node_modules", dep, "package.json");
|
|
403
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
404
|
+
const parent = path2.dirname(dir);
|
|
405
|
+
if (parent === dir) return void 0;
|
|
406
|
+
dir = parent;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
function getRequiredPeerDependencies(location, allDeps) {
|
|
410
|
+
const required = /* @__PURE__ */ new Set();
|
|
411
|
+
for (const dep of allDeps) {
|
|
412
|
+
const depPkgPath = findDepPackageJson(location, dep);
|
|
413
|
+
if (!depPkgPath) continue;
|
|
414
|
+
try {
|
|
415
|
+
const raw = fs.readFileSync(depPkgPath, "utf8");
|
|
416
|
+
const pkg = JSON.parse(raw);
|
|
417
|
+
const peerDeps = pkg.peerDependencies;
|
|
418
|
+
if (peerDeps) {
|
|
419
|
+
for (const peer of Object.keys(peerDeps)) {
|
|
420
|
+
required.add(peer);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
} catch {
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return required;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// src/actions/deplint/packageJsonEditor.ts
|
|
430
|
+
function readPackageJson(location) {
|
|
431
|
+
return JSON.parse(fs2.readFileSync(`${location}/package.json`, "utf8"));
|
|
432
|
+
}
|
|
433
|
+
function writePackageJson(location, pkg) {
|
|
434
|
+
const sorted = sortPackageJson(JSON.stringify(pkg, null, 2));
|
|
435
|
+
fs2.writeFileSync(`${location}/package.json`, `${sorted}
|
|
436
|
+
`);
|
|
437
|
+
}
|
|
438
|
+
function moveDep(pkg, dep, from, to) {
|
|
439
|
+
const fromSection = pkg[from];
|
|
440
|
+
if (!fromSection?.[dep]) return;
|
|
441
|
+
const version = fromSection[dep];
|
|
442
|
+
delete fromSection[dep];
|
|
443
|
+
if (Object.keys(fromSection).length === 0) {
|
|
444
|
+
delete pkg[from];
|
|
445
|
+
}
|
|
446
|
+
const toSection = pkg[to] ?? {};
|
|
447
|
+
toSection[dep] = version;
|
|
448
|
+
pkg[to] = toSection;
|
|
449
|
+
}
|
|
450
|
+
function removeDep(pkg, dep, section) {
|
|
451
|
+
const sectionObj = pkg[section];
|
|
452
|
+
if (!sectionObj?.[dep]) return;
|
|
453
|
+
delete sectionObj[dep];
|
|
454
|
+
if (Object.keys(sectionObj).length === 0) {
|
|
455
|
+
delete pkg[section];
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
function addDep(pkg, dep, version, section) {
|
|
459
|
+
const sectionObj = pkg[section] ?? {};
|
|
460
|
+
sectionObj[dep] = version;
|
|
461
|
+
pkg[section] = sectionObj;
|
|
462
|
+
}
|
|
463
|
+
function resolveDepVersion(location, dep) {
|
|
464
|
+
const depPkgPath = findDepPackageJson(location, dep);
|
|
465
|
+
if (depPkgPath) {
|
|
466
|
+
try {
|
|
467
|
+
const depPkg = JSON.parse(fs2.readFileSync(depPkgPath, "utf8"));
|
|
468
|
+
const version = depPkg.version;
|
|
469
|
+
if (version) return `~${version}`;
|
|
470
|
+
} catch {
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return "*";
|
|
474
|
+
}
|
|
475
|
+
function resolveExpectedPeerVersion(location, dep, currentRange) {
|
|
476
|
+
const depPkgPath = findDepPackageJson(location, dep);
|
|
477
|
+
if (depPkgPath) {
|
|
478
|
+
try {
|
|
479
|
+
const depPkg = JSON.parse(fs2.readFileSync(depPkgPath, "utf8"));
|
|
480
|
+
const version = depPkg.version;
|
|
481
|
+
if (version) {
|
|
482
|
+
const match = /^(\d+)\.(\d+)/.exec(version);
|
|
483
|
+
if (match) {
|
|
484
|
+
if (currentRange?.startsWith("^")) {
|
|
485
|
+
return `^${match[1]}`;
|
|
486
|
+
}
|
|
487
|
+
return `~${match[1]}.${match[2]}`;
|
|
488
|
+
}
|
|
489
|
+
return `~${version}`;
|
|
490
|
+
}
|
|
491
|
+
} catch {
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
return "*";
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// src/actions/deplint/packageEditor.ts
|
|
498
|
+
var DeplintPackageEditor = class {
|
|
499
|
+
constructor(workspace) {
|
|
500
|
+
this.workspace = workspace;
|
|
501
|
+
this.pkg = readPackageJson(workspace.location);
|
|
502
|
+
}
|
|
503
|
+
workspace;
|
|
504
|
+
pkg;
|
|
505
|
+
applyFix(fix2) {
|
|
506
|
+
switch (fix2.action) {
|
|
507
|
+
case "add": {
|
|
508
|
+
addDep(this.pkg, fix2.dependency, fix2.version, fix2.section);
|
|
509
|
+
break;
|
|
510
|
+
}
|
|
511
|
+
case "move": {
|
|
512
|
+
moveDep(this.pkg, fix2.dependency, fix2.fromSection, fix2.toSection);
|
|
513
|
+
if (fix2.version !== void 0 && this.pkg[fix2.toSection]?.[fix2.dependency] !== void 0) {
|
|
514
|
+
this.pkg[fix2.toSection][fix2.dependency] = fix2.version;
|
|
515
|
+
}
|
|
516
|
+
break;
|
|
517
|
+
}
|
|
518
|
+
case "remove": {
|
|
519
|
+
removeDep(this.pkg, fix2.dependency, fix2.section);
|
|
520
|
+
break;
|
|
521
|
+
}
|
|
522
|
+
case "set-version": {
|
|
523
|
+
addDep(this.pkg, fix2.dependency, fix2.version, fix2.section);
|
|
524
|
+
break;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
return {
|
|
528
|
+
dependency: fix2.dependency,
|
|
529
|
+
detail: fix2.detail,
|
|
530
|
+
workspace: this.workspace
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
save() {
|
|
534
|
+
writePackageJson(this.workspace.location, this.pkg);
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
// src/actions/deplint/fixer.ts
|
|
539
|
+
function applyDeplintFixes(diagnostics) {
|
|
540
|
+
const editors = /* @__PURE__ */ new Map();
|
|
541
|
+
const applied = [];
|
|
542
|
+
for (const diagnostic2 of diagnostics) {
|
|
543
|
+
for (const fix2 of diagnostic2.fixes ?? []) {
|
|
544
|
+
const workspaceKey = diagnostic2.workspace.location;
|
|
545
|
+
let editor = editors.get(workspaceKey);
|
|
546
|
+
if (!editor) {
|
|
547
|
+
editor = new DeplintPackageEditor(diagnostic2.workspace);
|
|
548
|
+
editors.set(workspaceKey, editor);
|
|
549
|
+
}
|
|
550
|
+
applied.push(editor.applyFix(fix2));
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
for (const editor of editors.values()) {
|
|
554
|
+
editor.save();
|
|
555
|
+
}
|
|
556
|
+
return applied;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// src/actions/deplint/findFiles.ts
|
|
560
|
+
import fs3 from "fs";
|
|
561
|
+
|
|
562
|
+
// src/actions/deplint/findFilesByGlob.ts
|
|
563
|
+
import { globSync } from "glob";
|
|
564
|
+
function findFilesByGlob(cwd, pattern, ignore) {
|
|
565
|
+
return globSync(pattern, {
|
|
566
|
+
cwd,
|
|
567
|
+
absolute: true,
|
|
568
|
+
ignore,
|
|
569
|
+
nodir: true
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// src/actions/deplint/findFiles.ts
|
|
574
|
+
var codeExtensions = "*.{ts,tsx,mts,cts,js,mjs,cjs}";
|
|
575
|
+
function getWorkspaceIgnores(location) {
|
|
576
|
+
try {
|
|
577
|
+
const raw = fs3.readFileSync(`${location}/package.json`, "utf8");
|
|
578
|
+
const pkg = JSON.parse(raw);
|
|
579
|
+
return pkg.workspaces ?? [];
|
|
580
|
+
} catch {
|
|
581
|
+
return [];
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
function findFiles(location) {
|
|
585
|
+
const workspaceIgnores = getWorkspaceIgnores(location).map((w) => `${w}/**`);
|
|
586
|
+
const ignore = ["**/node_modules/**", "dist/**", ...workspaceIgnores];
|
|
587
|
+
const allFiles = findFilesByGlob(location, `./**/${codeExtensions}`, ignore);
|
|
588
|
+
const distFiles = [
|
|
589
|
+
...findFilesByGlob(location, "./dist/**/*.d.ts"),
|
|
590
|
+
...findFilesByGlob(location, `./dist/**/${codeExtensions}`)
|
|
591
|
+
];
|
|
592
|
+
return { allFiles, distFiles };
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// src/actions/deplint/getDependenciesFromPackageJson.ts
|
|
596
|
+
import fs4 from "fs";
|
|
597
|
+
import path3 from "path";
|
|
598
|
+
function getDependenciesFromPackageJson(packageJsonPath) {
|
|
599
|
+
const packageJsonFullPath = path3.resolve(packageJsonPath);
|
|
600
|
+
const rawContent = fs4.readFileSync(packageJsonFullPath, "utf8");
|
|
601
|
+
const packageJson = JSON.parse(rawContent);
|
|
602
|
+
const depsRecord = packageJson.dependencies ?? {};
|
|
603
|
+
const devDepsRecord = packageJson.devDependencies ?? {};
|
|
604
|
+
const peerDepsRecord = packageJson.peerDependencies ?? {};
|
|
605
|
+
const dependencies = Object.keys(depsRecord);
|
|
606
|
+
const devDependencies = Object.keys(devDepsRecord);
|
|
607
|
+
const peerDependencies = Object.keys(peerDepsRecord);
|
|
608
|
+
const dependencyVersions = depsRecord;
|
|
609
|
+
const devDependencyVersions = devDepsRecord;
|
|
610
|
+
const peerDependencyVersions = peerDepsRecord;
|
|
611
|
+
return {
|
|
612
|
+
dependencies,
|
|
613
|
+
dependencyVersions,
|
|
614
|
+
devDependencies,
|
|
615
|
+
devDependencyVersions,
|
|
616
|
+
peerDependencies,
|
|
617
|
+
peerDependencyVersions
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
// src/actions/deplint/getExtendsFromTsconfigs.ts
|
|
622
|
+
import fs5 from "fs";
|
|
623
|
+
import { globSync as globSync2 } from "glob";
|
|
624
|
+
|
|
625
|
+
// src/actions/deplint/getBasePackageName.ts
|
|
626
|
+
function getBasePackageName(importName) {
|
|
627
|
+
const importNameScrubbed = importName.replaceAll('"', "").trim();
|
|
628
|
+
if (importNameScrubbed.startsWith("@")) {
|
|
629
|
+
const parts = importNameScrubbed.split("/");
|
|
630
|
+
return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : importNameScrubbed;
|
|
631
|
+
}
|
|
632
|
+
return importNameScrubbed.split("/")[0];
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// src/actions/deplint/getExtendsFromTsconfigs.ts
|
|
636
|
+
var isExternalReference = (ref) => !ref.startsWith(".") && !ref.startsWith("/");
|
|
637
|
+
function parseExtendsField(value) {
|
|
638
|
+
if (typeof value === "string") return [value];
|
|
639
|
+
if (Array.isArray(value)) return value.filter((v) => typeof v === "string");
|
|
640
|
+
return [];
|
|
641
|
+
}
|
|
642
|
+
function parseTypesField(value) {
|
|
643
|
+
if (Array.isArray(value)) return value.filter((v) => typeof v === "string");
|
|
644
|
+
return [];
|
|
645
|
+
}
|
|
646
|
+
function parseTsconfig(file) {
|
|
647
|
+
const content = fs5.readFileSync(file, "utf8");
|
|
648
|
+
const cleaned = content.replaceAll(/\/\/.*/g, "").replaceAll(/,\s*([}\]])/g, "$1");
|
|
649
|
+
return JSON.parse(cleaned);
|
|
650
|
+
}
|
|
651
|
+
function getExtendsFromTsconfigs(location) {
|
|
652
|
+
const tsconfigFiles = globSync2("./tsconfig*.json", { cwd: location, absolute: true });
|
|
653
|
+
const packages = /* @__PURE__ */ new Set();
|
|
654
|
+
for (const file of tsconfigFiles) {
|
|
655
|
+
try {
|
|
656
|
+
const parsed = parseTsconfig(file);
|
|
657
|
+
const refs = parseExtendsField(parsed.extends);
|
|
658
|
+
for (const ref of refs) {
|
|
659
|
+
if (isExternalReference(ref)) {
|
|
660
|
+
packages.add(getBasePackageName(ref));
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
} catch {
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
return [...packages];
|
|
667
|
+
}
|
|
668
|
+
function getTypesFromTsconfigs(location) {
|
|
669
|
+
const tsconfigFiles = globSync2("./tsconfig*.json", { cwd: location, absolute: true });
|
|
670
|
+
const packages = /* @__PURE__ */ new Set();
|
|
671
|
+
for (const file of tsconfigFiles) {
|
|
672
|
+
try {
|
|
673
|
+
const parsed = parseTsconfig(file);
|
|
674
|
+
const compilerOptions = parsed.compilerOptions;
|
|
675
|
+
const refs = parseTypesField(compilerOptions?.types);
|
|
676
|
+
for (const ref of refs) {
|
|
677
|
+
packages.add(getBasePackageName(ref));
|
|
678
|
+
}
|
|
679
|
+
} catch {
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
return [...packages];
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// src/actions/deplint/getExternalImportsFromFiles.ts
|
|
686
|
+
import fs7 from "fs";
|
|
687
|
+
|
|
688
|
+
// src/actions/deplint/getImportsFromFile.ts
|
|
689
|
+
import fs6 from "fs";
|
|
690
|
+
import path4 from "path";
|
|
691
|
+
import ts from "typescript";
|
|
692
|
+
function isTypeOnlyImportClause(clause) {
|
|
693
|
+
if (clause === void 0) {
|
|
694
|
+
return false;
|
|
695
|
+
}
|
|
696
|
+
if ("phaseModifier" in clause) {
|
|
697
|
+
const mod = clause.phaseModifier;
|
|
698
|
+
const kind = typeof mod === "number" ? mod : mod?.kind;
|
|
699
|
+
return kind === ts.SyntaxKind.TypeKeyword;
|
|
700
|
+
}
|
|
701
|
+
return clause.isTypeOnly ?? false;
|
|
702
|
+
}
|
|
703
|
+
function getImportsFromFile(filePath, importPaths, typeImportPaths) {
|
|
704
|
+
const sourceCode = fs6.readFileSync(filePath, "utf8");
|
|
705
|
+
const isMjsFile = filePath.endsWith(".mjs");
|
|
706
|
+
const sourceFile = ts.createSourceFile(
|
|
707
|
+
path4.basename(filePath),
|
|
708
|
+
sourceCode,
|
|
709
|
+
ts.ScriptTarget.Latest,
|
|
710
|
+
true,
|
|
711
|
+
isMjsFile ? ts.ScriptKind.JS : void 0
|
|
712
|
+
);
|
|
713
|
+
const imports = [];
|
|
714
|
+
const typeImports = [];
|
|
715
|
+
const isDeclarationFile2 = filePath.endsWith(".d.ts");
|
|
716
|
+
function visit(node) {
|
|
717
|
+
if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
|
|
718
|
+
const moduleSpecifier = node.moduleSpecifier?.getFullText();
|
|
719
|
+
const isTypeImport = ts.isImportDeclaration(node) ? isTypeOnlyImportClause(node.importClause) : false;
|
|
720
|
+
if (typeof moduleSpecifier === "string") {
|
|
721
|
+
const trimmed = moduleSpecifier.replaceAll("'", "").replaceAll('"', "").trim();
|
|
722
|
+
if (isTypeImport || isDeclarationFile2) {
|
|
723
|
+
typeImports.push(trimmed);
|
|
724
|
+
} else {
|
|
725
|
+
imports.push(trimmed);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
} else if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
|
729
|
+
const [arg] = node.arguments;
|
|
730
|
+
if (ts.isStringLiteral(arg)) {
|
|
731
|
+
imports.push(arg.text);
|
|
732
|
+
}
|
|
733
|
+
} else if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "require" && node.arguments.length > 0 && ts.isStringLiteral(node.arguments[0])) {
|
|
734
|
+
imports.push(node.arguments[0].text);
|
|
735
|
+
}
|
|
736
|
+
ts.forEachChild(node, visit);
|
|
737
|
+
}
|
|
738
|
+
visit(sourceFile);
|
|
739
|
+
for (const ref of sourceFile.typeReferenceDirectives) {
|
|
740
|
+
typeImports.push(ref.fileName);
|
|
741
|
+
}
|
|
742
|
+
const importsStartsWithExcludes = [".", "#", "node:"];
|
|
743
|
+
const isValidImport = (imp) => !importsStartsWithExcludes.some((exc) => imp.startsWith(exc)) && !imp.includes("*") && !imp.includes("!");
|
|
744
|
+
const cleanedImports = imports.filter(isValidImport).map(getBasePackageName);
|
|
745
|
+
const cleanedTypeImports = typeImports.filter(isValidImport).map(getBasePackageName);
|
|
746
|
+
for (const imp of cleanedImports) {
|
|
747
|
+
importPaths[imp] = importPaths[imp] ?? [];
|
|
748
|
+
importPaths[imp].push(filePath);
|
|
749
|
+
}
|
|
750
|
+
for (const imp of cleanedTypeImports) {
|
|
751
|
+
typeImportPaths[imp] = typeImportPaths[imp] ?? [];
|
|
752
|
+
typeImportPaths[imp].push(filePath);
|
|
753
|
+
}
|
|
754
|
+
return [cleanedImports, cleanedTypeImports];
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// src/actions/deplint/getExternalImportsFromFiles.ts
|
|
758
|
+
var internalImportPrefixes = [".", "#", "node:"];
|
|
759
|
+
var removeInternalImports = (imports) => {
|
|
760
|
+
return imports.filter((imp) => !internalImportPrefixes.some((prefix) => imp.startsWith(prefix)));
|
|
761
|
+
};
|
|
762
|
+
var isDeclarationFile = (file) => file.endsWith(".d.ts") || file.endsWith(".d.cts") || file.endsWith(".d.mts");
|
|
763
|
+
function shipsTsconfig(location) {
|
|
764
|
+
try {
|
|
765
|
+
const raw = fs7.readFileSync(`${location}/package.json`, "utf8");
|
|
766
|
+
const pkg = JSON.parse(raw);
|
|
767
|
+
const files = pkg.files;
|
|
768
|
+
return files?.some((f) => f === "tsconfig.json" || f.includes("tsconfig")) ?? false;
|
|
769
|
+
} catch {
|
|
770
|
+
return false;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
function getExternalImportsFromFiles({
|
|
774
|
+
allFiles,
|
|
775
|
+
distFiles,
|
|
776
|
+
location,
|
|
777
|
+
tsconfigExtends = [],
|
|
778
|
+
tsconfigTypes = []
|
|
779
|
+
}) {
|
|
780
|
+
const allImportPaths = {};
|
|
781
|
+
const distImportPaths = {};
|
|
782
|
+
const distTypeImportPaths = {};
|
|
783
|
+
for (const path9 of allFiles) getImportsFromFile(path9, allImportPaths, allImportPaths).flat();
|
|
784
|
+
const distTypeFiles = distFiles.filter(isDeclarationFile);
|
|
785
|
+
const distCodeFiles = distFiles.filter((file) => !isDeclarationFile(file));
|
|
786
|
+
for (const path9 of distCodeFiles) getImportsFromFile(path9, distImportPaths, distImportPaths).flat();
|
|
787
|
+
for (const path9 of distTypeFiles) getImportsFromFile(path9, distTypeImportPaths, distTypeImportPaths).flat();
|
|
788
|
+
const allImports = Object.keys(allImportPaths);
|
|
789
|
+
const distImports = Object.keys(distImportPaths);
|
|
790
|
+
const externalAllImports = removeInternalImports(allImports);
|
|
791
|
+
const externalDistImports = removeInternalImports(distImports);
|
|
792
|
+
const externalDistTypeImports = removeInternalImports(Object.keys(distTypeImportPaths));
|
|
793
|
+
const isDistTsconfig = shipsTsconfig(location);
|
|
794
|
+
for (const ext of tsconfigExtends) {
|
|
795
|
+
if (!externalAllImports.includes(ext)) externalAllImports.push(ext);
|
|
796
|
+
if (isDistTsconfig && !externalDistImports.includes(ext)) externalDistImports.push(ext);
|
|
797
|
+
}
|
|
798
|
+
for (const typ of tsconfigTypes) {
|
|
799
|
+
if (!externalAllImports.includes(typ)) externalAllImports.push(typ);
|
|
800
|
+
}
|
|
801
|
+
return {
|
|
802
|
+
allImportPaths,
|
|
803
|
+
allImports,
|
|
804
|
+
distImportPaths,
|
|
805
|
+
distImports,
|
|
806
|
+
externalAllImports,
|
|
807
|
+
externalDistImports,
|
|
808
|
+
externalDistTypeImports,
|
|
809
|
+
tsconfigExtends: [...tsconfigExtends]
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
// src/actions/deplint/checkPackage/getMismatchedPeerDevVersions.ts
|
|
814
|
+
import chalk8 from "chalk";
|
|
815
|
+
import semver from "semver";
|
|
816
|
+
function findMismatchedPeerDevVersions({
|
|
817
|
+
peerDependencies,
|
|
818
|
+
peerDependencyVersions,
|
|
819
|
+
devDependencyVersions
|
|
820
|
+
}, exclude) {
|
|
821
|
+
const mismatches = [];
|
|
822
|
+
for (const dep of peerDependencies) {
|
|
823
|
+
if (exclude?.has(dep)) continue;
|
|
824
|
+
const peerVersion = peerDependencyVersions[dep];
|
|
825
|
+
const devVersion = devDependencyVersions[dep];
|
|
826
|
+
const hasWorkspaceProtocol = devVersion?.startsWith("workspace:") || peerVersion?.startsWith("workspace:");
|
|
827
|
+
if (devVersion && peerVersion !== devVersion && !hasWorkspaceProtocol && !semver.subset(devVersion, peerVersion)) {
|
|
828
|
+
mismatches.push({
|
|
829
|
+
dep,
|
|
830
|
+
devVersion,
|
|
831
|
+
peerVersion
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
return mismatches;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// src/actions/deplint/checkPackage/getUnlistedDependencies.ts
|
|
839
|
+
import fs8 from "fs";
|
|
840
|
+
import { builtinModules } from "module";
|
|
841
|
+
import chalk9 from "chalk";
|
|
842
|
+
|
|
843
|
+
// src/actions/deplint/tsScriptsAliases.ts
|
|
844
|
+
var VARIANT_MAP = {
|
|
845
|
+
"@xylabs/ts-scripts-yarn3": "@xylabs/ts-scripts-pnpm",
|
|
846
|
+
"@xylabs/ts-scripts-pnpm": "@xylabs/ts-scripts-yarn3",
|
|
847
|
+
"@xylabs/ts-scripts-react-yarn3": "@xylabs/ts-scripts-react-pnpm",
|
|
848
|
+
"@xylabs/ts-scripts-react-pnpm": "@xylabs/ts-scripts-react-yarn3"
|
|
849
|
+
};
|
|
850
|
+
function isSatisfiedByTsScriptsVariant(imp, allDeps) {
|
|
851
|
+
const variant = VARIANT_MAP[imp];
|
|
852
|
+
return variant !== void 0 && allDeps.includes(variant);
|
|
853
|
+
}
|
|
854
|
+
function isUsedViaTsScriptsVariant(dep, imports) {
|
|
855
|
+
const variant = VARIANT_MAP[dep];
|
|
856
|
+
return variant !== void 0 && imports.includes(variant);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// src/actions/deplint/checkPackage/getUnlistedDependencies.ts
|
|
860
|
+
function isRuntimeImportListed(imp, name, dependencies, peerDependencies) {
|
|
861
|
+
return dependencies.includes(imp) || imp === name || peerDependencies.includes(imp) || builtinModules.includes(imp);
|
|
862
|
+
}
|
|
863
|
+
function isDistTypeImportListed(imp, name, dependencies, devDependencies, peerDependencies) {
|
|
864
|
+
return dependencies.includes(imp) || imp === name || dependencies.includes(`@types/${imp}`) || devDependencies.includes(`@types/${imp}`) || peerDependencies.includes(imp) || peerDependencies.includes(`@types/${imp}`) || builtinModules.includes(imp);
|
|
865
|
+
}
|
|
866
|
+
function shouldBePeerDependency(imp, location, currentPeers, distImports) {
|
|
867
|
+
if (currentPeers.length === 0) return false;
|
|
868
|
+
const depPkgPath = findDepPackageJson(location, imp);
|
|
869
|
+
if (!depPkgPath) return false;
|
|
870
|
+
try {
|
|
871
|
+
const pkg = JSON.parse(fs8.readFileSync(depPkgPath, "utf8"));
|
|
872
|
+
const importPeers = Object.keys(pkg.peerDependencies ?? {});
|
|
873
|
+
return importPeers.length > 0 && importPeers.every(
|
|
874
|
+
(peer) => currentPeers.includes(peer) && distImports.includes(peer)
|
|
875
|
+
);
|
|
876
|
+
} catch {
|
|
877
|
+
return false;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
function findUnlistedDependencies(name, dependencies, devDependencies, peerDependencies, externalDistImports, externalDistTypeImports) {
|
|
881
|
+
const allDeps = [...dependencies, ...devDependencies, ...peerDependencies];
|
|
882
|
+
const results = [];
|
|
883
|
+
for (const imp of externalDistImports) {
|
|
884
|
+
if (!isRuntimeImportListed(imp, name, dependencies, peerDependencies) && !isSatisfiedByTsScriptsVariant(imp, allDeps)) {
|
|
885
|
+
results.push({ imp, section: "dependencies" });
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
for (const imp of externalDistTypeImports) {
|
|
889
|
+
if (!isDistTypeImportListed(imp, name, dependencies, devDependencies, peerDependencies) && !isSatisfiedByTsScriptsVariant(imp, allDeps)) {
|
|
890
|
+
results.push({ imp, section: "dependencies" });
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
return results;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
// src/actions/deplint/checkPackage/getUnlistedDevDependencies.ts
|
|
897
|
+
import { builtinModules as builtinModules2 } from "module";
|
|
898
|
+
import chalk10 from "chalk";
|
|
899
|
+
function findUnlistedDevDeps(name, dependencies, devDependencies, peerDependencies, externalAllImports, distImports, externalDistTypeImports) {
|
|
900
|
+
const results = [];
|
|
901
|
+
for (const imp of externalAllImports) {
|
|
902
|
+
if (!distImports.includes(imp) && !externalDistTypeImports.includes(imp) && imp !== name && !dependencies.includes(imp) && !dependencies.includes(`@types/${imp}`) && !peerDependencies.includes(imp) && !peerDependencies.includes(`@types/${imp}`) && !devDependencies.includes(imp) && !devDependencies.includes(`@types/${imp}`) && !builtinModules2.includes(imp) && !isSatisfiedByTsScriptsVariant(imp, [...dependencies, ...devDependencies, ...peerDependencies])) {
|
|
903
|
+
results.push(imp);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
return results;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// src/actions/deplint/checkPackage/getUnnecessaryPeerDependencies.ts
|
|
910
|
+
import fs10 from "fs";
|
|
911
|
+
import chalk12 from "chalk";
|
|
912
|
+
|
|
913
|
+
// src/actions/deplint/checkPackage/getUnsatisfiedPeerDependencies.ts
|
|
914
|
+
import fs9 from "fs";
|
|
915
|
+
import chalk11 from "chalk";
|
|
916
|
+
import semver2 from "semver";
|
|
917
|
+
import sortPackageJson2 from "sort-package-json";
|
|
918
|
+
function readDepPackageJson(location, dep) {
|
|
919
|
+
const depPkgPath = findDepPackageJson(location, dep);
|
|
920
|
+
if (!depPkgPath) return void 0;
|
|
921
|
+
try {
|
|
922
|
+
return JSON.parse(fs9.readFileSync(depPkgPath, "utf8"));
|
|
923
|
+
} catch {
|
|
924
|
+
return void 0;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
function readPeerDeps(location, dep) {
|
|
928
|
+
const pkg = readDepPackageJson(location, dep);
|
|
929
|
+
if (!pkg) return [];
|
|
930
|
+
const peers = pkg.peerDependencies;
|
|
931
|
+
return Object.keys(peers ?? {});
|
|
932
|
+
}
|
|
933
|
+
function readPeerVersionRange(location, dep, peer) {
|
|
934
|
+
const pkg = readDepPackageJson(location, dep);
|
|
935
|
+
if (!pkg) return void 0;
|
|
936
|
+
const peers = pkg.peerDependencies;
|
|
937
|
+
return peers?.[peer];
|
|
938
|
+
}
|
|
939
|
+
function readInstalledVersion(location, dep) {
|
|
940
|
+
const pkg = readDepPackageJson(location, dep);
|
|
941
|
+
if (!pkg) return void 0;
|
|
942
|
+
return pkg.version;
|
|
943
|
+
}
|
|
944
|
+
function isPeerOptionalInAll(location, peer, sources) {
|
|
945
|
+
for (const source of sources) {
|
|
946
|
+
const pkg = readDepPackageJson(location, source.requiredBy);
|
|
947
|
+
if (!pkg) continue;
|
|
948
|
+
const meta = pkg.peerDependenciesMeta?.[peer];
|
|
949
|
+
if (!meta?.optional) return false;
|
|
950
|
+
}
|
|
951
|
+
return true;
|
|
952
|
+
}
|
|
953
|
+
var MAX_TRANSITIVE_DEPTH = 2;
|
|
954
|
+
function collectPeerSources(location, dependencies, devDependencies) {
|
|
955
|
+
const peerSources = /* @__PURE__ */ new Map();
|
|
956
|
+
const visited = /* @__PURE__ */ new Set();
|
|
957
|
+
function addPeerSource(peer, source) {
|
|
958
|
+
const sources = peerSources.get(peer) ?? [];
|
|
959
|
+
sources.push(source);
|
|
960
|
+
peerSources.set(peer, sources);
|
|
961
|
+
}
|
|
962
|
+
function collectFromDeps(deps, isRuntime, chain) {
|
|
963
|
+
for (const dep of deps) {
|
|
964
|
+
const visitKey = `${dep}:${chain.join(">")}`;
|
|
965
|
+
if (visited.has(visitKey)) continue;
|
|
966
|
+
visited.add(visitKey);
|
|
967
|
+
for (const peer of readPeerDeps(location, dep)) {
|
|
968
|
+
addPeerSource(peer, {
|
|
969
|
+
chain: chain.length > 0 ? [...chain, dep] : void 0,
|
|
970
|
+
isRuntimeDep: isRuntime,
|
|
971
|
+
requiredBy: dep
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
if (chain.length < MAX_TRANSITIVE_DEPTH) {
|
|
975
|
+
const depPkg = readDepPackageJson(location, dep);
|
|
976
|
+
if (depPkg) {
|
|
977
|
+
const transitiveDeps = Object.keys(depPkg.dependencies ?? {});
|
|
978
|
+
collectFromDeps(transitiveDeps, isRuntime, [...chain, dep]);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
collectFromDeps(dependencies, true, []);
|
|
984
|
+
const devOnly = devDependencies.filter((d) => !dependencies.includes(d));
|
|
985
|
+
collectFromDeps(devOnly, false, []);
|
|
986
|
+
return peerSources;
|
|
987
|
+
}
|
|
988
|
+
function getRequiredTransitivePeers(location, { dependencies, devDependencies }) {
|
|
989
|
+
const peerSources = collectPeerSources(location, dependencies, devDependencies);
|
|
990
|
+
return new Set(peerSources.keys());
|
|
991
|
+
}
|
|
992
|
+
function resolveVersionRange(location, sources, peer) {
|
|
993
|
+
for (const source of sources) {
|
|
994
|
+
const range = readPeerVersionRange(location, source.requiredBy, peer);
|
|
995
|
+
if (range) return range;
|
|
996
|
+
}
|
|
997
|
+
return "*";
|
|
998
|
+
}
|
|
999
|
+
function checkVersionSatisfaction(location, peer, requestedRange) {
|
|
1000
|
+
const installedVersion = readInstalledVersion(location, peer);
|
|
1001
|
+
if (!installedVersion) return { satisfied: true };
|
|
1002
|
+
if (requestedRange === "*") return { installedVersion, satisfied: true };
|
|
1003
|
+
if (requestedRange.startsWith("workspace:")) return { installedVersion, satisfied: true };
|
|
1004
|
+
try {
|
|
1005
|
+
const satisfied = semver2.satisfies(installedVersion, requestedRange, { includePrerelease: true });
|
|
1006
|
+
return { installedVersion, satisfied };
|
|
1007
|
+
} catch {
|
|
1008
|
+
return { installedVersion, satisfied: true };
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
function findDeclaredPeerVersionMismatches(name, location, peerDependencies, peerDependencyVersions, exclude) {
|
|
1012
|
+
const results = [];
|
|
1013
|
+
for (const peer of peerDependencies) {
|
|
1014
|
+
if (exclude?.has(peer) || peer === name) continue;
|
|
1015
|
+
const declaredRange = peerDependencyVersions[peer];
|
|
1016
|
+
if (!declaredRange || declaredRange === "*") continue;
|
|
1017
|
+
const { installedVersion, satisfied } = checkVersionSatisfaction(location, peer, declaredRange);
|
|
1018
|
+
if (!satisfied) {
|
|
1019
|
+
results.push({
|
|
1020
|
+
hasRuntimeSource: true,
|
|
1021
|
+
installedVersion,
|
|
1022
|
+
peer,
|
|
1023
|
+
reason: "version-mismatch",
|
|
1024
|
+
sources: [{ isRuntimeDep: true, requiredBy: name }],
|
|
1025
|
+
versionRange: declaredRange
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
return results;
|
|
1030
|
+
}
|
|
1031
|
+
function findUnsatisfiedPeers({ name, location }, {
|
|
1032
|
+
dependencies,
|
|
1033
|
+
devDependencies,
|
|
1034
|
+
peerDependencies,
|
|
1035
|
+
peerDependencyVersions
|
|
1036
|
+
}, exclude) {
|
|
1037
|
+
const peerSources = collectPeerSources(location, dependencies, devDependencies);
|
|
1038
|
+
const depsSet = new Set(dependencies);
|
|
1039
|
+
const devDepsSet = new Set(devDependencies);
|
|
1040
|
+
const unsatisfied = [];
|
|
1041
|
+
for (const [peer, sources] of peerSources) {
|
|
1042
|
+
if (exclude?.has(peer) || peer === name) continue;
|
|
1043
|
+
if (isPeerOptionalInAll(location, peer, sources)) continue;
|
|
1044
|
+
const hasRuntimeSource = sources.some((s) => s.isRuntimeDep);
|
|
1045
|
+
const isPresent = depsSet.has(peer) || devDepsSet.has(peer);
|
|
1046
|
+
if (!isPresent) {
|
|
1047
|
+
const versionRange2 = resolveVersionRange(location, sources, peer);
|
|
1048
|
+
unsatisfied.push({
|
|
1049
|
+
hasRuntimeSource,
|
|
1050
|
+
peer,
|
|
1051
|
+
reason: "missing",
|
|
1052
|
+
sources,
|
|
1053
|
+
versionRange: versionRange2
|
|
1054
|
+
});
|
|
1055
|
+
continue;
|
|
1056
|
+
}
|
|
1057
|
+
const versionRange = resolveVersionRange(location, sources, peer);
|
|
1058
|
+
const { installedVersion, satisfied } = checkVersionSatisfaction(location, peer, versionRange);
|
|
1059
|
+
if (!satisfied) {
|
|
1060
|
+
unsatisfied.push({
|
|
1061
|
+
hasRuntimeSource,
|
|
1062
|
+
installedVersion,
|
|
1063
|
+
peer,
|
|
1064
|
+
reason: "version-mismatch",
|
|
1065
|
+
sources,
|
|
1066
|
+
versionRange
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
return [
|
|
1071
|
+
...unsatisfied,
|
|
1072
|
+
...findDeclaredPeerVersionMismatches(name, location, peerDependencies, peerDependencyVersions, exclude)
|
|
1073
|
+
];
|
|
1074
|
+
}
|
|
1075
|
+
function resolvePeerTargetSections(hasRuntimeSource, isTerminal) {
|
|
1076
|
+
if (!hasRuntimeSource) return ["devDependencies"];
|
|
1077
|
+
if (isTerminal) return ["dependencies"];
|
|
1078
|
+
return ["peerDependencies", "devDependencies"];
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
// src/actions/deplint/checkPackage/getUnnecessaryPeerDependencies.ts
|
|
1082
|
+
function isPeerImportedInDist(dep, externalDistImports, externalDistTypeImports) {
|
|
1083
|
+
const baseName = dep.replace(/^@types\//, "");
|
|
1084
|
+
return externalDistImports.includes(dep) || externalDistImports.includes(baseName) || externalDistTypeImports.includes(dep) || externalDistTypeImports.includes(baseName);
|
|
1085
|
+
}
|
|
1086
|
+
function findUnrequestedPeerDeps(location, packageParams, { externalDistImports, externalDistTypeImports }, exclude) {
|
|
1087
|
+
const requiredPeers = getRequiredTransitivePeers(location, packageParams);
|
|
1088
|
+
const unrequested = [];
|
|
1089
|
+
for (const dep of packageParams.peerDependencies) {
|
|
1090
|
+
if (exclude?.has(dep)) continue;
|
|
1091
|
+
if (packageParams.dependencies.includes(dep)) continue;
|
|
1092
|
+
if (!isPeerImportedInDist(dep, externalDistImports, externalDistTypeImports)) continue;
|
|
1093
|
+
if (!requiredPeers.has(dep)) {
|
|
1094
|
+
unrequested.push(dep);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
return unrequested;
|
|
1098
|
+
}
|
|
1099
|
+
function findRedundantPeerDeps({ peerDependencies, dependencies }, exclude) {
|
|
1100
|
+
const depsSet = new Set(dependencies);
|
|
1101
|
+
const redundant = [];
|
|
1102
|
+
for (const dep of peerDependencies) {
|
|
1103
|
+
if (exclude?.has(dep)) continue;
|
|
1104
|
+
if (depsSet.has(dep)) {
|
|
1105
|
+
redundant.push(dep);
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
return redundant;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
// src/actions/deplint/checkPackage/getUnusedDependencies.ts
|
|
1112
|
+
import chalk13 from "chalk";
|
|
1113
|
+
function isDepImported(dep, distImports, distTypeImports) {
|
|
1114
|
+
const baseName = dep.replace(/^@types\//, "");
|
|
1115
|
+
return distImports.includes(dep) || distImports.includes(baseName) || distTypeImports.includes(dep) || distTypeImports.includes(baseName);
|
|
1116
|
+
}
|
|
1117
|
+
function findUnusedDependencies(location, dependencies, devDependencies, externalDistImports, externalDistTypeImports, externalAllImports, exclude) {
|
|
1118
|
+
const runtimeRequiredPeers = getRequiredPeerDependencies(location, dependencies);
|
|
1119
|
+
const devRequiredPeers = getRequiredPeerDependencies(location, devDependencies);
|
|
1120
|
+
const results = [];
|
|
1121
|
+
for (const dep of dependencies) {
|
|
1122
|
+
if (exclude?.has(dep)) continue;
|
|
1123
|
+
if (runtimeRequiredPeers.has(dep)) continue;
|
|
1124
|
+
const isImported = isDepImported(dep, externalDistImports, externalDistTypeImports);
|
|
1125
|
+
if (isImported || isUsedViaTsScriptsVariant(dep, [...externalDistImports, ...externalDistTypeImports])) continue;
|
|
1126
|
+
if (devRequiredPeers.has(dep)) {
|
|
1127
|
+
results.push({
|
|
1128
|
+
dep,
|
|
1129
|
+
kind: "move-to-dev",
|
|
1130
|
+
reason: "only needed as peer of devDependencies"
|
|
1131
|
+
});
|
|
1132
|
+
} else if (externalAllImports.includes(dep)) {
|
|
1133
|
+
results.push({ dep, kind: "move-to-dev" });
|
|
1134
|
+
} else {
|
|
1135
|
+
results.push({ dep, kind: "remove" });
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
return results;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
// src/actions/deplint/checkPackage/getUnusedDevDependencies.ts
|
|
1142
|
+
import chalk14 from "chalk";
|
|
1143
|
+
|
|
1144
|
+
// src/actions/deplint/getCliReferencedPackagesFromFiles.ts
|
|
1145
|
+
import fs12 from "fs";
|
|
1146
|
+
import path6 from "path";
|
|
1147
|
+
import ts2 from "typescript";
|
|
1148
|
+
|
|
1149
|
+
// src/actions/deplint/getScriptReferencedPackages.ts
|
|
1150
|
+
import fs11 from "fs";
|
|
1151
|
+
import path5 from "path";
|
|
1152
|
+
function getBinNames(location, dep) {
|
|
1153
|
+
const depPkgPath = findDepPackageJson(location, dep);
|
|
1154
|
+
if (!depPkgPath) return [];
|
|
1155
|
+
try {
|
|
1156
|
+
const raw = fs11.readFileSync(depPkgPath, "utf8");
|
|
1157
|
+
const pkg = JSON.parse(raw);
|
|
1158
|
+
if (!pkg.bin) return [];
|
|
1159
|
+
if (typeof pkg.bin === "string") return [pkg.name?.split("/").pop() ?? dep];
|
|
1160
|
+
return Object.keys(pkg.bin);
|
|
1161
|
+
} catch {
|
|
1162
|
+
return [];
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
function tokenizeScript(script) {
|
|
1166
|
+
return script.split(/[&|;$()"`\s]+/).map((t) => t.trim()).filter(Boolean);
|
|
1167
|
+
}
|
|
1168
|
+
function getScriptReferencedPackages(location, allDeps) {
|
|
1169
|
+
const pkgPath = path5.join(location, "package.json");
|
|
1170
|
+
let scripts;
|
|
1171
|
+
try {
|
|
1172
|
+
const raw = fs11.readFileSync(pkgPath, "utf8");
|
|
1173
|
+
const pkg = JSON.parse(raw);
|
|
1174
|
+
scripts = pkg.scripts ?? {};
|
|
1175
|
+
} catch {
|
|
1176
|
+
return /* @__PURE__ */ new Set();
|
|
1177
|
+
}
|
|
1178
|
+
const scriptText = Object.values(scripts).join(" ");
|
|
1179
|
+
const tokens = new Set(tokenizeScript(scriptText));
|
|
1180
|
+
const binToPackage = /* @__PURE__ */ new Map();
|
|
1181
|
+
for (const dep of allDeps) {
|
|
1182
|
+
const bins = getBinNames(location, dep);
|
|
1183
|
+
for (const bin of bins) {
|
|
1184
|
+
binToPackage.set(bin, dep);
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
1188
|
+
for (const token of tokens) {
|
|
1189
|
+
const baseName = getBasePackageName(token);
|
|
1190
|
+
if (allDeps.includes(baseName)) {
|
|
1191
|
+
referenced.add(baseName);
|
|
1192
|
+
}
|
|
1193
|
+
const pkg = binToPackage.get(token);
|
|
1194
|
+
if (pkg) {
|
|
1195
|
+
referenced.add(pkg);
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
return referenced;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
// src/actions/deplint/getCliReferencedPackagesFromFiles.ts
|
|
1202
|
+
var shellCommandFunctions = /* @__PURE__ */ new Set(["execSync", "exec"]);
|
|
1203
|
+
var directExecFunctions = /* @__PURE__ */ new Set(["spawn", "spawnSync", "execFile", "execFileSync"]);
|
|
1204
|
+
var allExecFunctions = /* @__PURE__ */ new Set([...shellCommandFunctions, ...directExecFunctions]);
|
|
1205
|
+
function getCommandTokensFromFile(filePath) {
|
|
1206
|
+
const tokens = /* @__PURE__ */ new Set();
|
|
1207
|
+
let sourceCode;
|
|
1208
|
+
try {
|
|
1209
|
+
sourceCode = fs12.readFileSync(filePath, "utf8");
|
|
1210
|
+
} catch {
|
|
1211
|
+
return tokens;
|
|
1212
|
+
}
|
|
1213
|
+
const isMjsFile = filePath.endsWith(".mjs");
|
|
1214
|
+
const sourceFile = ts2.createSourceFile(
|
|
1215
|
+
path6.basename(filePath),
|
|
1216
|
+
sourceCode,
|
|
1217
|
+
ts2.ScriptTarget.Latest,
|
|
1218
|
+
true,
|
|
1219
|
+
isMjsFile ? ts2.ScriptKind.JS : void 0
|
|
1220
|
+
);
|
|
1221
|
+
function visit(node) {
|
|
1222
|
+
if (ts2.isCallExpression(node) && node.arguments.length > 0) {
|
|
1223
|
+
const fnName = getFunctionName(node.expression);
|
|
1224
|
+
if (fnName && allExecFunctions.has(fnName)) {
|
|
1225
|
+
const firstArg = node.arguments[0];
|
|
1226
|
+
if (ts2.isStringLiteral(firstArg) || ts2.isNoSubstitutionTemplateLiteral(firstArg)) {
|
|
1227
|
+
const value = firstArg.text;
|
|
1228
|
+
if (shellCommandFunctions.has(fnName)) {
|
|
1229
|
+
for (const token of tokenizeScript(value)) {
|
|
1230
|
+
tokens.add(token);
|
|
1231
|
+
}
|
|
1232
|
+
} else {
|
|
1233
|
+
tokens.add(value);
|
|
1234
|
+
}
|
|
1235
|
+
} else if (ts2.isTemplateExpression(firstArg)) {
|
|
1236
|
+
const head = firstArg.head.text;
|
|
1237
|
+
if (head) {
|
|
1238
|
+
for (const token of tokenizeScript(head)) {
|
|
1239
|
+
tokens.add(token);
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
ts2.forEachChild(node, visit);
|
|
1246
|
+
}
|
|
1247
|
+
visit(sourceFile);
|
|
1248
|
+
return tokens;
|
|
1249
|
+
}
|
|
1250
|
+
function getFunctionName(expr) {
|
|
1251
|
+
if (ts2.isIdentifier(expr)) {
|
|
1252
|
+
return expr.text;
|
|
1253
|
+
}
|
|
1254
|
+
if (ts2.isPropertyAccessExpression(expr) && ts2.isIdentifier(expr.name)) {
|
|
1255
|
+
return expr.name.text;
|
|
1256
|
+
}
|
|
1257
|
+
return void 0;
|
|
1258
|
+
}
|
|
1259
|
+
function getCliReferencedPackagesFromFiles(allFiles, location, allDeps) {
|
|
1260
|
+
const allTokens = /* @__PURE__ */ new Set();
|
|
1261
|
+
for (const file of allFiles) {
|
|
1262
|
+
for (const token of getCommandTokensFromFile(file)) {
|
|
1263
|
+
allTokens.add(token);
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
if (allTokens.size === 0) return /* @__PURE__ */ new Set();
|
|
1267
|
+
const binToPackage = /* @__PURE__ */ new Map();
|
|
1268
|
+
for (const dep of allDeps) {
|
|
1269
|
+
for (const bin of getBinNames(location, dep)) {
|
|
1270
|
+
binToPackage.set(bin, dep);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
1274
|
+
for (const token of allTokens) {
|
|
1275
|
+
const baseName = getBasePackageName(token);
|
|
1276
|
+
if (allDeps.includes(baseName)) {
|
|
1277
|
+
referenced.add(baseName);
|
|
1278
|
+
}
|
|
1279
|
+
const pkg = binToPackage.get(token);
|
|
1280
|
+
if (pkg) {
|
|
1281
|
+
referenced.add(pkg);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
return referenced;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
// src/actions/deplint/implicitDevDependencies.ts
|
|
1288
|
+
import fs13 from "fs";
|
|
1289
|
+
var hasFileWithExtension = (files, extensions) => files.some((f) => extensions.some((ext) => f.endsWith(ext)));
|
|
1290
|
+
var tsExtensions = [".ts", ".tsx", ".mts", ".cts"];
|
|
1291
|
+
var hasTypescriptFiles = ({ allFiles }) => hasFileWithExtension(allFiles, tsExtensions);
|
|
1292
|
+
var decoratorPattern = /^\s*@[a-zA-Z]\w*/m;
|
|
1293
|
+
var hasDecorators = ({ allFiles }) => allFiles.filter((f) => tsExtensions.some((ext) => f.endsWith(ext))).some((file) => {
|
|
1294
|
+
try {
|
|
1295
|
+
const content = fs13.readFileSync(file, "utf8");
|
|
1296
|
+
return decoratorPattern.test(content);
|
|
1297
|
+
} catch {
|
|
1298
|
+
return false;
|
|
1299
|
+
}
|
|
1300
|
+
});
|
|
1301
|
+
var hasDependencyRequiringTslib = ({ location, allDependencies }) => allDependencies.some((dep) => {
|
|
1302
|
+
const pkgPath = findDepPackageJson(location, dep);
|
|
1303
|
+
if (!pkgPath) return false;
|
|
1304
|
+
try {
|
|
1305
|
+
const pkg = JSON.parse(fs13.readFileSync(pkgPath, "utf8"));
|
|
1306
|
+
const peers = pkg.peerDependencies;
|
|
1307
|
+
return peers !== void 0 && "tslib" in peers;
|
|
1308
|
+
} catch {
|
|
1309
|
+
return false;
|
|
1310
|
+
}
|
|
1311
|
+
});
|
|
1312
|
+
var importPlugins = /* @__PURE__ */ new Set(["eslint-plugin-import-x", "eslint-plugin-import"]);
|
|
1313
|
+
function hasImportPlugin({ location, allDependencies }) {
|
|
1314
|
+
if (allDependencies.some((d) => importPlugins.has(d))) return true;
|
|
1315
|
+
for (const dep of allDependencies) {
|
|
1316
|
+
const pkgPath = findDepPackageJson(location, dep);
|
|
1317
|
+
if (!pkgPath) continue;
|
|
1318
|
+
try {
|
|
1319
|
+
const pkg = JSON.parse(fs13.readFileSync(pkgPath, "utf8"));
|
|
1320
|
+
const transitiveDeps = [
|
|
1321
|
+
...Object.keys(pkg.dependencies ?? {}),
|
|
1322
|
+
...Object.keys(pkg.peerDependencies ?? {})
|
|
1323
|
+
];
|
|
1324
|
+
if (transitiveDeps.some((d) => importPlugins.has(d))) return true;
|
|
1325
|
+
} catch {
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
return false;
|
|
1329
|
+
}
|
|
1330
|
+
var hasVitest = ({ allDependencies }) => allDependencies.includes("vitest");
|
|
1331
|
+
var isYarnRepo = () => detectPackageManager() === "yarn";
|
|
1332
|
+
var isPnpmRepo = () => detectPackageManager() === "pnpm";
|
|
1333
|
+
var rules = [
|
|
1334
|
+
{
|
|
1335
|
+
package: "typescript",
|
|
1336
|
+
isNeeded: hasTypescriptFiles
|
|
1337
|
+
},
|
|
1338
|
+
{
|
|
1339
|
+
package: "eslint-import-resolver-typescript",
|
|
1340
|
+
isNeeded: (context) => hasTypescriptFiles(context) && context.allDependencies.includes("eslint") && hasImportPlugin(context)
|
|
1341
|
+
},
|
|
1342
|
+
{
|
|
1343
|
+
package: "tslib",
|
|
1344
|
+
isNeeded: (context) => hasDecorators(context) || hasDependencyRequiringTslib(context)
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
package: "@vitest/coverage-v8",
|
|
1348
|
+
isNeeded: hasVitest
|
|
1349
|
+
},
|
|
1350
|
+
{
|
|
1351
|
+
package: "@xylabs/ts-scripts-yarn3",
|
|
1352
|
+
isNeeded: isYarnRepo
|
|
1353
|
+
},
|
|
1354
|
+
{
|
|
1355
|
+
package: "@xylabs/ts-scripts-react-yarn3",
|
|
1356
|
+
isNeeded: isYarnRepo
|
|
1357
|
+
},
|
|
1358
|
+
{
|
|
1359
|
+
package: "@xylabs/ts-scripts-pnpm",
|
|
1360
|
+
isNeeded: isPnpmRepo
|
|
1361
|
+
},
|
|
1362
|
+
{
|
|
1363
|
+
package: "@xylabs/ts-scripts-react-pnpm",
|
|
1364
|
+
isNeeded: isPnpmRepo
|
|
1365
|
+
}
|
|
1366
|
+
];
|
|
1367
|
+
function getImplicitDevDependencies(context) {
|
|
1368
|
+
const implicit = /* @__PURE__ */ new Set();
|
|
1369
|
+
for (const rule of rules) {
|
|
1370
|
+
if (rule.isNeeded(context)) {
|
|
1371
|
+
implicit.add(rule.package);
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
return implicit;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
// src/actions/deplint/checkPackage/getUnusedDevDependencies.ts
|
|
1378
|
+
var allExternalImports = ({
|
|
1379
|
+
externalAllImports,
|
|
1380
|
+
externalDistImports,
|
|
1381
|
+
externalDistTypeImports
|
|
1382
|
+
}) => {
|
|
1383
|
+
return /* @__PURE__ */ new Set([
|
|
1384
|
+
...externalAllImports,
|
|
1385
|
+
...externalDistImports,
|
|
1386
|
+
...externalDistTypeImports
|
|
1387
|
+
]);
|
|
1388
|
+
};
|
|
1389
|
+
function isDevDepUsed(dep, allImports, implicitDeps, requiredPeers, scriptRefs, cliRefs) {
|
|
1390
|
+
if (implicitDeps.has(dep)) return true;
|
|
1391
|
+
if (requiredPeers.has(dep)) return true;
|
|
1392
|
+
if (scriptRefs.has(dep)) return true;
|
|
1393
|
+
if (cliRefs.has(dep)) return true;
|
|
1394
|
+
if (dep.startsWith("@types/")) {
|
|
1395
|
+
const baseName = dep.replace(/^@types\//, "");
|
|
1396
|
+
return allImports.has(baseName) || allImports.has(dep) || implicitDeps.has(baseName);
|
|
1397
|
+
}
|
|
1398
|
+
if (allImports.has(dep)) return true;
|
|
1399
|
+
return isUsedViaTsScriptsVariant(dep, [...allImports]);
|
|
1400
|
+
}
|
|
1401
|
+
function findUnusedDevDeps(location, dependencies, devDependencies, peerDependencies, sourceParams, fileContext, exclude) {
|
|
1402
|
+
const allImports = allExternalImports(sourceParams);
|
|
1403
|
+
const allDeps = [...dependencies, ...devDependencies, ...peerDependencies];
|
|
1404
|
+
const implicitDeps = getImplicitDevDependencies({
|
|
1405
|
+
...fileContext,
|
|
1406
|
+
allDependencies: allDeps,
|
|
1407
|
+
location
|
|
1408
|
+
});
|
|
1409
|
+
const requiredPeers = getRequiredPeerDependencies(location, allDeps);
|
|
1410
|
+
const scriptRefs = getScriptReferencedPackages(location, allDeps);
|
|
1411
|
+
const cliRefs = getCliReferencedPackagesFromFiles(fileContext.allFiles, location, allDeps);
|
|
1412
|
+
const unused = [];
|
|
1413
|
+
for (const dep of devDependencies) {
|
|
1414
|
+
if (exclude?.has(dep)) continue;
|
|
1415
|
+
if (dependencies.includes(dep) || peerDependencies.includes(dep)) continue;
|
|
1416
|
+
if (!isDevDepUsed(dep, allImports, implicitDeps, requiredPeers, scriptRefs, cliRefs)) {
|
|
1417
|
+
unused.push(dep);
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
return unused;
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
// src/actions/deplint/checkPackage/getUnusedPeerDependencies.ts
|
|
1424
|
+
import chalk15 from "chalk";
|
|
1425
|
+
function isPeerUsed(dep, externalDistImports, externalDistTypeImports) {
|
|
1426
|
+
const baseName = dep.replace(/^@types\//, "");
|
|
1427
|
+
return externalDistImports.includes(dep) || externalDistImports.includes(baseName) || externalDistTypeImports.includes(dep) || externalDistTypeImports.includes(baseName);
|
|
1428
|
+
}
|
|
1429
|
+
function findUnusedPeerDeps(peerDependencies, externalDistImports, externalDistTypeImports, exclude) {
|
|
1430
|
+
const unused = [];
|
|
1431
|
+
for (const dep of peerDependencies) {
|
|
1432
|
+
if (exclude?.has(dep)) continue;
|
|
1433
|
+
if (!isPeerUsed(dep, externalDistImports, externalDistTypeImports)) {
|
|
1434
|
+
unused.push(dep);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
return unused;
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
// src/actions/deplint/checkPackage/getWorkspaceVersionProblems.ts
|
|
1441
|
+
import chalk16 from "chalk";
|
|
1442
|
+
import semver3 from "semver";
|
|
1443
|
+
function checkSection(deps, versions, section, workspaceNames, problems) {
|
|
1444
|
+
for (const dep of deps) {
|
|
1445
|
+
if (!workspaceNames.has(dep)) continue;
|
|
1446
|
+
const version = versions[dep];
|
|
1447
|
+
if (version && !version.startsWith("workspace:")) {
|
|
1448
|
+
problems.push({
|
|
1449
|
+
dep,
|
|
1450
|
+
section,
|
|
1451
|
+
version
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
function findWorkspaceVersionProblems(packageParams, workspaceNames) {
|
|
1457
|
+
const problems = [];
|
|
1458
|
+
checkSection(packageParams.dependencies, packageParams.dependencyVersions, "dependencies", workspaceNames, problems);
|
|
1459
|
+
checkSection(packageParams.devDependencies, packageParams.devDependencyVersions, "devDependencies", workspaceNames, problems);
|
|
1460
|
+
return problems;
|
|
1461
|
+
}
|
|
1462
|
+
function findWorkspacePeerVersionProblems(packageParams, workspaceNames, location) {
|
|
1463
|
+
const problems = [];
|
|
1464
|
+
for (const dep of packageParams.peerDependencies) {
|
|
1465
|
+
if (!workspaceNames.has(dep)) continue;
|
|
1466
|
+
const declaredRange = packageParams.peerDependencyVersions[dep];
|
|
1467
|
+
if (!declaredRange || declaredRange.startsWith("workspace:")) continue;
|
|
1468
|
+
const resolved = resolveDepVersion(location, dep);
|
|
1469
|
+
const actualVersion = resolved.startsWith("~") ? resolved.slice(1) : resolved;
|
|
1470
|
+
if (actualVersion === "*") continue;
|
|
1471
|
+
if (!semver3.satisfies(actualVersion, declaredRange)) {
|
|
1472
|
+
problems.push({
|
|
1473
|
+
actualVersion,
|
|
1474
|
+
declaredRange,
|
|
1475
|
+
dep
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
return problems;
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
// src/actions/deplint/rules.ts
|
|
1483
|
+
function diagnostic(context, id, message, dependency, evidence, fixes) {
|
|
1484
|
+
return {
|
|
1485
|
+
dependency,
|
|
1486
|
+
evidence,
|
|
1487
|
+
file: context.packageJsonPath,
|
|
1488
|
+
fixes,
|
|
1489
|
+
id,
|
|
1490
|
+
message,
|
|
1491
|
+
severity: "error",
|
|
1492
|
+
workspace: context.workspace
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1495
|
+
function resolvedAddFix(context, dependency, section, detail) {
|
|
1496
|
+
return {
|
|
1497
|
+
action: "add",
|
|
1498
|
+
dependency,
|
|
1499
|
+
detail,
|
|
1500
|
+
section,
|
|
1501
|
+
version: resolveDepVersion(context.workspace.location, dependency)
|
|
1502
|
+
};
|
|
1503
|
+
}
|
|
1504
|
+
var unlistedDependenciesRule = {
|
|
1505
|
+
category: "dependencies",
|
|
1506
|
+
id: "deplint.dependencies.unlisted",
|
|
1507
|
+
evaluate(context) {
|
|
1508
|
+
const findings = findUnlistedDependencies(
|
|
1509
|
+
context.workspace.name,
|
|
1510
|
+
context.packageParams.dependencies,
|
|
1511
|
+
context.packageParams.devDependencies,
|
|
1512
|
+
context.packageParams.peerDependencies,
|
|
1513
|
+
context.sourceParams.externalDistImports,
|
|
1514
|
+
context.sourceParams.externalDistTypeImports
|
|
1515
|
+
);
|
|
1516
|
+
return findings.map(({ imp, section }) => {
|
|
1517
|
+
const isPeer = !context.isTerminalPackage && section === "dependencies" && !context.forceDeps.has(imp) && shouldBePeerDependency(imp, context.workspace.location, context.packageParams.peerDependencies, context.sourceParams.externalDistImports);
|
|
1518
|
+
const fixes = isPeer ? ["peerDependencies", "devDependencies"].map(
|
|
1519
|
+
(s) => resolvedAddFix(context, imp, s, `added to ${s}`)
|
|
1520
|
+
) : [resolvedAddFix(context, imp, section, `added to ${section}`)];
|
|
1521
|
+
return diagnostic(
|
|
1522
|
+
context,
|
|
1523
|
+
"deplint.dependencies.unlisted",
|
|
1524
|
+
`Missing dependency in package.json: ${imp}`,
|
|
1525
|
+
imp,
|
|
1526
|
+
context.sourceParams.distImportPaths[imp],
|
|
1527
|
+
fixes
|
|
1528
|
+
);
|
|
1529
|
+
});
|
|
1530
|
+
}
|
|
1531
|
+
};
|
|
1532
|
+
var unusedDependenciesRule = {
|
|
1533
|
+
category: "dependencies",
|
|
1534
|
+
id: "deplint.dependencies.unused",
|
|
1535
|
+
evaluate(context) {
|
|
1536
|
+
const findings = findUnusedDependencies(
|
|
1537
|
+
context.workspace.location,
|
|
1538
|
+
context.packageParams.dependencies,
|
|
1539
|
+
context.packageParams.devDependencies,
|
|
1540
|
+
context.sourceParams.externalDistImports,
|
|
1541
|
+
context.sourceParams.externalDistTypeImports,
|
|
1542
|
+
context.sourceParams.externalAllImports,
|
|
1543
|
+
context.unusedDependencyExclude
|
|
1544
|
+
);
|
|
1545
|
+
return findings.map(({
|
|
1546
|
+
dep,
|
|
1547
|
+
kind,
|
|
1548
|
+
reason
|
|
1549
|
+
}) => diagnostic(
|
|
1550
|
+
context,
|
|
1551
|
+
"deplint.dependencies.unused",
|
|
1552
|
+
kind === "move-to-dev" ? `dependency should be devDependency in package.json: ${dep}${reason ? ` (${reason})` : ""}` : `Unused dependency in package.json: ${dep}`,
|
|
1553
|
+
dep,
|
|
1554
|
+
void 0,
|
|
1555
|
+
[kind === "move-to-dev" ? {
|
|
1556
|
+
action: "move",
|
|
1557
|
+
dependency: dep,
|
|
1558
|
+
detail: "moved to devDependencies",
|
|
1559
|
+
fromSection: "dependencies",
|
|
1560
|
+
toSection: "devDependencies"
|
|
1561
|
+
} : {
|
|
1562
|
+
action: "remove",
|
|
1563
|
+
dependency: dep,
|
|
1564
|
+
detail: "removed from dependencies",
|
|
1565
|
+
section: "dependencies"
|
|
1566
|
+
}]
|
|
1567
|
+
));
|
|
1568
|
+
}
|
|
1569
|
+
};
|
|
1570
|
+
var unlistedDevDependenciesRule = {
|
|
1571
|
+
category: "devDependencies",
|
|
1572
|
+
id: "deplint.devDependencies.unlisted",
|
|
1573
|
+
evaluate(context) {
|
|
1574
|
+
const findings = findUnlistedDevDeps(
|
|
1575
|
+
context.workspace.name,
|
|
1576
|
+
context.packageParams.dependencies,
|
|
1577
|
+
context.packageParams.devDependencies,
|
|
1578
|
+
context.packageParams.peerDependencies,
|
|
1579
|
+
context.sourceParams.externalAllImports,
|
|
1580
|
+
context.sourceParams.distImports,
|
|
1581
|
+
context.sourceParams.externalDistTypeImports
|
|
1582
|
+
);
|
|
1583
|
+
return findings.map((imp) => diagnostic(
|
|
1584
|
+
context,
|
|
1585
|
+
"deplint.devDependencies.unlisted",
|
|
1586
|
+
`Missing devDependency in package.json: ${imp}`,
|
|
1587
|
+
imp,
|
|
1588
|
+
context.sourceParams.allImportPaths[imp],
|
|
1589
|
+
[resolvedAddFix(context, imp, "devDependencies", "added to devDependencies")]
|
|
1590
|
+
));
|
|
1591
|
+
}
|
|
1592
|
+
};
|
|
1593
|
+
var unusedDevDependenciesRule = {
|
|
1594
|
+
category: "devDependencies",
|
|
1595
|
+
id: "deplint.devDependencies.unused",
|
|
1596
|
+
evaluate(context) {
|
|
1597
|
+
const findings = findUnusedDevDeps(
|
|
1598
|
+
context.workspace.location,
|
|
1599
|
+
context.packageParams.dependencies,
|
|
1600
|
+
context.packageParams.devDependencies,
|
|
1601
|
+
context.packageParams.peerDependencies,
|
|
1602
|
+
context.sourceParams,
|
|
1603
|
+
context.fileContext,
|
|
1604
|
+
context.unusedDependencyExclude
|
|
1605
|
+
);
|
|
1606
|
+
return findings.map((dep) => diagnostic(
|
|
1607
|
+
context,
|
|
1608
|
+
"deplint.devDependencies.unused",
|
|
1609
|
+
`Unused devDependency in package.json: ${dep}`,
|
|
1610
|
+
dep,
|
|
1611
|
+
void 0,
|
|
1612
|
+
[{
|
|
1613
|
+
action: "remove",
|
|
1614
|
+
dependency: dep,
|
|
1615
|
+
detail: "removed from devDependencies",
|
|
1616
|
+
section: "devDependencies"
|
|
1617
|
+
}]
|
|
1618
|
+
));
|
|
1619
|
+
}
|
|
1620
|
+
};
|
|
1621
|
+
var redundantDevDependenciesRule = {
|
|
1622
|
+
category: "devDependencies",
|
|
1623
|
+
id: "deplint.devDependencies.redundant",
|
|
1624
|
+
evaluate(context) {
|
|
1625
|
+
const diagnostics = [];
|
|
1626
|
+
for (const dep of context.packageParams.devDependencies) {
|
|
1627
|
+
if (!context.packageParams.dependencies.includes(dep)) continue;
|
|
1628
|
+
if (!context.isTerminalPackage && !context.forceDeps.has(dep) && shouldBePeerDependency(dep, context.workspace.location, context.packageParams.peerDependencies, context.sourceParams.externalDistImports)) {
|
|
1629
|
+
continue;
|
|
1630
|
+
}
|
|
1631
|
+
diagnostics.push(diagnostic(
|
|
1632
|
+
context,
|
|
1633
|
+
"deplint.devDependencies.redundant",
|
|
1634
|
+
`Redundant devDependency ${dep} \u2014 already listed in dependencies`,
|
|
1635
|
+
dep,
|
|
1636
|
+
void 0,
|
|
1637
|
+
[{
|
|
1638
|
+
action: "remove",
|
|
1639
|
+
dependency: dep,
|
|
1640
|
+
detail: "removed redundant devDependency (kept in dependencies)",
|
|
1641
|
+
section: "devDependencies"
|
|
1642
|
+
}]
|
|
1643
|
+
));
|
|
1644
|
+
}
|
|
1645
|
+
return diagnostics;
|
|
1646
|
+
}
|
|
1647
|
+
};
|
|
1648
|
+
function generateVersionMismatchFixes(context, finding) {
|
|
1649
|
+
const expectedVersion = resolveExpectedPeerVersion(
|
|
1650
|
+
context.workspace.location,
|
|
1651
|
+
finding.peer,
|
|
1652
|
+
finding.versionRange
|
|
1653
|
+
);
|
|
1654
|
+
if (expectedVersion === "*") return [];
|
|
1655
|
+
const fixes = [];
|
|
1656
|
+
if (context.packageParams.peerDependencies.includes(finding.peer)) {
|
|
1657
|
+
fixes.push({
|
|
1658
|
+
action: "set-version",
|
|
1659
|
+
dependency: finding.peer,
|
|
1660
|
+
detail: `updated peerDependency version to match installed (${finding.installedVersion})`,
|
|
1661
|
+
section: "peerDependencies",
|
|
1662
|
+
version: expectedVersion
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1665
|
+
if (context.packageParams.devDependencies.includes(finding.peer)) {
|
|
1666
|
+
const devVersion = context.packageParams.devDependencyVersions[finding.peer];
|
|
1667
|
+
if (devVersion && !devVersion.startsWith("workspace:")) {
|
|
1668
|
+
fixes.push({
|
|
1669
|
+
action: "set-version",
|
|
1670
|
+
dependency: finding.peer,
|
|
1671
|
+
detail: `updated devDependency version to match installed (${finding.installedVersion})`,
|
|
1672
|
+
section: "devDependencies",
|
|
1673
|
+
version: expectedVersion
|
|
1674
|
+
});
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
return fixes;
|
|
1678
|
+
}
|
|
1679
|
+
var unsatisfiedPeersRule = {
|
|
1680
|
+
category: "peerDependencies",
|
|
1681
|
+
id: "deplint.peerDependencies.unsatisfied",
|
|
1682
|
+
evaluate(context) {
|
|
1683
|
+
const findings = findUnsatisfiedPeers(context.workspace, context.packageParams, context.exclude);
|
|
1684
|
+
return findings.map((finding) => {
|
|
1685
|
+
const requiredBy = finding.sources.map((source) => source.requiredBy).join(", ");
|
|
1686
|
+
const chain = finding.sources.find((source) => source.chain && source.chain.length > 0)?.chain?.join(" -> ");
|
|
1687
|
+
const evidence = chain ? [`via ${chain}`] : void 0;
|
|
1688
|
+
const message = finding.reason === "version-mismatch" ? `Peer dependency version mismatch ${finding.peer} \u2014 installed ${finding.installedVersion ?? "unknown"} does not satisfy ${finding.versionRange} (required by ${requiredBy})` : finding.hasRuntimeSource ? `Unsatisfied peer dependency ${finding.peer} (required by ${requiredBy}) \u2014 must be in dependencies or peerDependencies` : `Unsatisfied peer dependency ${finding.peer} (required by devDependency ${requiredBy}) \u2014 must be in dependencies, devDependencies, or peerDependencies`;
|
|
1689
|
+
const fixes = finding.reason === "missing" ? resolvePeerTargetSections(finding.hasRuntimeSource, context.isTerminalPackage).map((section) => ({
|
|
1690
|
+
action: "add",
|
|
1691
|
+
dependency: finding.peer,
|
|
1692
|
+
detail: `added to ${section}`,
|
|
1693
|
+
section,
|
|
1694
|
+
version: finding.versionRange
|
|
1695
|
+
})) : finding.reason === "version-mismatch" ? generateVersionMismatchFixes(context, finding) : void 0;
|
|
1696
|
+
return diagnostic(
|
|
1697
|
+
context,
|
|
1698
|
+
"deplint.peerDependencies.unsatisfied",
|
|
1699
|
+
message,
|
|
1700
|
+
finding.peer,
|
|
1701
|
+
evidence,
|
|
1702
|
+
fixes
|
|
1703
|
+
);
|
|
1704
|
+
});
|
|
1705
|
+
}
|
|
1706
|
+
};
|
|
1707
|
+
var unusedPeerDependenciesRule = {
|
|
1708
|
+
category: "peerDependencies",
|
|
1709
|
+
id: "deplint.peerDependencies.unused",
|
|
1710
|
+
evaluate(context) {
|
|
1711
|
+
const findings = findUnusedPeerDeps(
|
|
1712
|
+
context.packageParams.peerDependencies,
|
|
1713
|
+
context.sourceParams.externalDistImports,
|
|
1714
|
+
context.sourceParams.externalDistTypeImports,
|
|
1715
|
+
context.unusedDependencyExclude
|
|
1716
|
+
);
|
|
1717
|
+
return findings.map((dep) => diagnostic(
|
|
1718
|
+
context,
|
|
1719
|
+
"deplint.peerDependencies.unused",
|
|
1720
|
+
context.packageParams.dependencies.includes(dep) ? `Unused peerDependency [already a dependency] in package.json: ${dep}` : `Unused peerDependency in package.json: ${dep}`,
|
|
1721
|
+
dep,
|
|
1722
|
+
void 0,
|
|
1723
|
+
[{
|
|
1724
|
+
action: "remove",
|
|
1725
|
+
dependency: dep,
|
|
1726
|
+
detail: "removed from peerDependencies",
|
|
1727
|
+
section: "peerDependencies"
|
|
1728
|
+
}]
|
|
1729
|
+
));
|
|
1730
|
+
}
|
|
1731
|
+
};
|
|
1732
|
+
var unrequestedPeerDependenciesRule = {
|
|
1733
|
+
category: "peerDependencies",
|
|
1734
|
+
id: "deplint.peerDependencies.unrequested",
|
|
1735
|
+
evaluate(context) {
|
|
1736
|
+
if (!context.isTerminalPackage) return [];
|
|
1737
|
+
const findings = findUnrequestedPeerDeps(
|
|
1738
|
+
context.workspace.location,
|
|
1739
|
+
context.packageParams,
|
|
1740
|
+
context.sourceParams,
|
|
1741
|
+
context.exclude
|
|
1742
|
+
);
|
|
1743
|
+
return findings.map((dep) => diagnostic(
|
|
1744
|
+
context,
|
|
1745
|
+
"deplint.peerDependencies.unrequested",
|
|
1746
|
+
`Unnecessary peerDependency ${dep} \u2014 imported in dist but no dependency requires it as a peer; should be a dependency`,
|
|
1747
|
+
dep,
|
|
1748
|
+
void 0,
|
|
1749
|
+
[{
|
|
1750
|
+
action: "move",
|
|
1751
|
+
dependency: dep,
|
|
1752
|
+
detail: "moved from peerDependencies to dependencies",
|
|
1753
|
+
fromSection: "peerDependencies",
|
|
1754
|
+
toSection: "dependencies",
|
|
1755
|
+
version: context.packageParams.peerDependencyVersions[dep] ?? "*"
|
|
1756
|
+
}]
|
|
1757
|
+
));
|
|
1758
|
+
}
|
|
1759
|
+
};
|
|
1760
|
+
var misplacedDependenciesRule = {
|
|
1761
|
+
category: "dependencies",
|
|
1762
|
+
id: "deplint.dependencies.misplaced",
|
|
1763
|
+
evaluate(context) {
|
|
1764
|
+
if (context.isTerminalPackage) return [];
|
|
1765
|
+
const diagnostics = [];
|
|
1766
|
+
for (const dep of context.packageParams.dependencies) {
|
|
1767
|
+
if (context.forceDeps.has(dep)) continue;
|
|
1768
|
+
if (context.forcePeers.has(dep) || shouldBePeerDependency(dep, context.workspace.location, context.packageParams.peerDependencies, context.sourceParams.externalDistImports)) {
|
|
1769
|
+
const fixes = [{
|
|
1770
|
+
action: "move",
|
|
1771
|
+
dependency: dep,
|
|
1772
|
+
detail: "moved from dependencies to peerDependencies",
|
|
1773
|
+
fromSection: "dependencies",
|
|
1774
|
+
toSection: "peerDependencies"
|
|
1775
|
+
}];
|
|
1776
|
+
if (!context.packageParams.devDependencies.includes(dep)) {
|
|
1777
|
+
fixes.push(resolvedAddFix(context, dep, "devDependencies", "added to devDependencies"));
|
|
1778
|
+
}
|
|
1779
|
+
const reason = context.forcePeers.has(dep) ? 'configured as refType "peer"' : "it shares peers with existing peerDependencies";
|
|
1780
|
+
diagnostics.push(diagnostic(
|
|
1781
|
+
context,
|
|
1782
|
+
"deplint.dependencies.misplaced",
|
|
1783
|
+
`dependency ${dep} should be a peerDependency \u2014 ${reason}`,
|
|
1784
|
+
dep,
|
|
1785
|
+
void 0,
|
|
1786
|
+
fixes
|
|
1787
|
+
));
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
return diagnostics;
|
|
1791
|
+
}
|
|
1792
|
+
};
|
|
1793
|
+
var misplacedPeerDependenciesRule = {
|
|
1794
|
+
category: "peerDependencies",
|
|
1795
|
+
id: "deplint.peerDependencies.misplaced",
|
|
1796
|
+
evaluate(context) {
|
|
1797
|
+
const diagnostics = [];
|
|
1798
|
+
for (const dep of context.packageParams.peerDependencies) {
|
|
1799
|
+
if (context.forceDeps.has(dep)) {
|
|
1800
|
+
const fixes = [{
|
|
1801
|
+
action: "move",
|
|
1802
|
+
dependency: dep,
|
|
1803
|
+
detail: "moved from peerDependencies to dependencies",
|
|
1804
|
+
fromSection: "peerDependencies",
|
|
1805
|
+
toSection: "dependencies",
|
|
1806
|
+
version: context.packageParams.peerDependencyVersions[dep] ?? "*"
|
|
1807
|
+
}];
|
|
1808
|
+
diagnostics.push(diagnostic(
|
|
1809
|
+
context,
|
|
1810
|
+
"deplint.peerDependencies.misplaced",
|
|
1811
|
+
`peerDependency ${dep} should be a dependency \u2014 configured as refType "dep"`,
|
|
1812
|
+
dep,
|
|
1813
|
+
void 0,
|
|
1814
|
+
fixes
|
|
1815
|
+
));
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
return diagnostics;
|
|
1819
|
+
}
|
|
1820
|
+
};
|
|
1821
|
+
var redundantPeerDependenciesRule = {
|
|
1822
|
+
category: "peerDependencies",
|
|
1823
|
+
id: "deplint.peerDependencies.redundant",
|
|
1824
|
+
evaluate(context) {
|
|
1825
|
+
const findings = findRedundantPeerDeps(context.packageParams, context.exclude);
|
|
1826
|
+
return findings.map((dep) => diagnostic(
|
|
1827
|
+
context,
|
|
1828
|
+
"deplint.peerDependencies.redundant",
|
|
1829
|
+
`Redundant peerDependency ${dep} \u2014 already listed in dependencies`,
|
|
1830
|
+
dep,
|
|
1831
|
+
void 0,
|
|
1832
|
+
[{
|
|
1833
|
+
action: "remove",
|
|
1834
|
+
dependency: dep,
|
|
1835
|
+
detail: "removed redundant peerDependency (kept in dependencies)",
|
|
1836
|
+
section: "peerDependencies"
|
|
1837
|
+
}]
|
|
1838
|
+
));
|
|
1839
|
+
}
|
|
1840
|
+
};
|
|
1841
|
+
var mismatchedPeerDevVersionsRule = {
|
|
1842
|
+
category: "peerDependencies",
|
|
1843
|
+
id: "deplint.peerDependencies.version-mismatch",
|
|
1844
|
+
evaluate(context) {
|
|
1845
|
+
const findings = findMismatchedPeerDevVersions(context.packageParams, context.exclude);
|
|
1846
|
+
return findings.map(({
|
|
1847
|
+
dep,
|
|
1848
|
+
devVersion,
|
|
1849
|
+
peerVersion
|
|
1850
|
+
}) => diagnostic(
|
|
1851
|
+
context,
|
|
1852
|
+
"deplint.peerDependencies.version-mismatch",
|
|
1853
|
+
`Peer/dev version mismatch ${dep} \u2014 peer: ${peerVersion}, dev: ${devVersion}`,
|
|
1854
|
+
dep,
|
|
1855
|
+
void 0,
|
|
1856
|
+
[{
|
|
1857
|
+
action: "set-version",
|
|
1858
|
+
dependency: dep,
|
|
1859
|
+
detail: "synced peerDependency to devDependency version",
|
|
1860
|
+
section: "peerDependencies",
|
|
1861
|
+
version: devVersion
|
|
1862
|
+
}]
|
|
1863
|
+
));
|
|
1864
|
+
}
|
|
1865
|
+
};
|
|
1866
|
+
var workspaceVersionProblemsRule = {
|
|
1867
|
+
category: "peerDependencies",
|
|
1868
|
+
id: "deplint.workspace.protocol",
|
|
1869
|
+
evaluate(context) {
|
|
1870
|
+
if (!context.workspaceNames) return [];
|
|
1871
|
+
const protocolFindings = findWorkspaceVersionProblems(context.packageParams, context.workspaceNames);
|
|
1872
|
+
const protocolDiagnostics = protocolFindings.map(({
|
|
1873
|
+
dep,
|
|
1874
|
+
section,
|
|
1875
|
+
version
|
|
1876
|
+
}) => diagnostic(
|
|
1877
|
+
context,
|
|
1878
|
+
"deplint.workspace.protocol",
|
|
1879
|
+
`Workspace dependency ${dep} in ${section} should use workspace: protocol \u2014 found ${version}`,
|
|
1880
|
+
dep,
|
|
1881
|
+
void 0,
|
|
1882
|
+
[{
|
|
1883
|
+
action: "set-version",
|
|
1884
|
+
dependency: dep,
|
|
1885
|
+
detail: `set workspace:~ for ${section}`,
|
|
1886
|
+
section,
|
|
1887
|
+
version: "workspace:~"
|
|
1888
|
+
}]
|
|
1889
|
+
));
|
|
1890
|
+
const peerFindings = findWorkspacePeerVersionProblems(
|
|
1891
|
+
context.packageParams,
|
|
1892
|
+
context.workspaceNames,
|
|
1893
|
+
context.workspace.location
|
|
1894
|
+
);
|
|
1895
|
+
const peerDiagnostics = peerFindings.map(({
|
|
1896
|
+
dep,
|
|
1897
|
+
actualVersion,
|
|
1898
|
+
declaredRange
|
|
1899
|
+
}) => {
|
|
1900
|
+
const expectedRange = resolveExpectedPeerVersion(
|
|
1901
|
+
context.workspace.location,
|
|
1902
|
+
dep,
|
|
1903
|
+
declaredRange
|
|
1904
|
+
);
|
|
1905
|
+
return diagnostic(
|
|
1906
|
+
context,
|
|
1907
|
+
"deplint.workspace.protocol",
|
|
1908
|
+
`Workspace peerDependency ${dep} range ${declaredRange} does not satisfy workspace version ${actualVersion}`,
|
|
1909
|
+
dep,
|
|
1910
|
+
void 0,
|
|
1911
|
+
expectedRange === "*" ? void 0 : [{
|
|
1912
|
+
action: "set-version",
|
|
1913
|
+
dependency: dep,
|
|
1914
|
+
detail: "updated peerDependency to match workspace version",
|
|
1915
|
+
section: "peerDependencies",
|
|
1916
|
+
version: expectedRange
|
|
1917
|
+
}]
|
|
1918
|
+
);
|
|
1919
|
+
});
|
|
1920
|
+
return [...protocolDiagnostics, ...peerDiagnostics];
|
|
1921
|
+
}
|
|
1922
|
+
};
|
|
1923
|
+
var deplintRules = [
|
|
1924
|
+
unlistedDependenciesRule,
|
|
1925
|
+
unusedDependenciesRule,
|
|
1926
|
+
misplacedDependenciesRule,
|
|
1927
|
+
unlistedDevDependenciesRule,
|
|
1928
|
+
unusedDevDependenciesRule,
|
|
1929
|
+
redundantDevDependenciesRule,
|
|
1930
|
+
unsatisfiedPeersRule,
|
|
1931
|
+
unusedPeerDependenciesRule,
|
|
1932
|
+
unrequestedPeerDependenciesRule,
|
|
1933
|
+
misplacedPeerDependenciesRule,
|
|
1934
|
+
redundantPeerDependenciesRule,
|
|
1935
|
+
mismatchedPeerDevVersionsRule,
|
|
1936
|
+
workspaceVersionProblemsRule
|
|
1937
|
+
];
|
|
1938
|
+
|
|
1939
|
+
// src/actions/deplint/snapshot.ts
|
|
1940
|
+
import fs14 from "fs";
|
|
1941
|
+
function isTerminalPackage(location) {
|
|
1942
|
+
try {
|
|
1943
|
+
const pkg = JSON.parse(fs14.readFileSync(`${location}/package.json`, "utf8"));
|
|
1944
|
+
return pkg.private === true;
|
|
1945
|
+
} catch {
|
|
1946
|
+
return false;
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
function buildWorkspaceContext(workspace, exclude, workspaceNames, forceDeps, forcePeers) {
|
|
1950
|
+
const { allFiles, distFiles } = findFiles(workspace.location);
|
|
1951
|
+
const tsconfigExtends = getExtendsFromTsconfigs(workspace.location);
|
|
1952
|
+
const tsconfigTypes = getTypesFromTsconfigs(workspace.location);
|
|
1953
|
+
const sourceParams = getExternalImportsFromFiles({
|
|
1954
|
+
allFiles,
|
|
1955
|
+
distFiles,
|
|
1956
|
+
location: workspace.location,
|
|
1957
|
+
tsconfigExtends,
|
|
1958
|
+
tsconfigTypes
|
|
1959
|
+
});
|
|
1960
|
+
const packageJsonPath = `${workspace.location}/package.json`;
|
|
1961
|
+
const packageParams = getDependenciesFromPackageJson(packageJsonPath);
|
|
1962
|
+
const requiredTransitivePeers = getRequiredTransitivePeers(workspace.location, packageParams);
|
|
1963
|
+
return {
|
|
1964
|
+
exclude,
|
|
1965
|
+
fileContext: { allFiles, distFiles },
|
|
1966
|
+
forceDeps: forceDeps ?? /* @__PURE__ */ new Set(),
|
|
1967
|
+
forcePeers: forcePeers ?? /* @__PURE__ */ new Set(),
|
|
1968
|
+
isTerminalPackage: isTerminalPackage(workspace.location),
|
|
1969
|
+
packageJsonPath,
|
|
1970
|
+
packageParams,
|
|
1971
|
+
sourceParams,
|
|
1972
|
+
unusedDependencyExclude: /* @__PURE__ */ new Set([...exclude ?? [], ...requiredTransitivePeers]),
|
|
1973
|
+
workspace,
|
|
1974
|
+
workspaceNames
|
|
1975
|
+
};
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1978
|
+
// src/actions/deplint/engine.ts
|
|
1979
|
+
function resolveCheckFlags(deps = false, devDeps = false, peerDeps = false) {
|
|
1980
|
+
const noneExplicit = !(deps || devDeps || peerDeps);
|
|
1981
|
+
return {
|
|
1982
|
+
checkDependencies: deps || noneExplicit,
|
|
1983
|
+
checkDevDependencies: devDeps || noneExplicit,
|
|
1984
|
+
checkPeerDependencies: peerDeps || noneExplicit
|
|
1985
|
+
};
|
|
1986
|
+
}
|
|
1987
|
+
function shouldRunRule(category, ruleId, options) {
|
|
1988
|
+
const flags = resolveCheckFlags(options.deps, options.devDeps, options.peerDeps);
|
|
1989
|
+
if (ruleId === "deplint.peerDependencies.unsatisfied") {
|
|
1990
|
+
return flags.checkDependencies || flags.checkDevDependencies || flags.checkPeerDependencies;
|
|
1991
|
+
}
|
|
1992
|
+
if (ruleId === "deplint.workspace.protocol") {
|
|
1993
|
+
return flags.checkDependencies || flags.checkDevDependencies || flags.checkPeerDependencies;
|
|
1994
|
+
}
|
|
1995
|
+
if (category === "dependencies") return flags.checkDependencies;
|
|
1996
|
+
if (category === "devDependencies") return flags.checkDevDependencies;
|
|
1997
|
+
return flags.checkPeerDependencies;
|
|
1998
|
+
}
|
|
1999
|
+
async function evaluateWorkspaces(workspaces, options, workspaceNames) {
|
|
2000
|
+
const diagnostics = [];
|
|
2001
|
+
for (const workspace of workspaces) {
|
|
2002
|
+
const wsConfig = await loadWorkspaceCommandConfig(workspace.location, "deplint");
|
|
2003
|
+
const exclude = /* @__PURE__ */ new Set([
|
|
2004
|
+
...wsConfig.exclude ?? [],
|
|
2005
|
+
...options.cliExclude ?? []
|
|
2006
|
+
]);
|
|
2007
|
+
const packageEntries = Object.entries(wsConfig.packages ?? {});
|
|
2008
|
+
const forceDeps = new Set(
|
|
2009
|
+
packageEntries.filter(([, cfg]) => cfg.refType === "dep").map(([name]) => name)
|
|
2010
|
+
);
|
|
2011
|
+
const forcePeers = new Set(
|
|
2012
|
+
packageEntries.filter(([, cfg]) => cfg.refType === "peer").map(([name]) => name)
|
|
2013
|
+
);
|
|
2014
|
+
const context = buildWorkspaceContext(workspace, exclude, workspaceNames, forceDeps, forcePeers);
|
|
2015
|
+
if (options.verbose) {
|
|
2016
|
+
console.info(`Checking package: ${workspace.name} at ${workspace.location}`);
|
|
2017
|
+
console.info(`All files: ${context.fileContext.allFiles.length}, Distribution files: ${context.fileContext.distFiles.length}`);
|
|
2018
|
+
}
|
|
2019
|
+
for (const rule of deplintRules) {
|
|
2020
|
+
if (shouldRunRule(rule.category, rule.id, options)) {
|
|
2021
|
+
diagnostics.push(...rule.evaluate(context));
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
return diagnostics;
|
|
2026
|
+
}
|
|
2027
|
+
async function runDeplint(workspaces, options, workspaceNames) {
|
|
2028
|
+
let diagnostics = await evaluateWorkspaces(workspaces, options, workspaceNames);
|
|
2029
|
+
const appliedFixes = [];
|
|
2030
|
+
const MAX_FIX_PASSES = 5;
|
|
2031
|
+
for (let pass = 0; options.fix && diagnostics.length > 0 && pass < MAX_FIX_PASSES; pass++) {
|
|
2032
|
+
appliedFixes.push(...applyDeplintFixes(diagnostics));
|
|
2033
|
+
diagnostics = await evaluateWorkspaces(workspaces, options, workspaceNames);
|
|
2034
|
+
}
|
|
2035
|
+
const errorCount = diagnostics.filter((diagnostic2) => diagnostic2.severity === "error").length;
|
|
2036
|
+
const warningCount = diagnostics.filter((diagnostic2) => diagnostic2.severity === "warning").length;
|
|
2037
|
+
return {
|
|
2038
|
+
appliedFixes,
|
|
2039
|
+
diagnostics,
|
|
2040
|
+
summary: {
|
|
2041
|
+
appliedFixes: appliedFixes.length,
|
|
2042
|
+
errorCount,
|
|
2043
|
+
warningCount,
|
|
2044
|
+
workspacesChecked: workspaces.length
|
|
2045
|
+
}
|
|
2046
|
+
};
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
// src/actions/deplint/reporters.ts
|
|
2050
|
+
import chalk17 from "chalk";
|
|
2051
|
+
var humanDeplintReporter = {
|
|
2052
|
+
render(result) {
|
|
2053
|
+
for (const fix2 of result.appliedFixes) {
|
|
2054
|
+
console.log(`[${chalk17.blue(fix2.workspace.name)}] Fixed: ${fix2.detail} ${chalk17.green(fix2.dependency)}`);
|
|
2055
|
+
}
|
|
2056
|
+
for (const diagnostic2 of result.diagnostics) {
|
|
2057
|
+
console.log(`[${chalk17.blue(diagnostic2.workspace.name)}] ${diagnostic2.message}`);
|
|
2058
|
+
for (const line of diagnostic2.evidence ?? []) {
|
|
2059
|
+
console.log(` ${line}`);
|
|
2060
|
+
}
|
|
2061
|
+
console.log(` ${chalk17.yellow(diagnostic2.file)}
|
|
2062
|
+
`);
|
|
2063
|
+
}
|
|
2064
|
+
if (result.summary.errorCount > 0) {
|
|
2065
|
+
console.warn(`Deplint: Found ${chalk17.red(result.summary.errorCount)} dependency problems. ${chalk17.red("\u2716")}`);
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
console.info(`Deplint: Found no dependency problems. ${chalk17.green("\u2714")}`);
|
|
2069
|
+
}
|
|
2070
|
+
};
|
|
2071
|
+
var jsonDeplintReporter = {
|
|
2072
|
+
render(result) {
|
|
2073
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2074
|
+
}
|
|
2075
|
+
};
|
|
2076
|
+
function getDeplintReporter(format) {
|
|
2077
|
+
return format === "json" ? jsonDeplintReporter : humanDeplintReporter;
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
// src/actions/deplint/deplint.ts
|
|
2081
|
+
var deplint = async ({
|
|
2082
|
+
pkg,
|
|
2083
|
+
deps,
|
|
2084
|
+
devDeps,
|
|
2085
|
+
fix: fix2,
|
|
2086
|
+
peerDeps,
|
|
2087
|
+
verbose,
|
|
2088
|
+
cliExclude,
|
|
2089
|
+
format = "human"
|
|
2090
|
+
}) => {
|
|
2091
|
+
const pm = getPackageManager();
|
|
2092
|
+
const workspaces = pm.listWorkspaces();
|
|
2093
|
+
const workspaceNames = pm.name === "pnpm" ? new Set(workspaces.map((ws) => ws.name)) : void 0;
|
|
2094
|
+
if (pkg === void 0 && format === "human") {
|
|
2095
|
+
console.info("Deplint Started...");
|
|
2096
|
+
}
|
|
2097
|
+
const targetWorkspace = pkg === void 0 ? void 0 : pm.findWorkspace(pkg);
|
|
2098
|
+
const targetWorkspaces = pkg === void 0 ? workspaces : targetWorkspace ? [targetWorkspace] : [];
|
|
2099
|
+
if (targetWorkspaces.length === 0) {
|
|
2100
|
+
console.error(chalk18.red(`Workspace not found: ${pkg}`));
|
|
2101
|
+
return 1;
|
|
2102
|
+
}
|
|
2103
|
+
const result = await runDeplint(targetWorkspaces, {
|
|
2104
|
+
cliExclude,
|
|
2105
|
+
deps,
|
|
2106
|
+
devDeps,
|
|
2107
|
+
fix: fix2,
|
|
2108
|
+
peerDeps,
|
|
2109
|
+
reporter: format,
|
|
2110
|
+
verbose
|
|
2111
|
+
}, workspaceNames);
|
|
2112
|
+
getDeplintReporter(format).render(result);
|
|
2113
|
+
if (fix2 && result.summary.appliedFixes > 0) {
|
|
2114
|
+
runInstall();
|
|
2115
|
+
}
|
|
2116
|
+
return result.summary.errorCount > 0 ? 1 : 0;
|
|
2117
|
+
};
|
|
2118
|
+
|
|
2119
|
+
// src/actions/package-lint-deps.ts
|
|
2120
|
+
import { readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
2121
|
+
import PATH2 from "path";
|
|
2122
|
+
import chalk19 from "chalk";
|
|
2123
|
+
import semver4 from "semver";
|
|
2124
|
+
function readWorkspacePackageJson(cwd, location) {
|
|
2125
|
+
const pkgPath = PATH2.resolve(cwd, location, "package.json");
|
|
2126
|
+
try {
|
|
2127
|
+
return JSON.parse(readFileSync3(pkgPath, "utf8"));
|
|
2128
|
+
} catch {
|
|
2129
|
+
return void 0;
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
function writeWorkspacePackageJson(cwd, location, pkg) {
|
|
2133
|
+
const pkgPath = PATH2.resolve(cwd, location, "package.json");
|
|
2134
|
+
writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
2135
|
+
`, "utf8");
|
|
2136
|
+
}
|
|
2137
|
+
function buildWorkspaceVersionMap(cwd, workspaces) {
|
|
2138
|
+
const map = /* @__PURE__ */ new Map();
|
|
2139
|
+
for (const { location, name } of workspaces) {
|
|
2140
|
+
if (location === ".") continue;
|
|
2141
|
+
const pkg = readWorkspacePackageJson(cwd, location);
|
|
2142
|
+
if (!pkg) continue;
|
|
2143
|
+
const version = pkg.version;
|
|
2144
|
+
if (version) map.set(name, version);
|
|
2145
|
+
}
|
|
2146
|
+
return map;
|
|
2147
|
+
}
|
|
2148
|
+
function expectedPeerRange(devDepVersion, targetVersion) {
|
|
2149
|
+
const parsed = semver4.parse(targetVersion);
|
|
2150
|
+
if (!parsed) return `~${targetVersion}`;
|
|
2151
|
+
if (devDepVersion === "workspace:^") {
|
|
2152
|
+
return `^${parsed.major}`;
|
|
2153
|
+
}
|
|
2154
|
+
return `~${parsed.major}.${parsed.minor}`;
|
|
2155
|
+
}
|
|
2156
|
+
function checkInternalPeerVersions(cwd, workspaces) {
|
|
2157
|
+
const result = {
|
|
2158
|
+
errors: [],
|
|
2159
|
+
fixable: [],
|
|
2160
|
+
warnings: []
|
|
2161
|
+
};
|
|
2162
|
+
const workspaceVersions = buildWorkspaceVersionMap(cwd, workspaces);
|
|
2163
|
+
for (const { location, name } of workspaces) {
|
|
2164
|
+
const pkg = readWorkspacePackageJson(cwd, location);
|
|
2165
|
+
if (!pkg) continue;
|
|
2166
|
+
const peerDeps = pkg.peerDependencies;
|
|
2167
|
+
if (!peerDeps) continue;
|
|
2168
|
+
const devDeps = pkg.devDependencies;
|
|
2169
|
+
for (const [dep, version] of Object.entries(peerDeps)) {
|
|
2170
|
+
const targetVersion = workspaceVersions.get(dep);
|
|
2171
|
+
if (!targetVersion) continue;
|
|
2172
|
+
if (version.startsWith("workspace:")) {
|
|
2173
|
+
const expected2 = expectedPeerRange(devDeps?.[dep], targetVersion);
|
|
2174
|
+
result.fixable.push(
|
|
2175
|
+
`${name} (${location}) peerDependencies.${dep} uses workspace: protocol \u2014 should be "${expected2}"`
|
|
2176
|
+
);
|
|
2177
|
+
continue;
|
|
2178
|
+
}
|
|
2179
|
+
const expected = expectedPeerRange(devDeps?.[dep], targetVersion);
|
|
2180
|
+
if (version !== expected && !semver4.satisfies(targetVersion, version)) {
|
|
2181
|
+
result.fixable.push(
|
|
2182
|
+
`${name} (${location}) peerDependencies.${dep} is "${version}" \u2014 current version ${targetVersion} is not satisfied; expected "${expected}"`
|
|
2183
|
+
);
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
return result;
|
|
2188
|
+
}
|
|
2189
|
+
function fixInternalPeerVersions(cwd, workspaces) {
|
|
2190
|
+
const workspaceVersions = buildWorkspaceVersionMap(cwd, workspaces);
|
|
2191
|
+
for (const { location, name } of workspaces) {
|
|
2192
|
+
const pkg = readWorkspacePackageJson(cwd, location);
|
|
2193
|
+
if (!pkg) continue;
|
|
2194
|
+
const peerDeps = pkg.peerDependencies;
|
|
2195
|
+
if (!peerDeps) continue;
|
|
2196
|
+
const devDeps = pkg.devDependencies;
|
|
2197
|
+
let modified = false;
|
|
2198
|
+
for (const [dep, version] of Object.entries(peerDeps)) {
|
|
2199
|
+
const targetVersion = workspaceVersions.get(dep);
|
|
2200
|
+
if (!targetVersion) continue;
|
|
2201
|
+
const expected = expectedPeerRange(devDeps?.[dep], targetVersion);
|
|
2202
|
+
if (version !== expected) {
|
|
2203
|
+
peerDeps[dep] = expected;
|
|
2204
|
+
console.log(chalk19.green(` \u2714 Fixed: set peerDependencies.${dep} to "${expected}" in ${name} (${location})`));
|
|
2205
|
+
modified = true;
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
if (modified) {
|
|
2209
|
+
writeWorkspacePackageJson(cwd, location, pkg);
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
// src/actions/lintNext.ts
|
|
2215
|
+
import path7 from "path";
|
|
2216
|
+
import chalk20 from "chalk";
|
|
2217
|
+
import { ESLint } from "eslint";
|
|
2218
|
+
var dumpMessages = (lintResults) => {
|
|
2219
|
+
const colors = ["white", "yellow", "red"];
|
|
2220
|
+
const severity = ["none", "warning", "error"];
|
|
2221
|
+
for (const lintResult of lintResults) {
|
|
2222
|
+
if (lintResult.messages.length > 0) {
|
|
2223
|
+
console.log(chalk20.gray(`
|
|
2224
|
+
${lintResult.filePath}`));
|
|
2225
|
+
for (const message of lintResult.messages) {
|
|
2226
|
+
console.log(
|
|
2227
|
+
chalk20.gray(` ${message.line}:${message.column}`),
|
|
2228
|
+
chalk20[colors[message.severity]](` ${severity[message.severity]}`),
|
|
2229
|
+
chalk20.white(` ${message.message}`),
|
|
2230
|
+
chalk20.gray(` ${message.ruleId}`)
|
|
2231
|
+
);
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
};
|
|
2236
|
+
async function lintOnePackage({
|
|
2237
|
+
cache,
|
|
2238
|
+
cwd,
|
|
2239
|
+
fix: fix2,
|
|
2240
|
+
verbose
|
|
2241
|
+
}) {
|
|
2242
|
+
const engine = new ESLint({
|
|
2243
|
+
cache,
|
|
2244
|
+
cacheLocation: path7.join(cwd, ".eslintcache"),
|
|
2245
|
+
cacheStrategy: "content",
|
|
2246
|
+
cwd,
|
|
2247
|
+
fix: fix2,
|
|
2248
|
+
warnIgnored: false
|
|
2249
|
+
});
|
|
2250
|
+
const lintResults = await engine.lintFiles(".");
|
|
2251
|
+
dumpMessages(lintResults);
|
|
2252
|
+
if (fix2) {
|
|
2253
|
+
await ESLint.outputFixes(lintResults);
|
|
2254
|
+
}
|
|
2255
|
+
const errors = lintResults.reduce((sum, r) => sum + r.errorCount, 0);
|
|
2256
|
+
const warnings = lintResults.reduce((sum, r) => sum + r.warningCount, 0);
|
|
2257
|
+
const files = lintResults.length;
|
|
2258
|
+
if (verbose) {
|
|
2259
|
+
const filesColor = files < 100 ? "green" : files < 1e3 ? "yellow" : "red";
|
|
2260
|
+
console.log(chalk20.white(` ${chalk20[filesColor](files)} files linted`));
|
|
2261
|
+
}
|
|
2262
|
+
return {
|
|
2263
|
+
errors,
|
|
2264
|
+
files,
|
|
2265
|
+
warnings
|
|
2266
|
+
};
|
|
2267
|
+
}
|
|
2268
|
+
async function lintNext({
|
|
2269
|
+
cache = false,
|
|
2270
|
+
fix: fix2 = false,
|
|
2271
|
+
jobs,
|
|
2272
|
+
pkg,
|
|
2273
|
+
verbose = false
|
|
2274
|
+
}) {
|
|
2275
|
+
const rootDir = INIT_CWD();
|
|
2276
|
+
const pm = getPackageManager();
|
|
2277
|
+
const allWorkspaces = pm.listWorkspaces();
|
|
2278
|
+
const workspaces = pkg ? allWorkspaces.filter((ws) => ws.name === pkg) : allWorkspaces;
|
|
2279
|
+
if (workspaces.length === 0) {
|
|
2280
|
+
console.log(chalk20.red(pkg ? `Package "${pkg}" not found` : "No workspaces found"));
|
|
2281
|
+
return 1;
|
|
2282
|
+
}
|
|
2283
|
+
const concurrency = jobs;
|
|
2284
|
+
const label = fix2 ? "Fix" : "Lint";
|
|
2285
|
+
installOutputCapture();
|
|
2286
|
+
const results = Array.from(
|
|
2287
|
+
{ length: workspaces.length },
|
|
2288
|
+
() => ({
|
|
2289
|
+
errors: 0,
|
|
2290
|
+
files: 0,
|
|
2291
|
+
output: [],
|
|
2292
|
+
pkg: "",
|
|
2293
|
+
timeMs: 0,
|
|
2294
|
+
warnings: 0
|
|
2295
|
+
})
|
|
2296
|
+
);
|
|
2297
|
+
await runWithConcurrency(
|
|
2298
|
+
workspaces.map((ws, i) => ({ i, ws })),
|
|
2299
|
+
concurrency,
|
|
2300
|
+
async ({ i, ws }) => {
|
|
2301
|
+
const output = [];
|
|
2302
|
+
await outputStorage.run(output, async () => {
|
|
2303
|
+
const pkgStart = Date.now();
|
|
2304
|
+
const absCwd = path7.resolve(rootDir, ws.location);
|
|
2305
|
+
console.log(chalk20.green(`${label} [${ws.name}]`));
|
|
2306
|
+
try {
|
|
2307
|
+
const {
|
|
2308
|
+
errors,
|
|
2309
|
+
files,
|
|
2310
|
+
warnings
|
|
2311
|
+
} = await lintOnePackage({
|
|
2312
|
+
cache,
|
|
2313
|
+
cwd: absCwd,
|
|
2314
|
+
fix: fix2,
|
|
2315
|
+
verbose
|
|
2316
|
+
});
|
|
2317
|
+
const timeMs = Date.now() - pkgStart;
|
|
2318
|
+
results[i] = {
|
|
2319
|
+
errors,
|
|
2320
|
+
files,
|
|
2321
|
+
output,
|
|
2322
|
+
pkg: ws.name,
|
|
2323
|
+
timeMs,
|
|
2324
|
+
warnings
|
|
2325
|
+
};
|
|
2326
|
+
} catch (ex) {
|
|
2327
|
+
output.push(chalk20.red(`${label} failed for ${ws.name}: ${ex.message}
|
|
2328
|
+
`));
|
|
2329
|
+
results[i] = {
|
|
2330
|
+
errors: 1,
|
|
2331
|
+
files: 0,
|
|
2332
|
+
output,
|
|
2333
|
+
pkg: ws.name,
|
|
2334
|
+
timeMs: Date.now() - pkgStart,
|
|
2335
|
+
warnings: 0
|
|
2336
|
+
};
|
|
2337
|
+
}
|
|
2338
|
+
});
|
|
2339
|
+
}
|
|
2340
|
+
);
|
|
2341
|
+
let totalErrors = 0;
|
|
2342
|
+
let totalWarnings = 0;
|
|
2343
|
+
let totalFiles = 0;
|
|
2344
|
+
for (const result of results) {
|
|
2345
|
+
for (const line of result.output) {
|
|
2346
|
+
process.stdout.write(line);
|
|
2347
|
+
}
|
|
2348
|
+
totalErrors += result.errors;
|
|
2349
|
+
totalWarnings += result.warnings;
|
|
2350
|
+
totalFiles += result.files;
|
|
2351
|
+
}
|
|
2352
|
+
const errColor = totalErrors > 0 ? "red" : "green";
|
|
2353
|
+
const warnColor = totalWarnings > 0 ? "yellow" : "green";
|
|
2354
|
+
console.log(
|
|
2355
|
+
chalk20[errColor](`${totalErrors} errors`) + chalk20.gray(", ") + chalk20[warnColor](`${totalWarnings} warnings`) + chalk20.gray(` across ${totalFiles} files in ${workspaces.length} packages`)
|
|
2356
|
+
);
|
|
2357
|
+
return totalErrors;
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2360
|
+
// src/actions/lint.ts
|
|
2361
|
+
var lintPackage = ({
|
|
2362
|
+
pkg,
|
|
2363
|
+
fix: fix2,
|
|
2364
|
+
verbose
|
|
2365
|
+
}) => {
|
|
2366
|
+
const pm = getPackageManager();
|
|
2367
|
+
return runSteps(`${fix2 ? "Fix" : "Lint"} [${pkg}]`, [
|
|
2368
|
+
pm.runInWorkspace(pkg, fix2 ? "package-fix" : verbose ? "package-lint-verbose" : "package-lint")
|
|
2369
|
+
]);
|
|
2370
|
+
};
|
|
2371
|
+
var lint = ({
|
|
2372
|
+
cache,
|
|
2373
|
+
fix: fix2,
|
|
2374
|
+
jobs,
|
|
2375
|
+
next,
|
|
2376
|
+
pkg,
|
|
2377
|
+
verbose
|
|
2378
|
+
}) => {
|
|
2379
|
+
if (next) {
|
|
2380
|
+
return lintNext({
|
|
2381
|
+
cache,
|
|
2382
|
+
fix: fix2,
|
|
2383
|
+
jobs,
|
|
2384
|
+
pkg,
|
|
2385
|
+
verbose
|
|
2386
|
+
});
|
|
2387
|
+
}
|
|
2388
|
+
return pkg === void 0 ? lintAllPackages({ fix: fix2 }) : lintPackage({
|
|
2389
|
+
pkg,
|
|
2390
|
+
fix: fix2,
|
|
2391
|
+
verbose
|
|
2392
|
+
});
|
|
2393
|
+
};
|
|
2394
|
+
var lintAllPackages = ({ fix: fix2 = false } = {}) => {
|
|
2395
|
+
const fixOptions = fix2 ? ["--fix"] : [];
|
|
2396
|
+
return runSteps(`${fix2 ? "Fix" : "Lint"} [All-Packages]`, [
|
|
2397
|
+
["eslint", ["--cache", "--cache-location", ".eslintcache", "--cache-strategy", "content", ...fixOptions]]
|
|
2398
|
+
]);
|
|
2399
|
+
};
|
|
2400
|
+
|
|
2401
|
+
// src/actions/fix.ts
|
|
2402
|
+
var fix = (params) => {
|
|
2403
|
+
return lint({ ...params, fix: true });
|
|
2404
|
+
};
|
|
2405
|
+
|
|
2406
|
+
// src/actions/knip.ts
|
|
2407
|
+
var knip = () => {
|
|
2408
|
+
return runSteps("Knip", [["knip", ["--dependencies", "--no-exit-code"]]]);
|
|
2409
|
+
};
|
|
2410
|
+
|
|
2411
|
+
// src/actions/lint-init.ts
|
|
2412
|
+
import {
|
|
2413
|
+
existsSync as existsSync3,
|
|
2414
|
+
readFileSync as readFileSync4,
|
|
2415
|
+
unlinkSync,
|
|
2416
|
+
writeFileSync as writeFileSync2
|
|
2417
|
+
} from "fs";
|
|
2418
|
+
import PATH3 from "path";
|
|
2419
|
+
import { createInterface } from "readline";
|
|
2420
|
+
import chalk21 from "chalk";
|
|
2421
|
+
import { globSync as globSync3 } from "glob";
|
|
2422
|
+
function askConfirmation(question) {
|
|
2423
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
2424
|
+
return new Promise((resolve) => {
|
|
2425
|
+
rl.question(question, (answer) => {
|
|
2426
|
+
rl.close();
|
|
2427
|
+
resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
2428
|
+
});
|
|
2429
|
+
});
|
|
2430
|
+
}
|
|
2431
|
+
var DISALLOWED_IMPORTS_XYLABS = [
|
|
2432
|
+
"@xylabs/api",
|
|
2433
|
+
"@xylabs/array",
|
|
2434
|
+
"@xylabs/arraybuffer",
|
|
2435
|
+
"@xylabs/assert",
|
|
2436
|
+
"@xylabs/axios",
|
|
2437
|
+
"@xylabs/base",
|
|
2438
|
+
"@xylabs/bignumber",
|
|
2439
|
+
"@xylabs/buffer",
|
|
2440
|
+
"@xylabs/creatable",
|
|
2441
|
+
"@xylabs/decimal-precision",
|
|
2442
|
+
"@xylabs/delay",
|
|
2443
|
+
"@xylabs/enum",
|
|
2444
|
+
"@xylabs/error",
|
|
2445
|
+
"@xylabs/eth-address",
|
|
2446
|
+
"@xylabs/events",
|
|
2447
|
+
"@xylabs/exists",
|
|
2448
|
+
"@xylabs/forget",
|
|
2449
|
+
"@xylabs/function-name",
|
|
2450
|
+
"@xylabs/hex",
|
|
2451
|
+
"@xylabs/log",
|
|
2452
|
+
"@xylabs/logger",
|
|
2453
|
+
"@xylabs/object",
|
|
2454
|
+
"@xylabs/platform",
|
|
2455
|
+
"@xylabs/profile",
|
|
2456
|
+
"@xylabs/promise",
|
|
2457
|
+
"@xylabs/retry",
|
|
2458
|
+
"@xylabs/set",
|
|
2459
|
+
"@xylabs/static-implements",
|
|
2460
|
+
"@xylabs/storage",
|
|
2461
|
+
"@xylabs/telemetry",
|
|
2462
|
+
"@xylabs/telemetry-exporter",
|
|
2463
|
+
"@xylabs/timer",
|
|
2464
|
+
"@xylabs/typeof",
|
|
2465
|
+
"@xylabs/url",
|
|
2466
|
+
"@xylabs/zod"
|
|
2467
|
+
];
|
|
2468
|
+
var DISALLOWED_IMPORTS_XYO = [
|
|
2469
|
+
"@xyo-network/core-payload-plugins",
|
|
2470
|
+
"@xyo-network/manifest",
|
|
2471
|
+
"@xyo-network/modules",
|
|
2472
|
+
"@xyo-network/protocol",
|
|
2473
|
+
"@xyo-network/sdk-utils",
|
|
2474
|
+
"@xyo-network/shared",
|
|
2475
|
+
"@xyo-network/manifest-model",
|
|
2476
|
+
"@xyo-network/manifest-wrapper",
|
|
2477
|
+
"@xyo-network/boundwitness",
|
|
2478
|
+
"@xyo-network/core",
|
|
2479
|
+
"@xyo-network/crypto",
|
|
2480
|
+
"@xyo-network/payload",
|
|
2481
|
+
"@xyo-network/api",
|
|
2482
|
+
"@xyo-network/api-models",
|
|
2483
|
+
"@xyo-network/dns",
|
|
2484
|
+
"@xyo-network/metamask-connector",
|
|
2485
|
+
"@xyo-network/module-factory-locator",
|
|
2486
|
+
"@xyo-network/schema-payload-plugin",
|
|
2487
|
+
"@xyo-network/archivist-memory",
|
|
2488
|
+
"@xyo-network/id-payload-plugin",
|
|
2489
|
+
"@xyo-network/wallet",
|
|
2490
|
+
"@xyo-network/network",
|
|
2491
|
+
"@xyo-network/payload-plugin",
|
|
2492
|
+
"@xyo-network/payloadset-plugin",
|
|
2493
|
+
"@xyo-network/quadkey",
|
|
2494
|
+
"@xyo-network/schema-cache",
|
|
2495
|
+
"@xyo-network/schema-name-validator",
|
|
2496
|
+
"@xyo-network/witnesses"
|
|
2497
|
+
];
|
|
2498
|
+
function getRequiredDevDependencies(react) {
|
|
2499
|
+
const configPkg = react ? "@xylabs/eslint-config-react-flat" : "@xylabs/eslint-config-flat";
|
|
2500
|
+
return {
|
|
2501
|
+
[configPkg]: "workspace:^",
|
|
2502
|
+
eslint: "^10.0.0"
|
|
2503
|
+
};
|
|
2504
|
+
}
|
|
2505
|
+
function formatDisallowedArray(name, imports) {
|
|
2506
|
+
const items = imports.map((i) => ` '${i}',`).join("\n");
|
|
2507
|
+
return `const ${name} = [
|
|
2508
|
+
${items}
|
|
2509
|
+
]`;
|
|
2510
|
+
}
|
|
2511
|
+
function generateEslintConfig({
|
|
2512
|
+
react,
|
|
2513
|
+
useXyLabsBarrel,
|
|
2514
|
+
useXyoBarrel
|
|
2515
|
+
}) {
|
|
2516
|
+
const configPkg = react ? "@xylabs/eslint-config-react-flat" : "@xylabs/eslint-config-flat";
|
|
2517
|
+
const lines = [
|
|
2518
|
+
"import type { Linter } from 'eslint'",
|
|
2519
|
+
"",
|
|
2520
|
+
`import { config as xylabsConfig } from '${configPkg}'`,
|
|
2521
|
+
""
|
|
2522
|
+
];
|
|
2523
|
+
if (useXyLabsBarrel) {
|
|
2524
|
+
lines.push(formatDisallowedArray("disallowedImportsXyLabs", DISALLOWED_IMPORTS_XYLABS), "");
|
|
2525
|
+
}
|
|
2526
|
+
if (useXyoBarrel) {
|
|
2527
|
+
lines.push(formatDisallowedArray("disallowedImportsXyo", DISALLOWED_IMPORTS_XYO), "");
|
|
2528
|
+
}
|
|
2529
|
+
lines.push("const config: Linter.Config[] = [", " { ignores: ['.yarn/**', 'build', '**/build/**', '**/dist/**', 'dist', 'node_modules/**', '**/node_modules/**', '**/*.md/**', '.claude/worktrees/*'] },", " ...xylabsConfig,");
|
|
2530
|
+
if (useXyLabsBarrel || useXyoBarrel) {
|
|
2531
|
+
lines.push(" {", " rules:", " {", " 'no-restricted-imports': [", " 'warn',", " {");
|
|
2532
|
+
if (useXyLabsBarrel && useXyoBarrel) {
|
|
2533
|
+
lines.push(" paths: [", " ...disallowedImportsXyLabs,", " ...disallowedImportsXyo,", " ],");
|
|
2534
|
+
} else if (useXyLabsBarrel) {
|
|
2535
|
+
lines.push(" paths: [", " ...disallowedImportsXyLabs,", " ],");
|
|
2536
|
+
} else {
|
|
2537
|
+
lines.push(" paths: [", " ...disallowedImportsXyo,", " ],");
|
|
2538
|
+
}
|
|
2539
|
+
lines.push(" },", " ],", " },", " },");
|
|
2540
|
+
}
|
|
2541
|
+
lines.push("]", "", "export default config", "");
|
|
2542
|
+
return lines.join("\n");
|
|
2543
|
+
}
|
|
2544
|
+
function addDevDependencies(packageJsonPath, requiredDeps, verbose) {
|
|
2545
|
+
const content = readFileSync4(packageJsonPath, "utf8");
|
|
2546
|
+
const pkg = JSON.parse(content);
|
|
2547
|
+
const devDeps = pkg.devDependencies ?? {};
|
|
2548
|
+
let changed = false;
|
|
2549
|
+
for (const [name, version] of Object.entries(requiredDeps)) {
|
|
2550
|
+
if (!devDeps[name]) {
|
|
2551
|
+
devDeps[name] = version;
|
|
2552
|
+
changed = true;
|
|
2553
|
+
if (verbose) console.log(chalk21.gray(` Added ${name}@${version} to devDependencies`));
|
|
2554
|
+
} else if (verbose) {
|
|
2555
|
+
console.log(chalk21.gray(` ${name} already in devDependencies`));
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
if (changed) {
|
|
2559
|
+
const sorted = Object.fromEntries(Object.entries(devDeps).toSorted(([a], [b]) => a.localeCompare(b)));
|
|
2560
|
+
pkg.devDependencies = sorted;
|
|
2561
|
+
writeFileSync2(packageJsonPath, `${JSON.stringify(pkg, null, 2)}
|
|
2562
|
+
`, "utf8");
|
|
2563
|
+
console.log(chalk21.green("Updated package.json devDependencies"));
|
|
2564
|
+
} else {
|
|
2565
|
+
console.log(chalk21.gray("package.json devDependencies already up to date"));
|
|
2566
|
+
}
|
|
2567
|
+
return changed;
|
|
2568
|
+
}
|
|
2569
|
+
function detectReactInMonorepo(cwd, verbose) {
|
|
2570
|
+
const packageJsonPaths = globSync3("packages/**/package.json", {
|
|
2571
|
+
cwd,
|
|
2572
|
+
ignore: ["**/node_modules/**"]
|
|
2573
|
+
});
|
|
2574
|
+
for (const relPath of packageJsonPaths) {
|
|
2575
|
+
const fullPath = PATH3.resolve(cwd, relPath);
|
|
2576
|
+
try {
|
|
2577
|
+
const content = readFileSync4(fullPath, "utf8");
|
|
2578
|
+
const pkg = JSON.parse(content);
|
|
2579
|
+
const deps = pkg.dependencies;
|
|
2580
|
+
const peerDeps = pkg.peerDependencies;
|
|
2581
|
+
if (deps?.react || peerDeps?.react) {
|
|
2582
|
+
if (verbose) console.log(chalk21.gray(` React detected in ${relPath}`));
|
|
2583
|
+
return true;
|
|
2584
|
+
}
|
|
2585
|
+
} catch {
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
return false;
|
|
2589
|
+
}
|
|
2590
|
+
function findExistingConfig(configPath, legacyConfigPath) {
|
|
2591
|
+
if (existsSync3(configPath)) return configPath;
|
|
2592
|
+
if (existsSync3(legacyConfigPath)) return legacyConfigPath;
|
|
2593
|
+
return void 0;
|
|
2594
|
+
}
|
|
2595
|
+
function removeLegacyConfig(legacyConfigPath) {
|
|
2596
|
+
if (existsSync3(legacyConfigPath)) {
|
|
2597
|
+
unlinkSync(legacyConfigPath);
|
|
2598
|
+
console.log(chalk21.gray("Removed legacy eslint.config.mjs"));
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
function updateDependencies(packageJsonPath, react, cwd, verbose) {
|
|
2602
|
+
if (!existsSync3(packageJsonPath)) {
|
|
2603
|
+
console.log(chalk21.yellow("No package.json found \u2014 skipping dependency updates"));
|
|
2604
|
+
return;
|
|
2605
|
+
}
|
|
2606
|
+
const changed = addDevDependencies(packageJsonPath, getRequiredDevDependencies(react), verbose);
|
|
2607
|
+
if (changed) {
|
|
2608
|
+
runInstall(cwd);
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
async function lintInit({ verbose } = {}) {
|
|
2612
|
+
const cwd = INIT_CWD();
|
|
2613
|
+
const configPath = PATH3.resolve(cwd, "eslint.config.ts");
|
|
2614
|
+
const legacyConfigPath = PATH3.resolve(cwd, "eslint.config.mjs");
|
|
2615
|
+
const existingPath = findExistingConfig(configPath, legacyConfigPath);
|
|
2616
|
+
if (existingPath) {
|
|
2617
|
+
const filename = PATH3.basename(existingPath);
|
|
2618
|
+
const confirmed = await askConfirmation(
|
|
2619
|
+
chalk21.yellow(`${filename} already exists. Replace it with eslint.config.ts? (y/N) `)
|
|
2620
|
+
);
|
|
2621
|
+
if (!confirmed) {
|
|
2622
|
+
console.log(chalk21.gray(`Skipped \u2014 existing ${filename} preserved`));
|
|
2623
|
+
return 0;
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
const react = detectReactInMonorepo(cwd, verbose);
|
|
2627
|
+
if (react) {
|
|
2628
|
+
console.log(chalk21.cyan("Detected React packages \u2014 using @xylabs/eslint-config-react-flat"));
|
|
2629
|
+
} else if (verbose) {
|
|
2630
|
+
console.log(chalk21.gray(" No React packages detected \u2014 using @xylabs/eslint-config-flat"));
|
|
2631
|
+
}
|
|
2632
|
+
const useXyLabsBarrel = await askConfirmation(
|
|
2633
|
+
chalk21.cyan("Disallow @xylabs/sdk-js barrel imports? (y/N) ")
|
|
2634
|
+
);
|
|
2635
|
+
const useXyoBarrel = await askConfirmation(
|
|
2636
|
+
chalk21.cyan("Disallow @xyo-network/sdk-js barrel imports? (y/N) ")
|
|
2637
|
+
);
|
|
2638
|
+
const config2 = generateEslintConfig({
|
|
2639
|
+
react,
|
|
2640
|
+
useXyLabsBarrel,
|
|
2641
|
+
useXyoBarrel
|
|
2642
|
+
});
|
|
2643
|
+
writeFileSync2(configPath, config2, "utf8");
|
|
2644
|
+
console.log(chalk21.green("Generated eslint.config.ts"));
|
|
2645
|
+
removeLegacyConfig(legacyConfigPath);
|
|
2646
|
+
updateDependencies(PATH3.resolve(cwd, "package.json"), react, cwd, verbose);
|
|
2647
|
+
return 0;
|
|
2648
|
+
}
|
|
2649
|
+
|
|
2650
|
+
// src/actions/lintlint.ts
|
|
2651
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
2652
|
+
import {
|
|
2653
|
+
existsSync as existsSync4,
|
|
2654
|
+
readFileSync as readFileSync5,
|
|
2655
|
+
writeFileSync as writeFileSync3
|
|
2656
|
+
} from "fs";
|
|
2657
|
+
import PATH4 from "path";
|
|
2658
|
+
import chalk22 from "chalk";
|
|
2659
|
+
import { findUp } from "find-up";
|
|
2660
|
+
function parseRuleValue(value) {
|
|
2661
|
+
if (typeof value === "string") {
|
|
2662
|
+
return { level: value };
|
|
2663
|
+
}
|
|
2664
|
+
if (typeof value === "number") {
|
|
2665
|
+
return { level: String(value) };
|
|
2666
|
+
}
|
|
2667
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
2668
|
+
return {
|
|
2669
|
+
level: String(value[0]),
|
|
2670
|
+
options: value.length > 1 ? value.slice(1) : void 0
|
|
2671
|
+
};
|
|
2672
|
+
}
|
|
2673
|
+
return void 0;
|
|
2674
|
+
}
|
|
2675
|
+
function normalizeLevel(level) {
|
|
2676
|
+
if (level === "0" || level === "off") return "off";
|
|
2677
|
+
if (level === "1" || level === "warn") return "warn";
|
|
2678
|
+
if (level === "2" || level === "error") return "error";
|
|
2679
|
+
return level;
|
|
2680
|
+
}
|
|
2681
|
+
function rulesMatch(a, b) {
|
|
2682
|
+
if (normalizeLevel(a.level) !== normalizeLevel(b.level)) return false;
|
|
2683
|
+
return JSON.stringify(a.options) === JSON.stringify(b.options);
|
|
2684
|
+
}
|
|
2685
|
+
function formatRule(entry) {
|
|
2686
|
+
if (entry.options) {
|
|
2687
|
+
return JSON.stringify([entry.level, ...entry.options]);
|
|
2688
|
+
}
|
|
2689
|
+
return JSON.stringify([entry.level]);
|
|
2690
|
+
}
|
|
2691
|
+
function mergeRulesFromBlocks(blocks) {
|
|
2692
|
+
const merged = /* @__PURE__ */ new Map();
|
|
2693
|
+
for (const block of blocks) {
|
|
2694
|
+
if (!block.rules) continue;
|
|
2695
|
+
for (const [name, value] of Object.entries(block.rules)) {
|
|
2696
|
+
const parsed = parseRuleValue(value);
|
|
2697
|
+
if (parsed) merged.set(name, parsed);
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
return merged;
|
|
2701
|
+
}
|
|
2702
|
+
function detectSharedPackage(source) {
|
|
2703
|
+
if (source.includes("@xylabs/eslint-config-react-flat")) return "@xylabs/eslint-config-react-flat";
|
|
2704
|
+
if (source.includes("@xylabs/eslint-config-flat")) return "@xylabs/eslint-config-flat";
|
|
2705
|
+
return void 0;
|
|
2706
|
+
}
|
|
2707
|
+
function extractLocalRuleBlocks(source) {
|
|
2708
|
+
const blocks = [];
|
|
2709
|
+
const ruleBlockRegex = /\{\s*(?:files\s*:\s*\[.*?\]\s*,\s*)?rules\s*:\s*\{([^}]*(?:\{[^}]*\}[^}]*)*)\}/g;
|
|
2710
|
+
let match;
|
|
2711
|
+
while ((match = ruleBlockRegex.exec(source)) !== null) {
|
|
2712
|
+
blocks.push(match[1]);
|
|
2713
|
+
}
|
|
2714
|
+
return blocks;
|
|
2715
|
+
}
|
|
2716
|
+
function extractRulesFromSourceBlocks(blocks) {
|
|
2717
|
+
const rules2 = /* @__PURE__ */ new Map();
|
|
2718
|
+
for (const block of blocks) {
|
|
2719
|
+
const ruleRegex = /['"]([^'"]+)['"]\s*:\s*(\[[\s\S]*?\](?=\s*,|\s*$))/gm;
|
|
2720
|
+
let match;
|
|
2721
|
+
while ((match = ruleRegex.exec(block)) !== null) {
|
|
2722
|
+
rules2.set(match[1], match[2]);
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
return rules2;
|
|
2726
|
+
}
|
|
2727
|
+
function extractConfigBlocks(sharedModule) {
|
|
2728
|
+
const config2 = sharedModule.config ?? sharedModule.default;
|
|
2729
|
+
if (Array.isArray(config2)) return config2;
|
|
2730
|
+
return [];
|
|
2731
|
+
}
|
|
2732
|
+
async function resolveSharedConfig(configDir, sharedPkg) {
|
|
2733
|
+
try {
|
|
2734
|
+
const sharedModule = await import(sharedPkg);
|
|
2735
|
+
return extractConfigBlocks(sharedModule);
|
|
2736
|
+
} catch {
|
|
2737
|
+
const distPath = PATH4.resolve(configDir, "node_modules", sharedPkg, "dist", "node", "index.mjs");
|
|
2738
|
+
try {
|
|
2739
|
+
const sharedModule = await import(distPath);
|
|
2740
|
+
return extractConfigBlocks(sharedModule);
|
|
2741
|
+
} catch {
|
|
2742
|
+
const neutralPath = PATH4.resolve(configDir, "node_modules", sharedPkg, "dist", "neutral", "index.mjs");
|
|
2743
|
+
const sharedModule = await import(neutralPath);
|
|
2744
|
+
return extractConfigBlocks(sharedModule);
|
|
2745
|
+
}
|
|
2746
|
+
return [];
|
|
2747
|
+
}
|
|
2748
|
+
}
|
|
2749
|
+
async function loadSharedRules(configDir, sharedPkg, verbose) {
|
|
2750
|
+
const sharedBlocks = await resolveSharedConfig(configDir, sharedPkg);
|
|
2751
|
+
const sharedRules = mergeRulesFromBlocks(sharedBlocks);
|
|
2752
|
+
if (verbose) {
|
|
2753
|
+
console.log(chalk22.gray(`Shared config defines ${sharedRules.size} rules`));
|
|
2754
|
+
}
|
|
2755
|
+
if (sharedRules.size === 0) {
|
|
2756
|
+
console.error(chalk22.red("Could not load rules from shared config. Is it installed and built?"));
|
|
2757
|
+
return void 0;
|
|
2758
|
+
}
|
|
2759
|
+
return sharedRules;
|
|
2760
|
+
}
|
|
2761
|
+
async function loadLocalRules(eslintConfigPath, source, verbose) {
|
|
2762
|
+
const localModule = await import(eslintConfigPath);
|
|
2763
|
+
const localConfig = localModule.default ?? localModule;
|
|
2764
|
+
const localBlocks = Array.isArray(localConfig) ? localConfig : [localConfig];
|
|
2765
|
+
const resolved = mergeRulesFromBlocks(localBlocks);
|
|
2766
|
+
const localRuleBlocks = extractLocalRuleBlocks(source);
|
|
2767
|
+
const explicit = extractRulesFromSourceBlocks(localRuleBlocks);
|
|
2768
|
+
if (verbose) {
|
|
2769
|
+
console.log(chalk22.gray(`Local config has ${explicit.size} explicit rule setting(s)`));
|
|
2770
|
+
}
|
|
2771
|
+
return { explicit, resolved };
|
|
2772
|
+
}
|
|
2773
|
+
function compareRules(explicitRuleNames, allResolvedRules, sharedRules) {
|
|
2774
|
+
const redundant = [];
|
|
2775
|
+
const overrides = [];
|
|
2776
|
+
const additions = [];
|
|
2777
|
+
for (const ruleName of explicitRuleNames.keys()) {
|
|
2778
|
+
const resolvedEntry = allResolvedRules.get(ruleName);
|
|
2779
|
+
const sharedEntry = sharedRules.get(ruleName);
|
|
2780
|
+
if (!resolvedEntry) continue;
|
|
2781
|
+
if (!sharedEntry) {
|
|
2782
|
+
additions.push({ local: resolvedEntry, rule: ruleName });
|
|
2783
|
+
} else if (rulesMatch(resolvedEntry, sharedEntry)) {
|
|
2784
|
+
redundant.push({
|
|
2785
|
+
local: resolvedEntry,
|
|
2786
|
+
rule: ruleName,
|
|
2787
|
+
shared: sharedEntry
|
|
2788
|
+
});
|
|
2789
|
+
} else {
|
|
2790
|
+
overrides.push({
|
|
2791
|
+
local: resolvedEntry,
|
|
2792
|
+
rule: ruleName,
|
|
2793
|
+
shared: sharedEntry
|
|
2794
|
+
});
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2797
|
+
return {
|
|
2798
|
+
additions,
|
|
2799
|
+
overrides,
|
|
2800
|
+
redundant
|
|
2801
|
+
};
|
|
2802
|
+
}
|
|
2803
|
+
function reportResults({
|
|
2804
|
+
additions,
|
|
2805
|
+
overrides,
|
|
2806
|
+
redundant
|
|
2807
|
+
}, verbose) {
|
|
2808
|
+
if (redundant.length > 0) {
|
|
2809
|
+
console.log(chalk22.yellow(`
|
|
2810
|
+
${redundant.length} redundant rule(s) (same as shared config \u2014 can be removed):`));
|
|
2811
|
+
for (const { rule, local } of redundant) {
|
|
2812
|
+
console.log(chalk22.yellow(` ${rule}: ${formatRule(local)}`));
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
if (overrides.length > 0) {
|
|
2816
|
+
console.log(chalk22.cyan(`
|
|
2817
|
+
${overrides.length} rule override(s) (different from shared config):`));
|
|
2818
|
+
for (const {
|
|
2819
|
+
rule,
|
|
2820
|
+
local,
|
|
2821
|
+
shared
|
|
2822
|
+
} of overrides) {
|
|
2823
|
+
console.log(chalk22.cyan(` ${rule}:`));
|
|
2824
|
+
console.log(chalk22.gray(` shared: ${formatRule(shared)}`));
|
|
2825
|
+
console.log(chalk22.white(` local: ${formatRule(local)}`));
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
if (additions.length > 0 && verbose) {
|
|
2829
|
+
console.log(chalk22.gray(`
|
|
2830
|
+
${additions.length} local addition(s) (not in shared config):`));
|
|
2831
|
+
for (const { rule, local } of additions) {
|
|
2832
|
+
console.log(chalk22.gray(` ${rule}: ${formatRule(local)}`));
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
if (redundant.length === 0 && overrides.length === 0) {
|
|
2836
|
+
console.log(chalk22.green("No redundant or overridden rules found"));
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
function fixRedundantRules(eslintConfigPath, redundant) {
|
|
2840
|
+
let updated = readFileSync5(eslintConfigPath, "utf8");
|
|
2841
|
+
const original = updated;
|
|
2842
|
+
for (const { rule } of redundant) {
|
|
2843
|
+
const escaped = rule.replaceAll("/", String.raw`\/`);
|
|
2844
|
+
const pattern = new RegExp(String.raw`[ \t]*['"]${escaped}['"]\s*:\s*\[[^\]]*\],?[ \t]*\n?`, "g");
|
|
2845
|
+
updated = updated.replace(pattern, "");
|
|
2846
|
+
}
|
|
2847
|
+
updated = updated.replaceAll(/\{\s*rules\s*:\s*\{\s*\}\s*,?\s*\}\s*,?/g, "");
|
|
2848
|
+
updated = updated.replaceAll(/\n{3,}/g, "\n\n");
|
|
2849
|
+
if (updated !== original) {
|
|
2850
|
+
writeFileSync3(eslintConfigPath, updated, "utf8");
|
|
2851
|
+
console.log(chalk22.green(`
|
|
2852
|
+
Fixed: removed ${redundant.length} redundant rule(s)`));
|
|
2853
|
+
}
|
|
2854
|
+
}
|
|
2855
|
+
function formatConfigFile(eslintConfigPath) {
|
|
2856
|
+
spawnSync3("eslint", ["--fix", eslintConfigPath], { stdio: "inherit" });
|
|
2857
|
+
}
|
|
2858
|
+
function fixConfigMismatch(eslintConfigPath, configDir, source, sharedPkg, expectedPkg) {
|
|
2859
|
+
const updated = source.replaceAll(sharedPkg, expectedPkg);
|
|
2860
|
+
writeFileSync3(eslintConfigPath, updated, "utf8");
|
|
2861
|
+
console.log(chalk22.green(`Fixed: replaced ${sharedPkg} with ${expectedPkg}`));
|
|
2862
|
+
const packageJsonPath = PATH4.resolve(configDir, "package.json");
|
|
2863
|
+
if (!existsSync4(packageJsonPath)) return;
|
|
2864
|
+
const content = readFileSync5(packageJsonPath, "utf8");
|
|
2865
|
+
const pkg = JSON.parse(content);
|
|
2866
|
+
const devDeps = pkg.devDependencies ?? {};
|
|
2867
|
+
const oldVersion = devDeps[sharedPkg];
|
|
2868
|
+
if (!oldVersion) return;
|
|
2869
|
+
delete devDeps[sharedPkg];
|
|
2870
|
+
devDeps[expectedPkg] = oldVersion;
|
|
2871
|
+
const sorted = Object.fromEntries(Object.entries(devDeps).toSorted(([a], [b]) => a.localeCompare(b)));
|
|
2872
|
+
pkg.devDependencies = sorted;
|
|
2873
|
+
writeFileSync3(packageJsonPath, `${JSON.stringify(pkg, null, 2)}
|
|
2874
|
+
`, "utf8");
|
|
2875
|
+
console.log(chalk22.green(`Updated package.json: ${sharedPkg} \u2192 ${expectedPkg}`));
|
|
2876
|
+
runInstall(configDir);
|
|
2877
|
+
}
|
|
2878
|
+
function checkConfigVariant(eslintConfigPath, configDir, source, sharedPkg, fix2, verbose) {
|
|
2879
|
+
const hasReact = detectReactInMonorepo(configDir, verbose);
|
|
2880
|
+
const expectedPkg = hasReact ? "@xylabs/eslint-config-react-flat" : "@xylabs/eslint-config-flat";
|
|
2881
|
+
if (sharedPkg === expectedPkg) return false;
|
|
2882
|
+
console.log(chalk22.yellow(`
|
|
2883
|
+
Config mismatch: using ${sharedPkg} but ${hasReact ? "React packages detected" : "no React packages found"}`));
|
|
2884
|
+
console.log(chalk22.yellow(` Expected: ${expectedPkg}`));
|
|
2885
|
+
if (fix2) {
|
|
2886
|
+
fixConfigMismatch(eslintConfigPath, configDir, source, sharedPkg, expectedPkg);
|
|
2887
|
+
}
|
|
2888
|
+
return true;
|
|
2889
|
+
}
|
|
2890
|
+
async function lintlint({ fix: fix2, verbose } = {}) {
|
|
2891
|
+
const eslintConfigPath = await findUp(["eslint.config.ts", "eslint.config.mjs"]);
|
|
2892
|
+
if (!eslintConfigPath) {
|
|
2893
|
+
console.error(chalk22.red("No eslint.config.ts found"));
|
|
2894
|
+
return 1;
|
|
2895
|
+
}
|
|
2896
|
+
const configDir = PATH4.dirname(eslintConfigPath);
|
|
2897
|
+
if (verbose) {
|
|
2898
|
+
console.log(chalk22.gray(`Found config: ${eslintConfigPath}`));
|
|
2899
|
+
}
|
|
2900
|
+
const source = readFileSync5(eslintConfigPath, "utf8");
|
|
2901
|
+
const sharedPkg = detectSharedPackage(source);
|
|
2902
|
+
if (!sharedPkg) {
|
|
2903
|
+
console.log(chalk22.yellow("No @xylabs/eslint-config-flat or @xylabs/eslint-config-react-flat imports found"));
|
|
2904
|
+
return 0;
|
|
2905
|
+
}
|
|
2906
|
+
if (verbose) {
|
|
2907
|
+
console.log(chalk22.gray(`Shared package: ${sharedPkg}`));
|
|
2908
|
+
}
|
|
2909
|
+
const hasMismatch = checkConfigVariant(eslintConfigPath, configDir, source, sharedPkg, !!fix2, !!verbose);
|
|
2910
|
+
const currentSource = hasMismatch && fix2 ? readFileSync5(eslintConfigPath, "utf8") : source;
|
|
2911
|
+
const sharedRules = await loadSharedRules(configDir, sharedPkg, !!verbose);
|
|
2912
|
+
if (!sharedRules) return 1;
|
|
2913
|
+
const { explicit, resolved } = await loadLocalRules(eslintConfigPath, currentSource, !!verbose);
|
|
2914
|
+
const results = compareRules(explicit, resolved, sharedRules);
|
|
2915
|
+
reportResults(results, !!verbose);
|
|
2916
|
+
if (results.redundant.length > 0 && fix2) {
|
|
2917
|
+
fixRedundantRules(eslintConfigPath, results.redundant);
|
|
2918
|
+
}
|
|
2919
|
+
const didFix = fix2 && (hasMismatch || results.redundant.length > 0);
|
|
2920
|
+
if (didFix) {
|
|
2921
|
+
formatConfigFile(eslintConfigPath);
|
|
2922
|
+
}
|
|
2923
|
+
const hasUnfixedMismatch = hasMismatch && !fix2;
|
|
2924
|
+
const hasUnfixedRedundant = results.redundant.length > 0 && !fix2;
|
|
2925
|
+
return hasUnfixedMismatch || hasUnfixedRedundant ? 1 : 0;
|
|
2926
|
+
}
|
|
2927
|
+
|
|
2928
|
+
// src/actions/package/compile/XyConfig.ts
|
|
2929
|
+
var ALL_PUBLINT_CHECKS = [
|
|
2930
|
+
"files",
|
|
2931
|
+
"importToDefault",
|
|
2932
|
+
"main",
|
|
2933
|
+
"module",
|
|
2934
|
+
"peerDeps",
|
|
2935
|
+
"publint",
|
|
2936
|
+
"resolutions",
|
|
2937
|
+
"rootSource",
|
|
2938
|
+
"rootTypes",
|
|
2939
|
+
"sideEffects",
|
|
2940
|
+
"source",
|
|
2941
|
+
"types"
|
|
2942
|
+
];
|
|
2943
|
+
var PUBLISH_ONLY_CHECKS = [
|
|
2944
|
+
"files",
|
|
2945
|
+
"importToDefault",
|
|
2946
|
+
"main",
|
|
2947
|
+
"module",
|
|
2948
|
+
"publint",
|
|
2949
|
+
"rootSource",
|
|
2950
|
+
"rootTypes",
|
|
2951
|
+
"sideEffects",
|
|
2952
|
+
"source",
|
|
2953
|
+
"types"
|
|
2954
|
+
];
|
|
2955
|
+
|
|
2956
|
+
// src/actions/package/publint.ts
|
|
2957
|
+
import { promises as fs15 } from "fs";
|
|
2958
|
+
import path8 from "path";
|
|
2959
|
+
import chalk23 from "chalk";
|
|
2960
|
+
import { glob } from "glob";
|
|
2961
|
+
import sortPackageJson3 from "sort-package-json";
|
|
2962
|
+
var removeSourceFromExports = (exports) => {
|
|
2963
|
+
let removed = false;
|
|
2964
|
+
for (const [key, value] of Object.entries(exports)) {
|
|
2965
|
+
if (key === "source") {
|
|
2966
|
+
delete exports[key];
|
|
2967
|
+
removed = true;
|
|
2968
|
+
} else if (typeof value === "object" && value !== null && removeSourceFromExports(value)) removed = true;
|
|
2969
|
+
}
|
|
2970
|
+
return removed;
|
|
2971
|
+
};
|
|
2972
|
+
var hasSourceInExports = (exports) => {
|
|
2973
|
+
for (const [key, value] of Object.entries(exports)) {
|
|
2974
|
+
if (key === "source") return true;
|
|
2975
|
+
if (typeof value === "object" && value !== null && hasSourceInExports(value)) return true;
|
|
2976
|
+
}
|
|
2977
|
+
return false;
|
|
2978
|
+
};
|
|
2979
|
+
var hasImportKeyInExports = (exports) => {
|
|
2980
|
+
for (const [key, value] of Object.entries(exports)) {
|
|
2981
|
+
if (key === "import" && typeof value === "string" && value.endsWith(".mjs")) return true;
|
|
2982
|
+
if (typeof value === "object" && value !== null && hasImportKeyInExports(value)) return true;
|
|
2983
|
+
}
|
|
2984
|
+
return false;
|
|
2985
|
+
};
|
|
2986
|
+
var replaceImportWithDefault = (exports) => {
|
|
2987
|
+
let modified = false;
|
|
2988
|
+
for (const [key, value] of Object.entries(exports)) {
|
|
2989
|
+
if (key === "import" && typeof value === "string" && value.endsWith(".mjs")) {
|
|
2990
|
+
if (exports.default === void 0) {
|
|
2991
|
+
exports.default = value;
|
|
2992
|
+
}
|
|
2993
|
+
delete exports.import;
|
|
2994
|
+
if (exports.types === void 0) {
|
|
2995
|
+
exports.types = value.replace(/\.mjs$/, ".d.ts");
|
|
2996
|
+
}
|
|
2997
|
+
modified = true;
|
|
2998
|
+
} else if (typeof value === "object" && value !== null && replaceImportWithDefault(value)) modified = true;
|
|
2999
|
+
}
|
|
3000
|
+
return modified;
|
|
3001
|
+
};
|
|
3002
|
+
var hasTypesInExports = (exports) => {
|
|
3003
|
+
for (const [key, value] of Object.entries(exports)) {
|
|
3004
|
+
if (key === "types") return true;
|
|
3005
|
+
if (typeof value === "object" && value !== null && hasTypesInExports(value)) return true;
|
|
3006
|
+
}
|
|
3007
|
+
return false;
|
|
3008
|
+
};
|
|
3009
|
+
function ensureExportsPath(value) {
|
|
3010
|
+
if (value.startsWith("./") || value.startsWith("../")) return value;
|
|
3011
|
+
return `./${value}`;
|
|
3012
|
+
}
|
|
3013
|
+
function emptyCustomResult() {
|
|
3014
|
+
return {
|
|
3015
|
+
errors: 0,
|
|
3016
|
+
modified: false,
|
|
3017
|
+
warnings: 0
|
|
3018
|
+
};
|
|
3019
|
+
}
|
|
3020
|
+
function mergeResults(target, source) {
|
|
3021
|
+
target.errors += source.errors;
|
|
3022
|
+
target.warnings += source.warnings;
|
|
3023
|
+
target.modified = target.modified || source.modified;
|
|
3024
|
+
}
|
|
3025
|
+
function checkFiles(pkg, fix2) {
|
|
3026
|
+
const result = emptyCustomResult();
|
|
3027
|
+
const files = pkg.files;
|
|
3028
|
+
if (files === void 0) {
|
|
3029
|
+
console.warn(chalk23.yellow('Publint [custom]: "files" field is missing'));
|
|
3030
|
+
result.warnings++;
|
|
3031
|
+
}
|
|
3032
|
+
if (Array.isArray(files) && !files.includes("README.md")) {
|
|
3033
|
+
files.push("README.md");
|
|
3034
|
+
console.warn(chalk23.yellow('Publint [custom]: added "README.md" to "files"'));
|
|
3035
|
+
result.modified = true;
|
|
3036
|
+
result.warnings++;
|
|
3037
|
+
}
|
|
3038
|
+
if (Array.isArray(files) && files.includes("src")) {
|
|
3039
|
+
if (fix2) {
|
|
3040
|
+
pkg.files = files.filter((f) => f !== "src");
|
|
3041
|
+
console.warn(chalk23.yellow('Publint [custom]: removed "src" from "files"'));
|
|
3042
|
+
result.modified = true;
|
|
3043
|
+
} else {
|
|
3044
|
+
console.warn(chalk23.yellow('Publint [custom]: "src" should not be in "files" (use --fix to remove)'));
|
|
3045
|
+
}
|
|
3046
|
+
result.warnings++;
|
|
3047
|
+
}
|
|
3048
|
+
return result;
|
|
3049
|
+
}
|
|
3050
|
+
function checkExportsSource(pkg, fix2) {
|
|
3051
|
+
const result = emptyCustomResult();
|
|
3052
|
+
const exports = pkg.exports;
|
|
3053
|
+
if (exports && typeof exports === "object" && hasSourceInExports(exports)) {
|
|
3054
|
+
if (fix2) {
|
|
3055
|
+
removeSourceFromExports(exports);
|
|
3056
|
+
console.warn(chalk23.yellow('Publint [custom]: removed "source" entries from "exports"'));
|
|
3057
|
+
result.modified = true;
|
|
3058
|
+
} else {
|
|
3059
|
+
console.warn(chalk23.yellow('Publint [custom]: "source" entries should not be in "exports" (use --fix to remove)'));
|
|
3060
|
+
}
|
|
3061
|
+
result.warnings++;
|
|
3062
|
+
}
|
|
3063
|
+
return result;
|
|
3064
|
+
}
|
|
3065
|
+
function migrateFieldToExports(pkg, field, exportKey, fix2) {
|
|
3066
|
+
const result = emptyCustomResult();
|
|
3067
|
+
if (pkg[field] === void 0) return result;
|
|
3068
|
+
const fieldValue = pkg[field];
|
|
3069
|
+
if (!fieldValue.endsWith(".js") && !fieldValue.endsWith(".mjs") && !fieldValue.endsWith(".cjs")) return result;
|
|
3070
|
+
if (fix2) {
|
|
3071
|
+
const exportValue = ensureExportsPath(fieldValue);
|
|
3072
|
+
const exports = pkg.exports;
|
|
3073
|
+
if (exports && typeof exports === "object") {
|
|
3074
|
+
const dot = exports["."];
|
|
3075
|
+
if (dot && typeof dot === "object" && !dot[exportKey]) {
|
|
3076
|
+
dot[exportKey] = exportValue;
|
|
3077
|
+
console.warn(chalk23.yellow(`Publint [custom]: migrated "${field}" to "exports['.'].${exportKey}" (${fieldValue})`));
|
|
3078
|
+
}
|
|
3079
|
+
} else if (!pkg.exports) {
|
|
3080
|
+
pkg.exports = { ".": { [exportKey]: exportValue } };
|
|
3081
|
+
console.warn(chalk23.yellow(`Publint [custom]: migrated "${field}" to "exports" (.\u2192${fieldValue})`));
|
|
3082
|
+
}
|
|
3083
|
+
delete pkg[field];
|
|
3084
|
+
console.warn(chalk23.yellow(`Publint [custom]: removed deprecated "${field}" field`));
|
|
3085
|
+
result.modified = true;
|
|
3086
|
+
} else {
|
|
3087
|
+
console.warn(chalk23.yellow(`Publint [custom]: "${field}" field is deprecated, use "exports" instead (use --fix to remove)`));
|
|
3088
|
+
}
|
|
3089
|
+
result.warnings++;
|
|
3090
|
+
return result;
|
|
3091
|
+
}
|
|
3092
|
+
function checkSideEffects(pkg) {
|
|
3093
|
+
const result = emptyCustomResult();
|
|
3094
|
+
if (pkg.sideEffects !== false) {
|
|
3095
|
+
console.warn(chalk23.yellow('Publint [custom]: "sideEffects" field should be set to false'));
|
|
3096
|
+
result.warnings++;
|
|
3097
|
+
}
|
|
3098
|
+
return result;
|
|
3099
|
+
}
|
|
3100
|
+
function checkRootSource(pkg, fix2) {
|
|
3101
|
+
const result = emptyCustomResult();
|
|
3102
|
+
for (const field of ["source", "src"]) {
|
|
3103
|
+
if (pkg[field] !== void 0) {
|
|
3104
|
+
if (fix2) {
|
|
3105
|
+
delete pkg[field];
|
|
3106
|
+
console.warn(chalk23.yellow(`Publint [custom]: removed root-level "${field}" field`));
|
|
3107
|
+
result.modified = true;
|
|
3108
|
+
} else {
|
|
3109
|
+
console.warn(chalk23.yellow(`Publint [custom]: root-level "${field}" field should not be in package.json (use --fix to remove)`));
|
|
3110
|
+
}
|
|
3111
|
+
result.warnings++;
|
|
3112
|
+
}
|
|
3113
|
+
}
|
|
3114
|
+
return result;
|
|
3115
|
+
}
|
|
3116
|
+
function checkResolutions(pkg) {
|
|
3117
|
+
const result = emptyCustomResult();
|
|
3118
|
+
if (pkg.resolutions !== void 0) {
|
|
3119
|
+
console.warn(chalk23.yellow('Publint [custom]: "resolutions" in use'));
|
|
3120
|
+
console.warn(chalk23.gray(JSON.stringify(pkg.resolutions, null, 2)));
|
|
3121
|
+
result.warnings++;
|
|
3122
|
+
}
|
|
3123
|
+
return result;
|
|
3124
|
+
}
|
|
3125
|
+
function checkImportToDefault(pkg, fix2) {
|
|
3126
|
+
const result = emptyCustomResult();
|
|
3127
|
+
const exports = pkg.exports;
|
|
3128
|
+
if (!exports || typeof exports !== "object") return result;
|
|
3129
|
+
if (!hasImportKeyInExports(exports)) return result;
|
|
3130
|
+
if (fix2) {
|
|
3131
|
+
replaceImportWithDefault(exports);
|
|
3132
|
+
console.warn(chalk23.yellow('Publint [custom]: renamed "import" to "default" in "exports" and ensured "types" siblings'));
|
|
3133
|
+
result.modified = true;
|
|
3134
|
+
} else {
|
|
3135
|
+
console.warn(chalk23.yellow('Publint [custom]: "import" entries in "exports" should use "default" instead (use --fix to rename)'));
|
|
3136
|
+
}
|
|
3137
|
+
result.warnings++;
|
|
3138
|
+
return result;
|
|
3139
|
+
}
|
|
3140
|
+
function checkRootTypes(pkg, fix2) {
|
|
3141
|
+
const result = emptyCustomResult();
|
|
3142
|
+
if (pkg.types === void 0) return result;
|
|
3143
|
+
const exports = pkg.exports;
|
|
3144
|
+
if (!exports || typeof exports !== "object" || !hasTypesInExports(exports)) return result;
|
|
3145
|
+
if (fix2) {
|
|
3146
|
+
delete pkg.types;
|
|
3147
|
+
console.warn(chalk23.yellow('Publint [custom]: removed redundant root "types" field (already defined in "exports")'));
|
|
3148
|
+
result.modified = true;
|
|
3149
|
+
} else {
|
|
3150
|
+
console.warn(chalk23.yellow('Publint [custom]: root "types" field is redundant when "exports" defines types (use --fix to remove)'));
|
|
3151
|
+
}
|
|
3152
|
+
result.warnings++;
|
|
3153
|
+
return result;
|
|
3154
|
+
}
|
|
3155
|
+
function customPubLint(pkg, fix2 = false, exclude = /* @__PURE__ */ new Set()) {
|
|
3156
|
+
const result = emptyCustomResult();
|
|
3157
|
+
if (!exclude.has("files")) mergeResults(result, checkFiles(pkg, fix2));
|
|
3158
|
+
if (!exclude.has("source")) mergeResults(result, checkExportsSource(pkg, fix2));
|
|
3159
|
+
if (!exclude.has("rootSource")) mergeResults(result, checkRootSource(pkg, fix2));
|
|
3160
|
+
if (!exclude.has("main")) mergeResults(result, migrateFieldToExports(pkg, "main", "default", fix2));
|
|
3161
|
+
if (!exclude.has("types")) mergeResults(result, migrateFieldToExports(pkg, "types", "types", fix2));
|
|
3162
|
+
if (!exclude.has("module")) mergeResults(result, migrateFieldToExports(pkg, "module", "default", fix2));
|
|
3163
|
+
if (!exclude.has("importToDefault")) mergeResults(result, checkImportToDefault(pkg, fix2));
|
|
3164
|
+
if (!exclude.has("rootTypes")) mergeResults(result, checkRootTypes(pkg, fix2));
|
|
3165
|
+
if (!exclude.has("sideEffects")) mergeResults(result, checkSideEffects(pkg));
|
|
3166
|
+
if (!exclude.has("resolutions")) mergeResults(result, checkResolutions(pkg));
|
|
3167
|
+
return [result.errors, result.warnings, result.modified];
|
|
3168
|
+
}
|
|
3169
|
+
var ALWAYS_INCLUDED_PATTERNS = [
|
|
3170
|
+
"package.json",
|
|
3171
|
+
"README",
|
|
3172
|
+
"README.*",
|
|
3173
|
+
"LICENCE",
|
|
3174
|
+
"LICENCE.*",
|
|
3175
|
+
"LICENSE",
|
|
3176
|
+
"LICENSE.*",
|
|
3177
|
+
"CHANGELOG",
|
|
3178
|
+
"CHANGELOG.*"
|
|
3179
|
+
];
|
|
3180
|
+
async function resolvePackFiles(pkgDir, filesField) {
|
|
3181
|
+
const patterns = [...ALWAYS_INCLUDED_PATTERNS];
|
|
3182
|
+
if (filesField) {
|
|
3183
|
+
for (const pattern of filesField) {
|
|
3184
|
+
if (pattern.startsWith("!")) {
|
|
3185
|
+
patterns.push(pattern);
|
|
3186
|
+
} else {
|
|
3187
|
+
patterns.push(pattern, `${pattern}/**`);
|
|
3188
|
+
}
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
3191
|
+
const matched = await glob(patterns, {
|
|
3192
|
+
cwd: pkgDir,
|
|
3193
|
+
nodir: true,
|
|
3194
|
+
dot: false
|
|
3195
|
+
});
|
|
3196
|
+
const files = await Promise.all(
|
|
3197
|
+
matched.map(async (rel) => {
|
|
3198
|
+
const abs = path8.join(pkgDir, rel);
|
|
3199
|
+
const data = await fs15.readFile(abs, "utf8").catch(() => "");
|
|
3200
|
+
return { name: path8.join(pkgDir, rel), data };
|
|
3201
|
+
})
|
|
3202
|
+
);
|
|
3203
|
+
return files;
|
|
3204
|
+
}
|
|
3205
|
+
async function runPublintLibrary(pkgDir, pkg, strict, pack) {
|
|
3206
|
+
const { publint: publint2 } = await import("publint");
|
|
3207
|
+
let packOption = false;
|
|
3208
|
+
if (pack) {
|
|
3209
|
+
const files = await resolvePackFiles(pkgDir, pkg.files);
|
|
3210
|
+
packOption = { files };
|
|
3211
|
+
}
|
|
3212
|
+
const { messages } = await publint2({
|
|
3213
|
+
level: "suggestion",
|
|
3214
|
+
pack: packOption,
|
|
3215
|
+
pkgDir,
|
|
3216
|
+
strict
|
|
3217
|
+
});
|
|
3218
|
+
const { formatMessage } = await import("publint/utils");
|
|
3219
|
+
for (const message of messages) {
|
|
3220
|
+
switch (message.type) {
|
|
3221
|
+
case "error": {
|
|
3222
|
+
console.error(chalk23.red(`[${message.code}] ${formatMessage(message, pkg)}`));
|
|
3223
|
+
break;
|
|
3224
|
+
}
|
|
3225
|
+
case "warning": {
|
|
3226
|
+
console.warn(chalk23.yellow(`[${message.code}] ${formatMessage(message, pkg)}`));
|
|
3227
|
+
break;
|
|
3228
|
+
}
|
|
3229
|
+
default: {
|
|
3230
|
+
console.log(chalk23.white(`[${message.code}] ${formatMessage(message, pkg)}`));
|
|
3231
|
+
break;
|
|
3232
|
+
}
|
|
3233
|
+
}
|
|
3234
|
+
}
|
|
3235
|
+
return {
|
|
3236
|
+
errors: messages.filter((message) => message.type === "error").length,
|
|
3237
|
+
total: messages.length
|
|
3238
|
+
};
|
|
3239
|
+
}
|
|
3240
|
+
var packagePublint = async ({
|
|
3241
|
+
exclude = /* @__PURE__ */ new Set(),
|
|
3242
|
+
fix: fix2 = false,
|
|
3243
|
+
pack = true,
|
|
3244
|
+
pkgDir: pkgDirParam,
|
|
3245
|
+
strict = true,
|
|
3246
|
+
verbose: _verbose = false
|
|
3247
|
+
} = {}) => {
|
|
3248
|
+
const pkgDir = pkgDirParam ?? INIT_CWD();
|
|
3249
|
+
const sortedPkg = sortPackageJson3(await fs15.readFile(`${pkgDir}/package.json`, "utf8"));
|
|
3250
|
+
await fs15.writeFile(`${pkgDir}/package.json`, sortedPkg);
|
|
3251
|
+
const pkg = JSON.parse(await fs15.readFile(`${pkgDir}/package.json`, "utf8"));
|
|
3252
|
+
const effectiveExclude = pkg.private ? /* @__PURE__ */ new Set([...exclude, ...PUBLISH_ONLY_CHECKS]) : exclude;
|
|
3253
|
+
console.log(chalk23.green(`Publint: ${String(pkg.name)}${pkg.private ? chalk23.gray(" (private)") : ""}`));
|
|
3254
|
+
console.log(chalk23.gray(pkgDir));
|
|
3255
|
+
let libraryErrors = 0;
|
|
3256
|
+
if (!effectiveExclude.has("publint")) {
|
|
3257
|
+
const library = await runPublintLibrary(pkgDir, pkg, strict, pack);
|
|
3258
|
+
libraryErrors = library.errors;
|
|
3259
|
+
}
|
|
3260
|
+
const [errorCount, _warningCount, modified] = customPubLint(pkg, fix2, effectiveExclude);
|
|
3261
|
+
if (modified) {
|
|
3262
|
+
const sorted = sortPackageJson3(JSON.stringify(pkg, null, 2));
|
|
3263
|
+
await fs15.writeFile(`${pkgDir}/package.json`, sorted);
|
|
3264
|
+
}
|
|
3265
|
+
return libraryErrors + errorCount;
|
|
3266
|
+
};
|
|
3267
|
+
|
|
3268
|
+
// src/actions/publint.ts
|
|
3269
|
+
import chalk24 from "chalk";
|
|
3270
|
+
function resolveExclude(publintConfig, cliExclude, cliInclude) {
|
|
3271
|
+
const hasExclude = (publintConfig.exclude?.length ?? 0) > 0 || (cliExclude?.length ?? 0) > 0;
|
|
3272
|
+
const hasInclude = (publintConfig.include?.length ?? 0) > 0 || (cliInclude?.length ?? 0) > 0;
|
|
3273
|
+
if (hasExclude && hasInclude) {
|
|
3274
|
+
console.error(chalk24.red("Publint: --include and --exclude cannot be used together"));
|
|
3275
|
+
return void 0;
|
|
3276
|
+
}
|
|
3277
|
+
if (hasInclude) {
|
|
3278
|
+
const include = /* @__PURE__ */ new Set([
|
|
3279
|
+
...publintConfig.include ?? [],
|
|
3280
|
+
...cliInclude ?? []
|
|
3281
|
+
]);
|
|
3282
|
+
return new Set(ALL_PUBLINT_CHECKS.filter((c) => !include.has(c)));
|
|
3283
|
+
}
|
|
3284
|
+
return /* @__PURE__ */ new Set([
|
|
3285
|
+
...publintConfig.exclude ?? [],
|
|
3286
|
+
...cliExclude ?? []
|
|
3287
|
+
]);
|
|
3288
|
+
}
|
|
3289
|
+
function normalizePublintConfig(value) {
|
|
3290
|
+
if (typeof value === "object") return value;
|
|
3291
|
+
return {};
|
|
3292
|
+
}
|
|
3293
|
+
var publint = async ({
|
|
3294
|
+
cliExclude,
|
|
3295
|
+
cliInclude,
|
|
3296
|
+
fix: fix2,
|
|
3297
|
+
jobs,
|
|
3298
|
+
pack,
|
|
3299
|
+
verbose,
|
|
3300
|
+
pkg
|
|
3301
|
+
}) => {
|
|
3302
|
+
return pkg === void 0 ? await publintAll({
|
|
3303
|
+
cliExclude,
|
|
3304
|
+
cliInclude,
|
|
3305
|
+
fix: fix2,
|
|
3306
|
+
jobs,
|
|
3307
|
+
pack,
|
|
3308
|
+
verbose
|
|
3309
|
+
}) : await publintSingle({
|
|
3310
|
+
cliExclude,
|
|
3311
|
+
cliInclude,
|
|
3312
|
+
fix: fix2,
|
|
3313
|
+
pack,
|
|
3314
|
+
pkg,
|
|
3315
|
+
verbose
|
|
3316
|
+
});
|
|
3317
|
+
};
|
|
3318
|
+
function logPublintSummary(packages, errors, ms) {
|
|
3319
|
+
const color = errors > 0 ? chalk24.red : chalk24.blue;
|
|
3320
|
+
console.log(color(`Checked ${packages} package(s) in ${ms.toFixed(0)}ms with ${errors} issue(s) found.`));
|
|
3321
|
+
}
|
|
3322
|
+
var publintSingle = async ({
|
|
3323
|
+
cliExclude,
|
|
3324
|
+
cliInclude,
|
|
3325
|
+
fix: fix2,
|
|
3326
|
+
pack,
|
|
3327
|
+
pkg,
|
|
3328
|
+
verbose
|
|
3329
|
+
}) => {
|
|
3330
|
+
const start = performance.now();
|
|
3331
|
+
const pm = getPackageManager();
|
|
3332
|
+
const workspace = pm.findWorkspace(pkg);
|
|
3333
|
+
if (!workspace) {
|
|
3334
|
+
console.error(chalk24.red(`Publint: workspace "${pkg}" not found`));
|
|
3335
|
+
return 1;
|
|
3336
|
+
}
|
|
3337
|
+
const wsPublintConfig = normalizePublintConfig(
|
|
3338
|
+
await loadWorkspaceCommandConfig(workspace.location, "publint")
|
|
3339
|
+
);
|
|
3340
|
+
const exclude = resolveExclude(wsPublintConfig, cliExclude, cliInclude);
|
|
3341
|
+
if (!exclude) return 1;
|
|
3342
|
+
const shouldPack = pack ?? wsPublintConfig.pack ?? true;
|
|
3343
|
+
const errors = await packagePublint({
|
|
3344
|
+
exclude,
|
|
3345
|
+
fix: fix2,
|
|
3346
|
+
pack: shouldPack,
|
|
3347
|
+
pkgDir: workspace.location,
|
|
3348
|
+
verbose
|
|
3349
|
+
});
|
|
3350
|
+
logPublintSummary(1, errors, performance.now() - start);
|
|
3351
|
+
return errors;
|
|
3352
|
+
};
|
|
3353
|
+
var publintAll = async ({
|
|
3354
|
+
cliExclude,
|
|
3355
|
+
cliInclude,
|
|
3356
|
+
fix: fix2,
|
|
3357
|
+
jobs,
|
|
3358
|
+
pack,
|
|
3359
|
+
verbose
|
|
3360
|
+
}) => {
|
|
3361
|
+
const start = performance.now();
|
|
3362
|
+
const pm = getPackageManager();
|
|
3363
|
+
const workspaces = pm.listWorkspaces();
|
|
3364
|
+
const concurrency = jobs;
|
|
3365
|
+
const results = Array.from({ length: workspaces.length }, () => ({ errors: 0, output: [] }));
|
|
3366
|
+
installOutputCapture();
|
|
3367
|
+
await runWithConcurrency(
|
|
3368
|
+
workspaces.map((ws, i) => ({ i, ws })),
|
|
3369
|
+
concurrency,
|
|
3370
|
+
async ({ i, ws }) => {
|
|
3371
|
+
const output = [];
|
|
3372
|
+
await outputStorage.run(output, async () => {
|
|
3373
|
+
try {
|
|
3374
|
+
const wsPublintConfig = normalizePublintConfig(
|
|
3375
|
+
await loadWorkspaceCommandConfig(ws.location, "publint")
|
|
3376
|
+
);
|
|
3377
|
+
const exclude = resolveExclude(wsPublintConfig, cliExclude, cliInclude) ?? /* @__PURE__ */ new Set();
|
|
3378
|
+
const shouldPack = pack ?? wsPublintConfig.pack ?? true;
|
|
3379
|
+
const errors = await packagePublint({
|
|
3380
|
+
exclude,
|
|
3381
|
+
fix: fix2,
|
|
3382
|
+
pack: shouldPack,
|
|
3383
|
+
pkgDir: ws.location,
|
|
3384
|
+
verbose
|
|
3385
|
+
});
|
|
3386
|
+
results[i] = { errors, output };
|
|
3387
|
+
} catch (ex) {
|
|
3388
|
+
output.push(chalk24.red(`Publint failed for ${ws.name}: ${ex.message}
|
|
3389
|
+
`));
|
|
3390
|
+
results[i] = { errors: 1, output };
|
|
3391
|
+
}
|
|
3392
|
+
});
|
|
3393
|
+
}
|
|
3394
|
+
);
|
|
3395
|
+
let totalErrors = 0;
|
|
3396
|
+
for (const { errors, output } of results) {
|
|
3397
|
+
for (const line of output) {
|
|
3398
|
+
process.stdout.write(line);
|
|
3399
|
+
}
|
|
3400
|
+
totalErrors += errors;
|
|
3401
|
+
}
|
|
3402
|
+
const allExclude = resolveExclude({}, cliExclude, cliInclude) ?? /* @__PURE__ */ new Set();
|
|
3403
|
+
if (!allExclude.has("peerDeps")) {
|
|
3404
|
+
const cwd = INIT_CWD();
|
|
3405
|
+
const peerResult = checkInternalPeerVersions(cwd, workspaces);
|
|
3406
|
+
if (peerResult.fixable.length > 0) {
|
|
3407
|
+
if (fix2) {
|
|
3408
|
+
fixInternalPeerVersions(cwd, workspaces);
|
|
3409
|
+
runInstall();
|
|
3410
|
+
} else {
|
|
3411
|
+
for (const msg of peerResult.fixable) {
|
|
3412
|
+
console.log(chalk24.red(` \u2717 ${msg} (fixable)`));
|
|
3413
|
+
}
|
|
3414
|
+
totalErrors += peerResult.fixable.length;
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
3417
|
+
totalErrors += peerResult.errors.length;
|
|
3418
|
+
}
|
|
3419
|
+
logPublintSummary(workspaces.length, totalErrors, performance.now() - start);
|
|
3420
|
+
return totalErrors;
|
|
3421
|
+
};
|
|
3422
|
+
|
|
3423
|
+
// src/actions/relint.ts
|
|
3424
|
+
var relintPackage = ({
|
|
3425
|
+
pkg,
|
|
3426
|
+
fix: fix2,
|
|
3427
|
+
verbose
|
|
3428
|
+
}) => {
|
|
3429
|
+
const pm = getPackageManager();
|
|
3430
|
+
return runSteps(`${fix2 ? "Fix" : "Lint"} [${pkg}]`, [
|
|
3431
|
+
pm.runInWorkspace(pkg, fix2 ? "package-fix" : verbose ? "package-lint-verbose" : "package-lint")
|
|
3432
|
+
]);
|
|
3433
|
+
};
|
|
3434
|
+
var relint = ({
|
|
3435
|
+
fix: fix2,
|
|
3436
|
+
jobs,
|
|
3437
|
+
next,
|
|
3438
|
+
pkg,
|
|
3439
|
+
verbose
|
|
3440
|
+
}) => {
|
|
3441
|
+
if (next) {
|
|
3442
|
+
return lintNext({
|
|
3443
|
+
cache: false,
|
|
3444
|
+
fix: fix2,
|
|
3445
|
+
jobs,
|
|
3446
|
+
pkg,
|
|
3447
|
+
verbose
|
|
3448
|
+
});
|
|
3449
|
+
}
|
|
3450
|
+
return pkg === void 0 ? relintAllPackages({ fix: fix2 }) : relintPackage({
|
|
3451
|
+
pkg,
|
|
3452
|
+
fix: fix2,
|
|
3453
|
+
verbose
|
|
3454
|
+
});
|
|
3455
|
+
};
|
|
3456
|
+
var relintAllPackages = ({ fix: fix2 = false } = {}) => {
|
|
3457
|
+
const fixOptions = fix2 ? ["--fix"] : [];
|
|
3458
|
+
return runSteps(`${fix2 ? "Fix" : "Lint"} [All-Packages]`, [
|
|
3459
|
+
["eslint", fixOptions]
|
|
3460
|
+
]);
|
|
3461
|
+
};
|
|
3462
|
+
|
|
3463
|
+
// src/actions/sonar.ts
|
|
3464
|
+
var sonar = () => {
|
|
3465
|
+
return runSteps("Sonar", [["eslint", ["-c", "sonar.eslintrc", "."]]]);
|
|
3466
|
+
};
|
|
3467
|
+
|
|
3468
|
+
// src/xy/param.ts
|
|
3469
|
+
var packagePositionalParam = (yargs) => {
|
|
3470
|
+
return yargs.positional("package", { describe: "Specific package to target", type: "string" });
|
|
3471
|
+
};
|
|
3472
|
+
|
|
3473
|
+
// src/xy/lint/cycleCommand.ts
|
|
3474
|
+
var cycleCommand = {
|
|
3475
|
+
command: "cycle [package]",
|
|
3476
|
+
describe: "Cycle - Check for dependency cycles",
|
|
3477
|
+
builder: (yargs) => {
|
|
3478
|
+
return packagePositionalParam(yargs);
|
|
3479
|
+
},
|
|
3480
|
+
handler: async (argv) => {
|
|
3481
|
+
if (argv.verbose) console.log("Cycle");
|
|
3482
|
+
process.exitCode = await cycle({ jobs: argv.jobs, pkg: argv.package });
|
|
3483
|
+
}
|
|
3484
|
+
};
|
|
3485
|
+
|
|
3486
|
+
// src/xy/lint/deplintCommand.ts
|
|
3487
|
+
var deplintCommand = {
|
|
3488
|
+
command: "deplint [package]",
|
|
3489
|
+
describe: "Deplint - Run Deplint",
|
|
3490
|
+
builder: (yargs) => {
|
|
3491
|
+
return packagePositionalParam(yargs).option("deps", {
|
|
3492
|
+
alias: "d",
|
|
3493
|
+
default: false,
|
|
3494
|
+
description: "Check dependencies",
|
|
3495
|
+
type: "boolean"
|
|
3496
|
+
}).option("devDeps", {
|
|
3497
|
+
alias: "v",
|
|
3498
|
+
default: false,
|
|
3499
|
+
description: "Check devDependencies",
|
|
3500
|
+
type: "boolean"
|
|
3501
|
+
}).option("peerDeps", {
|
|
3502
|
+
alias: "p",
|
|
3503
|
+
default: true,
|
|
3504
|
+
description: "Check peerDependencies",
|
|
3505
|
+
type: "boolean"
|
|
3506
|
+
}).option("exclude", {
|
|
3507
|
+
alias: "e",
|
|
3508
|
+
description: "Package names to exclude from unused checks (comma-separated or repeated)",
|
|
3509
|
+
type: "array"
|
|
3510
|
+
}).option("fix", {
|
|
3511
|
+
alias: "f",
|
|
3512
|
+
default: false,
|
|
3513
|
+
description: "Fix unsatisfied peer dependencies by adding them to package.json",
|
|
3514
|
+
type: "boolean"
|
|
3515
|
+
}).option("format", {
|
|
3516
|
+
choices: ["human", "json"],
|
|
3517
|
+
default: "human",
|
|
3518
|
+
description: "Output format",
|
|
3519
|
+
type: "string"
|
|
3520
|
+
});
|
|
3521
|
+
},
|
|
3522
|
+
handler: async (argv) => {
|
|
3523
|
+
if (argv.verbose) console.log("Deplint");
|
|
3524
|
+
const cliExclude = argv.exclude?.flatMap((v) => String(v).split(",")).map((v) => v.trim()).filter(Boolean);
|
|
3525
|
+
process.exitCode = await deplint({
|
|
3526
|
+
cliExclude,
|
|
3527
|
+
pkg: argv.package,
|
|
3528
|
+
deps: !!argv.deps,
|
|
3529
|
+
devDeps: !!argv.devDeps,
|
|
3530
|
+
fix: !!argv.fix,
|
|
3531
|
+
format: argv.format,
|
|
3532
|
+
peerDeps: !!argv.peerDeps,
|
|
3533
|
+
verbose: !!argv.verbose
|
|
3534
|
+
});
|
|
3535
|
+
}
|
|
3536
|
+
};
|
|
3537
|
+
|
|
3538
|
+
// src/xy/lint/fixCommand.ts
|
|
3539
|
+
import chalk25 from "chalk";
|
|
3540
|
+
var fixCommand = {
|
|
3541
|
+
builder: (yargs) => {
|
|
3542
|
+
return packagePositionalParam(yargs).option("cache", {
|
|
3543
|
+
alias: "c",
|
|
3544
|
+
default: false,
|
|
3545
|
+
description: "Use caching for performance",
|
|
3546
|
+
type: "boolean"
|
|
3547
|
+
}).option("next", {
|
|
3548
|
+
alias: "n",
|
|
3549
|
+
default: false,
|
|
3550
|
+
description: "Fix per-package (lower memory, parallel)",
|
|
3551
|
+
type: "boolean"
|
|
3552
|
+
});
|
|
3553
|
+
},
|
|
3554
|
+
command: "fix [package]",
|
|
3555
|
+
deprecated: 'Use "xy lint --fix" instead',
|
|
3556
|
+
describe: "Fix - Run Eslint w/fix",
|
|
3557
|
+
handler: async (argv) => {
|
|
3558
|
+
console.warn(chalk25.yellow('Deprecated: use "xy lint --fix" instead of "xy fix"'));
|
|
3559
|
+
if (argv.verbose) console.log("Fix");
|
|
3560
|
+
process.exitCode = await fix({
|
|
3561
|
+
cache: argv.cache,
|
|
3562
|
+
jobs: argv.jobs,
|
|
3563
|
+
next: argv.next,
|
|
3564
|
+
pkg: argv.package,
|
|
3565
|
+
verbose: !!argv.verbose
|
|
3566
|
+
});
|
|
3567
|
+
}
|
|
3568
|
+
};
|
|
3569
|
+
|
|
3570
|
+
// src/xy/lint/knipCommand.ts
|
|
3571
|
+
import chalk26 from "chalk";
|
|
3572
|
+
var knipCommand = {
|
|
3573
|
+
command: "knip",
|
|
3574
|
+
describe: "Knip - Run Knip",
|
|
3575
|
+
builder: (yargs) => {
|
|
3576
|
+
return packagePositionalParam(yargs);
|
|
3577
|
+
},
|
|
3578
|
+
handler: (argv) => {
|
|
3579
|
+
if (argv.verbose) console.log("Knip");
|
|
3580
|
+
const start = Date.now();
|
|
3581
|
+
process.exitCode = knip();
|
|
3582
|
+
console.log(chalk26.blue(`Knip finished in ${Date.now() - start}ms`));
|
|
3583
|
+
}
|
|
3584
|
+
};
|
|
3585
|
+
|
|
3586
|
+
// src/xy/lint/lint/index.ts
|
|
3587
|
+
import chalk27 from "chalk";
|
|
3588
|
+
|
|
3589
|
+
// src/xy/lint/lint/initCommand.ts
|
|
3590
|
+
var initCommand = {
|
|
3591
|
+
command: "init",
|
|
3592
|
+
describe: "Generate eslint.config.ts and add ESLint dependencies",
|
|
3593
|
+
handler: async (argv) => {
|
|
3594
|
+
if (argv.verbose) console.log("Lint Init");
|
|
3595
|
+
process.exitCode = await lintInit({ verbose: !!argv.verbose });
|
|
3596
|
+
}
|
|
3597
|
+
};
|
|
3598
|
+
|
|
3599
|
+
// src/xy/lint/lint/runCommand.ts
|
|
3600
|
+
var runCommand = {
|
|
3601
|
+
aliases: ["$0"],
|
|
3602
|
+
builder: (yargs) => {
|
|
3603
|
+
return packagePositionalParam(yargs).option("fix", {
|
|
3604
|
+
alias: "f",
|
|
3605
|
+
default: false,
|
|
3606
|
+
description: "Fix fixable issues",
|
|
3607
|
+
type: "boolean"
|
|
3608
|
+
}).option("cache", {
|
|
3609
|
+
alias: "c",
|
|
3610
|
+
default: false,
|
|
3611
|
+
description: "Use caching for performance",
|
|
3612
|
+
type: "boolean"
|
|
3613
|
+
}).option("next", {
|
|
3614
|
+
alias: "n",
|
|
3615
|
+
default: false,
|
|
3616
|
+
description: "Lint per-package (lower memory, parallel)",
|
|
3617
|
+
type: "boolean"
|
|
3618
|
+
});
|
|
3619
|
+
},
|
|
3620
|
+
command: "run [package]",
|
|
3621
|
+
describe: "Run ESLint",
|
|
3622
|
+
handler: async (argv) => {
|
|
3623
|
+
if (argv.verbose) console.log("Lint");
|
|
3624
|
+
process.exitCode = argv.fix ? await fix({
|
|
3625
|
+
cache: argv.cache,
|
|
3626
|
+
jobs: argv.jobs,
|
|
3627
|
+
next: argv.next,
|
|
3628
|
+
pkg: argv.package,
|
|
3629
|
+
verbose: !!argv.verbose
|
|
3630
|
+
}) : await lint({
|
|
3631
|
+
cache: argv.cache,
|
|
3632
|
+
jobs: argv.jobs,
|
|
3633
|
+
next: argv.next,
|
|
3634
|
+
pkg: argv.package,
|
|
3635
|
+
verbose: !!argv.verbose
|
|
3636
|
+
});
|
|
3637
|
+
}
|
|
3638
|
+
};
|
|
3639
|
+
|
|
3640
|
+
// src/xy/lint/lint/index.ts
|
|
3641
|
+
var lintCommand = {
|
|
3642
|
+
builder: (yargs) => {
|
|
3643
|
+
return yargs.command(runCommand).command(initCommand).option("init", {
|
|
3644
|
+
default: false,
|
|
3645
|
+
description: "Generate eslint.config.ts and add ESLint dependencies",
|
|
3646
|
+
hidden: true,
|
|
3647
|
+
type: "boolean"
|
|
3648
|
+
});
|
|
3649
|
+
},
|
|
3650
|
+
command: "lint",
|
|
3651
|
+
describe: "Lint - Run ESLint",
|
|
3652
|
+
handler: async (argv) => {
|
|
3653
|
+
if (argv.init) {
|
|
3654
|
+
console.warn(chalk27.yellow('Deprecated: use "xy lint init" instead of "xy lint --init"'));
|
|
3655
|
+
process.exitCode = await lintInit({ verbose: !!argv.verbose });
|
|
3656
|
+
}
|
|
3657
|
+
}
|
|
3658
|
+
};
|
|
3659
|
+
|
|
3660
|
+
// src/xy/lint/lintlintCommand.ts
|
|
3661
|
+
var lintlintCommand = {
|
|
3662
|
+
command: "lintlint",
|
|
3663
|
+
describe: "Lint Lint - Check for redundant or overridden ESLint rules vs shared config",
|
|
3664
|
+
builder: (yargs) => {
|
|
3665
|
+
return yargs.option("fix", {
|
|
3666
|
+
default: false,
|
|
3667
|
+
description: "Remove redundant rules from local config",
|
|
3668
|
+
type: "boolean"
|
|
3669
|
+
});
|
|
3670
|
+
},
|
|
3671
|
+
handler: async (argv) => {
|
|
3672
|
+
if (argv.verbose) console.log("Lint Lint");
|
|
3673
|
+
process.exitCode = await lintlint({
|
|
3674
|
+
fix: argv.fix,
|
|
3675
|
+
verbose: !!argv.verbose
|
|
3676
|
+
});
|
|
3677
|
+
}
|
|
3678
|
+
};
|
|
3679
|
+
|
|
3680
|
+
// src/xy/lint/publintCommand.ts
|
|
3681
|
+
var publintCommand = {
|
|
3682
|
+
command: "publint [package]",
|
|
3683
|
+
describe: "Publint - Run Publint",
|
|
3684
|
+
builder: (yargs) => {
|
|
3685
|
+
return packagePositionalParam(yargs).option("fix", {
|
|
3686
|
+
describe: 'Auto-fix issues (e.g. remove "src" from files, "source" from exports, root-level "source"/"src" fields)',
|
|
3687
|
+
type: "boolean",
|
|
3688
|
+
default: false
|
|
3689
|
+
}).option("exclude", {
|
|
3690
|
+
alias: "e",
|
|
3691
|
+
description: "Checks to skip (comma-separated): publint, files, source, rootSource, main, types, module, sideEffects, resolutions, peerDeps",
|
|
3692
|
+
type: "string"
|
|
3693
|
+
}).option("include", {
|
|
3694
|
+
description: "Only run these checks (comma-separated): publint, files, source, rootSource, main, types, module, sideEffects, resolutions, peerDeps",
|
|
3695
|
+
type: "string"
|
|
3696
|
+
}).option("pack", {
|
|
3697
|
+
description: "Run pack before publint to verify published files (default: true)",
|
|
3698
|
+
type: "boolean"
|
|
3699
|
+
});
|
|
3700
|
+
},
|
|
3701
|
+
handler: async (argv) => {
|
|
3702
|
+
if (argv.verbose) console.log("Publint");
|
|
3703
|
+
const parseList = (raw) => raw?.split(",").map((v) => v.trim()).filter(Boolean);
|
|
3704
|
+
process.exitCode = await publint({
|
|
3705
|
+
cliExclude: parseList(argv.exclude),
|
|
3706
|
+
cliInclude: parseList(argv.include),
|
|
3707
|
+
fix: !!argv.fix,
|
|
3708
|
+
jobs: argv.jobs,
|
|
3709
|
+
pack: argv.pack,
|
|
3710
|
+
pkg: argv.package,
|
|
3711
|
+
verbose: !!argv.verbose
|
|
3712
|
+
});
|
|
3713
|
+
}
|
|
3714
|
+
};
|
|
3715
|
+
|
|
3716
|
+
// src/xy/lint/relintCommand.ts
|
|
3717
|
+
var relintCommand = {
|
|
3718
|
+
command: "relint [package]",
|
|
3719
|
+
describe: "Relint - Clean & Lint",
|
|
3720
|
+
builder: (yargs) => {
|
|
3721
|
+
return packagePositionalParam(yargs).option("next", {
|
|
3722
|
+
alias: "n",
|
|
3723
|
+
default: false,
|
|
3724
|
+
description: "Relint per-package (lower memory, parallel)",
|
|
3725
|
+
type: "boolean"
|
|
3726
|
+
});
|
|
3727
|
+
},
|
|
3728
|
+
handler: async (argv) => {
|
|
3729
|
+
if (argv.verbose) console.log("Relinting");
|
|
3730
|
+
process.exitCode = await relint({
|
|
3731
|
+
jobs: argv.jobs,
|
|
3732
|
+
next: argv.next,
|
|
3733
|
+
pkg: argv.package,
|
|
3734
|
+
verbose: !!argv.verbose
|
|
3735
|
+
});
|
|
3736
|
+
}
|
|
3737
|
+
};
|
|
3738
|
+
|
|
3739
|
+
// src/xy/lint/sonarCommand.ts
|
|
3740
|
+
var sonarCommand = {
|
|
3741
|
+
command: "sonar",
|
|
3742
|
+
describe: "Sonar - Run Sonar Check",
|
|
3743
|
+
builder: (yargs) => {
|
|
3744
|
+
return packagePositionalParam(yargs);
|
|
3745
|
+
},
|
|
3746
|
+
handler: (argv) => {
|
|
3747
|
+
if (argv.verbose) console.log("Sonar Check");
|
|
3748
|
+
process.exitCode = sonar();
|
|
3749
|
+
}
|
|
3750
|
+
};
|
|
3751
|
+
|
|
3752
|
+
// src/xy/lint/index.ts
|
|
3753
|
+
var xyLintCommands = (args) => {
|
|
3754
|
+
return args.command(cycleCommand).command(lintCommand).command(lintlintCommand).command(deplintCommand).command(fixCommand).command(relintCommand).command(publintCommand).command(knipCommand).command(sonarCommand);
|
|
3755
|
+
};
|
|
3756
|
+
export {
|
|
3757
|
+
xyLintCommands
|
|
3758
|
+
};
|
|
3759
|
+
//# sourceMappingURL=index.mjs.map
|