@savvy-web/silk-effects 0.6.1 → 1.0.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 +48 -17
- package/_virtual/_rolldown/runtime.js +18 -0
- package/changesets/api/categories.js +247 -0
- package/changesets/api/changelog.js +134 -0
- package/changesets/api/dependency-table.js +163 -0
- package/changesets/api/linter.js +168 -0
- package/changesets/api/transformer.js +140 -0
- package/changesets/categories/index.js +299 -0
- package/changesets/categories/types.js +66 -0
- package/changesets/changelog/formatting.js +119 -0
- package/changesets/changelog/getDependencyReleaseLine.js +114 -0
- package/changesets/changelog/getReleaseLine.js +122 -0
- package/changesets/changelog/index.js +99 -0
- package/changesets/constants.js +43 -0
- package/changesets/errors.js +305 -0
- package/changesets/index.js +146 -0
- package/changesets/markdownlint/index.js +29 -0
- package/changesets/markdownlint/rules/content-structure.js +98 -0
- package/changesets/markdownlint/rules/dependency-table-format.js +170 -0
- package/changesets/markdownlint/rules/heading-hierarchy.js +61 -0
- package/changesets/markdownlint/rules/required-sections.js +54 -0
- package/changesets/markdownlint/rules/uncategorized-content.js +54 -0
- package/changesets/markdownlint/rules/utils.js +30 -0
- package/changesets/remark/plugins/aggregate-dependency-tables.js +47 -0
- package/changesets/remark/plugins/contributor-footnotes.js +123 -0
- package/changesets/remark/plugins/deduplicate-items.js +30 -0
- package/changesets/remark/plugins/issue-link-refs.js +58 -0
- package/changesets/remark/plugins/merge-sections.js +43 -0
- package/changesets/remark/plugins/normalize-format.js +47 -0
- package/changesets/remark/plugins/reorder-sections.js +34 -0
- package/changesets/remark/presets.js +119 -0
- package/changesets/remark/rules/content-structure.js +22 -0
- package/changesets/remark/rules/dependency-table-format.js +40 -0
- package/changesets/remark/rules/heading-hierarchy.js +19 -0
- package/changesets/remark/rules/required-sections.js +17 -0
- package/changesets/remark/rules/uncategorized-content.js +31 -0
- package/changesets/schemas/changeset.js +146 -0
- package/changesets/schemas/dependency-table.js +189 -0
- package/changesets/schemas/git.js +69 -0
- package/changesets/schemas/github.js +175 -0
- package/changesets/schemas/options.js +182 -0
- package/changesets/schemas/package-scope.js +128 -0
- package/changesets/schemas/primitives.js +72 -0
- package/changesets/schemas/version-files.js +151 -0
- package/changesets/services/branch-analyzer.js +278 -0
- package/changesets/services/changelog.js +50 -0
- package/changesets/services/config-inspector.js +390 -0
- package/changesets/services/github.js +178 -0
- package/changesets/services/markdown.js +106 -0
- package/changesets/services/workspace-snapshot.js +182 -0
- package/changesets/utils/commit-parser.js +80 -0
- package/changesets/utils/dep-diff.js +77 -0
- package/changesets/utils/dependency-table.js +347 -0
- package/changesets/utils/issue-refs.js +101 -0
- package/changesets/utils/jsonpath.js +175 -0
- package/changesets/utils/logger.js +50 -0
- package/changesets/utils/markdown-link.js +57 -0
- package/changesets/utils/publishability.js +39 -0
- package/changesets/utils/remark-pipeline.js +79 -0
- package/changesets/utils/section-parser.js +94 -0
- package/changesets/utils/strip-frontmatter.js +46 -0
- package/changesets/utils/version-blocks.js +108 -0
- package/changesets/utils/version-files.js +336 -0
- package/changesets/utils/worktree-snapshot.js +142 -0
- package/changesets/vendor/github-info.js +55 -0
- package/commitlint/config/factory.js +69 -0
- package/commitlint/config/plugins.js +227 -0
- package/commitlint/config/rules.js +155 -0
- package/commitlint/config/schema.js +46 -0
- package/commitlint/detection/dco.js +53 -0
- package/commitlint/detection/scopes.js +45 -0
- package/commitlint/formatter/format.js +85 -0
- package/commitlint/formatter/messages.js +79 -0
- package/commitlint/hook/diagnostics/branch.js +36 -0
- package/commitlint/hook/diagnostics/cache.js +37 -0
- package/commitlint/hook/diagnostics/commitlint-config.js +36 -0
- package/commitlint/hook/diagnostics/open-issues.js +56 -0
- package/commitlint/hook/diagnostics/package-manager.js +51 -0
- package/commitlint/hook/diagnostics/signing.js +107 -0
- package/commitlint/hook/envelope.js +46 -0
- package/commitlint/hook/output.js +45 -0
- package/commitlint/hook/parse-bash-command.js +105 -0
- package/commitlint/hook/rules/closes-trailer.js +31 -0
- package/commitlint/hook/rules/forbidden-content.js +32 -0
- package/commitlint/hook/rules/plan-leakage.js +36 -0
- package/commitlint/hook/rules/signing-flag-conflict.js +25 -0
- package/commitlint/hook/rules/soft-wrap.js +37 -0
- package/commitlint/hook/rules/types.js +14 -0
- package/commitlint/hook/rules/verbosity.js +31 -0
- package/commitlint/hook/silence-logger.js +39 -0
- package/commitlint/index.js +146 -0
- package/commitlint/prompt/config.js +91 -0
- package/commitlint/prompt/emojis.js +74 -0
- package/commitlint/prompt/prompter.js +135 -0
- package/commitlint/static.js +73 -0
- package/errors/BiomeSyncError.js +21 -0
- package/errors/ChangesetConfigError.js +20 -0
- package/errors/ConfigNotFoundError.js +21 -0
- package/errors/SectionParseError.js +16 -0
- package/errors/SectionValidationError.js +16 -0
- package/errors/SectionWriteError.js +16 -0
- package/errors/TagFormatError.js +20 -0
- package/errors/ToolNotFoundError.js +11 -0
- package/errors/ToolResolutionError.js +11 -0
- package/errors/ToolVersionMismatchError.js +11 -0
- package/errors/VersioningDetectionError.js +20 -0
- package/errors/WorkspaceAnalysisError.js +21 -0
- package/index.d.ts +9743 -8380
- package/index.js +36 -6657
- package/lint/Handler.js +39 -0
- package/lint/cli/sections.js +65 -0
- package/lint/cli/templates/markdownlint.gen.js +183 -0
- package/lint/config/Preset.js +152 -0
- package/lint/config/createConfig.js +89 -0
- package/lint/handlers/Biome.js +179 -0
- package/lint/handlers/Markdown.js +139 -0
- package/lint/handlers/PackageJson.js +130 -0
- package/lint/handlers/PnpmWorkspace.js +141 -0
- package/lint/handlers/ShellScripts.js +58 -0
- package/lint/handlers/TypeScript.js +134 -0
- package/lint/handlers/Yaml.js +167 -0
- package/lint/index.js +52 -0
- package/lint/utils/Command.js +285 -0
- package/lint/utils/Filter.js +100 -0
- package/lint/utils/Workspace.js +86 -0
- package/package.json +52 -63
- package/schemas/CommentStyle.js +16 -0
- package/schemas/ResolvedTool.js +63 -0
- package/schemas/SavvySections.js +113 -0
- package/schemas/SectionBlock.js +70 -0
- package/schemas/SectionDefinition.js +121 -0
- package/schemas/SectionResults.js +12 -0
- package/schemas/TagStrategySchemas.js +18 -0
- package/schemas/ToolDefinition.js +39 -0
- package/schemas/ToolResults.js +14 -0
- package/schemas/VersioningSchemas.js +95 -0
- package/schemas/WorkspaceAnalysisSchemas.js +190 -0
- package/services/BiomeSchemaSync.js +133 -0
- package/services/ChangesetConfig.js +78 -0
- package/services/ChangesetConfigReader.js +106 -0
- package/services/ConfigDiscovery.js +71 -0
- package/services/ManagedSection.js +288 -0
- package/services/SilkPublishability.js +193 -0
- package/services/SilkWorkspaceAnalyzer.js +213 -0
- package/services/TagStrategy.js +54 -0
- package/services/ToolDiscovery.js +229 -0
- package/services/VersioningStrategy.js +67 -0
- package/tsdoc-metadata.json +11 -11
- package/turbo/digest.js +127 -0
- package/turbo/errors.js +48 -0
- package/turbo/index.js +32 -0
- package/turbo/schemas/DryRun.js +57 -0
- package/turbo/schemas/results.js +61 -0
- package/turbo/services/TurboInspector.js +100 -0
- package/utils/ToolCommand.js +40 -0
package/lint/Handler.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/lint/Handler.ts
|
|
2
|
+
/**
|
|
3
|
+
* Abstract base class for lint-staged handlers.
|
|
4
|
+
*
|
|
5
|
+
* All handler classes follow this pattern and implement:
|
|
6
|
+
* - `glob` - The recommended glob pattern for matching files
|
|
7
|
+
* - `defaultExcludes` - Default patterns to exclude
|
|
8
|
+
* - `handler` - Pre-configured handler with defaults
|
|
9
|
+
* - `create()` - Factory method for custom configuration
|
|
10
|
+
*/
|
|
11
|
+
var Handler = class {
|
|
12
|
+
/**
|
|
13
|
+
* Default glob pattern for this handler.
|
|
14
|
+
* Use as the key in lint-staged config.
|
|
15
|
+
*/
|
|
16
|
+
static glob;
|
|
17
|
+
/**
|
|
18
|
+
* Default exclude patterns applied when no options provided.
|
|
19
|
+
*/
|
|
20
|
+
static defaultExcludes;
|
|
21
|
+
/**
|
|
22
|
+
* Pre-configured handler with default options.
|
|
23
|
+
* Ready to use directly in lint-staged config.
|
|
24
|
+
*/
|
|
25
|
+
static handler;
|
|
26
|
+
/**
|
|
27
|
+
* Factory method to create a handler with custom options.
|
|
28
|
+
*
|
|
29
|
+
* @param _options - Configuration options for this handler
|
|
30
|
+
* @returns A lint-staged compatible handler function
|
|
31
|
+
*/
|
|
32
|
+
static create(_options) {
|
|
33
|
+
/* v8 ignore next -- abstract factory; always overridden by concrete subclasses */
|
|
34
|
+
throw new Error("Handler.create() must be implemented by subclass");
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
export { Handler };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { SectionDefinition } from "../../schemas/SectionDefinition.js";
|
|
2
|
+
import { savvyToolSection } from "../../schemas/SavvySections.js";
|
|
3
|
+
|
|
4
|
+
//#region src/lint/cli/sections.ts
|
|
5
|
+
/**
|
|
6
|
+
* Shared managed section definitions and constants for CLI commands.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
/** Path for the husky pre-commit hook. */
|
|
11
|
+
const HUSKY_HOOK_PATH = ".husky/pre-commit";
|
|
12
|
+
/** Path for the husky post-checkout hook. */
|
|
13
|
+
const POST_CHECKOUT_HOOK_PATH = ".husky/post-checkout";
|
|
14
|
+
/** Path for the husky post-merge hook. */
|
|
15
|
+
const POST_MERGE_HOOK_PATH = ".husky/post-merge";
|
|
16
|
+
/** Default path for the lint-staged config file. */
|
|
17
|
+
const DEFAULT_CONFIG_PATH = "lib/configs/lint-staged.config.ts";
|
|
18
|
+
/** Path for the markdownlint-cli2 config file. */
|
|
19
|
+
const MARKDOWNLINT_CONFIG_PATH = "lib/configs/.markdownlint-cli2.jsonc";
|
|
20
|
+
/** Identity definition for the savvy-lint tool section (read / check / remove). */
|
|
21
|
+
const SavvyLintSectionDef = SectionDefinition.make({ toolName: "savvy-lint" });
|
|
22
|
+
/**
|
|
23
|
+
* Identity definition for the legacy `SAVVY-LINT` hygiene section that previously
|
|
24
|
+
* lived in `.husky/post-checkout` and `.husky/post-merge`.
|
|
25
|
+
*
|
|
26
|
+
* @remarks
|
|
27
|
+
* The hygiene block has been replaced by a co-owned `savvy-hooks` section emitted from
|
|
28
|
+
* silk-effects. Use this definition with `ManagedSection.remove` during migration to
|
|
29
|
+
* delete the leftover block from those hooks. The marker matched is identical to
|
|
30
|
+
* `SavvyLintSectionDef`'s; the two definitions are split only by intent (live tool
|
|
31
|
+
* section vs. legacy hygiene block that lives in a different hook).
|
|
32
|
+
*/
|
|
33
|
+
const LegacySavvyLintHygieneDef = SectionDefinition.make({ toolName: "savvy-lint" });
|
|
34
|
+
/**
|
|
35
|
+
* Build the lint-staged command run inside the savvy-lint tool section.
|
|
36
|
+
*
|
|
37
|
+
* @param configPath - Path to the lint-staged config file (relative to repo root)
|
|
38
|
+
*/
|
|
39
|
+
function lintStagedCommand(configPath) {
|
|
40
|
+
return `lint-staged --config "$ROOT/${configPath}"`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build the savvy-lint tool section block for the given config path.
|
|
44
|
+
*
|
|
45
|
+
* @remarks
|
|
46
|
+
* Depends on the savvy-base preamble (`in_ci`, `pm_exec`) preceding it in the hook.
|
|
47
|
+
*/
|
|
48
|
+
function savvyLintBlock(configPath) {
|
|
49
|
+
return savvyToolSection("savvy-lint", lintStagedCommand(configPath));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Rendered content of the savvy-lint tool section.
|
|
53
|
+
*
|
|
54
|
+
* @remarks
|
|
55
|
+
* Equivalent to `savvyLintBlock(configPath).content`. Retained for the check command
|
|
56
|
+
* and tests.
|
|
57
|
+
*
|
|
58
|
+
* @param configPath - Path to the lint-staged config file
|
|
59
|
+
*/
|
|
60
|
+
function generateManagedContent(configPath) {
|
|
61
|
+
return savvyLintBlock(configPath).content;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//#endregion
|
|
65
|
+
export { DEFAULT_CONFIG_PATH, HUSKY_HOOK_PATH, LegacySavvyLintHygieneDef, MARKDOWNLINT_CONFIG_PATH, POST_CHECKOUT_HOOK_PATH, POST_MERGE_HOOK_PATH, SavvyLintSectionDef, generateManagedContent, savvyLintBlock };
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
//#region src/lint/cli/templates/markdownlint.gen.ts
|
|
2
|
+
/**
|
|
3
|
+
* Auto-generated markdownlint template data.
|
|
4
|
+
*
|
|
5
|
+
* DO NOT EDIT — regenerate with: pnpm generate:templates
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
/** Full markdownlint-cli2 config template. */
|
|
10
|
+
const MARKDOWNLINT_TEMPLATE = {
|
|
11
|
+
$schema: "https://raw.githubusercontent.com/DavidAnson/markdownlint-cli2/v0.22.0/schema/markdownlint-cli2-config-schema.json",
|
|
12
|
+
globs: ["**/*.{md,mdx}"],
|
|
13
|
+
fix: true,
|
|
14
|
+
gitignore: true,
|
|
15
|
+
noBanner: true,
|
|
16
|
+
ignores: [
|
|
17
|
+
"**/node_modules",
|
|
18
|
+
"**/.cache",
|
|
19
|
+
"**/coverage",
|
|
20
|
+
"**/.coverage",
|
|
21
|
+
"**/dist",
|
|
22
|
+
"**/CHANGELOG.md",
|
|
23
|
+
"**/.claude/plans",
|
|
24
|
+
"**/docs/superpowers"
|
|
25
|
+
],
|
|
26
|
+
customRules: ["@savvy-web/silk/changesets/markdownlint"],
|
|
27
|
+
config: {
|
|
28
|
+
default: true,
|
|
29
|
+
MD001: true,
|
|
30
|
+
MD002: true,
|
|
31
|
+
MD003: true,
|
|
32
|
+
MD004: true,
|
|
33
|
+
MD005: true,
|
|
34
|
+
MD006: true,
|
|
35
|
+
MD007: true,
|
|
36
|
+
MD008: true,
|
|
37
|
+
MD009: true,
|
|
38
|
+
MD010: true,
|
|
39
|
+
MD011: true,
|
|
40
|
+
MD012: true,
|
|
41
|
+
MD013: false,
|
|
42
|
+
MD014: true,
|
|
43
|
+
MD015: true,
|
|
44
|
+
MD016: true,
|
|
45
|
+
MD017: true,
|
|
46
|
+
MD018: true,
|
|
47
|
+
MD019: true,
|
|
48
|
+
MD020: true,
|
|
49
|
+
MD021: true,
|
|
50
|
+
MD022: true,
|
|
51
|
+
MD023: true,
|
|
52
|
+
MD024: { siblings_only: true },
|
|
53
|
+
MD025: true,
|
|
54
|
+
MD026: true,
|
|
55
|
+
MD027: true,
|
|
56
|
+
MD028: true,
|
|
57
|
+
MD029: true,
|
|
58
|
+
MD030: true,
|
|
59
|
+
MD031: true,
|
|
60
|
+
MD032: true,
|
|
61
|
+
MD033: { allowed_elements: [
|
|
62
|
+
"br",
|
|
63
|
+
"details",
|
|
64
|
+
"summary",
|
|
65
|
+
"img",
|
|
66
|
+
"sup",
|
|
67
|
+
"sub"
|
|
68
|
+
] },
|
|
69
|
+
MD034: true,
|
|
70
|
+
MD035: true,
|
|
71
|
+
MD036: true,
|
|
72
|
+
MD037: true,
|
|
73
|
+
MD038: true,
|
|
74
|
+
MD039: true,
|
|
75
|
+
MD040: true,
|
|
76
|
+
MD041: true,
|
|
77
|
+
MD042: true,
|
|
78
|
+
MD043: false,
|
|
79
|
+
MD044: false,
|
|
80
|
+
MD045: true,
|
|
81
|
+
MD046: true,
|
|
82
|
+
MD047: true,
|
|
83
|
+
MD048: true,
|
|
84
|
+
MD049: true,
|
|
85
|
+
MD050: true,
|
|
86
|
+
MD051: true,
|
|
87
|
+
MD052: true,
|
|
88
|
+
MD053: true,
|
|
89
|
+
MD054: true,
|
|
90
|
+
MD055: true,
|
|
91
|
+
MD056: true,
|
|
92
|
+
MD057: true,
|
|
93
|
+
MD058: true,
|
|
94
|
+
MD059: true,
|
|
95
|
+
MD060: { style: "compact" },
|
|
96
|
+
"changeset-heading-hierarchy": false,
|
|
97
|
+
"changeset-required-sections": false,
|
|
98
|
+
"changeset-content-structure": false,
|
|
99
|
+
"changeset-uncategorized-content": false,
|
|
100
|
+
"changeset-dependency-table-format": false
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
/** The `$schema` URL from the template. */
|
|
104
|
+
const MARKDOWNLINT_SCHEMA = "https://raw.githubusercontent.com/DavidAnson/markdownlint-cli2/v0.22.0/schema/markdownlint-cli2-config-schema.json";
|
|
105
|
+
/** The `config` rules object from the template. */
|
|
106
|
+
const MARKDOWNLINT_CONFIG = {
|
|
107
|
+
default: true,
|
|
108
|
+
MD001: true,
|
|
109
|
+
MD002: true,
|
|
110
|
+
MD003: true,
|
|
111
|
+
MD004: true,
|
|
112
|
+
MD005: true,
|
|
113
|
+
MD006: true,
|
|
114
|
+
MD007: true,
|
|
115
|
+
MD008: true,
|
|
116
|
+
MD009: true,
|
|
117
|
+
MD010: true,
|
|
118
|
+
MD011: true,
|
|
119
|
+
MD012: true,
|
|
120
|
+
MD013: false,
|
|
121
|
+
MD014: true,
|
|
122
|
+
MD015: true,
|
|
123
|
+
MD016: true,
|
|
124
|
+
MD017: true,
|
|
125
|
+
MD018: true,
|
|
126
|
+
MD019: true,
|
|
127
|
+
MD020: true,
|
|
128
|
+
MD021: true,
|
|
129
|
+
MD022: true,
|
|
130
|
+
MD023: true,
|
|
131
|
+
MD024: { siblings_only: true },
|
|
132
|
+
MD025: true,
|
|
133
|
+
MD026: true,
|
|
134
|
+
MD027: true,
|
|
135
|
+
MD028: true,
|
|
136
|
+
MD029: true,
|
|
137
|
+
MD030: true,
|
|
138
|
+
MD031: true,
|
|
139
|
+
MD032: true,
|
|
140
|
+
MD033: { allowed_elements: [
|
|
141
|
+
"br",
|
|
142
|
+
"details",
|
|
143
|
+
"summary",
|
|
144
|
+
"img",
|
|
145
|
+
"sup",
|
|
146
|
+
"sub"
|
|
147
|
+
] },
|
|
148
|
+
MD034: true,
|
|
149
|
+
MD035: true,
|
|
150
|
+
MD036: true,
|
|
151
|
+
MD037: true,
|
|
152
|
+
MD038: true,
|
|
153
|
+
MD039: true,
|
|
154
|
+
MD040: true,
|
|
155
|
+
MD041: true,
|
|
156
|
+
MD042: true,
|
|
157
|
+
MD043: false,
|
|
158
|
+
MD044: false,
|
|
159
|
+
MD045: true,
|
|
160
|
+
MD046: true,
|
|
161
|
+
MD047: true,
|
|
162
|
+
MD048: true,
|
|
163
|
+
MD049: true,
|
|
164
|
+
MD050: true,
|
|
165
|
+
MD051: true,
|
|
166
|
+
MD052: true,
|
|
167
|
+
MD053: true,
|
|
168
|
+
MD054: true,
|
|
169
|
+
MD055: true,
|
|
170
|
+
MD056: true,
|
|
171
|
+
MD057: true,
|
|
172
|
+
MD058: true,
|
|
173
|
+
MD059: true,
|
|
174
|
+
MD060: { style: "compact" },
|
|
175
|
+
"changeset-heading-hierarchy": false,
|
|
176
|
+
"changeset-required-sections": false,
|
|
177
|
+
"changeset-content-structure": false,
|
|
178
|
+
"changeset-uncategorized-content": false,
|
|
179
|
+
"changeset-dependency-table-format": false
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
//#endregion
|
|
183
|
+
export { MARKDOWNLINT_CONFIG, MARKDOWNLINT_SCHEMA, MARKDOWNLINT_TEMPLATE };
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { createConfig } from "./createConfig.js";
|
|
2
|
+
|
|
3
|
+
//#region src/lint/config/Preset.ts
|
|
4
|
+
/**
|
|
5
|
+
* Preset configurations for common lint-staged setups.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { Preset } from '@savvy-web/lint-staged';
|
|
10
|
+
*
|
|
11
|
+
* // Use a preset directly
|
|
12
|
+
* export default Preset.standard();
|
|
13
|
+
*
|
|
14
|
+
* // Extend a preset with customizations
|
|
15
|
+
* export default Preset.standard({
|
|
16
|
+
* biome: { exclude: ['vendor/'] },
|
|
17
|
+
* custom: {
|
|
18
|
+
* '*.css': (files) => `stylelint ${files.join(' ')}`,
|
|
19
|
+
* },
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
var Preset = class Preset {
|
|
24
|
+
/**
|
|
25
|
+
* Minimal preset: formatting only.
|
|
26
|
+
*
|
|
27
|
+
* Includes:
|
|
28
|
+
* - PackageJson (sort + format)
|
|
29
|
+
* - Biome (format JS/TS/JSON)
|
|
30
|
+
*
|
|
31
|
+
* @param extend - Options to customize or extend the preset
|
|
32
|
+
* @returns A lint-staged configuration object
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* import { Preset } from '@savvy-web/lint-staged';
|
|
37
|
+
*
|
|
38
|
+
* export default Preset.minimal();
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
static minimal(extend = {}) {
|
|
42
|
+
const options = {
|
|
43
|
+
packageJson: extend.packageJson ?? {},
|
|
44
|
+
biome: extend.biome ?? {},
|
|
45
|
+
markdown: extend.markdown ?? false,
|
|
46
|
+
yaml: extend.yaml ?? false,
|
|
47
|
+
pnpmWorkspace: extend.pnpmWorkspace ?? false,
|
|
48
|
+
shellScripts: extend.shellScripts ?? false,
|
|
49
|
+
typescript: extend.typescript ?? false
|
|
50
|
+
};
|
|
51
|
+
if (extend.custom !== void 0) options.custom = extend.custom;
|
|
52
|
+
return createConfig(options);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Standard preset: formatting + linting.
|
|
56
|
+
*
|
|
57
|
+
* Includes:
|
|
58
|
+
* - PackageJson (sort + format)
|
|
59
|
+
* - Biome (format JS/TS/JSON)
|
|
60
|
+
* - Markdown (lint + fix)
|
|
61
|
+
* - Yaml (format + lint)
|
|
62
|
+
* - PnpmWorkspace (sort + format)
|
|
63
|
+
* - ShellScripts (chmod management)
|
|
64
|
+
*
|
|
65
|
+
* @param extend - Options to customize or extend the preset
|
|
66
|
+
* @returns A lint-staged configuration object
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* import { Preset } from '@savvy-web/lint-staged';
|
|
71
|
+
*
|
|
72
|
+
* export default Preset.standard({
|
|
73
|
+
* biome: { exclude: ['legacy/'] },
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
static standard(extend = {}) {
|
|
78
|
+
const options = {
|
|
79
|
+
packageJson: extend.packageJson ?? {},
|
|
80
|
+
biome: extend.biome ?? {},
|
|
81
|
+
markdown: extend.markdown ?? {},
|
|
82
|
+
yaml: extend.yaml ?? {},
|
|
83
|
+
pnpmWorkspace: extend.pnpmWorkspace ?? {},
|
|
84
|
+
shellScripts: extend.shellScripts ?? {},
|
|
85
|
+
typescript: extend.typescript ?? false
|
|
86
|
+
};
|
|
87
|
+
if (extend.custom !== void 0) options.custom = extend.custom;
|
|
88
|
+
return createConfig(options);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Silk preset: all handlers enabled.
|
|
92
|
+
*
|
|
93
|
+
* Includes:
|
|
94
|
+
* - PackageJson (sort + format)
|
|
95
|
+
* - Biome (format JS/TS/JSON)
|
|
96
|
+
* - Markdown (lint + fix)
|
|
97
|
+
* - Yaml (format + lint)
|
|
98
|
+
* - PnpmWorkspace (sort + format)
|
|
99
|
+
* - ShellScripts (chmod management)
|
|
100
|
+
* - TypeScript (TSDoc + typecheck)
|
|
101
|
+
*
|
|
102
|
+
* @param extend - Options to customize or extend the preset
|
|
103
|
+
* @returns A lint-staged configuration object
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* import { Preset } from '@savvy-web/lint-staged';
|
|
108
|
+
*
|
|
109
|
+
* export default Preset.silk({
|
|
110
|
+
* typescript: { skipTypecheck: true },
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
static silk(extend = {}) {
|
|
115
|
+
const options = {
|
|
116
|
+
packageJson: extend.packageJson ?? {},
|
|
117
|
+
biome: extend.biome ?? {},
|
|
118
|
+
markdown: extend.markdown ?? {},
|
|
119
|
+
yaml: extend.yaml ?? {},
|
|
120
|
+
pnpmWorkspace: extend.pnpmWorkspace ?? {},
|
|
121
|
+
shellScripts: extend.shellScripts ?? {},
|
|
122
|
+
typescript: extend.typescript ?? {}
|
|
123
|
+
};
|
|
124
|
+
if (extend.custom !== void 0) options.custom = extend.custom;
|
|
125
|
+
return createConfig(options);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get a preset by name.
|
|
129
|
+
*
|
|
130
|
+
* @param name - The preset name: 'minimal', 'standard', or 'silk'
|
|
131
|
+
* @param extend - Options to customize or extend the preset
|
|
132
|
+
* @returns A lint-staged configuration object
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* import { Preset } from '@savvy-web/lint-staged';
|
|
137
|
+
*
|
|
138
|
+
* const presetName = process.env.LINT_PRESET || 'standard';
|
|
139
|
+
* export default Preset.get(presetName);
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
static get(name, extend = {}) {
|
|
143
|
+
switch (name) {
|
|
144
|
+
case "minimal": return Preset.minimal(extend);
|
|
145
|
+
case "silk": return Preset.silk(extend);
|
|
146
|
+
default: return Preset.standard(extend);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
//#endregion
|
|
152
|
+
export { Preset };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Biome } from "../handlers/Biome.js";
|
|
2
|
+
import { Markdown } from "../handlers/Markdown.js";
|
|
3
|
+
import { PackageJson } from "../handlers/PackageJson.js";
|
|
4
|
+
import { PnpmWorkspace } from "../handlers/PnpmWorkspace.js";
|
|
5
|
+
import { ShellScripts } from "../handlers/ShellScripts.js";
|
|
6
|
+
import { TypeScript } from "../handlers/TypeScript.js";
|
|
7
|
+
import { Yaml } from "../handlers/Yaml.js";
|
|
8
|
+
|
|
9
|
+
//#region src/lint/config/createConfig.ts
|
|
10
|
+
/**
|
|
11
|
+
* Configuration factory for generating complete lint-staged configurations.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Create a complete lint-staged configuration with all handlers.
|
|
15
|
+
*
|
|
16
|
+
* @param options - Configuration options for each handler
|
|
17
|
+
* @returns A lint-staged compatible configuration object
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { createConfig } from '@savvy-web/lint-staged';
|
|
22
|
+
*
|
|
23
|
+
* // Use all defaults
|
|
24
|
+
* export default createConfig();
|
|
25
|
+
*
|
|
26
|
+
* // Customize specific handlers
|
|
27
|
+
* export default createConfig({
|
|
28
|
+
* packageJson: { skipSort: true },
|
|
29
|
+
* biome: { exclude: ['vendor/'] },
|
|
30
|
+
* custom: {
|
|
31
|
+
* '*.css': (files) => `stylelint ${files.join(' ')}`,
|
|
32
|
+
* },
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
function createConfig(options = {}) {
|
|
37
|
+
const config = {};
|
|
38
|
+
const pkgJsonEnabled = options.packageJson !== false;
|
|
39
|
+
const biomeEnabled = options.biome !== false;
|
|
40
|
+
if (pkgJsonEnabled && biomeEnabled) {
|
|
41
|
+
const pkgOpts = typeof options.packageJson === "object" ? options.packageJson : {};
|
|
42
|
+
const biomeOpts = typeof options.biome === "object" ? options.biome : {};
|
|
43
|
+
config[PackageJson.glob] = [PackageJson.fmtCommand(pkgOpts), Biome.create({
|
|
44
|
+
...biomeOpts,
|
|
45
|
+
exclude: [...PackageJson.defaultExcludes]
|
|
46
|
+
})];
|
|
47
|
+
} else if (pkgJsonEnabled) {
|
|
48
|
+
const pkgOpts = typeof options.packageJson === "object" ? options.packageJson : {};
|
|
49
|
+
config[PackageJson.glob] = PackageJson.create(pkgOpts);
|
|
50
|
+
}
|
|
51
|
+
if (biomeEnabled) {
|
|
52
|
+
const handlerOptions = typeof options.biome === "object" ? options.biome : {};
|
|
53
|
+
config[Biome.glob] = Biome.create(handlerOptions);
|
|
54
|
+
}
|
|
55
|
+
if (options.markdown !== false) {
|
|
56
|
+
const handlerOptions = typeof options.markdown === "object" ? options.markdown : {};
|
|
57
|
+
config[Markdown.glob] = Markdown.create(handlerOptions);
|
|
58
|
+
}
|
|
59
|
+
const pnpmEnabled = options.pnpmWorkspace !== false;
|
|
60
|
+
const yamlEnabled = options.yaml !== false;
|
|
61
|
+
if (pnpmEnabled && yamlEnabled) config[PnpmWorkspace.glob] = [PnpmWorkspace.fmtCommand(), Yaml.create({
|
|
62
|
+
exclude: [],
|
|
63
|
+
skipFormat: true
|
|
64
|
+
})];
|
|
65
|
+
else if (pnpmEnabled) {
|
|
66
|
+
const pnpmOpts = typeof options.pnpmWorkspace === "object" ? options.pnpmWorkspace : {};
|
|
67
|
+
config[PnpmWorkspace.glob] = PnpmWorkspace.create(pnpmOpts);
|
|
68
|
+
}
|
|
69
|
+
if (yamlEnabled) {
|
|
70
|
+
const yamlOpts = typeof options.yaml === "object" ? options.yaml : {};
|
|
71
|
+
config[Yaml.glob] = [Yaml.fmtCommand(yamlOpts), Yaml.create({
|
|
72
|
+
...yamlOpts,
|
|
73
|
+
skipFormat: true
|
|
74
|
+
})];
|
|
75
|
+
}
|
|
76
|
+
if (options.shellScripts !== false) {
|
|
77
|
+
const handlerOptions = typeof options.shellScripts === "object" ? options.shellScripts : {};
|
|
78
|
+
config[ShellScripts.glob] = ShellScripts.create(handlerOptions);
|
|
79
|
+
}
|
|
80
|
+
if (options.typescript !== false) {
|
|
81
|
+
const handlerOptions = typeof options.typescript === "object" ? options.typescript : {};
|
|
82
|
+
config[TypeScript.glob] = TypeScript.create(handlerOptions);
|
|
83
|
+
}
|
|
84
|
+
if (options.custom) for (const [glob, handler] of Object.entries(options.custom)) config[glob] = handler;
|
|
85
|
+
return config;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//#endregion
|
|
89
|
+
export { createConfig };
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { Command } from "../utils/Command.js";
|
|
2
|
+
import { Filter } from "../utils/Filter.js";
|
|
3
|
+
import { getWorkspacePackagePaths, getWorkspaceRoot } from "../utils/Workspace.js";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
|
|
7
|
+
//#region src/lint/handlers/Biome.ts
|
|
8
|
+
/**
|
|
9
|
+
* Handler for JavaScript/TypeScript/JSON files.
|
|
10
|
+
*
|
|
11
|
+
* Formats and lints with Biome.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Handler for JavaScript, TypeScript, and JSON files.
|
|
15
|
+
*
|
|
16
|
+
* Formats and lints with Biome.
|
|
17
|
+
*
|
|
18
|
+
* Biome discovery order:
|
|
19
|
+
* 1. Global `biome` command (preferred)
|
|
20
|
+
* 2. Local installation via `pnpm exec biome`
|
|
21
|
+
* 3. Local installation via `npx biome`
|
|
22
|
+
*
|
|
23
|
+
* Config file discovery:
|
|
24
|
+
* - Searches the workspace root for `biome.jsonc` or `biome.json`.
|
|
25
|
+
* - Falls back to CWD when not in a workspace.
|
|
26
|
+
* - No `lib/configs/` convention — biome configs live at workspace roots only.
|
|
27
|
+
*
|
|
28
|
+
* @throws Error if Biome is not available (globally or locally)
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* import { Biome } from '@savvy-web/lint-staged';
|
|
33
|
+
*
|
|
34
|
+
* export default {
|
|
35
|
+
* // Auto-discovers biome command and config file
|
|
36
|
+
* [Biome.glob]: Biome.handler,
|
|
37
|
+
*
|
|
38
|
+
* // Or with custom excludes
|
|
39
|
+
* [Biome.glob]: Biome.create({
|
|
40
|
+
* exclude: ['vendor/', 'generated/'],
|
|
41
|
+
* }),
|
|
42
|
+
* };
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
var Biome = class Biome {
|
|
46
|
+
/**
|
|
47
|
+
* Glob pattern for matching JavaScript/TypeScript/JSON files.
|
|
48
|
+
* @defaultValue `'*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}'`
|
|
49
|
+
*/
|
|
50
|
+
static glob = "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}";
|
|
51
|
+
/**
|
|
52
|
+
* Default patterns to exclude from processing.
|
|
53
|
+
* Excludes package.json since PackageJson handler processes those files.
|
|
54
|
+
* @defaultValue `['package.json', 'package-lock.json', '__fixtures__', '__test__/fixtures']`
|
|
55
|
+
*/
|
|
56
|
+
static defaultExcludes = [
|
|
57
|
+
"package.json",
|
|
58
|
+
"package-lock.json",
|
|
59
|
+
"__fixtures__",
|
|
60
|
+
"__test__/fixtures"
|
|
61
|
+
];
|
|
62
|
+
/** Candidate config file names in preference order. */
|
|
63
|
+
static CONFIG_NAMES = ["biome.jsonc", "biome.json"];
|
|
64
|
+
/**
|
|
65
|
+
* Pre-configured handler with default options.
|
|
66
|
+
* Auto-discovers biome command and config file location.
|
|
67
|
+
*/
|
|
68
|
+
static handler = Biome.create();
|
|
69
|
+
/**
|
|
70
|
+
* Find the Biome executable.
|
|
71
|
+
*
|
|
72
|
+
* Searches in order:
|
|
73
|
+
* 1. Global `biome` command
|
|
74
|
+
* 2. `pnpm exec biome`
|
|
75
|
+
* 3. `npx biome`
|
|
76
|
+
*
|
|
77
|
+
* @returns The command to run biome, or undefined if not found
|
|
78
|
+
*/
|
|
79
|
+
static findBiome() {
|
|
80
|
+
return Command.findTool("biome").command;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Check if Biome is available.
|
|
84
|
+
*
|
|
85
|
+
* @returns `true` if biome is available globally or locally
|
|
86
|
+
*/
|
|
87
|
+
static isAvailable() {
|
|
88
|
+
return Command.findTool("biome").available;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Find the Biome config file at the workspace root.
|
|
92
|
+
*
|
|
93
|
+
* @remarks
|
|
94
|
+
* Searches the workspace root directory for `biome.jsonc` then `biome.json`.
|
|
95
|
+
* Falls back to CWD when not running inside a workspace. The `lib/configs/`
|
|
96
|
+
* convention is not used — biome configs are expected at workspace roots only.
|
|
97
|
+
*
|
|
98
|
+
* @returns Absolute path to the config file, or undefined if not found
|
|
99
|
+
*/
|
|
100
|
+
static findConfig() {
|
|
101
|
+
const searchDir = getWorkspaceRoot() ?? process.cwd();
|
|
102
|
+
for (const name of Biome.CONFIG_NAMES) {
|
|
103
|
+
const fullPath = join(searchDir, name);
|
|
104
|
+
if (existsSync(fullPath)) return fullPath;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Find all Biome config files across workspace roots.
|
|
109
|
+
*
|
|
110
|
+
* @remarks
|
|
111
|
+
* Searches the workspace root and each leaf workspace root for a
|
|
112
|
+
* `biome.jsonc` or `biome.json` config file. At most one config is
|
|
113
|
+
* collected per directory (the first match in preference order).
|
|
114
|
+
* Falls back to CWD when not running inside a workspace.
|
|
115
|
+
*
|
|
116
|
+
* This method is intended for the CLI check command, which validates
|
|
117
|
+
* `$schema` URLs across all workspace biome configs.
|
|
118
|
+
*
|
|
119
|
+
* @returns Array of absolute config file paths (may be empty)
|
|
120
|
+
*/
|
|
121
|
+
static findAllConfigs() {
|
|
122
|
+
const root = getWorkspaceRoot();
|
|
123
|
+
const configs = [];
|
|
124
|
+
if (root === null) {
|
|
125
|
+
const cwd = process.cwd();
|
|
126
|
+
for (const name of Biome.CONFIG_NAMES) {
|
|
127
|
+
const fullPath = join(cwd, name);
|
|
128
|
+
if (existsSync(fullPath)) {
|
|
129
|
+
configs.push(fullPath);
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return configs;
|
|
134
|
+
}
|
|
135
|
+
for (const name of Biome.CONFIG_NAMES) {
|
|
136
|
+
const fullPath = join(root, name);
|
|
137
|
+
if (existsSync(fullPath)) {
|
|
138
|
+
configs.push(fullPath);
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
for (const pkgPath of getWorkspacePackagePaths()) for (const name of Biome.CONFIG_NAMES) {
|
|
143
|
+
const fullPath = join(pkgPath, name);
|
|
144
|
+
if (existsSync(fullPath)) {
|
|
145
|
+
configs.push(fullPath);
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return configs;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Create a handler with custom options.
|
|
153
|
+
*
|
|
154
|
+
* @param options - Configuration options
|
|
155
|
+
* @returns A lint-staged compatible handler function
|
|
156
|
+
* @throws Error if Biome is not available when handler is invoked
|
|
157
|
+
*/
|
|
158
|
+
static create(options = {}) {
|
|
159
|
+
const excludes = options.exclude ?? [...Biome.defaultExcludes];
|
|
160
|
+
const config = options.config ?? Biome.findConfig();
|
|
161
|
+
return (filenames) => {
|
|
162
|
+
const filtered = Filter.exclude(filenames, excludes);
|
|
163
|
+
if (filtered.length === 0) return [];
|
|
164
|
+
const biomeCmd = Command.requireTool("biome", "Biome is not available. Install it globally (recommended) or add @biomejs/biome as a dev dependency.");
|
|
165
|
+
const files = Filter.shellEscape(filtered);
|
|
166
|
+
const flags = options.flags ?? [];
|
|
167
|
+
const configFlag = config ? `--config-path=${config}` : "";
|
|
168
|
+
return [
|
|
169
|
+
`${biomeCmd} check --write --no-errors-on-unmatched`,
|
|
170
|
+
configFlag,
|
|
171
|
+
...flags,
|
|
172
|
+
files
|
|
173
|
+
].filter(Boolean).join(" ");
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
//#endregion
|
|
179
|
+
export { Biome };
|