@codefast/cli 0.8.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +596 -0
- package/LICENSE +1 -1
- package/README.md +335 -129
- package/dist/arrange/analyze.d.ts +10 -0
- package/dist/arrange/cli-schema.d.ts +50 -0
- package/dist/arrange/command.d.ts +7 -0
- package/dist/arrange/domain/analyze-service.d.ts +18 -0
- 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/targets.d.ts +20 -0
- 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/output.d.ts +26 -0
- package/dist/arrange/process-file.d.ts +11 -0
- 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-process-file.d.ts +11 -0
- package/dist/arrange/simplify-sync.d.ts +13 -0
- package/dist/arrange/source-parse.d.ts +7 -0
- package/dist/arrange/suggest.d.ts +8 -0
- package/dist/arrange/sync.d.ts +11 -0
- package/dist/arrange/typescript-ast-translator.d.ts +31 -0
- package/dist/arrange/workspace.d.ts +13 -0
- package/dist/arrange/workspace.js +2 -2
- package/dist/audit/cli-schema.d.ts +93 -0
- package/dist/audit/cli-schema.js +14 -3
- package/dist/audit/command.d.ts +8 -0
- package/dist/audit/command.js +52 -12
- package/dist/audit/domain/audit-file.d.ts +7 -0
- package/dist/audit/domain/comment-content.d.ts +26 -0
- package/dist/audit/domain/comment-dividers.d.ts +62 -0
- package/dist/audit/domain/comment-dividers.js +48 -20
- package/dist/audit/domain/display-names.d.ts +11 -0
- package/dist/audit/domain/display-names.js +71 -0
- package/dist/audit/domain/import-policy.d.ts +34 -0
- package/dist/audit/domain/import-policy.js +147 -0
- package/dist/audit/domain/link-references.d.ts +40 -0
- package/dist/audit/domain/mappings.d.ts +45 -0
- package/dist/audit/domain/markdown-links.d.ts +44 -0
- package/dist/audit/domain/since-versions.d.ts +26 -0
- package/dist/audit/domain/tokenize.d.ts +14 -0
- package/dist/audit/domain/tsdoc-syntax.d.ts +20 -0
- package/dist/audit/domain/types.d.ts +171 -0
- package/dist/audit/output.d.ts +91 -0
- package/dist/audit/output.js +52 -11
- package/dist/audit/prepare.d.ts +70 -0
- package/dist/audit/prepare.js +41 -10
- package/dist/audit/run-comments.d.ts +17 -0
- package/dist/audit/run-comments.js +22 -18
- package/dist/audit/run-display-names.d.ts +14 -0
- package/dist/audit/run-display-names.js +60 -0
- package/dist/audit/run-imports.d.ts +14 -0
- package/dist/audit/{run-react.js → run-imports.js} +15 -5
- package/dist/audit/run-links.d.ts +14 -0
- package/dist/audit/run.d.ts +14 -0
- package/dist/bin.d.ts +2 -0
- package/dist/cli.d.ts +6 -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/positional.d.ts +6 -0
- package/dist/core/cli/result-handle.d.ts +19 -0
- 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 +7 -75
- 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/node.d.ts +7 -0
- package/dist/core/filesystem/node.js +1 -0
- package/dist/core/filesystem/port.d.ts +44 -0
- 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 +33 -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 +14 -20
- 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/command.d.ts +7 -0
- package/dist/mirror/dist-filesystem-impl.d.ts +8 -0
- 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 +131 -0
- package/dist/mirror/output.d.ts +23 -0
- package/dist/mirror/package-path.d.ts +19 -0
- package/dist/mirror/prepare.d.ts +15 -0
- package/dist/mirror/prepare.js +2 -2
- package/dist/mirror/supplement-exports.d.ts +27 -0
- package/dist/mirror/supplement-exports.js +2 -2
- package/dist/mirror/sync-reporter.d.ts +60 -0
- package/dist/mirror/sync-reporter.js +4 -0
- package/dist/mirror/sync-types.d.ts +43 -0
- package/dist/mirror/sync-workspace-package.d.ts +9 -0
- package/dist/mirror/sync-workspace-package.js +3 -3
- package/dist/mirror/sync.d.ts +12 -0
- package/dist/mirror/sync.js +5 -3
- 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/command.d.ts +7 -0
- package/dist/pack-slim/command.js +5 -4
- package/dist/pack-slim/domain/transform.d.ts +69 -0
- package/dist/pack-slim/domain/transform.js +141 -15
- package/dist/pack-slim/domain/types.d.ts +46 -0
- package/dist/pack-slim/output.d.ts +15 -0
- package/dist/pack-slim/output.js +10 -1
- package/dist/pack-slim/sync.d.ts +23 -0
- package/dist/pack-slim/sync.js +14 -8
- package/dist/pack-slim/working-tree.d.ts +20 -0
- package/dist/tag/cli-result.d.ts +7 -0
- package/dist/tag/cli-schema.d.ts +8 -0
- package/dist/tag/command.d.ts +7 -0
- package/dist/tag/domain/types.d.ts +111 -0
- package/dist/tag/output.d.ts +17 -0
- package/dist/tag/prepare.d.ts +13 -0
- package/dist/tag/prepare.js +2 -2
- package/dist/tag/resolve-target-path.d.ts +10 -0
- package/dist/tag/since-writer.d.ts +32 -0
- package/dist/tag/sync.d.ts +42 -0
- package/dist/tag/target-candidates.d.ts +8 -0
- package/dist/tag/target-candidates.js +1 -1
- package/dist/tag/target-runner.d.ts +8 -0
- package/dist/tag/version-resolver.d.ts +7 -0
- package/package.json +16 -33
- package/dist/audit/domain/react-imports.js +0 -91
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* A config hook invoked with the written file paths after a command rewrites files.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.3.16-canary.0
|
|
6
|
+
*/
|
|
7
|
+
export type CodefastAfterWriteHook = (context: {
|
|
8
|
+
files: Array<string>;
|
|
9
|
+
}) => void | Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* CSS export configuration for a mirrored package — a flag, or per-file overrides.
|
|
12
|
+
*/
|
|
13
|
+
type MirrorCssConfig = boolean | {
|
|
14
|
+
enabled?: boolean | undefined;
|
|
15
|
+
customExports?: Record<string, string> | undefined;
|
|
16
|
+
forceExportFiles?: boolean | undefined;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Per-package mirror configuration. Setting a package to `false` skips it entirely.
|
|
20
|
+
*/
|
|
21
|
+
interface MirrorPackageConfig {
|
|
22
|
+
/** Preserve the existing `package.json#exports` map and only add missing conditions
|
|
23
|
+
* (`source`, `types`, `import`); no `dist/` scan is performed. */
|
|
24
|
+
preserve?: boolean | undefined;
|
|
25
|
+
strip?: string | undefined;
|
|
26
|
+
/** Specifiers to leave out of the generated map, so a package's public surface is a decision
|
|
27
|
+
* rather than a consequence of its `dist/` layout. Matched against the specifier as it would
|
|
28
|
+
* appear in `exports` (after `strip`); a trailing `/*` excludes a whole subtree. The root
|
|
29
|
+
* export and `./package.json` are never excluded. */
|
|
30
|
+
exclude?: Array<string> | undefined;
|
|
31
|
+
exports?: Record<string, string> | undefined;
|
|
32
|
+
/** All three default to `true`; the mirror resolves an omitted value the same as `true`. */
|
|
33
|
+
source?: boolean | string | undefined;
|
|
34
|
+
types?: boolean | undefined;
|
|
35
|
+
import?: boolean | undefined;
|
|
36
|
+
css?: MirrorCssConfig | undefined;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The validated `mirror` configuration, keyed by package name.
|
|
40
|
+
*
|
|
41
|
+
* @since 0.3.16-canary.0
|
|
42
|
+
*/
|
|
43
|
+
export type MirrorConfig = Record<string, false | MirrorPackageConfig>;
|
|
44
|
+
/**
|
|
45
|
+
* The validated `tag` command configuration.
|
|
46
|
+
*
|
|
47
|
+
* @since 0.3.16-canary.0
|
|
48
|
+
*/
|
|
49
|
+
export interface CodefastTagConfig {
|
|
50
|
+
skipPackages?: Array<string> | undefined;
|
|
51
|
+
onAfterWrite?: CodefastAfterWriteHook | undefined;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The validated `arrange` command configuration.
|
|
55
|
+
*
|
|
56
|
+
* @since 0.3.16-canary.0
|
|
57
|
+
*/
|
|
58
|
+
export interface CodefastArrangeConfig {
|
|
59
|
+
onAfterWrite?: CodefastAfterWriteHook | undefined;
|
|
60
|
+
}
|
|
61
|
+
/** An audit's per-command defaults: entries to ignore, as bare tokens or `repo/relative/path:token`. */
|
|
62
|
+
interface CodefastAuditAllowlistConfig {
|
|
63
|
+
allowlist?: Array<string> | undefined;
|
|
64
|
+
}
|
|
65
|
+
/** Per-audit defaults grouped under `audit`; the scan always starts at the repo root. */
|
|
66
|
+
interface CodefastAuditConfig {
|
|
67
|
+
rtl?: {
|
|
68
|
+
target?: string | undefined;
|
|
69
|
+
allowlist?: Array<string> | undefined;
|
|
70
|
+
} | undefined;
|
|
71
|
+
links?: CodefastAuditAllowlistConfig | undefined;
|
|
72
|
+
comments?: CodefastAuditAllowlistConfig | undefined;
|
|
73
|
+
imports?: CodefastAuditAllowlistConfig | undefined;
|
|
74
|
+
displayNames?: CodefastAuditAllowlistConfig | undefined;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The validated root `codefast.config` shape.
|
|
78
|
+
*
|
|
79
|
+
* @since 0.3.16-canary.0
|
|
80
|
+
*/
|
|
81
|
+
export interface CodefastConfig {
|
|
82
|
+
mirror?: MirrorConfig | undefined;
|
|
83
|
+
tag?: CodefastTagConfig | undefined;
|
|
84
|
+
arrange?: CodefastArrangeConfig | undefined;
|
|
85
|
+
audit?: CodefastAuditConfig | undefined;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Zod validator for the `mirror` configuration record; its output is a {@link MirrorConfig}.
|
|
89
|
+
*
|
|
90
|
+
* @since 0.3.16-canary.0
|
|
91
|
+
*/
|
|
92
|
+
export declare const mirrorConfigSchema: z.ZodType<MirrorConfig>;
|
|
93
|
+
/**
|
|
94
|
+
* Zod validator for a raw `codefast.config` object; its output is a {@link CodefastConfig}.
|
|
95
|
+
*
|
|
96
|
+
* @since 0.3.16-canary.0
|
|
97
|
+
*/
|
|
98
|
+
export declare const codefastConfigRootSchema: z.ZodType<CodefastConfig>;
|
|
99
|
+
export {};
|
|
@@ -12,27 +12,10 @@ const mirrorCssConfigSchema = z.union([
|
|
|
12
12
|
})
|
|
13
13
|
.strict(),
|
|
14
14
|
]);
|
|
15
|
-
/**
|
|
16
|
-
* Per-package mirror configuration. Setting a package to `false` skips it entirely.
|
|
17
|
-
*
|
|
18
|
-
* - `source` — include a `source` condition pointing to the original `.ts` file (default `true`).
|
|
19
|
-
* Pass a string to override the root-export source path explicitly.
|
|
20
|
-
* - `types` — include the `types` condition when `.d.ts` files exist (default `true`).
|
|
21
|
-
* - `import` — include the `import` condition (default `true`).
|
|
22
|
-
* - `css` — CSS export configuration (wildcard or per-file).
|
|
23
|
-
*
|
|
24
|
-
* @since 0.3.16-canary.0
|
|
25
|
-
*/
|
|
26
15
|
const mirrorPackageConfigSchema = z
|
|
27
16
|
.object({
|
|
28
|
-
/** Preserve the existing `package.json#exports` map and only add missing conditions
|
|
29
|
-
* (`source`, `types`, `import`). No dist/ scan is performed. */
|
|
30
17
|
preserve: z.boolean().optional(),
|
|
31
18
|
strip: z.string().optional(),
|
|
32
|
-
/** Specifiers to leave out of the generated map, so a package's public surface is a decision
|
|
33
|
-
* rather than a consequence of its `dist/` layout. Matched against the specifier as it would
|
|
34
|
-
* appear in `exports` (after `strip`); a trailing `/*` excludes a whole subtree. The root
|
|
35
|
-
* export and `./package.json` are never excluded. */
|
|
36
19
|
exclude: z.array(z.string()).optional(),
|
|
37
20
|
exports: z.record(z.string(), z.string()).optional(),
|
|
38
21
|
source: z.union([z.boolean(), z.string()]).default(true),
|
|
@@ -42,95 +25,44 @@ const mirrorPackageConfigSchema = z
|
|
|
42
25
|
})
|
|
43
26
|
.strict();
|
|
44
27
|
/**
|
|
45
|
-
*
|
|
46
|
-
* omit it entirely to process it with default settings.
|
|
28
|
+
* Zod validator for the `mirror` configuration record; its output is a {@link MirrorConfig}.
|
|
47
29
|
*
|
|
48
30
|
* @since 0.3.16-canary.0
|
|
49
31
|
*/
|
|
50
32
|
export const mirrorConfigSchema = z.record(z.string(), z.union([z.literal(false), mirrorPackageConfigSchema]));
|
|
51
|
-
/**
|
|
52
|
-
* Zod schema for the `tag` command's configuration.
|
|
53
|
-
*
|
|
54
|
-
* @since 0.3.16-canary.0
|
|
55
|
-
*/
|
|
56
33
|
const codefastTagConfigSchema = z
|
|
57
34
|
.object({
|
|
58
35
|
skipPackages: z.array(z.string()).optional(),
|
|
59
36
|
onAfterWrite: afterWriteHookSchema.optional(),
|
|
60
37
|
})
|
|
61
38
|
.strict();
|
|
62
|
-
/**
|
|
63
|
-
* Zod schema for the `arrange` command's configuration.
|
|
64
|
-
*
|
|
65
|
-
* @since 0.3.16-canary.0
|
|
66
|
-
*/
|
|
67
39
|
const codefastArrangeConfigSchema = z
|
|
68
40
|
.object({
|
|
69
41
|
onAfterWrite: afterWriteHookSchema.optional(),
|
|
70
42
|
})
|
|
71
43
|
.strict();
|
|
72
|
-
/**
|
|
73
|
-
* RTL audit defaults — `target` is relative to the repo root (where `codefast.config` lives).
|
|
74
|
-
*
|
|
75
|
-
* @since 0.3.16-canary.0
|
|
76
|
-
*/
|
|
77
44
|
const codefastAuditRtlConfigSchema = z
|
|
78
45
|
.object({
|
|
79
|
-
/** Directory or file to scan when no CLI target is passed. */
|
|
80
46
|
target: z.string().optional(),
|
|
81
|
-
/** Bare class tokens or `repo/relative/path.tsx:token` entries to ignore. */
|
|
82
|
-
allowlist: z.array(z.string()).optional(),
|
|
83
|
-
})
|
|
84
|
-
.strict();
|
|
85
|
-
/**
|
|
86
|
-
* Link audit defaults — the scan always starts at the repo root, so only exceptions are configured.
|
|
87
|
-
*
|
|
88
|
-
* @since 0.5.0
|
|
89
|
-
*/
|
|
90
|
-
const codefastAuditLinksConfigSchema = z
|
|
91
|
-
.object({
|
|
92
|
-
/** Bare link targets or `repo/relative/doc.md:target` entries to ignore. */
|
|
93
47
|
allowlist: z.array(z.string()).optional(),
|
|
94
48
|
})
|
|
95
49
|
.strict();
|
|
96
|
-
|
|
97
|
-
* Comment-divider audit defaults — the scan always starts at the repo root, so only exceptions are configured.
|
|
98
|
-
*
|
|
99
|
-
* @since 0.6.0
|
|
100
|
-
*/
|
|
101
|
-
const codefastAuditCommentsConfigSchema = z
|
|
50
|
+
const codefastAuditAllowlistConfigSchema = z
|
|
102
51
|
.object({
|
|
103
|
-
/** Divider lines as written, or `repo/relative/path.ts:<divider>` entries, to ignore. */
|
|
104
52
|
allowlist: z.array(z.string()).optional(),
|
|
105
53
|
})
|
|
106
54
|
.strict();
|
|
107
|
-
/**
|
|
108
|
-
* React import-policy audit defaults — the scan always starts at the repo root, so only
|
|
109
|
-
* exceptions are configured.
|
|
110
|
-
*
|
|
111
|
-
* @since 0.8.0
|
|
112
|
-
*/
|
|
113
|
-
const codefastAuditReactConfigSchema = z
|
|
114
|
-
.object({
|
|
115
|
-
/** Offending source text as written, or `repo/relative/path.tsx:<text>` entries, to ignore. */
|
|
116
|
-
allowlist: z.array(z.string()).optional(),
|
|
117
|
-
})
|
|
118
|
-
.strict();
|
|
119
|
-
/**
|
|
120
|
-
* Zod schema grouping the per-audit configurations under `audit`.
|
|
121
|
-
*
|
|
122
|
-
* @since 0.3.16-canary.0
|
|
123
|
-
*/
|
|
124
55
|
const codefastAuditConfigSchema = z
|
|
125
56
|
.object({
|
|
126
57
|
rtl: codefastAuditRtlConfigSchema.optional(),
|
|
127
|
-
links:
|
|
128
|
-
comments:
|
|
129
|
-
|
|
58
|
+
links: codefastAuditAllowlistConfigSchema.optional(),
|
|
59
|
+
comments: codefastAuditAllowlistConfigSchema.optional(),
|
|
60
|
+
imports: codefastAuditAllowlistConfigSchema.optional(),
|
|
61
|
+
displayNames: codefastAuditAllowlistConfigSchema.optional(),
|
|
130
62
|
})
|
|
131
63
|
.strict();
|
|
132
64
|
/**
|
|
133
|
-
*
|
|
65
|
+
* Zod validator for a raw `codefast.config` object; its output is a {@link CodefastConfig}.
|
|
134
66
|
*
|
|
135
67
|
* @since 0.3.16-canary.0
|
|
136
68
|
*/
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CodefastConfig } from "#/core/config/schema";
|
|
2
|
+
import { AppError } from "#/core/errors";
|
|
3
|
+
import type { FilesystemPort } from "#/core/filesystem/port";
|
|
4
|
+
import type { Result } from "#/core/result";
|
|
5
|
+
/**
|
|
6
|
+
* Loads the `codefast.config.js` for a workspace root, reporting schema warnings along the way.
|
|
7
|
+
*
|
|
8
|
+
* @since 0.3.16-canary.0
|
|
9
|
+
*/
|
|
10
|
+
export declare function loadCodefastConfig(rootDir: string, fs: FilesystemPort): Promise<Result<{
|
|
11
|
+
config: CodefastConfig;
|
|
12
|
+
}, AppError>>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-context application errors for Result-based flows.
|
|
3
|
+
* Does not extend the global `Error` type — instances are carried in `Result` values, not thrown.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.3.16-canary.0
|
|
6
|
+
*/
|
|
7
|
+
export type AppErrorCode = "NOT_FOUND" | "VALIDATION_ERROR" | "INFRA_FAILURE";
|
|
8
|
+
/**
|
|
9
|
+
* A coded application error carried in `Result` values rather than thrown.
|
|
10
|
+
*
|
|
11
|
+
* @since 0.3.16-canary.0
|
|
12
|
+
*/
|
|
13
|
+
export declare class AppError {
|
|
14
|
+
readonly name: "AppError";
|
|
15
|
+
readonly code: AppErrorCode;
|
|
16
|
+
readonly message: string;
|
|
17
|
+
readonly cause?: unknown;
|
|
18
|
+
constructor(code: AppErrorCode, message: string, cause?: unknown);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Stable, user-facing text for values caught as `unknown`.
|
|
22
|
+
*
|
|
23
|
+
* @since 0.3.16-canary.0
|
|
24
|
+
*/
|
|
25
|
+
export declare function messageFrom(value: unknown): string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process exit codes for the `codefast` CLI.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.3.16-canary.0
|
|
5
|
+
*/
|
|
6
|
+
export declare const CLI_EXIT_SUCCESS = 0;
|
|
7
|
+
/**
|
|
8
|
+
* The exit code for a run that failed for any reason other than bad usage.
|
|
9
|
+
*
|
|
10
|
+
* @since 0.3.16-canary.0
|
|
11
|
+
*/
|
|
12
|
+
export declare const CLI_EXIT_GENERAL_ERROR = 1;
|
|
13
|
+
/**
|
|
14
|
+
* The exit code for invalid arguments or configuration.
|
|
15
|
+
*
|
|
16
|
+
* @since 0.3.16-canary.0
|
|
17
|
+
*/
|
|
18
|
+
export declare const CLI_EXIT_USAGE = 2;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem surface for CLI flows (real implementation: {@link nodeFilesystem}).
|
|
3
|
+
*
|
|
4
|
+
* @since 0.3.16-canary.0
|
|
5
|
+
*/
|
|
6
|
+
export type CliFileEncoding = "utf8";
|
|
7
|
+
/**
|
|
8
|
+
* A directory listing entry with its name, parent path, and kind predicates.
|
|
9
|
+
*
|
|
10
|
+
* @since 0.3.16-canary.0
|
|
11
|
+
*/
|
|
12
|
+
export interface DirectoryEntry {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly parentPath: string;
|
|
15
|
+
isFile(): boolean;
|
|
16
|
+
isDirectory(): boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The filesystem operations a CLI flow depends on, swappable for tests.
|
|
20
|
+
*
|
|
21
|
+
* @since 0.3.16-canary.0
|
|
22
|
+
*/
|
|
23
|
+
export interface FilesystemPort {
|
|
24
|
+
existsSync(filePath: string): boolean;
|
|
25
|
+
canonicalPathSync(inputPath: string): string;
|
|
26
|
+
statSync(filePath: string): {
|
|
27
|
+
isDirectory(): boolean;
|
|
28
|
+
isFile(): boolean;
|
|
29
|
+
};
|
|
30
|
+
readFileSync(filePath: string, encoding: CliFileEncoding): string;
|
|
31
|
+
writeFileSync(filePath: string, data: string, encoding: CliFileEncoding): void;
|
|
32
|
+
readdirSync(filePath: string): Array<string>;
|
|
33
|
+
readFile(filePath: string, encoding: CliFileEncoding): Promise<string>;
|
|
34
|
+
writeFile(filePath: string, data: string, encoding: CliFileEncoding): Promise<void>;
|
|
35
|
+
readdir(filePath: string, options?: {
|
|
36
|
+
recursive?: boolean;
|
|
37
|
+
withFileTypes?: boolean;
|
|
38
|
+
}): Promise<Array<string> | Array<DirectoryEntry>>;
|
|
39
|
+
globSync(pattern: string, options: {
|
|
40
|
+
readonly cwd: string;
|
|
41
|
+
}): Array<string>;
|
|
42
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
43
|
+
unlink(filePath: string): Promise<void>;
|
|
44
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import picomatch from "picomatch";
|
|
2
|
+
/**
|
|
3
|
+
* A predicate over a string — returns `true` when the value matches.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.5.0-canary.0
|
|
6
|
+
*/
|
|
7
|
+
export type StringMatcher = (value: string) => boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Compile a list of glob patterns into a predicate that returns `true` when its
|
|
10
|
+
* argument matches **any** of them (picomatch semantics). Returns a never-match
|
|
11
|
+
* predicate when no patterns are supplied.
|
|
12
|
+
*
|
|
13
|
+
* Shared by every "match a name/path against a configured pattern list" use
|
|
14
|
+
* (workspace excludes, `tag.skipPackages`, …) so the compile-then-`some` logic
|
|
15
|
+
* lives in one place.
|
|
16
|
+
*
|
|
17
|
+
* @since 0.5.0-canary.0
|
|
18
|
+
*/
|
|
19
|
+
export declare function createAnyGlobMatcher(patterns: ReadonlyArray<string> | undefined, options?: Parameters<typeof picomatch>[1]): StringMatcher;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight functional Result type for CLI boundaries.
|
|
3
|
+
*/
|
|
4
|
+
type Ok<Value> = {
|
|
5
|
+
readonly ok: true;
|
|
6
|
+
readonly value: Value;
|
|
7
|
+
};
|
|
8
|
+
type Err<ErrorValue> = {
|
|
9
|
+
readonly ok: false;
|
|
10
|
+
readonly error: ErrorValue;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* A discriminated success-or-error union tagged by its `ok` flag.
|
|
14
|
+
*
|
|
15
|
+
* @since 0.3.16-canary.0
|
|
16
|
+
*/
|
|
17
|
+
export type Result<Value, ErrorValue> = Ok<Value> | Err<ErrorValue>;
|
|
18
|
+
/**
|
|
19
|
+
* Wraps a value in a success `Result`.
|
|
20
|
+
*
|
|
21
|
+
* @since 0.3.16-canary.0
|
|
22
|
+
*/
|
|
23
|
+
export declare function ok<Value>(value: Value): Ok<Value>;
|
|
24
|
+
/**
|
|
25
|
+
* Wraps an error in a failure `Result`.
|
|
26
|
+
*
|
|
27
|
+
* @since 0.3.16-canary.0
|
|
28
|
+
*/
|
|
29
|
+
export declare function err<ErrorValue>(error: ErrorValue): Err<ErrorValue>;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
import { AppError } from "#/core/errors";
|
|
3
|
+
import type { Result } from "#/core/result";
|
|
4
|
+
/**
|
|
5
|
+
* Parses an input against a Zod schema and returns a `Result` with the value or a validation `AppError`.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.3.16-canary.0
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseWithSchema<Value>(schema: ZodType<Value>, input: unknown): Result<Value, AppError>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure string utilities for applying non-overlapping text edits and reading line indentation.
|
|
3
|
+
*/
|
|
4
|
+
type SourceTextEdit = Readonly<{
|
|
5
|
+
start: number;
|
|
6
|
+
end: number;
|
|
7
|
+
replacement: string;
|
|
8
|
+
}>;
|
|
9
|
+
/**
|
|
10
|
+
* Returns the leading whitespace of the line containing a position.
|
|
11
|
+
*
|
|
12
|
+
* @since 0.3.16-canary.0
|
|
13
|
+
*/
|
|
14
|
+
export declare function indentOfLineContaining(source: string, pos: number): string;
|
|
15
|
+
/**
|
|
16
|
+
* Returns the text from the start of a position's line up to that position.
|
|
17
|
+
*
|
|
18
|
+
* @since 0.3.16-canary.0
|
|
19
|
+
*/
|
|
20
|
+
export declare function textPrefixFromLineStartToPosition(source: string, pos: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Extends a token's end position past any whitespace-separated trailing comma.
|
|
23
|
+
*
|
|
24
|
+
* @since 0.3.16-canary.0
|
|
25
|
+
*/
|
|
26
|
+
export declare function endAfterOptionalCommaFollowingInSource(source: string, tokenEnd: number): number;
|
|
27
|
+
/**
|
|
28
|
+
* Applies non-overlapping text edits from the highest offset down and returns the edited source.
|
|
29
|
+
*
|
|
30
|
+
* @since 0.3.16-canary.0
|
|
31
|
+
*/
|
|
32
|
+
export declare function applyEditsDescending(sourceText: string, edits: ReadonlyArray<SourceTextEdit>): string;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Each directory from `fromDirectory` up to and including the filesystem root.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.10.0
|
|
5
|
+
*/
|
|
6
|
+
export declare function ancestorDirectories(fromDirectory: string): Generator<string>;
|
|
7
|
+
/**
|
|
8
|
+
* The nearest ancestor directory (starting at `fromDirectory`) the predicate accepts, or undefined at the filesystem root.
|
|
9
|
+
*
|
|
10
|
+
* @since 0.10.0
|
|
11
|
+
*/
|
|
12
|
+
export declare function findNearestAncestor(fromDirectory: string, isMatch: (directoryPath: string) => boolean): string | undefined;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
/**
|
|
3
|
+
* Each directory from `fromDirectory` up to and including the filesystem root.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.10.0
|
|
6
|
+
*/
|
|
7
|
+
export function* ancestorDirectories(fromDirectory) {
|
|
8
|
+
let directoryPath = path.resolve(fromDirectory);
|
|
9
|
+
for (;;) {
|
|
10
|
+
yield directoryPath;
|
|
11
|
+
const parent = path.dirname(directoryPath);
|
|
12
|
+
if (parent === directoryPath) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
directoryPath = parent;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The nearest ancestor directory (starting at `fromDirectory`) the predicate accepts, or undefined at the filesystem root.
|
|
20
|
+
*
|
|
21
|
+
* @since 0.10.0
|
|
22
|
+
*/
|
|
23
|
+
export function findNearestAncestor(fromDirectory, isMatch) {
|
|
24
|
+
for (const directoryPath of ancestorDirectories(fromDirectory)) {
|
|
25
|
+
if (isMatch(directoryPath)) {
|
|
26
|
+
return directoryPath;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FilesystemPort } from "#/core/filesystem/port";
|
|
2
|
+
/**
|
|
3
|
+
* Every markdown file under a root, skipping build output and vendored trees.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.5.0
|
|
6
|
+
*/
|
|
7
|
+
export declare function walkMarkdownFiles(rootDirectoryPath: string, fs: FilesystemPort): Array<string>;
|
|
@@ -1,27 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { defaultSkipDirectoryNames } from "#/core/workspace/skip-directories";
|
|
1
|
+
import { walkFiles } from "#/core/workspace/walk-files";
|
|
3
2
|
/**
|
|
4
3
|
* Every markdown file under a root, skipping build output and vendored trees.
|
|
5
4
|
*
|
|
6
5
|
* @since 0.5.0
|
|
7
6
|
*/
|
|
8
7
|
export function walkMarkdownFiles(rootDirectoryPath, fs) {
|
|
9
|
-
|
|
10
|
-
visitMarkdownPaths(result, rootDirectoryPath, fs);
|
|
11
|
-
return result;
|
|
12
|
-
}
|
|
13
|
-
function visitMarkdownPaths(result, entryPath, fs) {
|
|
14
|
-
const entryStats = fs.statSync(entryPath);
|
|
15
|
-
if (entryStats.isDirectory()) {
|
|
16
|
-
for (const childName of fs.readdirSync(entryPath)) {
|
|
17
|
-
if (defaultSkipDirectoryNames.has(childName)) {
|
|
18
|
-
continue;
|
|
19
|
-
}
|
|
20
|
-
visitMarkdownPaths(result, path.join(entryPath, childName), fs);
|
|
21
|
-
}
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
if (entryPath.endsWith(".md")) {
|
|
25
|
-
result.push(entryPath);
|
|
26
|
-
}
|
|
8
|
+
return walkFiles(rootDirectoryPath, fs, (filePath) => filePath.endsWith(".md"));
|
|
27
9
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FilesystemPort } from "#/core/filesystem/port";
|
|
2
|
+
/**
|
|
3
|
+
* Finds the `version` of the nearest enclosing `package.json`, or null when the first
|
|
4
|
+
* one found declares none (the private workspace root is version-less by design).
|
|
5
|
+
*
|
|
6
|
+
* @since 0.8.0
|
|
7
|
+
*/
|
|
8
|
+
declare function findNearestPackageVersion(fs: FilesystemPort, targetPath: string): string | null;
|
|
9
|
+
export { findNearestPackageVersion };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { findNearestAncestor } from "#/core/workspace/ancestor-directories";
|
|
3
|
+
import { packageJsonFileName } from "#/core/workspace/well-known-files";
|
|
2
4
|
/**
|
|
3
5
|
* Finds the `version` of the nearest enclosing `package.json`, or null when the first
|
|
4
6
|
* one found declares none (the private workspace root is version-less by design).
|
|
@@ -7,18 +9,12 @@ import path from "node:path";
|
|
|
7
9
|
*/
|
|
8
10
|
function findNearestPackageVersion(fs, targetPath) {
|
|
9
11
|
const resolved = path.resolve(targetPath);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const version = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")).version;
|
|
15
|
-
return typeof version === "string" && version.length > 0 ? version : null;
|
|
16
|
-
}
|
|
17
|
-
const parent = path.dirname(current);
|
|
18
|
-
if (parent === current) {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
current = parent;
|
|
12
|
+
const startDirectory = fs.statSync(resolved).isDirectory() ? resolved : path.dirname(resolved);
|
|
13
|
+
const packageDirectory = findNearestAncestor(startDirectory, (directoryPath) => fs.existsSync(path.join(directoryPath, packageJsonFileName)));
|
|
14
|
+
if (packageDirectory === undefined) {
|
|
15
|
+
return null;
|
|
22
16
|
}
|
|
17
|
+
const version = JSON.parse(fs.readFileSync(path.join(packageDirectory, packageJsonFileName), "utf8")).version;
|
|
18
|
+
return typeof version === "string" && version.length > 0 ? version : null;
|
|
23
19
|
}
|
|
24
20
|
export { findNearestPackageVersion };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { FilesystemPort } from "#/core/filesystem/port";
|
|
2
|
+
/**
|
|
3
|
+
* A resolved project root and whether it is a pnpm workspace or a standalone single package.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.10.0
|
|
6
|
+
*/
|
|
7
|
+
export type ResolvedProjectRoot = {
|
|
8
|
+
readonly rootDir: string;
|
|
9
|
+
readonly mode: "workspace" | "single-package";
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Resolves the project root: the `pnpm-workspace.yaml` directory, or the nearest `package.json` for a single package.
|
|
13
|
+
*
|
|
14
|
+
* @since 0.10.0
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveProjectRoot(fromDirectory: string, fs: FilesystemPort): ResolvedProjectRoot;
|
|
17
|
+
/**
|
|
18
|
+
* Where the workspace package patterns came from.
|
|
19
|
+
*
|
|
20
|
+
* @since 0.3.16-canary.0
|
|
21
|
+
*/
|
|
22
|
+
type WorkspacePackageLayoutSource = "pnpm-workspace-yaml" | "default-patterns" | "declared-empty" | "single-package";
|
|
23
|
+
/**
|
|
24
|
+
* The discovered workspace package directories together with how the layout was determined.
|
|
25
|
+
*
|
|
26
|
+
* @since 0.3.16-canary.0
|
|
27
|
+
*/
|
|
28
|
+
export type WorkspacePackageLayoutOutcome = {
|
|
29
|
+
readonly packageDirectoryPathsAbsolute: Array<string>;
|
|
30
|
+
readonly layoutSource: WorkspacePackageLayoutSource;
|
|
31
|
+
readonly hasPnpmWorkspaceYamlFile: boolean;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Lists the workspace's package directories per `pnpm-workspace.yaml`, falling back to default patterns.
|
|
35
|
+
*
|
|
36
|
+
* @since 0.3.16-canary.0
|
|
37
|
+
*/
|
|
38
|
+
export declare function listWorkspacePackageDirectories(rootDirectoryPathAbsolute: string, fs: FilesystemPort, suppressGlobPermissionDiagnostics?: boolean): Promise<WorkspacePackageLayoutOutcome>;
|
|
39
|
+
export {};
|