@codefast/cli 0.3.14 → 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 +8 -3
- package/dist/arrange/analyze.mjs +24 -0
- package/dist/{lib/arrange/presentation/arrange-cli.schema.mjs → arrange/cli-schema.mjs} +10 -1
- package/dist/arrange/command.mjs +106 -0
- package/dist/{lib/arrange/domain/arrange-analyze.service.mjs → arrange/domain/analyze-service.mjs} +17 -10
- package/dist/{lib/arrange/domain/ast/ast-node.model.mjs → arrange/domain/ast/ast-node.mjs} +57 -3
- package/dist/{lib/arrange/domain/ast/collectors-cn.collector.mjs → arrange/domain/ast/collectors-cn.mjs} +21 -9
- package/dist/{lib/arrange/domain/ast/collectors-jsx.collector.mjs → arrange/domain/ast/collectors-jsx.mjs} +5 -2
- package/dist/{lib/arrange/domain/ast/collectors-tv.collector.mjs → arrange/domain/ast/collectors-tv.mjs} +21 -6
- package/dist/{lib/arrange/domain/ast/ast-helpers.helper.mjs → arrange/domain/ast/helpers.mjs} +26 -9
- package/dist/{lib/arrange/domain/ast/targets.model.mjs → arrange/domain/ast/targets.mjs} +19 -10
- package/dist/{lib/arrange/domain/constants.domain.mjs → arrange/domain/constants.mjs} +63 -18
- package/dist/{lib/arrange/domain/arrange-grouping.service.mjs → arrange/domain/grouping-service.mjs} +31 -10
- package/dist/{lib/arrange/domain/grouping.domain.mjs → arrange/domain/grouping.mjs} +39 -18
- package/dist/{lib/arrange/domain/imports.domain.mjs → arrange/domain/imports.mjs} +7 -3
- package/dist/{lib/arrange/domain/source-text-formatters.formatter.mjs → arrange/domain/source-text-formatters.mjs} +22 -5
- package/dist/{lib/arrange/domain/tailwind-token.value-object.mjs → arrange/domain/tailwind-token.mjs} +12 -3
- package/dist/{lib/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 -19
- 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/{lib/config/infrastructure/config-schema.adapter.mjs → core/config/schema.mjs} +20 -6
- package/dist/core/config/warnings.mjs +12 -0
- package/dist/core/config.mjs +19 -0
- package/dist/{lib/core/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/{lib/core/domain/result.model.mjs → core/result.mjs} +7 -3
- package/dist/{lib/core/application/services/schema-validator.service.mjs → core/schema-parse.mjs} +6 -5
- package/dist/{lib/shared/source-code/domain/text-edit.model.mjs → core/source-text-edit.mjs} +15 -14
- 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/mirror/cli-result.mjs +21 -0
- package/dist/{lib/mirror/presentation/mirror-cli.schema.mjs → mirror/cli-schema.mjs} +4 -4
- package/dist/mirror/command.mjs +57 -0
- package/dist/mirror/dist-filesystem-impl.mjs +42 -0
- package/dist/{lib/mirror/domain/constants.domain.mjs → mirror/domain/constants.mjs} +16 -1
- package/dist/{lib/mirror/infrastructure/dirent-list.guard.mjs → mirror/domain/dirent-guard.mjs} +5 -2
- package/dist/{lib/mirror/domain/errors.domain.mjs → mirror/domain/errors.mjs} +7 -1
- package/dist/{lib/mirror/application/services/generate-mirror-exports.service.mjs → mirror/domain/exports.mjs} +17 -10
- package/dist/{lib/mirror/domain/package-display-name.policy.mjs → mirror/domain/package-display-name.mjs} +5 -2
- package/dist/{lib/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/{lib/mirror/infrastructure/package-json-exports.repository.mjs → mirror/write-exports.mjs} +35 -31
- package/dist/tag/cli-result.mjs +11 -0
- package/dist/{lib/tag/presentation/tag-cli.schema.mjs → tag/cli-schema.mjs} +4 -1
- package/dist/tag/command.mjs +56 -0
- package/dist/{lib/tag/presentation/tag-sync.presenter.mjs → tag/output.mjs} +54 -28
- 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 +8 -9
- package/dist/lib/arrange/adapters/primary/cli/arrange.command.mjs +0 -324
- package/dist/lib/arrange/adapters/primary/cli/arrange.presentation.module.mjs +0 -14
- package/dist/lib/arrange/adapters/primary/cli/presentation.tokens.mjs +0 -5
- package/dist/lib/arrange/adapters/secondary/domain-source-parser.adapter.mjs +0 -239
- package/dist/lib/arrange/adapters/secondary/file-walker.adapter.mjs +0 -241
- package/dist/lib/arrange/adapters/secondary/workspace-resolver.adapter.mjs +0 -233
- package/dist/lib/arrange/application/requests/suggest-groups.request.mjs +0 -1
- package/dist/lib/arrange/application/services/arrange-file-processor.service.mjs +0 -267
- package/dist/lib/arrange/application/services/arrange-target-path-resolver.service.mjs +0 -21
- package/dist/lib/arrange/application/services/arrange-target-scanner.service.mjs +0 -243
- package/dist/lib/arrange/application/use-cases/analyze-directory.use-case.mjs +0 -255
- package/dist/lib/arrange/application/use-cases/prepare-arrange-workspace.use-case.mjs +0 -263
- package/dist/lib/arrange/application/use-cases/run-arrange-sync.use-case.mjs +0 -274
- package/dist/lib/arrange/application/use-cases/suggest-cn-groups.use-case.mjs +0 -237
- package/dist/lib/arrange/arrange.module.mjs +0 -31
- package/dist/lib/arrange/contracts/analyze-report-presenter.contract.mjs +0 -1
- package/dist/lib/arrange/contracts/models.mjs +0 -1
- package/dist/lib/arrange/contracts/services.contract.mjs +0 -1
- package/dist/lib/arrange/contracts/tokens.mjs +0 -15
- package/dist/lib/arrange/domain/tailwind-grouping.service.mjs +0 -231
- package/dist/lib/arrange/domain/types.domain.mjs +0 -1
- package/dist/lib/arrange/infrastructure/typescript-ast-translator.adapter.mjs +0 -355
- package/dist/lib/arrange/presentation/arrange-analyze.presenter.mjs +0 -259
- package/dist/lib/arrange/presentation/arrange-sync.presenter.mjs +0 -33
- package/dist/lib/arrange/presentation/group-file-preview.presenter.mjs +0 -271
- package/dist/lib/bootstrap/composition-root.mjs +0 -33
- package/dist/lib/config/application/ports/config-loader.port.mjs +0 -1
- package/dist/lib/config/application/ports/config-warning-reporter.port.mjs +0 -1
- package/dist/lib/config/application/services/load-config.service.mjs +0 -17
- package/dist/lib/config/contracts/tokens.mjs +0 -6
- package/dist/lib/config/domain/schema.domain.mjs +0 -1
- package/dist/lib/config/infrastructure/config-loader.adapter.mjs +0 -306
- package/dist/lib/config/infrastructure/config-warning-reporter.adapter.mjs +0 -234
- package/dist/lib/core/application/load-codefast-config.use-case.mjs +0 -245
- package/dist/lib/core/application/ports/cli-io.port.mjs +0 -1
- package/dist/lib/core/application/ports/path.port.mjs +0 -1
- package/dist/lib/core/application/ports/repo-root-resolver.port.mjs +0 -1
- package/dist/lib/core/application/ports/runtime.port.mjs +0 -1
- package/dist/lib/core/application/services/global-cli-options-parser.service.mjs +0 -9
- package/dist/lib/core/contracts/tokens.mjs +0 -10
- package/dist/lib/core/core.module.mjs +0 -9
- package/dist/lib/core/domain/cli-exit-codes.domain.mjs +0 -11
- package/dist/lib/core/domain/errors.domain.mjs +0 -17
- package/dist/lib/core/infrastructure/infrastructure.module.mjs +0 -30
- package/dist/lib/core/infrastructure/path.adapter.mjs +0 -246
- package/dist/lib/core/infrastructure/port-telemetry.decorator.mjs +0 -62
- package/dist/lib/core/infrastructure/repo-root-resolver.adapter.mjs +0 -233
- package/dist/lib/core/infrastructure/verbose-diagnostics.policy.mjs +0 -9
- package/dist/lib/core/presentation/cli-executor.presenter.mjs +0 -42
- package/dist/lib/core/presentation/cli-schema.parser.mjs +0 -7
- package/dist/lib/core/presentation/format-app-error.presenter.mjs +0 -17
- package/dist/lib/core/presentation/presentation.module.mjs +0 -5
- package/dist/lib/infrastructure/node-io.adapter.mjs +0 -285
- package/dist/lib/infrastructure/workspace/repo-root-resolver.service.mjs +0 -21
- package/dist/lib/kernel/contracts/cli-command.contract.mjs +0 -1
- package/dist/lib/kernel/contracts/tokens.mjs +0 -5
- package/dist/lib/mirror/adapters/primary/cli/mirror.command.mjs +0 -272
- package/dist/lib/mirror/adapters/secondary/file-system-service.adapter.mjs +0 -261
- package/dist/lib/mirror/adapters/secondary/mirror-sync-reporter.adapter.mjs +0 -243
- package/dist/lib/mirror/adapters/secondary/package-repository.adapter.mjs +0 -241
- package/dist/lib/mirror/adapters/secondary/sync-workspace-package.adapter.mjs +0 -351
- package/dist/lib/mirror/adapters/secondary/workspace-service.adapter.mjs +0 -237
- package/dist/lib/mirror/application/mirror-sync-json.format.mjs +0 -12
- package/dist/lib/mirror/application/ports/file-system-service.port.mjs +0 -1
- package/dist/lib/mirror/application/ports/mirror-sync-reporter.port.mjs +0 -1
- package/dist/lib/mirror/application/ports/package-repository.port.mjs +0 -1
- package/dist/lib/mirror/application/ports/sync-workspace-package.port.mjs +0 -1
- package/dist/lib/mirror/application/ports/workspace-service.port.mjs +0 -1
- package/dist/lib/mirror/application/requests/mirror-sync.request.mjs +0 -1
- package/dist/lib/mirror/application/services/mirror-package-arg-resolver.service.mjs +0 -20
- package/dist/lib/mirror/application/use-cases/prepare-mirror-sync.use-case.mjs +0 -264
- package/dist/lib/mirror/application/use-cases/run-mirror-sync.use-case.mjs +0 -302
- package/dist/lib/mirror/contracts/models.mjs +0 -1
- package/dist/lib/mirror/contracts/tokens.mjs +0 -11
- package/dist/lib/mirror/domain/types.domain.mjs +0 -1
- package/dist/lib/mirror/infrastructure/mirror-console-reporter.presenter.mjs +0 -99
- package/dist/lib/mirror/infrastructure/package-filter-resolver.service.mjs +0 -25
- package/dist/lib/mirror/infrastructure/workspace-packages.service.mjs +0 -158
- package/dist/lib/mirror/mirror.module.mjs +0 -25
- package/dist/lib/shared/source-code/infrastructure/typescript-source-file-walker.service.mjs +0 -33
- package/dist/lib/tag/adapters/primary/cli/presentation.tokens.mjs +0 -6
- package/dist/lib/tag/adapters/primary/cli/tag.command.mjs +0 -285
- package/dist/lib/tag/adapters/primary/cli/tag.presentation.module.mjs +0 -13
- package/dist/lib/tag/adapters/secondary/tag-since-writer.adapter.mjs +0 -348
- package/dist/lib/tag/adapters/secondary/tag-target-resolver.adapter.mjs +0 -233
- package/dist/lib/tag/adapters/secondary/tag-version-resolver.adapter.mjs +0 -249
- package/dist/lib/tag/adapters/secondary/typescript-tree-walk.adapter.mjs +0 -233
- package/dist/lib/tag/application/ports/tag-since-writer.port.mjs +0 -1
- package/dist/lib/tag/application/ports/tag-version-resolver.port.mjs +0 -1
- package/dist/lib/tag/application/ports/target-resolver.port.mjs +0 -1
- package/dist/lib/tag/application/ports/typescript-tree-walk.port.mjs +0 -1
- package/dist/lib/tag/application/requests/tag-sync.request.mjs +0 -1
- package/dist/lib/tag/application/services/tag-cli-target-path-resolver.service.mjs +0 -9
- package/dist/lib/tag/application/services/tag-target-runner.service.mjs +0 -21
- package/dist/lib/tag/application/tag-sync-cli-result.mjs +0 -11
- package/dist/lib/tag/application/tag-sync-json.format.mjs +0 -14
- package/dist/lib/tag/application/use-cases/prepare-tag-sync.use-case.mjs +0 -264
- package/dist/lib/tag/application/use-cases/run-tag-sync.use-case.mjs +0 -381
- package/dist/lib/tag/contracts/models.mjs +0 -1
- package/dist/lib/tag/contracts/tag-sync-result-presenter.contract.mjs +0 -1
- package/dist/lib/tag/contracts/tokens.mjs +0 -10
- package/dist/lib/tag/domain/types.domain.mjs +0 -1
- package/dist/lib/tag/infrastructure/tag-target-candidates.adapter.mjs +0 -170
- package/dist/lib/tag/presentation/colors.presenter.mjs +0 -12
- package/dist/lib/tag/presentation/present-tag-sync-result.presenter.mjs +0 -233
- package/dist/lib/tag/presentation/tag-sync-progress-listener.presenter.mjs +0 -243
- package/dist/lib/tag/tag.module.mjs +0 -23
- /package/dist/{lib/arrange/application/ports/domain-source-parser.port.mjs → arrange/domain/types.mjs} +0 -0
- /package/dist/{lib/arrange/application/ports/file-walker.port.mjs → core/filesystem/port.mjs} +0 -0
- /package/dist/{lib/arrange/application/ports/group-file-preview.port.mjs → mirror/domain/dist-filesystem.mjs} +0 -0
- /package/dist/{lib/arrange/application/ports/workspace-resolver.port.mjs → mirror/domain/types.mjs} +0 -0
- /package/dist/{lib/arrange/application/requests/analyze-directory.request.mjs → mirror/sync-types.mjs} +0 -0
- /package/dist/{lib/arrange/application/requests/arrange-sync.request.mjs → tag/domain/types.mjs} +0 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { messageFrom } from "../errors.mjs";
|
|
2
|
+
import { logger } from "../logger.mjs";
|
|
3
|
+
import { globSync } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import picomatch from "picomatch";
|
|
7
|
+
import { parse } from "yaml";
|
|
8
|
+
//#region src/core/workspace/resolver.ts
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the monorepo root (directory containing `pnpm-workspace.yaml`).
|
|
11
|
+
*
|
|
12
|
+
* @since 0.3.16-canary.0
|
|
13
|
+
*/
|
|
14
|
+
function findRepoRoot(fromDirectory, fs) {
|
|
15
|
+
const candidates = [path.dirname(fileURLToPath(import.meta.url)), fromDirectory];
|
|
16
|
+
for (const start of candidates) {
|
|
17
|
+
let dir = path.resolve(start);
|
|
18
|
+
for (;;) {
|
|
19
|
+
if (fs.existsSync(path.join(dir, "pnpm-workspace.yaml"))) return dir;
|
|
20
|
+
const parent = path.dirname(dir);
|
|
21
|
+
if (parent === dir) break;
|
|
22
|
+
dir = parent;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
throw new Error(`Could not locate monorepo root (missing pnpm-workspace.yaml). Searched from: ${candidates.join(", ")}`);
|
|
26
|
+
}
|
|
27
|
+
const workspaceYamlFileName = "pnpm-workspace.yaml";
|
|
28
|
+
const defaultIncludePatterns = ["packages/*"];
|
|
29
|
+
const packageJsonFileName = "package.json";
|
|
30
|
+
function toPosix(filePath) {
|
|
31
|
+
return filePath.split(path.sep).join("/");
|
|
32
|
+
}
|
|
33
|
+
function isGlobPermissionError(caughtError) {
|
|
34
|
+
if (typeof caughtError !== "object" || caughtError === null || !("code" in caughtError)) return false;
|
|
35
|
+
const code = caughtError.code;
|
|
36
|
+
return code === "EACCES" || code === "EPERM";
|
|
37
|
+
}
|
|
38
|
+
function workspacePatternToPackageJsonGlob(pattern) {
|
|
39
|
+
const normalizedPattern = toPosix(pattern.trim()).replace(/\/+$/, "");
|
|
40
|
+
if (!normalizedPattern) return `**/${packageJsonFileName}`;
|
|
41
|
+
return `${normalizedPattern}/${packageJsonFileName}`;
|
|
42
|
+
}
|
|
43
|
+
function splitPnpmWorkspacePackagesArray(raw) {
|
|
44
|
+
const include = [];
|
|
45
|
+
const exclude = [];
|
|
46
|
+
if (!Array.isArray(raw)) return {
|
|
47
|
+
include,
|
|
48
|
+
exclude
|
|
49
|
+
};
|
|
50
|
+
for (const entry of raw) {
|
|
51
|
+
if (typeof entry !== "string") continue;
|
|
52
|
+
const trimmed = entry.trim();
|
|
53
|
+
if (!trimmed) continue;
|
|
54
|
+
if (trimmed.startsWith("!")) exclude.push(trimmed.slice(1).trim());
|
|
55
|
+
else include.push(trimmed);
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
include,
|
|
59
|
+
exclude
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function parsePnpmWorkspaceDocument(doc) {
|
|
63
|
+
const wf = workspaceYamlFileName;
|
|
64
|
+
if (doc === null || doc === void 0) throw new Error(`${wf} root document must be an object (got empty or null)`);
|
|
65
|
+
if (typeof doc !== "object" || Array.isArray(doc)) throw new Error(`${wf} root must be a mapping, not an array or scalar`);
|
|
66
|
+
const parsedDoc = doc;
|
|
67
|
+
if (!Object.prototype.hasOwnProperty.call(parsedDoc, "packages")) return {
|
|
68
|
+
include: [],
|
|
69
|
+
exclude: [],
|
|
70
|
+
hasPackagesKey: false,
|
|
71
|
+
isEmptyPackagesArray: false
|
|
72
|
+
};
|
|
73
|
+
const pkgs = parsedDoc.packages;
|
|
74
|
+
if (!Array.isArray(pkgs)) throw new Error(`${wf} field "packages" must be an array`);
|
|
75
|
+
if (pkgs.length === 0) return {
|
|
76
|
+
include: [],
|
|
77
|
+
exclude: [],
|
|
78
|
+
hasPackagesKey: true,
|
|
79
|
+
isEmptyPackagesArray: true
|
|
80
|
+
};
|
|
81
|
+
return {
|
|
82
|
+
...splitPnpmWorkspacePackagesArray(pkgs),
|
|
83
|
+
hasPackagesKey: true,
|
|
84
|
+
isEmptyPackagesArray: false
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
async function readWorkspaceYaml(rootDir, fs) {
|
|
88
|
+
const wf = workspaceYamlFileName;
|
|
89
|
+
const workspaceYamlPath = path.join(rootDir, wf);
|
|
90
|
+
if (!fs.existsSync(workspaceYamlPath)) return { exists: false };
|
|
91
|
+
let raw;
|
|
92
|
+
try {
|
|
93
|
+
raw = await fs.readFile(workspaceYamlPath, "utf8");
|
|
94
|
+
} catch (caughtReadError) {
|
|
95
|
+
throw new Error(`Failed to read ${wf}: ${messageFrom(caughtReadError)}`);
|
|
96
|
+
}
|
|
97
|
+
let doc;
|
|
98
|
+
try {
|
|
99
|
+
doc = parse(raw);
|
|
100
|
+
} catch (caughtYamlParseError) {
|
|
101
|
+
throw new Error(`Failed to parse ${wf}: ${messageFrom(caughtYamlParseError)}`);
|
|
102
|
+
}
|
|
103
|
+
if (doc === null || doc === void 0) throw new Error(`${wf} must define a mapping at the document root`);
|
|
104
|
+
return {
|
|
105
|
+
exists: true,
|
|
106
|
+
doc
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* @since 0.3.16-canary.0
|
|
111
|
+
*/
|
|
112
|
+
async function listWorkspacePackageDirectories(rootDirectoryPathAbsolute, fs, suppressGlobPermissionDiagnostics) {
|
|
113
|
+
const workspaceYaml = await readWorkspaceYaml(rootDirectoryPathAbsolute, fs);
|
|
114
|
+
const defInc = defaultIncludePatterns;
|
|
115
|
+
let include;
|
|
116
|
+
let exclude;
|
|
117
|
+
let layoutSource;
|
|
118
|
+
const hasPnpmWorkspaceYamlFile = workspaceYaml.exists;
|
|
119
|
+
if (!workspaceYaml.exists) {
|
|
120
|
+
include = [...defInc];
|
|
121
|
+
exclude = [];
|
|
122
|
+
layoutSource = "default-patterns";
|
|
123
|
+
} else {
|
|
124
|
+
const parsed = parsePnpmWorkspaceDocument(workspaceYaml.doc);
|
|
125
|
+
if (!parsed.hasPackagesKey) {
|
|
126
|
+
include = [...defInc];
|
|
127
|
+
exclude = [];
|
|
128
|
+
layoutSource = "default-patterns";
|
|
129
|
+
} else if (parsed.isEmptyPackagesArray) return {
|
|
130
|
+
packageDirectoryPathsAbsolute: [],
|
|
131
|
+
layoutSource: "declared-empty",
|
|
132
|
+
hasPnpmWorkspaceYamlFile: true
|
|
133
|
+
};
|
|
134
|
+
else {
|
|
135
|
+
include = parsed.include;
|
|
136
|
+
exclude = parsed.exclude;
|
|
137
|
+
layoutSource = "pnpm-workspace-yaml";
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const foundRelativePosixPackageRoots = /* @__PURE__ */ new Set();
|
|
141
|
+
const globOpts = {
|
|
142
|
+
cwd: rootDirectoryPathAbsolute,
|
|
143
|
+
posix: true,
|
|
144
|
+
...path.sep === "\\" ? { windowsPathsNoEscape: true } : {}
|
|
145
|
+
};
|
|
146
|
+
for (const pattern of include) {
|
|
147
|
+
const globPat = workspacePatternToPackageJsonGlob(pattern);
|
|
148
|
+
let matches;
|
|
149
|
+
try {
|
|
150
|
+
matches = globSync(globPat, globOpts);
|
|
151
|
+
} catch (caughtGlobError) {
|
|
152
|
+
if (isGlobPermissionError(caughtGlobError)) {
|
|
153
|
+
if (!suppressGlobPermissionDiagnostics) logger.out(`⚠ Skipping workspace glob "${pattern}" (${messageFrom(caughtGlobError)})`);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
throw new Error(`Invalid workspace glob "${pattern}": ${messageFrom(caughtGlobError)}`);
|
|
157
|
+
}
|
|
158
|
+
for (const matchedPath of matches) {
|
|
159
|
+
const posix = toPosix(matchedPath);
|
|
160
|
+
const suffix = `/${packageJsonFileName}`;
|
|
161
|
+
if (!posix.endsWith(suffix)) continue;
|
|
162
|
+
const rel = posix.slice(0, -suffix.length);
|
|
163
|
+
if (!rel) continue;
|
|
164
|
+
foundRelativePosixPackageRoots.add(rel);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const excludeMatchers = exclude.map((pat) => picomatch(pat, { dot: true }));
|
|
168
|
+
const filteredRelative = [...foundRelativePosixPackageRoots].filter((rel) => !excludeMatchers.some((isMatch) => isMatch(rel)));
|
|
169
|
+
filteredRelative.sort((a, b) => a.localeCompare(b));
|
|
170
|
+
return {
|
|
171
|
+
packageDirectoryPathsAbsolute: filteredRelative.map((rel) => path.resolve(rootDirectoryPathAbsolute, rel.split("/").join(path.sep))),
|
|
172
|
+
layoutSource,
|
|
173
|
+
hasPnpmWorkspaceYamlFile
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
//#endregion
|
|
177
|
+
export { findRepoRoot, listWorkspacePackageDirectories };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
//#region src/core/workspace/typescript-walk.ts
|
|
3
|
+
const defaultSkipDirectoryNames = new Set([
|
|
4
|
+
"node_modules",
|
|
5
|
+
"dist",
|
|
6
|
+
".git",
|
|
7
|
+
".turbo",
|
|
8
|
+
".next",
|
|
9
|
+
".cache",
|
|
10
|
+
"out",
|
|
11
|
+
"build",
|
|
12
|
+
"coverage",
|
|
13
|
+
".vercel",
|
|
14
|
+
".output"
|
|
15
|
+
]);
|
|
16
|
+
/**
|
|
17
|
+
* @since 0.3.16-canary.0
|
|
18
|
+
*/
|
|
19
|
+
function walkTsxFiles(rootDirectoryPath, fs) {
|
|
20
|
+
const result = [];
|
|
21
|
+
visitTsxPaths(result, rootDirectoryPath, fs);
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
function visitTsxPaths(result, entryPath, fs) {
|
|
25
|
+
if (fs.statSync(entryPath).isDirectory()) {
|
|
26
|
+
for (const childName of fs.readdirSync(entryPath)) {
|
|
27
|
+
if (defaultSkipDirectoryNames.has(childName)) continue;
|
|
28
|
+
visitTsxPaths(result, path.join(entryPath, childName), fs);
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (entryPath.endsWith(".d.ts")) return;
|
|
33
|
+
if (entryPath.endsWith(".tsx") || entryPath.endsWith(".ts")) result.push(entryPath);
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { walkTsxFiles };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import "../core/exit-codes.mjs";
|
|
2
|
+
//#region src/mirror/cli-result.ts
|
|
3
|
+
/**
|
|
4
|
+
* @since 0.3.16-canary.0
|
|
5
|
+
*/
|
|
6
|
+
function exitCodeForMirrorSyncResult(stats) {
|
|
7
|
+
return stats.packagesErrored > 0 ? 1 : 0;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* @since 0.3.16-canary.0
|
|
11
|
+
*/
|
|
12
|
+
function formatMirrorSyncJsonOutput(stats, elapsedSeconds) {
|
|
13
|
+
return JSON.stringify({
|
|
14
|
+
schemaVersion: 1,
|
|
15
|
+
ok: stats.packagesErrored === 0,
|
|
16
|
+
elapsedSeconds,
|
|
17
|
+
stats
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { exitCodeForMirrorSyncResult, formatMirrorSyncJsonOutput };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
//#region src/
|
|
2
|
+
//#region src/mirror/cli-schema.ts
|
|
3
|
+
/**
|
|
4
|
+
* @since 0.3.16-canary.0
|
|
5
|
+
*/
|
|
3
6
|
const mirrorSyncRunRequestSchema = z.object({
|
|
4
7
|
rootDir: z.string().min(1),
|
|
5
|
-
verbose: z.boolean().optional(),
|
|
6
|
-
noColor: z.boolean().optional(),
|
|
7
|
-
json: z.boolean().optional(),
|
|
8
8
|
packageFilter: z.string().optional(),
|
|
9
9
|
config: z.unknown().optional()
|
|
10
10
|
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { parseWithSchema } from "../core/schema-parse.mjs";
|
|
2
|
+
import { logger } from "../core/logger.mjs";
|
|
3
|
+
import { consumeCliAppError } from "../core/cli/result-handle.mjs";
|
|
4
|
+
import { nodeFilesystem } from "../core/filesystem/node.mjs";
|
|
5
|
+
import { readOptionalPositionalArg } from "../core/cli/positional.mjs";
|
|
6
|
+
import { globalCliCommanderOptionsSchema } from "../core/cli/global-options.mjs";
|
|
7
|
+
import { prepareMirrorSync } from "./prepare.mjs";
|
|
8
|
+
import { runMirrorSync } from "./sync.mjs";
|
|
9
|
+
import { mirrorSyncRunRequestSchema } from "./cli-schema.mjs";
|
|
10
|
+
import { exitCodeForMirrorSyncResult, formatMirrorSyncJsonOutput } from "./cli-result.mjs";
|
|
11
|
+
import { MirrorSyncProgressPresenter } from "./output.mjs";
|
|
12
|
+
import process from "node:process";
|
|
13
|
+
import { Command } from "commander";
|
|
14
|
+
//#region src/mirror/command.ts
|
|
15
|
+
/**
|
|
16
|
+
* @since 0.3.16-canary.0
|
|
17
|
+
*/
|
|
18
|
+
function createMirrorCommand() {
|
|
19
|
+
const cmd = new Command("mirror").description("Keep package manifests aligned with what you ship");
|
|
20
|
+
cmd.command("sync").description("Write package.json exports from dist/ for workspace packages").argument("[package]", "Optional package path relative to repo root (e.g. packages/ui)").option("-v, --verbose", "Print extra diagnostics", false).option("--json", "Print one JSON summary on stdout (suppresses human progress)", false).action(async (packageArg, opts, command) => {
|
|
21
|
+
const globalOptionsOutcome = parseWithSchema(globalCliCommanderOptionsSchema, command.optsWithGlobals?.() ?? command.opts());
|
|
22
|
+
if (!consumeCliAppError(globalOptionsOutcome)) return;
|
|
23
|
+
const prelude = await prepareMirrorSync(nodeFilesystem, {
|
|
24
|
+
currentWorkingDirectory: process.cwd(),
|
|
25
|
+
packageArg: readOptionalPositionalArg(packageArg),
|
|
26
|
+
globals: globalOptionsOutcome.value
|
|
27
|
+
});
|
|
28
|
+
if (!consumeCliAppError(prelude)) return;
|
|
29
|
+
const { rootDir, config, packageFilter } = prelude.value;
|
|
30
|
+
const parsed = parseWithSchema(mirrorSyncRunRequestSchema, {
|
|
31
|
+
rootDir,
|
|
32
|
+
config: config.mirror ?? {},
|
|
33
|
+
packageFilter
|
|
34
|
+
});
|
|
35
|
+
if (!consumeCliAppError(parsed)) return;
|
|
36
|
+
const json = !!opts.json;
|
|
37
|
+
const noColor = globalOptionsOutcome.value.color === false;
|
|
38
|
+
const verbose = !!opts.verbose;
|
|
39
|
+
const progressPresenter = new MirrorSyncProgressPresenter();
|
|
40
|
+
const listener = json ? void 0 : progressPresenter;
|
|
41
|
+
if (!json) progressPresenter.configure({
|
|
42
|
+
noColor,
|
|
43
|
+
verbose
|
|
44
|
+
});
|
|
45
|
+
const startTime = performance.now();
|
|
46
|
+
const outcome = await runMirrorSync(nodeFilesystem, {
|
|
47
|
+
...parsed.value,
|
|
48
|
+
listener
|
|
49
|
+
});
|
|
50
|
+
if (!consumeCliAppError(outcome)) return;
|
|
51
|
+
if (json) logger.out(formatMirrorSyncJsonOutput(outcome.value, (performance.now() - startTime) / 1e3));
|
|
52
|
+
process.exitCode = exitCodeForMirrorSyncResult(outcome.value);
|
|
53
|
+
});
|
|
54
|
+
return cmd;
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { createMirrorCommand };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { normalizePath } from "./domain/path-normalizer.mjs";
|
|
2
|
+
import { isDirentList } from "./domain/dirent-guard.mjs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
//#region src/mirror/dist-filesystem-impl.ts
|
|
5
|
+
/**
|
|
6
|
+
* @since 0.3.16-canary.0
|
|
7
|
+
*/
|
|
8
|
+
function createMirrorDistFilesystem(fs) {
|
|
9
|
+
return {
|
|
10
|
+
async listRelativeFilesRecursively(dirPath) {
|
|
11
|
+
try {
|
|
12
|
+
const raw = await fs.readdir(dirPath, {
|
|
13
|
+
recursive: true,
|
|
14
|
+
withFileTypes: true
|
|
15
|
+
});
|
|
16
|
+
if (!isDirentList(raw)) return [];
|
|
17
|
+
return raw.filter((dirent) => dirent.isFile()).map((dirent) => {
|
|
18
|
+
const fullPath = path.join(dirent.parentPath, dirent.name);
|
|
19
|
+
return normalizePath(path.relative(dirPath, fullPath));
|
|
20
|
+
});
|
|
21
|
+
} catch (caughtError) {
|
|
22
|
+
if (isKnownReadDirError(caughtError)) return [];
|
|
23
|
+
throw caughtError;
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
async isDirectoryCssOnly(distDir, dirPath) {
|
|
27
|
+
try {
|
|
28
|
+
const raw = await fs.readdir(path.join(distDir, dirPath), { withFileTypes: true });
|
|
29
|
+
if (!isDirentList(raw)) return false;
|
|
30
|
+
if (raw.length === 0) return true;
|
|
31
|
+
return raw.every((dirent) => dirent.isFile() && dirent.name.endsWith(".css"));
|
|
32
|
+
} catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function isKnownReadDirError(caughtError) {
|
|
39
|
+
return typeof caughtError === "object" && caughtError !== null && "code" in caughtError && (caughtError.code === "ENOENT" || caughtError.code === "EACCES");
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { createMirrorDistFilesystem };
|
|
@@ -1,16 +1,31 @@
|
|
|
1
|
-
//#region src/
|
|
1
|
+
//#region src/mirror/domain/constants.ts
|
|
2
|
+
/**
|
|
3
|
+
* @since 0.3.16-canary.0
|
|
4
|
+
*/
|
|
2
5
|
const DIST_DIR = "dist";
|
|
6
|
+
/**
|
|
7
|
+
* @since 0.3.16-canary.0
|
|
8
|
+
*/
|
|
3
9
|
const PACKAGE_JSON = "package.json";
|
|
10
|
+
/**
|
|
11
|
+
* @since 0.3.16-canary.0
|
|
12
|
+
*/
|
|
4
13
|
const VALID_JS_EXTENSIONS = new Set([
|
|
5
14
|
".js",
|
|
6
15
|
".mjs",
|
|
7
16
|
".cjs"
|
|
8
17
|
]);
|
|
18
|
+
/**
|
|
19
|
+
* @since 0.3.16-canary.0
|
|
20
|
+
*/
|
|
9
21
|
const VALID_DTS_EXTENSIONS = new Set([
|
|
10
22
|
".d.ts",
|
|
11
23
|
".d.mts",
|
|
12
24
|
".d.cts"
|
|
13
25
|
]);
|
|
26
|
+
/**
|
|
27
|
+
* @since 0.3.16-canary.0
|
|
28
|
+
*/
|
|
14
29
|
const PACKAGE_JSON_EXPORT = "./package.json";
|
|
15
30
|
//#endregion
|
|
16
31
|
export { DIST_DIR, PACKAGE_JSON, PACKAGE_JSON_EXPORT, VALID_DTS_EXTENSIONS, VALID_JS_EXTENSIONS };
|
package/dist/{lib/mirror/infrastructure/dirent-list.guard.mjs → mirror/domain/dirent-guard.mjs}
RENAMED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
//#region src/
|
|
1
|
+
//#region src/mirror/domain/dirent-guard.ts
|
|
2
2
|
/**
|
|
3
3
|
* Narrow `fs.promises.readdir` overload result to `Dirent[]` when `withFileTypes: true`.
|
|
4
4
|
* Accepts both historical checks (`isFile` / `isDirectory`) in one guard.
|
|
5
5
|
* Returning `true` for an empty array is intentional: callers treat empty lists
|
|
6
6
|
* the same regardless of the element type, so `[]` is safely accepted as `Dirent[]`.
|
|
7
|
-
|
|
7
|
+
*
|
|
8
|
+
* @since 0.3.16-canary.0
|
|
9
|
+
*/
|
|
10
|
+
function isDirentList(x) {
|
|
8
11
|
if (x.length === 0) return true;
|
|
9
12
|
const first = x[0];
|
|
10
13
|
return typeof first === "object" && first !== null && "isFile" in first && "isDirectory" in first;
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
//#region src/
|
|
1
|
+
//#region src/mirror/domain/errors.ts
|
|
2
|
+
/**
|
|
3
|
+
* @since 0.3.16-canary.0
|
|
4
|
+
*/
|
|
2
5
|
const MirrorErrorCode = {
|
|
3
6
|
FATAL: "FATAL",
|
|
4
7
|
PACKAGE_WRITE: "PACKAGE_WRITE"
|
|
5
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* @since 0.3.16-canary.0
|
|
11
|
+
*/
|
|
6
12
|
var MirrorError = class extends Error {
|
|
7
13
|
code;
|
|
8
14
|
constructor(code, message, options) {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { PACKAGE_JSON_EXPORT, VALID_DTS_EXTENSIONS, VALID_JS_EXTENSIONS } from "
|
|
2
|
-
|
|
1
|
+
import { PACKAGE_JSON_EXPORT, VALID_DTS_EXTENSIONS, VALID_JS_EXTENSIONS } from "./constants.mjs";
|
|
2
|
+
import * as nodePath from "node:path";
|
|
3
|
+
//#region src/mirror/domain/exports.ts
|
|
3
4
|
function resolvePackageScopedConfig(configMap, pkgMeta) {
|
|
4
5
|
if (!configMap) return;
|
|
5
6
|
return configMap[pkgMeta.packageName];
|
|
6
7
|
}
|
|
7
|
-
function groupFilesByModule(files
|
|
8
|
+
function groupFilesByModule(files) {
|
|
8
9
|
const modules = /* @__PURE__ */ new Map();
|
|
9
10
|
for (const file of files) {
|
|
10
11
|
let ext;
|
|
@@ -14,11 +15,11 @@ function groupFilesByModule(files, pathService) {
|
|
|
14
15
|
ext = dtsExt;
|
|
15
16
|
modulePath = file.slice(0, -dtsExt.length);
|
|
16
17
|
} else {
|
|
17
|
-
ext =
|
|
18
|
+
ext = nodePath.extname(file);
|
|
18
19
|
if (!VALID_JS_EXTENSIONS.has(ext)) continue;
|
|
19
20
|
modulePath = file.slice(0, -ext.length);
|
|
20
21
|
}
|
|
21
|
-
if (!
|
|
22
|
+
if (!nodePath.basename(modulePath)) continue;
|
|
22
23
|
let distModule = modules.get(modulePath);
|
|
23
24
|
if (!distModule) {
|
|
24
25
|
distModule = {
|
|
@@ -103,6 +104,9 @@ function getExportGroup(exportPath, pathTransform) {
|
|
|
103
104
|
1
|
|
104
105
|
];
|
|
105
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* @since 0.3.16-canary.0
|
|
109
|
+
*/
|
|
106
110
|
function createPathTransform(config, pkgMeta) {
|
|
107
111
|
const pathConfig = resolvePackageScopedConfig(config?.pathTransformations, pkgMeta);
|
|
108
112
|
if (!pathConfig) return null;
|
|
@@ -131,7 +135,7 @@ function compareTuples(left, right) {
|
|
|
131
135
|
if (left[3] !== right[3]) return left[3] < right[3] ? -1 : 1;
|
|
132
136
|
return 0;
|
|
133
137
|
}
|
|
134
|
-
async function generateCssExports(
|
|
138
|
+
async function generateCssExports(fileSystemService, distDir, cssConfig) {
|
|
135
139
|
if (cssConfig === false) return {};
|
|
136
140
|
if (cssConfig === true) cssConfig = { enabled: true };
|
|
137
141
|
if (!cssConfig || cssConfig.enabled === false) return {};
|
|
@@ -141,7 +145,7 @@ async function generateCssExports(pathService, fileSystemService, distDir, cssCo
|
|
|
141
145
|
const cssByDir = /* @__PURE__ */ new Map();
|
|
142
146
|
const rootCss = [];
|
|
143
147
|
for (const file of cssFiles) {
|
|
144
|
-
const dirName =
|
|
148
|
+
const dirName = nodePath.dirname(file).split(nodePath.sep).join("/");
|
|
145
149
|
if (dirName === ".") rootCss.push(file);
|
|
146
150
|
else {
|
|
147
151
|
const arr = cssByDir.get(dirName) || [];
|
|
@@ -164,7 +168,10 @@ async function generateCssExports(pathService, fileSystemService, distDir, cssCo
|
|
|
164
168
|
}
|
|
165
169
|
/**
|
|
166
170
|
* Compute `package.json#exports` from a built `dist/` tree. No logging; no writes.
|
|
167
|
-
|
|
171
|
+
*
|
|
172
|
+
* @since 0.3.16-canary.0
|
|
173
|
+
*/
|
|
174
|
+
async function generateExports(fileSystemService, distDir, pathTransform, cssConfig, customExports) {
|
|
168
175
|
const files = await fileSystemService.listRelativeFilesRecursively(distDir);
|
|
169
176
|
if (!files.length) return {
|
|
170
177
|
exports: { [PACKAGE_JSON_EXPORT]: PACKAGE_JSON_EXPORT },
|
|
@@ -172,7 +179,7 @@ async function generateCssExports(pathService, fileSystemService, distDir, cssCo
|
|
|
172
179
|
jsCount: 0,
|
|
173
180
|
cssCount: 0
|
|
174
181
|
};
|
|
175
|
-
const modules = groupFilesByModule(files
|
|
182
|
+
const modules = groupFilesByModule(files);
|
|
176
183
|
const validModules = Array.from(modules.values()).filter((moduleEntry) => (moduleEntry.files.js || moduleEntry.files.mjs) && moduleEntry.files.dts);
|
|
177
184
|
if (!validModules.length) return {
|
|
178
185
|
exports: { [PACKAGE_JSON_EXPORT]: PACKAGE_JSON_EXPORT },
|
|
@@ -198,7 +205,7 @@ async function generateCssExports(pathService, fileSystemService, distDir, cssCo
|
|
|
198
205
|
let sortedKeys = Object.keys(exportsObj).sort((pathA, pathB) => compareTuples(getSortTuple(pathA, pathTransform), getSortTuple(pathB, pathTransform)));
|
|
199
206
|
const sortedExports = {};
|
|
200
207
|
for (const exportKey of sortedKeys) sortedExports[exportKey] = exportsObj[exportKey];
|
|
201
|
-
const cssExports = await generateCssExports(
|
|
208
|
+
const cssExports = await generateCssExports(fileSystemService, distDir, cssConfig ?? { enabled: true });
|
|
202
209
|
Object.assign(sortedExports, cssExports);
|
|
203
210
|
for (const [specifier, mappedPath] of Object.entries(customExports || {})) if (specifier !== "./package.json") sortedExports[specifier] = mappedPath;
|
|
204
211
|
for (const cssSpecifier of Object.keys(cssExports)) if (!(cssSpecifier in originalPathBySpecifier)) originalPathBySpecifier[cssSpecifier] = cssSpecifier;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
//#region src/
|
|
1
|
+
//#region src/mirror/domain/package-display-name.ts
|
|
2
2
|
/**
|
|
3
3
|
* Domain rule: prefer `package.json#name` when it is present, otherwise use folder basename.
|
|
4
|
-
|
|
4
|
+
*
|
|
5
|
+
* @since 0.3.16-canary.0
|
|
6
|
+
*/
|
|
7
|
+
function resolvePackageDisplayName(packageJson, folderBasename) {
|
|
5
8
|
const declaredName = packageJson.name;
|
|
6
9
|
return typeof declaredName === "string" && declaredName.length > 0 ? declaredName : folderBasename;
|
|
7
10
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
//#region src/
|
|
2
|
+
//#region src/mirror/domain/path-normalizer.ts
|
|
3
|
+
/**
|
|
4
|
+
* @since 0.3.16-canary.0
|
|
5
|
+
*/
|
|
3
6
|
function normalizePath(pathString) {
|
|
4
7
|
return pathString.split(path.sep).join("/").replace(/\\/g, "/");
|
|
5
8
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { logger } from "../core/logger.mjs";
|
|
2
|
+
import { MirrorSyncReporter } from "./sync-reporter.mjs";
|
|
3
|
+
//#region src/mirror/output.ts
|
|
4
|
+
const cliLogger = logger;
|
|
5
|
+
/**
|
|
6
|
+
* @since 0.3.16-canary.0
|
|
7
|
+
*/
|
|
8
|
+
var MirrorSyncProgressPresenter = class {
|
|
9
|
+
reporter = new MirrorSyncReporter();
|
|
10
|
+
verbose = false;
|
|
11
|
+
configure(options) {
|
|
12
|
+
this.verbose = options.verbose;
|
|
13
|
+
this.reporter.configureMirrorColors(options.noColor);
|
|
14
|
+
}
|
|
15
|
+
onBanner() {
|
|
16
|
+
this.reporter.mirrorBanner(cliLogger);
|
|
17
|
+
}
|
|
18
|
+
onProcessingMode(mode) {
|
|
19
|
+
this.reporter.mirrorProcessingMode(cliLogger, mode);
|
|
20
|
+
}
|
|
21
|
+
onNoPackages() {
|
|
22
|
+
this.reporter.mirrorNoPackages(cliLogger);
|
|
23
|
+
}
|
|
24
|
+
onPackageComplete(pkgStats, ordinal, total) {
|
|
25
|
+
if (pkgStats.skipped) {
|
|
26
|
+
this.reporter.logSkippedWorkspacePackage(cliLogger, ordinal, total, pkgStats.name, pkgStats.skipReason);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (pkgStats.error !== null) {
|
|
30
|
+
this.reporter.logPackageError(cliLogger, ordinal, total, pkgStats.name, pkgStats.error, this.verbose);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
for (const exportSpecifier of pkgStats.prunedExportKeys) this.reporter.logPrunedStaleExport(cliLogger, exportSpecifier);
|
|
34
|
+
this.reporter.logPackageSuccess(cliLogger, ordinal, total, pkgStats, {
|
|
35
|
+
jsCount: pkgStats.jsModules,
|
|
36
|
+
cssCount: pkgStats.cssExports
|
|
37
|
+
}, this.verbose);
|
|
38
|
+
}
|
|
39
|
+
onComplete(stats, elapsedSeconds) {
|
|
40
|
+
this.reporter.mirrorSummarySeparator(cliLogger);
|
|
41
|
+
this.reporter.mirrorSummary(cliLogger, stats, elapsedSeconds);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
export { MirrorSyncProgressPresenter };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { AppError } from "../core/errors.mjs";
|
|
2
|
+
import { err, ok } from "../core/result.mjs";
|
|
3
|
+
import { normalizePath } from "./domain/path-normalizer.mjs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
//#region src/mirror/package-path.ts
|
|
6
|
+
/**
|
|
7
|
+
* @since 0.3.16-canary.0
|
|
8
|
+
*/
|
|
9
|
+
function resolveMirrorPackageFromCliArg(fs, args) {
|
|
10
|
+
const { rootDir, packageArg, currentWorkingDirectory } = args;
|
|
11
|
+
if (!packageArg) return ok(void 0);
|
|
12
|
+
const rootReal = fs.canonicalPathSync(path.resolve(rootDir));
|
|
13
|
+
const cwdReal = fs.canonicalPathSync(currentWorkingDirectory);
|
|
14
|
+
const resolved = path.isAbsolute(packageArg) ? path.resolve(packageArg) : path.resolve(cwdReal, packageArg);
|
|
15
|
+
const targetReal = fs.canonicalPathSync(resolved);
|
|
16
|
+
const normalized = normalizePath(path.relative(rootReal, targetReal));
|
|
17
|
+
if (normalized.startsWith("..") || path.isAbsolute(normalized) || normalized === "" || normalized === ".") return err(new AppError("VALIDATION_ERROR", `Package path must be a subdirectory under monorepo root: ${rootDir}`));
|
|
18
|
+
return ok(normalized);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @since 0.3.16-canary.0
|
|
22
|
+
*/
|
|
23
|
+
function resolvePackageFilterUnderRoot(fs, rootDir, packageFilter) {
|
|
24
|
+
const rootResolved = path.resolve(rootDir);
|
|
25
|
+
const rootReal = fs.canonicalPathSync(rootResolved);
|
|
26
|
+
const resolved = path.isAbsolute(packageFilter) ? fs.canonicalPathSync(path.resolve(packageFilter)) : fs.canonicalPathSync(path.join(rootReal, packageFilter));
|
|
27
|
+
const normalized = normalizePath(path.relative(rootReal, resolved));
|
|
28
|
+
if (normalized.startsWith("..") || path.isAbsolute(normalized) || normalized === "" || normalized === ".") return err(new AppError("VALIDATION_ERROR", `Package path must be a subdirectory under monorepo root: ${rootDir}`));
|
|
29
|
+
return ok(normalized);
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { resolveMirrorPackageFromCliArg, resolvePackageFilterUnderRoot };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { AppError, messageFrom } from "../core/errors.mjs";
|
|
2
|
+
import { err, ok } from "../core/result.mjs";
|
|
3
|
+
import { loadCodefastConfig } from "../core/config.mjs";
|
|
4
|
+
import { findRepoRoot } from "../core/workspace/resolver.mjs";
|
|
5
|
+
import { resolveMirrorPackageFromCliArg } from "./package-path.mjs";
|
|
6
|
+
//#region src/mirror/prepare.ts
|
|
7
|
+
/**
|
|
8
|
+
* @since 0.3.16-canary.0
|
|
9
|
+
*/
|
|
10
|
+
async function prepareMirrorSync(fs, args) {
|
|
11
|
+
let rootDir;
|
|
12
|
+
try {
|
|
13
|
+
rootDir = findRepoRoot(args.currentWorkingDirectory, fs);
|
|
14
|
+
} catch (caughtError) {
|
|
15
|
+
return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
|
|
16
|
+
}
|
|
17
|
+
const filterOutcome = resolveMirrorPackageFromCliArg(fs, {
|
|
18
|
+
rootDir,
|
|
19
|
+
packageArg: args.packageArg,
|
|
20
|
+
currentWorkingDirectory: args.currentWorkingDirectory
|
|
21
|
+
});
|
|
22
|
+
if (!filterOutcome.ok) return filterOutcome;
|
|
23
|
+
const loadedOutcome = await loadCodefastConfig(rootDir, fs);
|
|
24
|
+
if (!loadedOutcome.ok) return loadedOutcome;
|
|
25
|
+
return ok({
|
|
26
|
+
globals: args.globals,
|
|
27
|
+
rootDir,
|
|
28
|
+
config: loadedOutcome.value.config,
|
|
29
|
+
packageFilter: filterOutcome.value
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { prepareMirrorSync };
|