@codefast/cli 0.9.0 → 0.11.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/CHANGELOG.md +61 -0
- package/README.md +345 -151
- package/dist/arrange/command.d.ts +7 -0
- package/dist/arrange/command.js +96 -132
- package/dist/arrange/domain/ast/ast-node.d.ts +394 -0
- package/dist/arrange/domain/ast/collectors-cn.d.ts +26 -0
- package/dist/arrange/domain/ast/collectors-jsx.d.ts +8 -0
- package/dist/arrange/domain/ast/collectors-tv.d.ts +34 -0
- package/dist/arrange/domain/ast/helpers.d.ts +36 -0
- package/dist/arrange/domain/ast/helpers.js +1 -0
- package/dist/arrange/domain/ast/simplify-targets.d.ts +22 -0
- package/dist/arrange/domain/ast/simplify-targets.js +18 -23
- package/dist/arrange/domain/ast/targets.d.ts +20 -0
- package/dist/arrange/domain/ast/translator.d.ts +32 -0
- package/dist/arrange/{typescript-ast-translator.js → domain/ast/translator.js} +19 -22
- package/dist/arrange/domain/constants.d.ts +111 -0
- package/dist/arrange/domain/grouping-service.d.ts +100 -0
- package/dist/arrange/domain/grouping.d.ts +21 -0
- package/dist/arrange/domain/imports.d.ts +14 -0
- package/dist/arrange/domain/source-text-formatters.d.ts +33 -0
- package/dist/arrange/domain/tailwind-token.d.ts +24 -0
- package/dist/arrange/domain/token-classifier.d.ts +47 -0
- package/dist/arrange/domain/types.d.ts +208 -0
- package/dist/arrange/group/cli-result.d.ts +7 -0
- package/dist/arrange/group/cli-result.js +12 -0
- package/dist/arrange/group/cli-schema.d.ts +17 -0
- package/dist/arrange/group/cli-schema.js +13 -0
- package/dist/arrange/group/output.d.ts +7 -0
- package/dist/arrange/group/output.js +10 -0
- package/dist/arrange/group/suggest.d.ts +8 -0
- package/dist/arrange/inspect/cli-result.d.ts +7 -0
- package/dist/arrange/inspect/cli-result.js +8 -0
- package/dist/arrange/inspect/cli-schema.d.ts +15 -0
- package/dist/arrange/inspect/cli-schema.js +9 -0
- package/dist/arrange/inspect/domain/analyze-service.d.ts +18 -0
- package/dist/arrange/inspect/output.d.ts +7 -0
- package/dist/arrange/inspect/output.js +42 -0
- package/dist/arrange/inspect/run.d.ts +10 -0
- package/dist/arrange/{analyze.js → inspect/run.js} +2 -2
- package/dist/arrange/prepare.d.ts +13 -0
- package/dist/arrange/{workspace.js → prepare.js} +5 -8
- package/dist/arrange/regroup/cli-result.d.ts +13 -0
- package/dist/arrange/regroup/cli-result.js +23 -0
- package/dist/arrange/regroup/cli-schema.d.ts +20 -0
- package/dist/arrange/regroup/cli-schema.js +14 -0
- package/dist/arrange/regroup/output.d.ts +14 -0
- package/dist/arrange/regroup/output.js +72 -0
- package/dist/arrange/regroup/process-file.d.ts +11 -0
- package/dist/arrange/regroup/run.d.ts +11 -0
- package/dist/arrange/{sync.js → regroup/run.js} +2 -2
- package/dist/arrange/resolve-target.d.ts +10 -0
- package/dist/arrange/resolve-target.js +3 -16
- package/dist/arrange/scan-target.d.ts +7 -0
- package/dist/arrange/simplify/cli-result.d.ts +7 -0
- package/dist/arrange/simplify/cli-result.js +8 -0
- package/dist/arrange/simplify/cli-schema.d.ts +17 -0
- package/dist/arrange/simplify/cli-schema.js +11 -0
- package/dist/arrange/simplify/fold-targets.d.ts +13 -0
- package/dist/arrange/simplify/fold-targets.js +139 -0
- package/dist/arrange/simplify/output.d.ts +7 -0
- package/dist/arrange/simplify/output.js +15 -0
- package/dist/arrange/simplify/process-file.d.ts +13 -0
- package/dist/arrange/simplify/process-file.js +49 -0
- package/dist/arrange/simplify/run.d.ts +14 -0
- package/dist/arrange/simplify/run.js +38 -0
- package/dist/arrange/simplify/variant-classname-probe.d.ts +35 -0
- package/dist/arrange/simplify/variant-classname-probe.js +95 -0
- package/dist/arrange/source-parse.d.ts +7 -0
- package/dist/arrange/source-parse.js +1 -1
- package/dist/audit/command.d.ts +8 -0
- package/dist/audit/command.js +134 -211
- package/dist/audit/comments/cli-result.d.ts +13 -0
- package/dist/audit/comments/cli-result.js +22 -0
- package/dist/audit/comments/cli-schema.d.ts +19 -0
- package/dist/audit/comments/cli-schema.js +13 -0
- package/dist/audit/comments/domain/comment-content.d.ts +26 -0
- package/dist/audit/comments/domain/comment-dividers.d.ts +62 -0
- package/dist/audit/comments/domain/link-references.d.ts +40 -0
- package/dist/audit/comments/domain/since-versions.d.ts +26 -0
- package/dist/audit/comments/domain/tsdoc-syntax.d.ts +20 -0
- package/dist/audit/comments/output.d.ts +7 -0
- package/dist/audit/comments/output.js +27 -0
- package/dist/audit/comments/prepare.d.ts +16 -0
- package/dist/audit/comments/prepare.js +12 -0
- package/dist/audit/comments/run.d.ts +17 -0
- package/dist/audit/{run-comments.js → comments/run.js} +5 -5
- package/dist/audit/display-names/cli-result.d.ts +13 -0
- package/dist/audit/display-names/cli-result.js +22 -0
- package/dist/audit/display-names/cli-schema.d.ts +18 -0
- package/dist/audit/display-names/cli-schema.js +12 -0
- package/dist/audit/display-names/domain/display-names.d.ts +11 -0
- package/dist/audit/display-names/output.d.ts +7 -0
- package/dist/audit/display-names/output.js +21 -0
- package/dist/audit/display-names/prepare.d.ts +16 -0
- package/dist/audit/display-names/prepare.js +12 -0
- package/dist/audit/display-names/run.d.ts +14 -0
- package/dist/audit/{run-display-names.js → display-names/run.js} +1 -1
- package/dist/audit/domain/types.d.ts +171 -0
- package/dist/audit/imports/cli-result.d.ts +13 -0
- package/dist/audit/imports/cli-result.js +22 -0
- package/dist/audit/imports/cli-schema.d.ts +18 -0
- package/dist/audit/imports/cli-schema.js +12 -0
- package/dist/audit/imports/domain/import-policy.d.ts +34 -0
- package/dist/audit/imports/domain/import-policy.js +140 -0
- package/dist/audit/imports/output.d.ts +7 -0
- package/dist/audit/imports/output.js +21 -0
- package/dist/audit/imports/prepare.d.ts +16 -0
- package/dist/audit/imports/prepare.js +12 -0
- package/dist/audit/imports/run.d.ts +14 -0
- package/dist/audit/{run-react.js → imports/run.js} +15 -5
- package/dist/audit/links/cli-result.d.ts +13 -0
- package/dist/audit/links/cli-result.js +22 -0
- package/dist/audit/links/cli-schema.d.ts +18 -0
- package/dist/audit/links/cli-schema.js +12 -0
- package/dist/audit/links/domain/markdown-links.d.ts +44 -0
- package/dist/audit/links/output.d.ts +7 -0
- package/dist/audit/links/output.js +21 -0
- package/dist/audit/links/prepare.d.ts +16 -0
- package/dist/audit/links/prepare.js +12 -0
- package/dist/audit/links/run.d.ts +14 -0
- package/dist/audit/{run-links.js → links/run.js} +1 -1
- package/dist/audit/prepare.d.ts +31 -0
- package/dist/audit/prepare.js +11 -134
- package/dist/audit/rtl/cli-result.d.ts +13 -0
- package/dist/audit/rtl/cli-result.js +22 -0
- package/dist/audit/rtl/cli-schema.d.ts +18 -0
- package/dist/audit/rtl/cli-schema.js +12 -0
- package/dist/audit/rtl/domain/audit-file.d.ts +7 -0
- package/dist/audit/{domain → rtl/domain}/audit-file.js +2 -2
- package/dist/audit/rtl/domain/mappings.d.ts +45 -0
- package/dist/audit/rtl/domain/tokenize.d.ts +14 -0
- package/dist/audit/rtl/output.d.ts +7 -0
- package/dist/audit/rtl/output.js +21 -0
- package/dist/audit/rtl/prepare.d.ts +13 -0
- package/dist/audit/rtl/prepare.js +41 -0
- package/dist/audit/rtl/run.d.ts +14 -0
- package/dist/audit/{run.js → rtl/run.js} +1 -1
- package/dist/bin.d.ts +2 -0
- package/dist/cli.d.ts +6 -0
- package/dist/core/cli/command-pipeline.d.ts +91 -0
- package/dist/core/cli/command-pipeline.js +83 -0
- package/dist/core/cli/format-error.d.ts +7 -0
- package/dist/core/cli/global-options.d.ts +15 -0
- package/dist/core/cli/global-options.js +1 -1
- package/dist/core/cli/positional.d.ts +6 -0
- package/dist/core/cli/resolve-root.d.ts +9 -0
- package/dist/core/cli/resolve-root.js +16 -0
- package/dist/core/cli/result-handle.d.ts +13 -0
- package/dist/core/cli/result-handle.js +0 -13
- package/dist/core/config/define-config.d.ts +7 -0
- package/dist/core/config/define-config.js +8 -0
- package/dist/core/config/loader.d.ts +18 -0
- package/dist/core/config/loader.js +2 -7
- package/dist/core/config/schema.d.ts +99 -0
- package/dist/core/config/schema.js +8 -86
- package/dist/core/config/warnings.d.ts +6 -0
- package/dist/core/config.d.ts +12 -0
- package/dist/core/errors.d.ts +25 -0
- package/dist/core/exit-codes.d.ts +18 -0
- package/dist/core/filesystem/filesystem.d.ts +44 -0
- package/dist/core/filesystem/node.d.ts +7 -0
- package/dist/core/filesystem/node.js +2 -1
- package/dist/core/glob.d.ts +19 -0
- package/dist/core/logger.d.ts +9 -0
- package/dist/core/result.d.ts +30 -0
- package/dist/core/schema-parse.d.ts +9 -0
- package/dist/core/source-text-edit.d.ts +47 -0
- package/dist/core/source-text-edit.js +22 -0
- package/dist/core/verbose-diagnostics.d.ts +6 -0
- package/dist/core/workspace/ancestor-directories.d.ts +12 -0
- package/dist/core/workspace/ancestor-directories.js +30 -0
- package/dist/core/workspace/markdown-walk.d.ts +7 -0
- package/dist/core/workspace/markdown-walk.js +2 -20
- package/dist/core/workspace/package-version.d.ts +9 -0
- package/dist/core/workspace/package-version.js +8 -12
- package/dist/core/workspace/resolver.d.ts +39 -0
- package/dist/core/workspace/resolver.js +58 -75
- package/dist/core/workspace/skip-directories.d.ts +6 -0
- package/dist/core/workspace/source-walk.d.ts +16 -0
- package/dist/core/workspace/source-walk.js +2 -19
- package/dist/core/workspace/typescript-walk.d.ts +7 -0
- package/dist/core/workspace/typescript-walk.js +2 -23
- package/dist/core/workspace/walk-files.d.ts +7 -0
- package/dist/core/workspace/walk-files.js +27 -0
- package/dist/core/workspace/well-known-files.d.ts +18 -0
- package/dist/core/workspace/well-known-files.js +18 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -0
- package/dist/mirror/cli-result.d.ts +13 -0
- package/dist/mirror/cli-schema.d.ts +8 -0
- package/dist/mirror/cli-schema.js +1 -1
- package/dist/mirror/command.d.ts +7 -0
- package/dist/mirror/command.js +31 -60
- package/dist/mirror/dist-filesystem-node.d.ts +8 -0
- package/dist/mirror/{dist-filesystem-impl.js → dist-filesystem-node.js} +1 -1
- package/dist/mirror/domain/constants.d.ts +18 -0
- package/dist/mirror/domain/constants.js +0 -12
- package/dist/mirror/domain/dirent-guard.d.ts +10 -0
- package/dist/mirror/domain/dist-filesystem.d.ts +9 -0
- package/dist/mirror/domain/errors.d.ts +24 -0
- package/dist/mirror/domain/exports.d.ts +36 -0
- package/dist/mirror/domain/package-display-name.d.ts +8 -0
- package/dist/mirror/domain/path-normalizer.d.ts +6 -0
- package/dist/mirror/domain/types.d.ts +188 -0
- package/dist/mirror/output.d.ts +21 -0
- package/dist/mirror/output.js +126 -1
- package/dist/mirror/package-path.d.ts +19 -0
- package/dist/mirror/prepare.d.ts +15 -0
- package/dist/mirror/prepare.js +6 -10
- package/dist/mirror/run.d.ts +12 -0
- package/dist/mirror/{sync.js → run.js} +5 -3
- package/dist/mirror/supplement-exports.d.ts +27 -0
- package/dist/mirror/supplement-exports.js +2 -2
- package/dist/mirror/sync-workspace-package.d.ts +9 -0
- package/dist/mirror/sync-workspace-package.js +4 -4
- package/dist/mirror/write-exports.d.ts +15 -0
- package/dist/pack-slim/cli-result.d.ts +13 -0
- package/dist/pack-slim/cli-schema.d.ts +17 -0
- package/dist/pack-slim/cli-schema.js +1 -1
- package/dist/pack-slim/command.d.ts +7 -0
- package/dist/pack-slim/command.js +31 -66
- package/dist/pack-slim/domain/transform.d.ts +69 -0
- package/dist/pack-slim/domain/types.d.ts +46 -0
- package/dist/pack-slim/output.d.ts +15 -0
- package/dist/pack-slim/prepare.d.ts +21 -0
- package/dist/pack-slim/prepare.js +14 -0
- package/dist/pack-slim/run.d.ts +23 -0
- package/dist/pack-slim/{sync.js → run.js} +4 -4
- package/dist/pack-slim/working-tree.d.ts +20 -0
- package/dist/tag/cli-result.d.ts +13 -0
- package/dist/tag/cli-result.js +14 -1
- package/dist/tag/cli-schema.d.ts +8 -0
- package/dist/tag/cli-schema.js +3 -4
- package/dist/tag/command.d.ts +7 -0
- package/dist/tag/command.js +33 -60
- package/dist/tag/domain/skip-filter.d.ts +13 -0
- package/dist/tag/domain/skip-filter.js +29 -0
- package/dist/tag/domain/types.d.ts +131 -0
- package/dist/tag/domain/version-summary.d.ts +13 -0
- package/dist/tag/domain/version-summary.js +24 -0
- package/dist/tag/output.d.ts +17 -0
- package/dist/tag/output.js +6 -9
- package/dist/tag/prepare.d.ts +13 -0
- package/dist/tag/prepare.js +4 -4
- package/dist/tag/run.d.ts +10 -0
- package/dist/tag/{sync.js → run.js} +20 -50
- package/dist/tag/target/candidates.d.ts +8 -0
- package/dist/tag/{target-candidates.js → target/candidates.js} +2 -2
- package/dist/tag/target/resolve-path.d.ts +10 -0
- package/dist/tag/target/runner.d.ts +8 -0
- package/dist/tag/{target-runner.js → target/runner.js} +2 -2
- package/dist/tag/writer/since-writer.d.ts +32 -0
- package/dist/tag/writer/version-resolver.d.ts +7 -0
- package/package.json +21 -2
- package/dist/arrange/cli-schema.js +0 -34
- package/dist/arrange/output.js +0 -127
- package/dist/arrange/simplify-process-file.js +0 -30
- package/dist/arrange/simplify-sync.js +0 -30
- package/dist/audit/cli-schema.js +0 -66
- package/dist/audit/domain/react-imports.js +0 -91
- package/dist/audit/output.js +0 -213
- package/dist/mirror/sync-reporter.js +0 -124
- package/dist/mirror/sync-types.js +0 -1
- /package/dist/arrange/{suggest.js → group/suggest.js} +0 -0
- /package/dist/arrange/{domain → inspect/domain}/analyze-service.js +0 -0
- /package/dist/arrange/{process-file.js → regroup/process-file.js} +0 -0
- /package/dist/audit/{domain → comments/domain}/comment-content.js +0 -0
- /package/dist/audit/{domain → comments/domain}/comment-dividers.js +0 -0
- /package/dist/audit/{domain → comments/domain}/link-references.js +0 -0
- /package/dist/audit/{domain → comments/domain}/since-versions.js +0 -0
- /package/dist/audit/{domain → comments/domain}/tsdoc-syntax.js +0 -0
- /package/dist/audit/{domain → display-names/domain}/display-names.js +0 -0
- /package/dist/audit/{domain → links/domain}/markdown-links.js +0 -0
- /package/dist/audit/{domain → rtl/domain}/mappings.js +0 -0
- /package/dist/audit/{domain → rtl/domain}/tokenize.js +0 -0
- /package/dist/core/filesystem/{port.js → filesystem.js} +0 -0
- /package/dist/tag/{resolve-target-path.js → target/resolve-path.js} +0 -0
- /package/dist/tag/{since-writer.js → writer/since-writer.js} +0 -0
- /package/dist/tag/{version-resolver.js → writer/version-resolver.js} +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ArrangeRunResult } from "#/arrange/domain/types";
|
|
2
|
+
import type { ArrangeRunRequest } from "#/arrange/regroup/cli-schema";
|
|
3
|
+
import type { AppError } from "#/core/errors";
|
|
4
|
+
import type { Filesystem } from "#/core/filesystem/filesystem";
|
|
5
|
+
import type { Result } from "#/core/result";
|
|
6
|
+
/**
|
|
7
|
+
* Runs the grouping pipeline over every target file and returns the aggregated result.
|
|
8
|
+
*
|
|
9
|
+
* @since 0.3.16-canary.0
|
|
10
|
+
*/
|
|
11
|
+
export declare function runArrange(fs: Filesystem, request: ArrangeRunRequest): Promise<Result<ArrangeRunResult, AppError>>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { processArrangeGroupFile } from "#/arrange/process-file";
|
|
1
|
+
import { processArrangeGroupFile } from "#/arrange/regroup/process-file";
|
|
2
2
|
import { scanArrangeTargets } from "#/arrange/scan-target";
|
|
3
3
|
import { messageFrom } from "#/core/errors";
|
|
4
4
|
import { ok } from "#/core/result";
|
|
@@ -19,7 +19,7 @@ async function runOnAfterWriteHook(hook, modifiedFiles) {
|
|
|
19
19
|
*
|
|
20
20
|
* @since 0.3.16-canary.0
|
|
21
21
|
*/
|
|
22
|
-
export async function
|
|
22
|
+
export async function runArrange(fs, request) {
|
|
23
23
|
const filePaths = scanArrangeTargets(fs, request.targetPath);
|
|
24
24
|
const modifiedFiles = [];
|
|
25
25
|
const previewPlans = [];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Filesystem } from "#/core/filesystem/filesystem";
|
|
2
|
+
/**
|
|
3
|
+
* Resolves the arrange target to a canonical path, defaulting to the nearest package directory.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.3.16-canary.0
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveArrangeTargetPath(fs: Filesystem, args: {
|
|
8
|
+
readonly currentWorkingDirectory: string;
|
|
9
|
+
readonly rawTarget: string | undefined;
|
|
10
|
+
}): string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
|
|
2
|
+
import { findNearestAncestor } from "#/core/workspace/ancestor-directories";
|
|
3
|
+
import { packageJsonFileName } from "#/core/workspace/well-known-files";
|
|
3
4
|
/**
|
|
4
5
|
* Resolves the arrange target to a canonical path, defaulting to the nearest package directory.
|
|
5
6
|
*
|
|
@@ -14,21 +15,7 @@ export function resolveArrangeTargetPath(fs, args) {
|
|
|
14
15
|
if (explicitTargetPath) {
|
|
15
16
|
return fs.canonicalPathSync(explicitTargetPath);
|
|
16
17
|
}
|
|
17
|
-
const nearestPackageDirectory =
|
|
18
|
+
const nearestPackageDirectory = findNearestAncestor(args.currentWorkingDirectory, (directoryPath) => fs.existsSync(path.join(directoryPath, packageJsonFileName)));
|
|
18
19
|
const resolvedDefaultTarget = nearestPackageDirectory ?? args.currentWorkingDirectory;
|
|
19
20
|
return fs.canonicalPathSync(resolvedDefaultTarget);
|
|
20
|
-
}
|
|
21
|
-
function findNearestPackageDirectory(fs, currentWorkingDirectory) {
|
|
22
|
-
let currentDir = path.resolve(currentWorkingDirectory);
|
|
23
|
-
while (true) {
|
|
24
|
-
const packageJsonPath = path.join(currentDir, packageJsonFileName);
|
|
25
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
26
|
-
return currentDir;
|
|
27
|
-
}
|
|
28
|
-
const parentDirectory = path.dirname(currentDir);
|
|
29
|
-
if (parentDirectory === currentDir) {
|
|
30
|
-
return undefined;
|
|
31
|
-
}
|
|
32
|
-
currentDir = parentDirectory;
|
|
33
|
-
}
|
|
34
21
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Filesystem } from "#/core/filesystem/filesystem";
|
|
2
|
+
/**
|
|
3
|
+
* Lists the files an arrange run visits — a directory's non-test `.ts`/`.tsx` files, or the single target.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.3.16-canary.0
|
|
6
|
+
*/
|
|
7
|
+
export declare function scanArrangeTargets(fs: Filesystem, targetPath: string): Array<string>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* The request payload for an `arrange simplify` run.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.11.0
|
|
6
|
+
*/
|
|
7
|
+
export type ArrangeSimplifyRunRequest = {
|
|
8
|
+
targetPath: string;
|
|
9
|
+
write: boolean;
|
|
10
|
+
foldVariantClassName?: boolean | undefined;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* The `zod` schema validating an `arrange simplify` run request.
|
|
14
|
+
*
|
|
15
|
+
* @since 0.11.0
|
|
16
|
+
*/
|
|
17
|
+
export declare const arrangeSimplifyRunRequestSchema: z.ZodType<ArrangeSimplifyRunRequest>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* The `zod` schema validating an `arrange simplify` run request.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.11.0
|
|
6
|
+
*/
|
|
7
|
+
export const arrangeSimplifyRunRequestSchema = z.object({
|
|
8
|
+
targetPath: z.string().min(1),
|
|
9
|
+
write: z.boolean(),
|
|
10
|
+
foldVariantClassName: z.boolean().optional(),
|
|
11
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Collects cn() calls whose override classes can fold into a variant function's `className` option. */
|
|
2
|
+
import type { DomainSourceFile } from "#/arrange/domain/ast/ast-node";
|
|
3
|
+
import type { PlannedSimplifyEdit } from "#/arrange/domain/ast/simplify-targets";
|
|
4
|
+
import type { FileClassNameProbe } from "#/arrange/simplify/variant-classname-probe";
|
|
5
|
+
/**
|
|
6
|
+
* Collects `className` fold edits for every foldable `cn(variant({…}), …)` call in a source file.
|
|
7
|
+
*
|
|
8
|
+
* @remarks The type server is loaded lazily via `resolveFileProbe` — only once a syntactic candidate
|
|
9
|
+
* exists — so files with no foldable call never pay for a type query.
|
|
10
|
+
*
|
|
11
|
+
* @since 0.11.0
|
|
12
|
+
*/
|
|
13
|
+
export declare function collectClassNameFoldTargets(sourceFile: DomainSourceFile, resolveFileProbe: () => FileClassNameProbe | null): Array<PlannedSimplifyEdit>;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/** Collects cn() calls whose override classes can fold into a variant function's `className` option. */
|
|
2
|
+
import { forEachDomainChild, isDomainCallExpression, isDomainIdentifier, isDomainObjectLiteralExpression, isDomainPropertyAccessExpression, isDomainPropertyAssignment, isDomainTailwindClassLiteral, } from "#/arrange/domain/ast/ast-node";
|
|
3
|
+
import { buildKnownCnTvBindings, isCnOrTvIdentifier, propertyAssignmentNameText } from "#/arrange/domain/ast/helpers";
|
|
4
|
+
import { escapeTsStringLiteralContent } from "#/arrange/domain/source-text-formatters";
|
|
5
|
+
/** Groups a run of trailing cn() arguments, coalescing adjacent static literals into one piece. */
|
|
6
|
+
function coalesceTrailingArgs(args, sourceText) {
|
|
7
|
+
const pieces = [];
|
|
8
|
+
for (const arg of args) {
|
|
9
|
+
if (isDomainTailwindClassLiteral(arg)) {
|
|
10
|
+
const last = pieces.at(-1);
|
|
11
|
+
if (last?.kind === "static") {
|
|
12
|
+
last.texts.push(arg.text);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
pieces.push({ kind: "static", texts: [arg.text] });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
pieces.push({ kind: "dynamic", src: sourceText.slice(arg.pos, arg.end) });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return pieces;
|
|
23
|
+
}
|
|
24
|
+
/** Renders one class piece as either a quoted merged string or the raw source of a dynamic argument. */
|
|
25
|
+
function renderPiece(piece) {
|
|
26
|
+
return piece.kind === "static" ? `"${escapeTsStringLiteralContent(piece.texts.join(" ").trim())}"` : piece.src;
|
|
27
|
+
}
|
|
28
|
+
/** The source offset of the callee's name — an identifier or the property of a member access. */
|
|
29
|
+
function calleeNameOffset(expression) {
|
|
30
|
+
if (isDomainIdentifier(expression)) {
|
|
31
|
+
return expression.pos;
|
|
32
|
+
}
|
|
33
|
+
if (isDomainPropertyAccessExpression(expression)) {
|
|
34
|
+
return expression.name.pos;
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
/** True when the object literal is a plain bag of assignments that does not already set `className`/`class`. */
|
|
39
|
+
function objectAcceptsClassNameFold(objectArg) {
|
|
40
|
+
for (const property of objectArg.properties) {
|
|
41
|
+
// A spread or shorthand parses as a non-assignment node — its `className` cannot be reasoned about.
|
|
42
|
+
if (!isDomainPropertyAssignment(property)) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
const name = propertyAssignmentNameText(property);
|
|
46
|
+
if (name === "className" || name === "class") {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
/** Builds a fold candidate from syntax alone — no type server — or `null` when the shape is not foldable. */
|
|
53
|
+
function buildFoldCandidate(cnCall, sourceText) {
|
|
54
|
+
const args = cnCall.arguments;
|
|
55
|
+
const variantCall = args[0];
|
|
56
|
+
if (args.length < 2 || variantCall === undefined || !isDomainCallExpression(variantCall)) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const objectArg = variantCall.arguments[0];
|
|
60
|
+
if (variantCall.arguments.length !== 1 ||
|
|
61
|
+
objectArg === undefined ||
|
|
62
|
+
!isDomainObjectLiteralExpression(objectArg) ||
|
|
63
|
+
!objectAcceptsClassNameFold(objectArg)) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const calleeOffset = calleeNameOffset(variantCall.expression);
|
|
67
|
+
if (calleeOffset === null) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const pieces = coalesceTrailingArgs(args.slice(1), sourceText);
|
|
71
|
+
if (pieces.length === 0) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
// A dynamic override or more than one piece becomes an array, so the option must accept one; a
|
|
75
|
+
// single static override stays a scalar string. Types decide whether either shape is legal.
|
|
76
|
+
const needsArray = pieces.length > 1 || pieces.some((piece) => piece.kind === "dynamic");
|
|
77
|
+
const rendered = pieces.map(renderPiece);
|
|
78
|
+
const classNameValue = pieces.length > 1 ? `[${rendered.join(", ")}]` : rendered[0];
|
|
79
|
+
// Splice `className` in right after the last property (or just inside an empty object), keeping the
|
|
80
|
+
// object's original text — a trailing comma or line comment would break a re-serialized `{ … }`.
|
|
81
|
+
const lastProperty = objectArg.properties.at(-1);
|
|
82
|
+
const insertOffset = lastProperty ? lastProperty.end : objectArg.pos + 1;
|
|
83
|
+
const insertion = lastProperty ? `, className: ${classNameValue}` : ` className: ${classNameValue} `;
|
|
84
|
+
const replacement = sourceText.slice(variantCall.pos, insertOffset) + insertion + sourceText.slice(insertOffset, variantCall.end);
|
|
85
|
+
return {
|
|
86
|
+
calleeOffset,
|
|
87
|
+
needsArray,
|
|
88
|
+
edit: {
|
|
89
|
+
start: cnCall.pos,
|
|
90
|
+
end: cnCall.end,
|
|
91
|
+
replacement,
|
|
92
|
+
label: "cn-fold-classname",
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Collects `className` fold edits for every foldable `cn(variant({…}), …)` call in a source file.
|
|
98
|
+
*
|
|
99
|
+
* @remarks The type server is loaded lazily via `resolveFileProbe` — only once a syntactic candidate
|
|
100
|
+
* exists — so files with no foldable call never pay for a type query.
|
|
101
|
+
*
|
|
102
|
+
* @since 0.11.0
|
|
103
|
+
*/
|
|
104
|
+
export function collectClassNameFoldTargets(sourceFile, resolveFileProbe) {
|
|
105
|
+
const sourceText = sourceFile.text;
|
|
106
|
+
const knownBindings = buildKnownCnTvBindings(sourceFile);
|
|
107
|
+
const candidates = [];
|
|
108
|
+
const visit = (node) => {
|
|
109
|
+
if (isDomainCallExpression(node) && isCnOrTvIdentifier(node.expression, "cn", knownBindings)) {
|
|
110
|
+
const candidate = buildFoldCandidate(node, sourceText);
|
|
111
|
+
if (candidate) {
|
|
112
|
+
candidates.push(candidate);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
forEachDomainChild(node, visit);
|
|
116
|
+
};
|
|
117
|
+
for (const statement of sourceFile.statements) {
|
|
118
|
+
visit(statement);
|
|
119
|
+
}
|
|
120
|
+
if (candidates.length === 0) {
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
const fileProbe = resolveFileProbe();
|
|
124
|
+
if (!fileProbe) {
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
const results = [];
|
|
128
|
+
for (const candidate of candidates) {
|
|
129
|
+
const acceptance = fileProbe.classNameAcceptance(candidate.calleeOffset);
|
|
130
|
+
if (!acceptance) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (candidate.needsArray ? !acceptance.acceptsArray : !acceptance.acceptsString) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
results.push(candidate.edit);
|
|
137
|
+
}
|
|
138
|
+
return results;
|
|
139
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { logger } from "#/core/logger";
|
|
2
|
+
/**
|
|
3
|
+
* Presents the totals for an `arrange simplify` run.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.3.16-canary.0
|
|
6
|
+
*/
|
|
7
|
+
export function presentSimplifyResult(result, write) {
|
|
8
|
+
logger.out(`\nTotal: ${result.filePaths.length} file(s), ${result.totalFound} site(s) to simplify.`);
|
|
9
|
+
if (write) {
|
|
10
|
+
logger.out(`Applied: ${result.totalChanged} site(s) updated.`);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
logger.out(`(Run "simplify" to write changes, or "pnpm cli:arrange-simplify" / "pnpm exec codefast arrange simplify")`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { GroupFileResult } from "#/arrange/domain/types";
|
|
2
|
+
import type { VariantClassNameProbe } from "#/arrange/simplify/variant-classname-probe";
|
|
3
|
+
import type { Filesystem } from "#/core/filesystem/filesystem";
|
|
4
|
+
/**
|
|
5
|
+
* Runs the simplify pass on one file — flattening class expressions and pruning an unused `cn` import.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.3.16-canary.0
|
|
8
|
+
*/
|
|
9
|
+
export declare function processArrangeSimplifyFile(fs: Filesystem, args: {
|
|
10
|
+
readonly filePath: string;
|
|
11
|
+
readonly write: boolean;
|
|
12
|
+
readonly probe?: VariantClassNameProbe | null;
|
|
13
|
+
}): GroupFileResult;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { collectSimplifyTargets } from "#/arrange/domain/ast/simplify-targets";
|
|
2
|
+
import { dropCnImportIfUnused } from "#/arrange/domain/imports";
|
|
3
|
+
import { collectClassNameFoldTargets } from "#/arrange/simplify/fold-targets";
|
|
4
|
+
import { parseDomainSourceFile } from "#/arrange/source-parse";
|
|
5
|
+
import { applyEditsDescending, dropOverlappingEdits } from "#/core/source-text-edit";
|
|
6
|
+
// A file simplify can act on names `cn`/`tv` (a call or an import to prune) or carries a `class`/`className`;
|
|
7
|
+
// a source with none of these has nothing to flatten or fold, so it never needs parsing.
|
|
8
|
+
const SIMPLIFY_MARKER = /\b(?:cn|tv)\b|className|\bclass\s*[=:]/;
|
|
9
|
+
/**
|
|
10
|
+
* Runs the simplify pass on one file — flattening class expressions and pruning an unused `cn` import.
|
|
11
|
+
*
|
|
12
|
+
* @since 0.3.16-canary.0
|
|
13
|
+
*/
|
|
14
|
+
export function processArrangeSimplifyFile(fs, args) {
|
|
15
|
+
const { filePath, write, probe } = args;
|
|
16
|
+
const sourceText = fs.readFileSync(filePath, "utf8");
|
|
17
|
+
if (!SIMPLIFY_MARKER.test(sourceText)) {
|
|
18
|
+
return { filePath, totalFound: 0, changed: 0 };
|
|
19
|
+
}
|
|
20
|
+
const domainSf = parseDomainSourceFile(filePath, sourceText);
|
|
21
|
+
// Resolve the file's type-server project at most once, and only if a syntactic fold candidate needs it.
|
|
22
|
+
let resolvedFileProbe;
|
|
23
|
+
const resolveFileProbe = () => {
|
|
24
|
+
resolvedFileProbe ??= probe ? probe.forFile(filePath) : null;
|
|
25
|
+
return resolvedFileProbe;
|
|
26
|
+
};
|
|
27
|
+
// Combine fold and base edits, drop no-ops, then remove overlaps so applyEditsDescending only sees
|
|
28
|
+
// non-overlapping ranges. Fold edits lead the list, so a fold wins an exact-range tie with a base
|
|
29
|
+
// edit on the same call and nested calls keep only the outermost edit.
|
|
30
|
+
const foldEdits = probe ? collectClassNameFoldTargets(domainSf, resolveFileProbe) : [];
|
|
31
|
+
const baseEdits = collectSimplifyTargets(domainSf);
|
|
32
|
+
const meaningful = dropOverlappingEdits([...foldEdits, ...baseEdits].filter((edit) => sourceText.slice(edit.start, edit.end) !== edit.replacement));
|
|
33
|
+
// Apply class-simplification edits first, then prune any cn import that
|
|
34
|
+
// became (or was already) unused. With no edits the text is unchanged, so the
|
|
35
|
+
// already-parsed tree is reused rather than parsing every untouched file twice.
|
|
36
|
+
const textAfterEdits = meaningful.length > 0 ? applyEditsDescending(sourceText, meaningful) : sourceText;
|
|
37
|
+
const domainSfAfterEdits = meaningful.length > 0 ? parseDomainSourceFile(filePath, textAfterEdits) : domainSf;
|
|
38
|
+
const textAfterImportDrop = dropCnImportIfUnused(domainSfAfterEdits);
|
|
39
|
+
const importDropped = textAfterImportDrop !== textAfterEdits;
|
|
40
|
+
const totalFound = meaningful.length + (importDropped ? 1 : 0);
|
|
41
|
+
if (totalFound === 0) {
|
|
42
|
+
return { filePath, totalFound: 0, changed: 0 };
|
|
43
|
+
}
|
|
44
|
+
if (!write) {
|
|
45
|
+
return { filePath, totalFound, changed: 0 };
|
|
46
|
+
}
|
|
47
|
+
fs.writeFileSync(filePath, textAfterImportDrop, "utf8");
|
|
48
|
+
return { filePath, totalFound, changed: totalFound };
|
|
49
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ArrangeRunResult } from "#/arrange/domain/types";
|
|
2
|
+
import type { AppError } from "#/core/errors";
|
|
3
|
+
import type { Filesystem } from "#/core/filesystem/filesystem";
|
|
4
|
+
import type { Result } from "#/core/result";
|
|
5
|
+
/**
|
|
6
|
+
* Runs the simplify pass over every target file and returns the aggregated result.
|
|
7
|
+
*
|
|
8
|
+
* @since 0.3.16-canary.0
|
|
9
|
+
*/
|
|
10
|
+
export declare function runArrangeSimplify(fs: Filesystem, args: {
|
|
11
|
+
targetPath: string;
|
|
12
|
+
write: boolean;
|
|
13
|
+
foldVariantClassName?: boolean | undefined;
|
|
14
|
+
}): Promise<Result<ArrangeRunResult, AppError>>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { scanArrangeTargets } from "#/arrange/scan-target";
|
|
2
|
+
import { processArrangeSimplifyFile } from "#/arrange/simplify/process-file";
|
|
3
|
+
import { createVariantClassNameProbe } from "#/arrange/simplify/variant-classname-probe";
|
|
4
|
+
import { ok } from "#/core/result";
|
|
5
|
+
/**
|
|
6
|
+
* Runs the simplify pass over every target file and returns the aggregated result.
|
|
7
|
+
*
|
|
8
|
+
* @since 0.3.16-canary.0
|
|
9
|
+
*/
|
|
10
|
+
export async function runArrangeSimplify(fs, args) {
|
|
11
|
+
const filePaths = scanArrangeTargets(fs, args.targetPath);
|
|
12
|
+
const modifiedFiles = [];
|
|
13
|
+
let totalFound = 0;
|
|
14
|
+
let totalChanged = 0;
|
|
15
|
+
// The type probe spawns a TypeScript server, so it is created once and only when the fold is requested.
|
|
16
|
+
const probe = args.foldVariantClassName ? await createVariantClassNameProbe() : null;
|
|
17
|
+
try {
|
|
18
|
+
for (const filePath of filePaths) {
|
|
19
|
+
const result = processArrangeSimplifyFile(fs, { filePath, write: args.write, probe });
|
|
20
|
+
totalFound += result.totalFound;
|
|
21
|
+
totalChanged += result.changed;
|
|
22
|
+
if (result.changed > 0) {
|
|
23
|
+
modifiedFiles.push(result.filePath);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
probe?.dispose();
|
|
29
|
+
}
|
|
30
|
+
return ok({
|
|
31
|
+
filePaths,
|
|
32
|
+
modifiedFiles,
|
|
33
|
+
totalFound,
|
|
34
|
+
totalChanged,
|
|
35
|
+
hookError: null,
|
|
36
|
+
previewPlans: [],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Type probe that asks whether a variant function's options accept a folded `className`. */
|
|
2
|
+
/**
|
|
3
|
+
* What a variant function's `className`/`class` option accepts, resolved from its type.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.11.0
|
|
6
|
+
*/
|
|
7
|
+
export interface VariantClassNameAcceptance {
|
|
8
|
+
readonly acceptsString: boolean;
|
|
9
|
+
readonly acceptsArray: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A per-file view that resolves a callee's `className` acceptance from a source offset.
|
|
13
|
+
*
|
|
14
|
+
* @since 0.11.0
|
|
15
|
+
*/
|
|
16
|
+
export interface FileClassNameProbe {
|
|
17
|
+
classNameAcceptance(calleeOffset: number): VariantClassNameAcceptance | null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A whole-run type probe backing the opt-in `className` fold, bound to one type server.
|
|
21
|
+
*
|
|
22
|
+
* @since 0.11.0
|
|
23
|
+
*/
|
|
24
|
+
export interface VariantClassNameProbe {
|
|
25
|
+
forFile(filePath: string): FileClassNameProbe | null;
|
|
26
|
+
dispose(): void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Creates a type probe over the native TypeScript type server for the opt-in `className` fold.
|
|
30
|
+
*
|
|
31
|
+
* @throws AppError when the `typescript` package providing the type server cannot be loaded.
|
|
32
|
+
*
|
|
33
|
+
* @since 0.11.0
|
|
34
|
+
*/
|
|
35
|
+
export declare function createVariantClassNameProbe(): Promise<VariantClassNameProbe>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/** Type probe that asks whether a variant function's options accept a folded `className`. */
|
|
2
|
+
import { AppError, messageFrom } from "#/core/errors";
|
|
3
|
+
// ── Type inspection ──────────────────────────────────────────────────────────────────────────────────────────────────
|
|
4
|
+
/** The type of the callee's first-parameter `className` (preferred) or `class` option, if any. */
|
|
5
|
+
function classNameOptionType(checker, optionsType) {
|
|
6
|
+
for (const name of ["className", "class"]) {
|
|
7
|
+
const symbol = checker.getPropertyOfType(optionsType, name);
|
|
8
|
+
if (symbol) {
|
|
9
|
+
const propertyType = checker.getTypeOfSymbol(symbol);
|
|
10
|
+
if (propertyType) {
|
|
11
|
+
return propertyType;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
/** True when any constituent of the option type is array-like — the option accepts a class array. */
|
|
18
|
+
function optionAcceptsArray(checker, optionType) {
|
|
19
|
+
const constituents = optionType.isUnionType() ? optionType.getTypes() : [optionType];
|
|
20
|
+
return constituents.some((constituent) => checker.isArrayType(constituent) || checker.isTupleType(constituent) || checker.isArrayLikeType(constituent));
|
|
21
|
+
}
|
|
22
|
+
/** Resolves how the function called at `offset` accepts a `className`, or `null` when it is not a variant function. */
|
|
23
|
+
function classNameAcceptanceAt(checker, callKind, filePath, offset) {
|
|
24
|
+
const calleeType = checker.getTypeAtPosition(filePath, offset);
|
|
25
|
+
if (!calleeType) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const signature = checker.getSignaturesOfType(calleeType, callKind)[0];
|
|
29
|
+
if (!signature) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const parameterType = checker.getParameterType(signature, 0);
|
|
33
|
+
if (!parameterType) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const nonNullableType = checker.getNonNullableType(parameterType);
|
|
37
|
+
if (!nonNullableType) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const optionsType = checker.getApparentType(nonNullableType);
|
|
41
|
+
if (!optionsType) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const optionType = classNameOptionType(checker, optionsType);
|
|
45
|
+
if (!optionType) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
acceptsString: checker.isTypeAssignableTo(checker.getStringType(), optionType),
|
|
50
|
+
acceptsArray: optionAcceptsArray(checker, optionType),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// ── Probe lifecycle ──────────────────────────────────────────────────────────────────────────────────────────────────
|
|
54
|
+
/** Loads the native TypeScript type-server API, or fails with a coded error naming the missing package. */
|
|
55
|
+
async function loadTypeServer() {
|
|
56
|
+
try {
|
|
57
|
+
return await import("typescript/unstable/sync");
|
|
58
|
+
}
|
|
59
|
+
catch (cause) {
|
|
60
|
+
throw new AppError("INFRA_FAILURE", `--fold-variant-classname needs the "typescript" package (v7) resolvable from the target: ${messageFrom(cause)}`, cause);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Creates a type probe over the native TypeScript type server for the opt-in `className` fold.
|
|
65
|
+
*
|
|
66
|
+
* @throws AppError when the `typescript` package providing the type server cannot be loaded.
|
|
67
|
+
*
|
|
68
|
+
* @since 0.11.0
|
|
69
|
+
*/
|
|
70
|
+
export async function createVariantClassNameProbe() {
|
|
71
|
+
const sync = await loadTypeServer();
|
|
72
|
+
const api = new sync.API();
|
|
73
|
+
const callKind = sync.SignatureKind.Call;
|
|
74
|
+
return {
|
|
75
|
+
forFile(filePath) {
|
|
76
|
+
try {
|
|
77
|
+
const project = api.updateSnapshot({ openFiles: [filePath] }).getDefaultProjectForFile(filePath);
|
|
78
|
+
if (!project) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const { checker } = project;
|
|
82
|
+
return {
|
|
83
|
+
classNameAcceptance: (offset) => classNameAcceptanceAt(checker, callKind, filePath, offset),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// A file outside any tsconfig has no project to type against — skip its fold, keep the base pass.
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
dispose() {
|
|
92
|
+
api.close();
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DomainSourceFile } from "#/arrange/domain/ast/ast-node";
|
|
2
|
+
/**
|
|
3
|
+
* Parses source text into a domain source file via the shared `oxc-parser` translator.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.3.16-canary.0
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseDomainSourceFile(filePath: string, sourceText: string): DomainSourceFile;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TypeScriptAstTranslator } from "#/arrange/
|
|
1
|
+
import { TypeScriptAstTranslator } from "#/arrange/domain/ast/translator";
|
|
2
2
|
import { messageFrom } from "#/core/errors";
|
|
3
3
|
import { logger } from "#/core/logger";
|
|
4
4
|
const translator = new TypeScriptAstTranslator();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
/**
|
|
3
|
+
* Top-level `audit` command — the source scans. Every one of them reports by default; only
|
|
4
|
+
* `comments --fix` writes, and only where the rewrite discards nothing a person wrote.
|
|
5
|
+
*
|
|
6
|
+
* @since 0.5.0-canary.6
|
|
7
|
+
*/
|
|
8
|
+
export declare function createAuditCommand(): Command;
|