@codefast/cli 0.3.15 → 0.3.16-canary.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/README.md +1 -1
- package/dist/arrange/analyze.mjs +24 -0
- package/dist/{domains/arrange/presentation/presenters/arrange-cli.schema.mjs → arrange/cli-schema.mjs} +10 -1
- package/dist/arrange/command.mjs +106 -0
- package/dist/{domains/arrange/domain/arrange-analyze.domain-service.mjs → arrange/domain/analyze-service.mjs} +17 -10
- package/dist/{domains/arrange/domain/ast/ast-node.model.mjs → arrange/domain/ast/ast-node.mjs} +57 -3
- package/dist/{domains/arrange/domain/ast/collectors-cn.collector.mjs → arrange/domain/ast/collectors-cn.mjs} +21 -9
- package/dist/{domains/arrange/domain/ast/collectors-jsx.collector.mjs → arrange/domain/ast/collectors-jsx.mjs} +5 -2
- package/dist/{domains/arrange/domain/ast/collectors-tv.collector.mjs → arrange/domain/ast/collectors-tv.mjs} +21 -6
- package/dist/{domains/arrange/domain/ast/ast-helpers.helper.mjs → arrange/domain/ast/helpers.mjs} +26 -9
- package/dist/{domains/arrange/domain/ast/targets.model.mjs → arrange/domain/ast/targets.mjs} +19 -10
- package/dist/{domains/arrange/domain/constants.domain.mjs → arrange/domain/constants.mjs} +63 -18
- package/dist/{domains/arrange/domain/arrange-grouping.domain-service.mjs → arrange/domain/grouping-service.mjs} +31 -10
- package/dist/{domains/arrange/domain/grouping.domain.mjs → arrange/domain/grouping.mjs} +39 -18
- package/dist/{domains/arrange/domain/imports.domain.mjs → arrange/domain/imports.mjs} +7 -3
- package/dist/{domains/arrange/domain/source-text-formatters.formatter.mjs → arrange/domain/source-text-formatters.mjs} +22 -5
- package/dist/{domains/arrange/domain/tailwind-token.value-object.mjs → arrange/domain/tailwind-token.mjs} +12 -3
- package/dist/{domains/arrange/domain/tailwind-token-classifier.domain-service.mjs → arrange/domain/token-classifier.mjs} +40 -15
- package/dist/arrange/output.mjs +79 -0
- package/dist/arrange/process-file.mjs +42 -0
- package/dist/arrange/resolve-target.mjs +24 -0
- package/dist/arrange/scan-target.mjs +20 -0
- package/dist/arrange/source-parse.mjs +18 -0
- package/dist/arrange/suggest.mjs +15 -0
- package/dist/arrange/sync.mjs +51 -0
- package/dist/arrange/typescript-ast-translator.mjs +354 -0
- package/dist/arrange/workspace.mjs +31 -0
- package/dist/bin.mjs +1 -1
- package/dist/{program.mjs → cli.mjs} +14 -20
- package/dist/core/cli/format-error.mjs +15 -0
- package/dist/core/cli/global-options.mjs +10 -0
- package/dist/core/cli/positional.mjs +11 -0
- package/dist/core/cli/result-handle.mjs +51 -0
- package/dist/core/config/loader.mjs +79 -0
- package/dist/{domains/config/domain/codefast-config.schema.mjs → core/config/schema.mjs} +16 -2
- package/dist/core/config/warnings.mjs +12 -0
- package/dist/core/config.mjs +19 -0
- package/dist/{shell/domain/caught-unknown-message.value-object.mjs → core/errors.mjs} +20 -4
- package/dist/core/exit-codes.mjs +17 -0
- package/dist/core/filesystem/node.mjs +32 -0
- package/dist/core/logger.mjs +15 -0
- package/dist/{shell/domain/result.model.mjs → core/result.mjs} +7 -3
- package/dist/core/schema-parse.mjs +18 -0
- package/dist/{shell/domain/source-text-edit.support.mjs → core/source-text-edit.mjs} +14 -13
- package/dist/core/verbose-diagnostics.mjs +11 -0
- package/dist/core/workspace/resolver.mjs +177 -0
- package/dist/core/workspace/typescript-walk.mjs +36 -0
- package/dist/{domains/mirror/application/mirror-sync-cli-result.mjs → mirror/cli-result.mjs} +8 -2
- package/dist/{domains/mirror/presentation/presenters/mirror-cli.schema.mjs → mirror/cli-schema.mjs} +4 -1
- package/dist/mirror/command.mjs +57 -0
- package/dist/mirror/dist-filesystem-impl.mjs +42 -0
- package/dist/{domains/mirror/domain/constants.domain.mjs → mirror/domain/constants.mjs} +16 -1
- package/dist/{domains/mirror/infrastructure/guards/dirent-list.guard.mjs → mirror/domain/dirent-guard.mjs} +5 -2
- package/dist/{domains/mirror/domain/errors.domain.mjs → mirror/domain/errors.mjs} +7 -1
- package/dist/{domains/mirror/domain/generate-mirror-exports.domain-service.mjs → mirror/domain/exports.mjs} +17 -10
- package/dist/{domains/mirror/domain/package-display-name.policy.mjs → mirror/domain/package-display-name.mjs} +5 -2
- package/dist/{domains/mirror/domain/path-normalizer.value-object.mjs → mirror/domain/path-normalizer.mjs} +4 -1
- package/dist/mirror/output.mjs +45 -0
- package/dist/mirror/package-path.mjs +32 -0
- package/dist/mirror/prepare.mjs +33 -0
- package/dist/mirror/sync-reporter.mjs +104 -0
- package/dist/mirror/sync-workspace-package.mjs +103 -0
- package/dist/mirror/sync.mjs +87 -0
- package/dist/{domains/mirror/infrastructure/package-json-exports.repository.mjs → mirror/write-exports.mjs} +11 -7
- package/dist/tag/cli-result.mjs +11 -0
- package/dist/{domains/tag/presentation/presenters/tag-cli.schema.mjs → tag/cli-schema.mjs} +4 -1
- package/dist/tag/command.mjs +56 -0
- package/dist/tag/output.mjs +87 -0
- package/dist/tag/prepare.mjs +29 -0
- package/dist/tag/resolve-target-path.mjs +12 -0
- package/dist/tag/since-writer.mjs +130 -0
- package/dist/tag/sync.mjs +141 -0
- package/dist/tag/target-candidates.mjs +68 -0
- package/dist/tag/target-runner.mjs +26 -0
- package/dist/tag/version-resolver.mjs +25 -0
- package/package.json +4 -7
- package/dist/bootstrap/cli-application.module.mjs +0 -18
- package/dist/bootstrap/composition-root.mjs +0 -14
- package/dist/bootstrap/register-cli-command-trees.mjs +0 -7
- package/dist/domains/arrange/application/ports/outbound/arrange-target-scanner.port.mjs +0 -1
- package/dist/domains/arrange/application/ports/outbound/domain-source-parser.port.mjs +0 -1
- package/dist/domains/arrange/application/ports/outbound/file-walker.port.mjs +0 -1
- package/dist/domains/arrange/application/ports/presenting/present-analyze-report.presenter.mjs +0 -1
- package/dist/domains/arrange/application/ports/presenting/present-arrange-sync-result.presenter.mjs +0 -1
- package/dist/domains/arrange/application/ports/presenting/present-group-file-preview.presenter.mjs +0 -1
- package/dist/domains/arrange/application/requests/analyze-directory.request.mjs +0 -1
- package/dist/domains/arrange/application/requests/arrange-sync.request.mjs +0 -1
- package/dist/domains/arrange/application/requests/suggest-groups.request.mjs +0 -1
- package/dist/domains/arrange/application/use-cases/analyze-directory.use-case.mjs +0 -255
- package/dist/domains/arrange/application/use-cases/prepare-arrange-workspace.use-case.mjs +0 -264
- package/dist/domains/arrange/application/use-cases/run-arrange-sync.use-case.mjs +0 -274
- package/dist/domains/arrange/application/use-cases/suggest-cn-groups.use-case.mjs +0 -237
- package/dist/domains/arrange/arrange.module.mjs +0 -38
- package/dist/domains/arrange/composition/tokens.mjs +0 -17
- package/dist/domains/arrange/contracts/models.mjs +0 -1
- package/dist/domains/arrange/domain/tailwind-grouping.domain-service.mjs +0 -231
- package/dist/domains/arrange/domain/types.domain.mjs +0 -1
- package/dist/domains/arrange/infrastructure/adapters/arrange-file-processor.adapter.mjs +0 -267
- package/dist/domains/arrange/infrastructure/adapters/arrange-target-path-resolver.adapter.mjs +0 -247
- package/dist/domains/arrange/infrastructure/adapters/arrange-target-scanner.adapter.mjs +0 -243
- package/dist/domains/arrange/infrastructure/adapters/domain-source-parser.adapter.mjs +0 -241
- package/dist/domains/arrange/infrastructure/adapters/file-walker.adapter.mjs +0 -240
- package/dist/domains/arrange/infrastructure/typescript-ast-translator.mjs +0 -580
- package/dist/domains/arrange/presentation/cli/arrange.command.mjs +0 -465
- package/dist/domains/arrange/presentation/presenters/arrange-analyze.presenter.mjs +0 -252
- package/dist/domains/arrange/presentation/presenters/arrange-sync.presenter.mjs +0 -236
- package/dist/domains/arrange/presentation/presenters/group-file-preview.presenter.mjs +0 -271
- package/dist/domains/config/application/ports/outbound/codefast-config-schema.port.mjs +0 -1
- package/dist/domains/config/application/ports/outbound/config-loader.port.mjs +0 -1
- package/dist/domains/config/application/ports/outbound/config-warning-reporter.port.mjs +0 -1
- package/dist/domains/config/composition/tokens.mjs +0 -7
- package/dist/domains/config/domain/schema.domain.mjs +0 -1
- package/dist/domains/config/infrastructure/adapters/config-loader.adapter.mjs +0 -305
- package/dist/domains/config/infrastructure/adapters/config-warning-reporter.adapter.mjs +0 -234
- package/dist/domains/config/infrastructure/adapters/zod-codefast-config-schema.adapter.mjs +0 -236
- package/dist/domains/mirror/application/ports/inbound/prepare-mirror-sync.port.mjs +0 -1
- package/dist/domains/mirror/application/ports/inbound/run-mirror-sync.port.mjs +0 -1
- package/dist/domains/mirror/application/ports/outbound/file-system-service.port.mjs +0 -1
- package/dist/domains/mirror/application/ports/outbound/mirror-package-path.port.mjs +0 -1
- package/dist/domains/mirror/application/ports/outbound/mirror-sync-reporter.port.mjs +0 -1
- package/dist/domains/mirror/application/ports/outbound/package-repository.port.mjs +0 -1
- package/dist/domains/mirror/application/ports/outbound/sync-workspace-package.port.mjs +0 -1
- package/dist/domains/mirror/application/ports/presenting/present-mirror-sync-progress.presenter.mjs +0 -1
- package/dist/domains/mirror/application/requests/mirror-sync-execution-input.mjs +0 -1
- package/dist/domains/mirror/application/requests/mirror-sync.request.mjs +0 -1
- package/dist/domains/mirror/application/use-cases/prepare-mirror-sync.use-case.mjs +0 -263
- package/dist/domains/mirror/application/use-cases/run-mirror-sync.use-case.mjs +0 -317
- package/dist/domains/mirror/composition/tokens.mjs +0 -12
- package/dist/domains/mirror/contracts/models.mjs +0 -1
- package/dist/domains/mirror/domain/types.domain.mjs +0 -1
- package/dist/domains/mirror/infrastructure/adapters/file-system-service.adapter.mjs +0 -261
- package/dist/domains/mirror/infrastructure/adapters/mirror-package-path-resolver.adapter.mjs +0 -252
- package/dist/domains/mirror/infrastructure/adapters/mirror-sync-reporter.adapter.mjs +0 -322
- package/dist/domains/mirror/infrastructure/adapters/package-repository.adapter.mjs +0 -241
- package/dist/domains/mirror/infrastructure/adapters/sync-workspace-package.adapter.mjs +0 -328
- package/dist/domains/mirror/mirror.module.mjs +0 -26
- package/dist/domains/mirror/presentation/cli/mirror.command.mjs +0 -328
- package/dist/domains/mirror/presentation/presenters/present-mirror-sync-progress.presenter.mjs +0 -265
- package/dist/domains/tag/application/ports/inbound/prepare-tag-sync.port.mjs +0 -1
- package/dist/domains/tag/application/ports/inbound/run-tag-sync.port.mjs +0 -1
- package/dist/domains/tag/application/ports/outbound/tag-eligible-workspace-paths.port.mjs +0 -1
- package/dist/domains/tag/application/ports/outbound/tag-since-writer.port.mjs +0 -1
- package/dist/domains/tag/application/ports/outbound/tag-target-path-resolver.port.mjs +0 -1
- package/dist/domains/tag/application/ports/outbound/tag-target-runner.port.mjs +0 -1
- package/dist/domains/tag/application/ports/outbound/tag-version-resolver.port.mjs +0 -1
- package/dist/domains/tag/application/ports/presenting/present-tag-sync-progress.presenter.mjs +0 -1
- package/dist/domains/tag/application/ports/presenting/present-tag-sync-result.presenter.mjs +0 -1
- package/dist/domains/tag/application/requests/tag-sync-execution-input.mjs +0 -1
- package/dist/domains/tag/application/requests/tag-sync.request.mjs +0 -1
- package/dist/domains/tag/application/tag-sync-cli-result.mjs +0 -11
- package/dist/domains/tag/application/use-cases/prepare-tag-sync.use-case.mjs +0 -260
- package/dist/domains/tag/application/use-cases/run-tag-sync.use-case.mjs +0 -375
- package/dist/domains/tag/composition/tokens.mjs +0 -13
- package/dist/domains/tag/contracts/models.mjs +0 -1
- package/dist/domains/tag/domain/types.domain.mjs +0 -1
- package/dist/domains/tag/infrastructure/adapters/tag-since-writer.adapter.mjs +0 -348
- package/dist/domains/tag/infrastructure/adapters/tag-target-path-resolver.adapter.mjs +0 -235
- package/dist/domains/tag/infrastructure/adapters/tag-target-resolver.adapter.mjs +0 -302
- package/dist/domains/tag/infrastructure/adapters/tag-target-runner.adapter.mjs +0 -259
- package/dist/domains/tag/infrastructure/adapters/tag-version-resolver.adapter.mjs +0 -249
- package/dist/domains/tag/presentation/cli/tag.command.mjs +0 -325
- package/dist/domains/tag/presentation/presenters/present-tag-sync-progress.presenter.mjs +0 -248
- package/dist/domains/tag/presentation/presenters/present-tag-sync-result.presenter.mjs +0 -290
- package/dist/domains/tag/tag.module.mjs +0 -28
- package/dist/shell/application/cli-runtime.tokens.mjs +0 -18
- package/dist/shell/application/coordination/cli-executor.coordination.mjs +0 -1
- package/dist/shell/application/coordination/cli-schema-parsing.coordination.mjs +0 -1
- package/dist/shell/application/global-cli-options.model.mjs +0 -5
- package/dist/shell/application/ports/inbound/load-codefast-config.port.mjs +0 -1
- package/dist/shell/application/ports/outbound/cli-fs.port.mjs +0 -1
- package/dist/shell/application/ports/outbound/cli-logger.port.mjs +0 -1
- package/dist/shell/application/ports/outbound/cli-path.port.mjs +0 -1
- package/dist/shell/application/ports/outbound/cli-runtime.port.mjs +0 -1
- package/dist/shell/application/ports/outbound/cli-telemetry.port.mjs +0 -1
- package/dist/shell/application/ports/outbound/cli-verbose-diagnostics.port.mjs +0 -1
- package/dist/shell/application/ports/outbound/format-app-error.port.mjs +0 -1
- package/dist/shell/application/ports/outbound/global-cli-options-parse.port.mjs +0 -1
- package/dist/shell/application/ports/outbound/repo-root-resolver.port.mjs +0 -1
- package/dist/shell/application/ports/outbound/typescript-source-file-walker.port.mjs +0 -1
- package/dist/shell/application/ports/outbound/workspace-package-layout.port.mjs +0 -1
- package/dist/shell/application/ports/primary/command.port.mjs +0 -1
- package/dist/shell/application/services/cli-executor.service.mjs +0 -267
- package/dist/shell/application/services/schema-validator.service.mjs +0 -236
- package/dist/shell/application/use-cases/load-codefast-config.use-case.mjs +0 -243
- package/dist/shell/composition/tokens.mjs +0 -5
- package/dist/shell/contracts/cli-command-slots.mjs +0 -11
- package/dist/shell/domain/cli-exit-codes.domain.mjs +0 -11
- package/dist/shell/domain/cli-positional-arg.value-object.mjs +0 -6
- package/dist/shell/domain/errors.domain.mjs +0 -17
- package/dist/shell/infrastructure/adapters/cli-verbose-diagnostics.adapter.mjs +0 -228
- package/dist/shell/infrastructure/adapters/format-app-error.adapter.mjs +0 -236
- package/dist/shell/infrastructure/adapters/global-cli-options-parser.adapter.mjs +0 -233
- package/dist/shell/infrastructure/adapters/repo-root-resolver.adapter.mjs +0 -244
- package/dist/shell/infrastructure/adapters/typescript-source-file-walker.adapter.mjs +0 -259
- package/dist/shell/infrastructure/commander/commander-cli-host.adapter.mjs +0 -69
- package/dist/shell/infrastructure/node/node-cli-fs.adapter.mjs +0 -249
- package/dist/shell/infrastructure/node/node-cli-logger.adapter.mjs +0 -231
- package/dist/shell/infrastructure/node/node-cli-path.adapter.mjs +0 -246
- package/dist/shell/infrastructure/node/node-cli-runtime.adapter.mjs +0 -234
- package/dist/shell/infrastructure/telemetry/cli-telemetry.adapter.mjs +0 -280
- package/dist/shell/infrastructure/workspace/node-pnpm-workspace-package-layout.adapter.mjs +0 -385
- package/dist/shell/shell.module.mjs +0 -43
- package/dist/shell/wiring/optional-cli-port-telemetry-activation.mjs +0 -13
- /package/dist/{domains/arrange/application/ports/inbound/analyze-directory.port.mjs → arrange/domain/types.mjs} +0 -0
- /package/dist/{domains/arrange/application/ports/inbound/prepare-arrange-workspace.port.mjs → core/filesystem/port.mjs} +0 -0
- /package/dist/{domains/arrange/application/ports/inbound/run-arrange-sync.port.mjs → mirror/domain/dist-filesystem.mjs} +0 -0
- /package/dist/{domains/arrange/application/ports/inbound/suggest-cn-groups.port.mjs → mirror/domain/types.mjs} +0 -0
- /package/dist/{domains/arrange/application/ports/outbound/arrange-file-processor.port.mjs → mirror/sync-types.mjs} +0 -0
- /package/dist/{domains/arrange/application/ports/outbound/arrange-target-path-resolver.port.mjs → tag/domain/types.mjs} +0 -0
package/README.md
CHANGED
|
@@ -339,7 +339,7 @@ Contract:
|
|
|
339
339
|
|
|
340
340
|
Adjacent buckets may be merged into a single string literal when declared _compatible_ (e.g. Layout + Sizing), which keeps `cn()` calls readable without flattening unrelated concerns.
|
|
341
341
|
|
|
342
|
-
To change placement, extend `classifyBareUtility` in `src/
|
|
342
|
+
To change placement, extend `classifyBareUtility` in `packages/cli/src/arrange/domain/token-classifier.ts` (and cover the new rule with arrange tests if you introduce a new bucket).
|
|
343
343
|
|
|
344
344
|
---
|
|
345
345
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { AppError, messageFrom } from "../core/errors.mjs";
|
|
2
|
+
import { err, ok } from "../core/result.mjs";
|
|
3
|
+
import { accumulateAnalyzeReportForSourceFile, createEmptyAnalyzeReport } from "./domain/analyze-service.mjs";
|
|
4
|
+
import { scanArrangeTargets } from "./scan-target.mjs";
|
|
5
|
+
import { parseDomainSourceFile } from "./source-parse.mjs";
|
|
6
|
+
//#region src/arrange/analyze.ts
|
|
7
|
+
/**
|
|
8
|
+
* @since 0.3.16-canary.0
|
|
9
|
+
*/
|
|
10
|
+
function analyzeDirectory(fs, analyzeRootPath) {
|
|
11
|
+
const report = createEmptyAnalyzeReport();
|
|
12
|
+
try {
|
|
13
|
+
const files = scanArrangeTargets(fs, analyzeRootPath);
|
|
14
|
+
for (const filePath of files) {
|
|
15
|
+
const sourceText = fs.readFileSync(filePath, "utf8");
|
|
16
|
+
accumulateAnalyzeReportForSourceFile(report, parseDomainSourceFile(filePath, sourceText), sourceText, filePath);
|
|
17
|
+
}
|
|
18
|
+
return ok(report);
|
|
19
|
+
} catch (caughtError) {
|
|
20
|
+
return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { analyzeDirectory };
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
//#region src/
|
|
2
|
+
//#region src/arrange/cli-schema.ts
|
|
3
|
+
/**
|
|
4
|
+
* @since 0.3.16-canary.0
|
|
5
|
+
*/
|
|
3
6
|
const arrangeAnalyzeDirectoryRequestSchema = z.object({ analyzeRootPath: z.string().min(1, "analyzeRootPath is required") });
|
|
7
|
+
/**
|
|
8
|
+
* @since 0.3.16-canary.0
|
|
9
|
+
*/
|
|
4
10
|
const arrangeSyncRunRequestSchema = z.object({
|
|
5
11
|
rootDir: z.string().min(1),
|
|
6
12
|
targetPath: z.string().min(1),
|
|
@@ -9,6 +15,9 @@ const arrangeSyncRunRequestSchema = z.object({
|
|
|
9
15
|
cnImport: z.string().optional(),
|
|
10
16
|
config: z.unknown().optional()
|
|
11
17
|
});
|
|
18
|
+
/**
|
|
19
|
+
* @since 0.3.16-canary.0
|
|
20
|
+
*/
|
|
12
21
|
const arrangeSuggestGroupsRequestSchema = z.object({
|
|
13
22
|
inlineClasses: z.string().min(1, "Pass a class string. Example: codefast arrange group \"flex gap-2 text-sm rounded-md\""),
|
|
14
23
|
emitTvStyleArray: z.boolean(),
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { parseWithSchema } from "../core/schema-parse.mjs";
|
|
2
|
+
import "../core/exit-codes.mjs";
|
|
3
|
+
import { logger } from "../core/logger.mjs";
|
|
4
|
+
import { consumeCliAppError, runCliResultAsync } from "../core/cli/result-handle.mjs";
|
|
5
|
+
import { nodeFilesystem } from "../core/filesystem/node.mjs";
|
|
6
|
+
import { arrangeAnalyzeDirectoryRequestSchema, arrangeSuggestGroupsRequestSchema, arrangeSyncRunRequestSchema } from "./cli-schema.mjs";
|
|
7
|
+
import { prepareArrangeWorkspace } from "./workspace.mjs";
|
|
8
|
+
import { analyzeDirectory } from "./analyze.mjs";
|
|
9
|
+
import { runArrangeSync } from "./sync.mjs";
|
|
10
|
+
import { suggestCnGroupsFromCli } from "./suggest.mjs";
|
|
11
|
+
import { printAnalyzeReport, printGroupFilePreviewFromWork, printSyncResult } from "./output.mjs";
|
|
12
|
+
import { readOptionalPositionalArg } from "../core/cli/positional.mjs";
|
|
13
|
+
import process from "node:process";
|
|
14
|
+
import { Command } from "commander";
|
|
15
|
+
//#region src/arrange/command.ts
|
|
16
|
+
/**
|
|
17
|
+
* @since 0.3.16-canary.0
|
|
18
|
+
*/
|
|
19
|
+
function createArrangeCommand() {
|
|
20
|
+
const cmd = new Command("arrange").description("Analyze and regroup Tailwind classes in cn() / tv() calls (Tailwind v4)");
|
|
21
|
+
cmd.command("analyze").description("Report long strings, nested cn in tv(), and related findings").argument("[target]", "Directory or file (default: nearest package directory from cwd)").option("--json", "Print one JSON object on stdout instead of a human report", false).action(async (target, opts) => {
|
|
22
|
+
const prelude = await prepareArrangeWorkspace(nodeFilesystem, {
|
|
23
|
+
currentWorkingDirectory: process.cwd(),
|
|
24
|
+
rawTarget: readOptionalPositionalArg(target)
|
|
25
|
+
});
|
|
26
|
+
if (!consumeCliAppError(prelude)) return;
|
|
27
|
+
const { resolvedTarget } = prelude.value;
|
|
28
|
+
const parsed = parseWithSchema(arrangeAnalyzeDirectoryRequestSchema, { analyzeRootPath: resolvedTarget });
|
|
29
|
+
if (!consumeCliAppError(parsed)) return;
|
|
30
|
+
const outcome = analyzeDirectory(nodeFilesystem, parsed.value.analyzeRootPath);
|
|
31
|
+
if (!consumeCliAppError(outcome)) return;
|
|
32
|
+
if (opts.json) logger.out(formatArrangeAnalyzeJsonOutput(resolvedTarget, outcome.value));
|
|
33
|
+
else printAnalyzeReport(resolvedTarget, outcome.value);
|
|
34
|
+
});
|
|
35
|
+
const previewOrApply = (write) => async (target, opts) => {
|
|
36
|
+
const prelude = await prepareArrangeWorkspace(nodeFilesystem, {
|
|
37
|
+
currentWorkingDirectory: process.cwd(),
|
|
38
|
+
rawTarget: readOptionalPositionalArg(target)
|
|
39
|
+
});
|
|
40
|
+
if (!consumeCliAppError(prelude)) return;
|
|
41
|
+
const { resolvedTarget, rootDir, config } = prelude.value;
|
|
42
|
+
const parsed = parseWithSchema(arrangeSyncRunRequestSchema, {
|
|
43
|
+
rootDir,
|
|
44
|
+
targetPath: resolvedTarget,
|
|
45
|
+
write,
|
|
46
|
+
withClassName: opts.withClassName,
|
|
47
|
+
cnImport: opts.cnImport,
|
|
48
|
+
config: config.arrange ?? {}
|
|
49
|
+
});
|
|
50
|
+
if (!consumeCliAppError(parsed)) return;
|
|
51
|
+
await runCliResultAsync(runArrangeSync(nodeFilesystem, parsed.value), (value) => {
|
|
52
|
+
if (!write) for (const plan of value.previewPlans) printGroupFilePreviewFromWork(plan);
|
|
53
|
+
if (opts.json) {
|
|
54
|
+
logger.out(formatArrangeSyncJsonOutput(value, write));
|
|
55
|
+
return exitCodeForArrangeSyncResult(value);
|
|
56
|
+
}
|
|
57
|
+
printSyncResult(value, write);
|
|
58
|
+
return exitCodeForArrangeSyncResult(value);
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
cmd.command("preview").description("Dry-run: print suggested replacements without writing files").argument("[target]", "Directory or file (default: nearest package directory from cwd)").option("--with-classname, --with-class-name", "Append className as final cn() argument", false).option("--cn-import <spec>", "Override module specifier when adding cn import").option("--json", "Print one JSON object on stdout (suppresses human progress)", false).action(previewOrApply(false));
|
|
62
|
+
cmd.command("apply").description("Apply grouping and cn-in-tv unwrap edits to files").argument("[target]", "Directory or file (default: nearest package directory from cwd)").option("--with-classname, --with-class-name", "Append className as final cn() argument", false).option("--cn-import <spec>", "Override module specifier when adding cn import").option("--json", "Print one JSON object on stdout (suppresses human progress)", false).action(previewOrApply(true));
|
|
63
|
+
cmd.command("group").description("Try grouping on a pasted class string (stdout: cn(...) or tv array with --tv)").argument("<tokens...>", "Class tokens (quote a single string if it contains spaces)").option("--tv", "Emit tv()-style array instead of cn() call", false).option("--with-classname, --with-class-name", "Append className as final cn() argument", false).option("--json", "Print one JSON object on stdout instead of plain lines", false).action(async (classTokenSeries, opts) => {
|
|
64
|
+
const parsed = parseWithSchema(arrangeSuggestGroupsRequestSchema, {
|
|
65
|
+
inlineClasses: classTokenSeries.join(" ").trim(),
|
|
66
|
+
emitTvStyleArray: !!opts.tv,
|
|
67
|
+
trailingClassName: !!opts.withClassName
|
|
68
|
+
});
|
|
69
|
+
if (!consumeCliAppError(parsed)) return;
|
|
70
|
+
const output = suggestCnGroupsFromCli(parsed.value);
|
|
71
|
+
if (opts.json) logger.out(formatArrangeGroupJsonOutput(output));
|
|
72
|
+
else {
|
|
73
|
+
logger.out(output.primaryLine);
|
|
74
|
+
logger.out(output.bucketsCommentLine);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return cmd;
|
|
78
|
+
}
|
|
79
|
+
function formatArrangeAnalyzeJsonOutput(analyzeRootPath, report) {
|
|
80
|
+
return JSON.stringify({
|
|
81
|
+
schemaVersion: 1,
|
|
82
|
+
analyzeRootPath,
|
|
83
|
+
report
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function formatArrangeSyncJsonOutput(result, write) {
|
|
87
|
+
const { previewPlans: _plans, ...serializableResult } = result;
|
|
88
|
+
return JSON.stringify({
|
|
89
|
+
schemaVersion: 1,
|
|
90
|
+
ok: result.hookError === null,
|
|
91
|
+
write,
|
|
92
|
+
result: serializableResult
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function formatArrangeGroupJsonOutput(output) {
|
|
96
|
+
return JSON.stringify({
|
|
97
|
+
schemaVersion: 1,
|
|
98
|
+
primaryLine: output.primaryLine,
|
|
99
|
+
bucketsCommentLine: output.bucketsCommentLine
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function exitCodeForArrangeSyncResult(result) {
|
|
103
|
+
return result.hookError !== null ? 1 : 0;
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
export { createArrangeCommand };
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import "./constants.
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { forEachStringLiteralInClassExpression } from "./ast/collectors-cn.
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
//#region src/
|
|
1
|
+
import "./constants.mjs";
|
|
2
|
+
import { tokenizeClassString } from "./tailwind-token.mjs";
|
|
3
|
+
import { forEachDomainChild, isDomainCallExpression, isDomainJsxAttribute, isDomainObjectLiteralExpression } from "./ast/ast-node.mjs";
|
|
4
|
+
import { forEachStringLiteralInClassExpression } from "./ast/collectors-cn.mjs";
|
|
5
|
+
import { jsxClassNameStaticLiteral } from "./ast/collectors-jsx.mjs";
|
|
6
|
+
import { buildKnownCnTvBindings, isCnOrTvIdentifier, lineOf } from "./ast/helpers.mjs";
|
|
7
|
+
import { collectCnCallsInsideTv, traverseTvObject } from "./ast/collectors-tv.mjs";
|
|
8
|
+
//#region src/arrange/domain/analyze-service.ts
|
|
9
9
|
/**
|
|
10
10
|
* Rich domain: Tailwind/cn/tv analysis rules (counts, long literals, nested cn in tv).
|
|
11
11
|
* Pure orchestration of domain collectors and invariants — no I/O.
|
|
12
|
-
*/
|
|
12
|
+
*/
|
|
13
|
+
const PREVIEW_MAX_LENGTH = 72;
|
|
13
14
|
function previewText(text) {
|
|
14
15
|
return text.length > PREVIEW_MAX_LENGTH ? `${text.slice(0, PREVIEW_MAX_LENGTH)}…` : text;
|
|
15
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* @since 0.3.16-canary.0
|
|
19
|
+
*/
|
|
16
20
|
function createEmptyAnalyzeReport() {
|
|
17
21
|
return {
|
|
18
22
|
files: 0,
|
|
@@ -81,7 +85,10 @@ function visitJsxAttributeForArrangeAnalyze(jsxClassAttribute, domainSf, filePat
|
|
|
81
85
|
}
|
|
82
86
|
/**
|
|
83
87
|
* Accumulates findings for one parsed source file into `report` (mutates report).
|
|
84
|
-
|
|
88
|
+
*
|
|
89
|
+
* @since 0.3.16-canary.0
|
|
90
|
+
*/
|
|
91
|
+
function accumulateAnalyzeReportForSourceFile(report, domainSf, sourceText, filePath) {
|
|
85
92
|
report.files++;
|
|
86
93
|
const knownBindings = buildKnownCnTvBindings(domainSf);
|
|
87
94
|
const visitTypeScriptSubtree = (tsNode) => {
|
package/dist/{domains/arrange/domain/ast/ast-node.model.mjs → arrange/domain/ast/ast-node.mjs}
RENAMED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
//#region src/
|
|
1
|
+
//#region src/arrange/domain/ast/ast-node.ts
|
|
2
2
|
/**
|
|
3
3
|
* Pure-domain AST shapes for arrange analysis. No TypeScript compiler types.
|
|
4
4
|
* Positions mirror `getStart(sourceFile)` / `getEnd()` semantics from translation.
|
|
5
|
-
|
|
5
|
+
*
|
|
6
|
+
* @since 0.3.16-canary.0
|
|
7
|
+
*/
|
|
8
|
+
let DomainSyntaxKind = /* @__PURE__ */ function(DomainSyntaxKind) {
|
|
6
9
|
DomainSyntaxKind[DomainSyntaxKind["Unknown"] = 1] = "Unknown";
|
|
7
10
|
DomainSyntaxKind[DomainSyntaxKind["Identifier"] = 2] = "Identifier";
|
|
8
11
|
DomainSyntaxKind[DomainSyntaxKind["StringLiteral"] = 3] = "StringLiteral";
|
|
@@ -29,56 +32,104 @@
|
|
|
29
32
|
DomainSyntaxKind[DomainSyntaxKind["JsxExpression"] = 24] = "JsxExpression";
|
|
30
33
|
return DomainSyntaxKind;
|
|
31
34
|
}({});
|
|
32
|
-
|
|
35
|
+
/**
|
|
36
|
+
* @since 0.3.16-canary.0
|
|
37
|
+
*/
|
|
38
|
+
let DomainBinaryOperator = /* @__PURE__ */ function(DomainBinaryOperator) {
|
|
33
39
|
DomainBinaryOperator[DomainBinaryOperator["Plus"] = 0] = "Plus";
|
|
34
40
|
DomainBinaryOperator[DomainBinaryOperator["Other"] = 1] = "Other";
|
|
35
41
|
return DomainBinaryOperator;
|
|
36
42
|
}({});
|
|
43
|
+
/**
|
|
44
|
+
* @since 0.3.16-canary.0
|
|
45
|
+
*/
|
|
37
46
|
function isDomainIdentifier(node) {
|
|
38
47
|
return node.kind === 2;
|
|
39
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* @since 0.3.16-canary.0
|
|
51
|
+
*/
|
|
40
52
|
function isDomainStringLiteral(node) {
|
|
41
53
|
return node.kind === 3;
|
|
42
54
|
}
|
|
43
55
|
function isDomainNoSubstitutionTemplateLiteral(node) {
|
|
44
56
|
return node.kind === 4;
|
|
45
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* @since 0.3.16-canary.0
|
|
60
|
+
*/
|
|
46
61
|
function isDomainTailwindClassLiteral(node) {
|
|
47
62
|
return isDomainStringLiteral(node) || isDomainNoSubstitutionTemplateLiteral(node);
|
|
48
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* @since 0.3.16-canary.0
|
|
66
|
+
*/
|
|
49
67
|
function isDomainImportDeclaration(node) {
|
|
50
68
|
return node.kind === 5;
|
|
51
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* @since 0.3.16-canary.0
|
|
72
|
+
*/
|
|
52
73
|
function isDomainNamedImports(node) {
|
|
53
74
|
return node.kind === 7;
|
|
54
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* @since 0.3.16-canary.0
|
|
78
|
+
*/
|
|
55
79
|
function isDomainNamespaceImport(node) {
|
|
56
80
|
return node.kind === 8;
|
|
57
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* @since 0.3.16-canary.0
|
|
84
|
+
*/
|
|
58
85
|
function isDomainCallExpression(node) {
|
|
59
86
|
return node.kind === 10;
|
|
60
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* @since 0.3.16-canary.0
|
|
90
|
+
*/
|
|
61
91
|
function isDomainObjectLiteralExpression(node) {
|
|
62
92
|
return node.kind === 12;
|
|
63
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* @since 0.3.16-canary.0
|
|
96
|
+
*/
|
|
64
97
|
function isDomainPropertyAssignment(node) {
|
|
65
98
|
return node.kind === 13;
|
|
66
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* @since 0.3.16-canary.0
|
|
102
|
+
*/
|
|
67
103
|
function isDomainArrayLiteralExpression(node) {
|
|
68
104
|
return node.kind === 14;
|
|
69
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* @since 0.3.16-canary.0
|
|
108
|
+
*/
|
|
70
109
|
function isDomainSpreadElement(node) {
|
|
71
110
|
return node.kind === 15;
|
|
72
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* @since 0.3.16-canary.0
|
|
114
|
+
*/
|
|
73
115
|
function isDomainPropertyAccessExpression(node) {
|
|
74
116
|
return node.kind === 11;
|
|
75
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* @since 0.3.16-canary.0
|
|
120
|
+
*/
|
|
76
121
|
function isDomainJsxAttribute(node) {
|
|
77
122
|
return node.kind === 23;
|
|
78
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* @since 0.3.16-canary.0
|
|
126
|
+
*/
|
|
79
127
|
function isDomainJsxExpression(node) {
|
|
80
128
|
return node.kind === 24;
|
|
81
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* @since 0.3.16-canary.0
|
|
132
|
+
*/
|
|
82
133
|
function forEachDomainChild(node, visit) {
|
|
83
134
|
switch (node.kind) {
|
|
84
135
|
case 1:
|
|
@@ -151,6 +202,9 @@ function forEachDomainChild(node, visit) {
|
|
|
151
202
|
default: return;
|
|
152
203
|
}
|
|
153
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* @since 0.3.16-canary.0
|
|
207
|
+
*/
|
|
154
208
|
function lineOfSourcePosition(sourceText, pos) {
|
|
155
209
|
const boundedPos = Math.max(0, Math.min(pos, sourceText.length));
|
|
156
210
|
let line = 1;
|
|
@@ -1,44 +1,56 @@
|
|
|
1
|
-
import "../constants.
|
|
2
|
-
import {
|
|
3
|
-
//#region src/
|
|
1
|
+
import "../constants.mjs";
|
|
2
|
+
import { isDomainArrayLiteralExpression, isDomainTailwindClassLiteral } from "./ast-node.mjs";
|
|
3
|
+
//#region src/arrange/domain/ast/collectors-cn.ts
|
|
4
|
+
/**
|
|
5
|
+
* @since 0.3.16-canary.0
|
|
6
|
+
*/
|
|
4
7
|
function forEachStringLiteralInClassExpression(expr, sink, depth = 0, options) {
|
|
5
8
|
if (depth > 12) return;
|
|
6
9
|
if (isDomainTailwindClassLiteral(expr)) {
|
|
7
10
|
sink(expr);
|
|
8
11
|
return;
|
|
9
12
|
}
|
|
10
|
-
if (expr.kind ===
|
|
13
|
+
if (expr.kind === 16) {
|
|
11
14
|
forEachStringLiteralInClassExpression(expr.expression, sink, depth + 1, options);
|
|
12
15
|
return;
|
|
13
16
|
}
|
|
14
|
-
if (expr.kind ===
|
|
17
|
+
if (expr.kind === 17 || expr.kind === 18) {
|
|
15
18
|
forEachStringLiteralInClassExpression(expr.expression, sink, depth + 1, options);
|
|
16
19
|
return;
|
|
17
20
|
}
|
|
18
|
-
if (expr.kind ===
|
|
21
|
+
if (expr.kind === 19) {
|
|
19
22
|
forEachStringLiteralInClassExpression(expr.expression, sink, depth + 1, options);
|
|
20
23
|
return;
|
|
21
24
|
}
|
|
22
|
-
if (expr.kind ===
|
|
25
|
+
if (expr.kind === 20) {
|
|
23
26
|
if (options?.descendIntoConditional === false) return;
|
|
24
27
|
forEachStringLiteralInClassExpression(expr.whenTrue, sink, depth + 1, options);
|
|
25
28
|
forEachStringLiteralInClassExpression(expr.whenFalse, sink, depth + 1, options);
|
|
26
29
|
return;
|
|
27
30
|
}
|
|
28
|
-
if (expr.kind ===
|
|
31
|
+
if (expr.kind === 21 && expr.operator === 0) {
|
|
29
32
|
forEachStringLiteralInClassExpression(expr.left, sink, depth + 1, options);
|
|
30
33
|
forEachStringLiteralInClassExpression(expr.right, sink, depth + 1, options);
|
|
31
34
|
return;
|
|
32
35
|
}
|
|
33
36
|
if (isDomainArrayLiteralExpression(expr)) for (const arrayElement of expr.elements) {
|
|
34
|
-
if (arrayElement.kind ===
|
|
37
|
+
if (arrayElement.kind === 15) continue;
|
|
35
38
|
forEachStringLiteralInClassExpression(arrayElement, sink, depth + 1, options);
|
|
36
39
|
}
|
|
37
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* @since 0.3.16-canary.0
|
|
43
|
+
*/
|
|
38
44
|
function isUnsafeLiteralForCnStyleApplySplit(classLiteral) {
|
|
39
45
|
return classLiteral.parent !== null && isDomainArrayLiteralExpression(classLiteral.parent);
|
|
40
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* @since 0.3.16-canary.0
|
|
49
|
+
*/
|
|
41
50
|
const CN_APPLY_LITERAL_WALK_OPTS = { descendIntoConditional: false };
|
|
51
|
+
/**
|
|
52
|
+
* @since 0.3.16-canary.0
|
|
53
|
+
*/
|
|
42
54
|
function collectUnconditionalTailwindLiteralsFromCnArguments(args) {
|
|
43
55
|
const staticLits = [];
|
|
44
56
|
for (const arg of args) if (isDomainTailwindClassLiteral(arg)) {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { isDomainIdentifier, isDomainJsxExpression, isDomainTailwindClassLiteral } from "./ast-node.
|
|
2
|
-
//#region src/
|
|
1
|
+
import { isDomainIdentifier, isDomainJsxExpression, isDomainTailwindClassLiteral } from "./ast-node.mjs";
|
|
2
|
+
//#region src/arrange/domain/ast/collectors-jsx.ts
|
|
3
|
+
/**
|
|
4
|
+
* @since 0.3.16-canary.0
|
|
5
|
+
*/
|
|
3
6
|
function jsxClassNameStaticLiteral(jsxClassNameAttribute) {
|
|
4
7
|
if (!isDomainIdentifier(jsxClassNameAttribute.name) || jsxClassNameAttribute.name.text !== "className") return;
|
|
5
8
|
const init = jsxClassNameAttribute.initializer;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import "../constants.
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { CN_APPLY_LITERAL_WALK_OPTS, collectUnconditionalTailwindLiteralsFromCnArguments, forEachStringLiteralInClassExpression, isUnsafeLiteralForCnStyleApplySplit } from "./collectors-cn.
|
|
5
|
-
import {
|
|
6
|
-
//#region src/
|
|
1
|
+
import "../constants.mjs";
|
|
2
|
+
import { tokenizeClassString } from "../tailwind-token.mjs";
|
|
3
|
+
import { forEachDomainChild, isDomainArrayLiteralExpression, isDomainCallExpression, isDomainObjectLiteralExpression, isDomainPropertyAssignment, isDomainSpreadElement, isDomainTailwindClassLiteral } from "./ast-node.mjs";
|
|
4
|
+
import { CN_APPLY_LITERAL_WALK_OPTS, collectUnconditionalTailwindLiteralsFromCnArguments, forEachStringLiteralInClassExpression, isUnsafeLiteralForCnStyleApplySplit } from "./collectors-cn.mjs";
|
|
5
|
+
import { buildKnownCnTvBindings, isCnOrTvIdentifier, propertyAssignmentNameText } from "./helpers.mjs";
|
|
6
|
+
//#region src/arrange/domain/ast/collectors-tv.ts
|
|
7
|
+
/**
|
|
8
|
+
* @since 0.3.16-canary.0
|
|
9
|
+
*/
|
|
7
10
|
function traverseTvObject(sourceFile, obj, visitor, depth = 0, knownBindings) {
|
|
8
11
|
if (depth > 12) return;
|
|
9
12
|
for (const prop of obj.properties) {
|
|
@@ -37,6 +40,9 @@ function traverseTvObject(sourceFile, obj, visitor, depth = 0, knownBindings) {
|
|
|
37
40
|
});
|
|
38
41
|
}
|
|
39
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* @since 0.3.16-canary.0
|
|
45
|
+
*/
|
|
40
46
|
function collectCnCallsInsideTv(sourceFile, obj, knownBindings, depth = 0) {
|
|
41
47
|
if (depth > 12) return [];
|
|
42
48
|
const calls = [];
|
|
@@ -59,6 +65,9 @@ function collectCnCallsInsideTv(sourceFile, obj, knownBindings, depth = 0) {
|
|
|
59
65
|
}
|
|
60
66
|
return calls;
|
|
61
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* @since 0.3.16-canary.0
|
|
70
|
+
*/
|
|
62
71
|
function listAllCnCallsInsideTvInSourceFile(sourceFile, knownBindings) {
|
|
63
72
|
const calls = [];
|
|
64
73
|
const visitSubtree = (tsNode) => {
|
|
@@ -84,6 +93,9 @@ function makeStringNode(nodes, sourceFile, isTvContext, cnCall) {
|
|
|
84
93
|
}
|
|
85
94
|
};
|
|
86
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* @since 0.3.16-canary.0
|
|
98
|
+
*/
|
|
87
99
|
function slotClassString(stringNode) {
|
|
88
100
|
return stringNode.nodes.map((literal) => literal.text).join(" ");
|
|
89
101
|
}
|
|
@@ -144,6 +156,9 @@ function collectTvSlots(sourceFile, obj, knownBindings, results, seenNodePos, de
|
|
|
144
156
|
}
|
|
145
157
|
}
|
|
146
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* @since 0.3.16-canary.0
|
|
161
|
+
*/
|
|
147
162
|
function collectGroupableStringNodes(sourceFile) {
|
|
148
163
|
const results = [];
|
|
149
164
|
const seenNodePos = /* @__PURE__ */ new Set();
|
package/dist/{domains/arrange/domain/ast/ast-helpers.helper.mjs → arrange/domain/ast/helpers.mjs}
RENAMED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { EMPTY_CN_TV_BINDINGS } from "../constants.
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
//#region src/
|
|
1
|
+
import { EMPTY_CN_TV_BINDINGS } from "../constants.mjs";
|
|
2
|
+
import { isDomainIdentifier, isDomainImportDeclaration, isDomainNamedImports, isDomainNamespaceImport, isDomainPropertyAccessExpression, isDomainStringLiteral, lineOfSourcePosition } from "./ast-node.mjs";
|
|
3
|
+
import { applyEditsDescending, indentOfLineContaining } from "../../../core/source-text-edit.mjs";
|
|
4
|
+
//#region src/arrange/domain/ast/helpers.ts
|
|
5
5
|
/**
|
|
6
6
|
* Known module specifiers that export `cn` / `tv`.
|
|
7
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
const KNOWN_CN_TV_MODULES = new Set([
|
|
8
9
|
"@codefast/tailwind-variants",
|
|
9
10
|
"clsx",
|
|
10
11
|
"class-variance-authority",
|
|
@@ -16,7 +17,8 @@ import { isDomainIdentifier, isDomainImportDeclaration, isDomainNamedImports, is
|
|
|
16
17
|
/**
|
|
17
18
|
* True for typical shadcn-style re-exports: `./utils`, `@/lib/utils`, `…/utils/…`,
|
|
18
19
|
* or a dedicated `cn.ts` / `cn.tsx` module.
|
|
19
|
-
*/
|
|
20
|
+
*/
|
|
21
|
+
function moduleLooksLikeCnTvReexport(moduleSpecifier) {
|
|
20
22
|
const norm = moduleSpecifier.replace(/\\/g, "/");
|
|
21
23
|
if (/(?:^|[./])utils(?:\/|$)/.test(norm)) return true;
|
|
22
24
|
if (/\/utils\//.test(norm) || /\/utils$/.test(norm)) return true;
|
|
@@ -26,7 +28,10 @@ import { isDomainIdentifier, isDomainImportDeclaration, isDomainNamedImports, is
|
|
|
26
28
|
/**
|
|
27
29
|
* Build a set of local binding names that are imported from a known cn/tv
|
|
28
30
|
* module in `sourceFile`.
|
|
29
|
-
|
|
31
|
+
*
|
|
32
|
+
* @since 0.3.16-canary.0
|
|
33
|
+
*/
|
|
34
|
+
function buildKnownCnTvBindings(sourceFile) {
|
|
30
35
|
const bindings = /* @__PURE__ */ new Set();
|
|
31
36
|
for (const stmt of sourceFile.statements) {
|
|
32
37
|
if (!isDomainImportDeclaration(stmt) || !stmt.importClause) continue;
|
|
@@ -50,23 +55,35 @@ import { isDomainIdentifier, isDomainImportDeclaration, isDomainNamedImports, is
|
|
|
50
55
|
/**
|
|
51
56
|
* Returns true when `expr` is an identifier whose name matches `name` AND
|
|
52
57
|
* that name is listed in `knownBindings` from a recognized import.
|
|
53
|
-
|
|
58
|
+
*
|
|
59
|
+
* @since 0.3.16-canary.0
|
|
60
|
+
*/
|
|
61
|
+
function isCnOrTvIdentifier(expr, name, knownBindings = EMPTY_CN_TV_BINDINGS) {
|
|
54
62
|
if (knownBindings.size === 0) return false;
|
|
55
63
|
if (isDomainIdentifier(expr) && expr.text === name) return knownBindings.has(expr.text);
|
|
56
64
|
if (isDomainPropertyAccessExpression(expr) && expr.name.text === name) return isDomainIdentifier(expr.expression) && knownBindings.has(expr.expression.text);
|
|
57
65
|
return false;
|
|
58
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* @since 0.3.16-canary.0
|
|
69
|
+
*/
|
|
59
70
|
function propertyAssignmentNameText(prop) {
|
|
60
71
|
if (isDomainIdentifier(prop.name)) return prop.name.text;
|
|
61
72
|
if (isDomainStringLiteral(prop.name)) return prop.name.text;
|
|
62
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* @since 0.3.16-canary.0
|
|
76
|
+
*/
|
|
63
77
|
function lineOf(sourceFile, node) {
|
|
64
78
|
return lineOfSourcePosition(sourceFile.text, node.pos);
|
|
65
79
|
}
|
|
66
80
|
/**
|
|
67
81
|
* Replace `cn(...)` nested in `tv({...})` with a plain string (one arg) or a string
|
|
68
82
|
* array (multiple args). Returns undefined when there are zero arguments.
|
|
69
|
-
|
|
83
|
+
*
|
|
84
|
+
* @since 0.3.16-canary.0
|
|
85
|
+
*/
|
|
86
|
+
function unwrapCnInsideTvCallReplacement(call, sourceText) {
|
|
70
87
|
const args = call.arguments;
|
|
71
88
|
if (args.length === 0) return;
|
|
72
89
|
const baseIndent = indentOfLineContaining(sourceText, call.pos);
|
package/dist/{domains/arrange/domain/ast/targets.model.mjs → arrange/domain/ast/targets.mjs}
RENAMED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import "../constants.
|
|
2
|
-
import {
|
|
3
|
-
import { forEachDomainChild, isDomainArrayLiteralExpression, isDomainJsxAttribute, isDomainTailwindClassLiteral } from "./ast-node.
|
|
4
|
-
import { isUnsafeLiteralForCnStyleApplySplit } from "./collectors-cn.
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
//#region src/
|
|
1
|
+
import "../constants.mjs";
|
|
2
|
+
import { tokenizeClassString } from "../tailwind-token.mjs";
|
|
3
|
+
import { forEachDomainChild, isDomainArrayLiteralExpression, isDomainJsxAttribute, isDomainTailwindClassLiteral } from "./ast-node.mjs";
|
|
4
|
+
import { isUnsafeLiteralForCnStyleApplySplit } from "./collectors-cn.mjs";
|
|
5
|
+
import { jsxClassNameStaticLiteral } from "./collectors-jsx.mjs";
|
|
6
|
+
import { endAfterOptionalCommaFollowingInSource, indentOfLineContaining, textPrefixFromLineStartToPosition } from "../../../core/source-text-edit.mjs";
|
|
7
|
+
import { collectGroupableStringNodes, slotClassString } from "./collectors-tv.mjs";
|
|
8
|
+
import { areCnTailwindPartitionsEquivalent, suggestCnGroups, summarizeGroupBucketLabels } from "../grouping.mjs";
|
|
9
|
+
import { escapeTsStringLiteralContent, formatArray, formatArrayElementsAsSiblingLines, formatJsxCnAttributeValue } from "../source-text-formatters.mjs";
|
|
10
|
+
//#region src/arrange/domain/ast/targets.ts
|
|
11
|
+
/**
|
|
12
|
+
* @since 0.3.16-canary.0
|
|
13
|
+
*/
|
|
11
14
|
function targetReplaceStart(target) {
|
|
12
15
|
if (target.kind === "cnArg") return target.item.cnCall ? target.item.cnCall.pos : target.item.primaryClassLiteral.pos;
|
|
13
16
|
return target.valueNode.pos;
|
|
@@ -29,6 +32,9 @@ function collectLongJsxClassNameTargets(sourceFile) {
|
|
|
29
32
|
for (const stmt of sourceFile.statements) visitTypeScriptSubtree(stmt);
|
|
30
33
|
return results;
|
|
31
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* @since 0.3.16-canary.0
|
|
37
|
+
*/
|
|
32
38
|
function collectGroupTargets(sourceFile, filePath) {
|
|
33
39
|
const cnPart = collectGroupableStringNodes(sourceFile).map((stringNode) => ({
|
|
34
40
|
kind: "cnArg",
|
|
@@ -58,6 +64,9 @@ function formatCnCallReplacement(stringNode, sourceText, withClassName) {
|
|
|
58
64
|
const commaAfterLastArg = allArgs.length > 1;
|
|
59
65
|
return `cn(\n${allArgs.map((argLine, lineIndex) => lineIndex < allArgs.length - 1 || commaAfterLastArg ? `${argLine},` : `${argLine}`).join("\n")}\n${baseIndent})`;
|
|
60
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* @since 0.3.16-canary.0
|
|
69
|
+
*/
|
|
61
70
|
function planGroupEditForTarget(target, textAfterUnwrap, withClassName) {
|
|
62
71
|
if (target.kind === "jsxClassName") {
|
|
63
72
|
const groups = suggestCnGroups(target.lit.text);
|