@savvy-web/silk-effects 7.5.3 → 8.0.1
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/changesets/api/changelog.js +10 -5
- package/changesets/changelog/getReleaseLine.js +2 -5
- package/changesets/changelog/index.js +39 -19
- package/changesets/index.js +5 -2
- package/changesets/utils/logger.js +47 -20
- package/index.d.ts +171 -1336
- package/index.js +2 -10
- package/lint/cli/sections.js +1 -1
- package/package.json +6 -5
- package/services/BiomeSchemaSync.js +3 -3
- package/services/ChangesetConfigReader.js +3 -4
- package/services/ConfigDiscovery.js +2 -2
- package/services/SilkPublishability.js +2 -3
- package/services/SilkWorkspaceAnalyzer.js +2 -3
- package/errors/BiomeSyncError.js +0 -22
- package/errors/ChangesetConfigError.js +0 -21
- package/errors/ConfigNotFoundError.js +0 -22
- package/errors/PublishTargetBindingError.js +0 -30
- package/errors/WorkspaceAnalysisError.js +0 -22
- package/pr-body/body.js +0 -145
- package/pr-body/diagnostics.js +0 -104
- package/pr-body/index.js +0 -22
- package/pr-body/linked-issue.js +0 -44
- package/pr-body/markers.js +0 -103
- package/pr-body/references.js +0 -157
- package/pr-body/region.js +0 -105
- package/schemas/SavvyInstallSection.js +0 -232
- package/schemas/SavvySections.js +0 -194
- package/schemas/VersioningSchemas.js +0 -87
- package/schemas/WorkspaceAnalysisSchemas.js +0 -209
- package/utils/TrailingSlash.js +0 -18
package/schemas/SavvySections.js
DELETED
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import { CommentStyle, SectionId } from "@effected/templates";
|
|
2
|
-
|
|
3
|
-
//#region src/schemas/SavvySections.ts
|
|
4
|
-
/**
|
|
5
|
-
* Build a shell-hook section identity from a Silk tool name.
|
|
6
|
-
*
|
|
7
|
-
* @remarks
|
|
8
|
-
* **The key is uppercased here, and that is load-bearing.** The kit renders a
|
|
9
|
-
* key verbatim into its markers (`# --- BEGIN <key> MANAGED SECTION ---`),
|
|
10
|
-
* while the section model this replaces uppercased `toolName` on the way in. A
|
|
11
|
-
* lowercase key would therefore emit `# --- BEGIN savvy-base MANAGED SECTION ---`
|
|
12
|
-
* and no longer match the `SAVVY-BASE` markers already written into every
|
|
13
|
-
* consumer repo's hook files — `check` would report the section absent and
|
|
14
|
-
* `sync` would append a second copy beside the first. Uppercasing keeps the
|
|
15
|
-
* marker bytes identical across the migration.
|
|
16
|
-
*/
|
|
17
|
-
const shellSection = (toolName) => SectionId.make({
|
|
18
|
-
key: toolName.toUpperCase(),
|
|
19
|
-
commentStyle: CommentStyle.hash
|
|
20
|
-
});
|
|
21
|
-
/**
|
|
22
|
-
* Section identity for the shared package-manager preamble.
|
|
23
|
-
*
|
|
24
|
-
* `toolName` is `"savvy-base"`; pair with {@link savvyBasePreamble} to build the block:
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```ts
|
|
28
|
-
* const section = SavvyBaseSection.section(savvyBasePreamble());
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* @since 0.5.0
|
|
32
|
-
* @public
|
|
33
|
-
*/
|
|
34
|
-
const SavvyBaseSection = shellSection("savvy-base");
|
|
35
|
-
/**
|
|
36
|
-
* Section identity for the shared repo-hygiene block.
|
|
37
|
-
*
|
|
38
|
-
* `toolName` is `"savvy-hooks"`; pair with {@link savvyHooksHygiene}.
|
|
39
|
-
*
|
|
40
|
-
* @since 0.5.0
|
|
41
|
-
* @public
|
|
42
|
-
*/
|
|
43
|
-
const SavvyHooksSection = shellSection("savvy-hooks");
|
|
44
|
-
/**
|
|
45
|
-
* Package-manager detection preamble shared across Silk Suite hook files.
|
|
46
|
-
*
|
|
47
|
-
* @remarks
|
|
48
|
-
* Side-effect-free definitions meant to run unconditionally — no markers, no outer CI
|
|
49
|
-
* guard. Defines `ROOT`, the `in_ci` predicate, `PM` (via `detect_pm`), and `pm_exec`.
|
|
50
|
-
* `pm_exec` uses local/exec semantics for every package manager and `bun x` (space form),
|
|
51
|
-
* which works regardless of how bun was installed (the `bunx` shim is not always on PATH).
|
|
52
|
-
*
|
|
53
|
-
* @returns The preamble shell, with no surrounding markers or trailing newline.
|
|
54
|
-
*
|
|
55
|
-
* @since 0.5.0
|
|
56
|
-
* @public
|
|
57
|
-
*/
|
|
58
|
-
function savvyBasePreamble() {
|
|
59
|
-
return `ROOT=$(git rev-parse --show-toplevel)
|
|
60
|
-
|
|
61
|
-
in_ci() { [ -n "$CI" ] || [ -n "$GITHUB_ACTIONS" ]; }
|
|
62
|
-
|
|
63
|
-
detect_pm() {
|
|
64
|
-
if [ -f "$ROOT/package.json" ]; then
|
|
65
|
-
pm=$(jq -r '.packageManager // empty' "$ROOT/package.json" 2>/dev/null | cut -d'@' -f1)
|
|
66
|
-
if [ -n "$pm" ]; then echo "$pm"; return; fi
|
|
67
|
-
fi
|
|
68
|
-
if [ -f "$ROOT/pnpm-lock.yaml" ]; then echo "pnpm"
|
|
69
|
-
elif [ -f "$ROOT/yarn.lock" ]; then echo "yarn"
|
|
70
|
-
elif [ -f "$ROOT/bun.lock" ]; then echo "bun"
|
|
71
|
-
else echo "npm"; fi
|
|
72
|
-
}
|
|
73
|
-
PM=$(detect_pm)
|
|
74
|
-
|
|
75
|
-
pm_exec() {
|
|
76
|
-
case "$PM" in
|
|
77
|
-
pnpm) pnpm exec "$@" ;;
|
|
78
|
-
yarn) yarn exec "$@" ;;
|
|
79
|
-
bun) bun x "$@" ;;
|
|
80
|
-
*) npx --no -- "$@" ;;
|
|
81
|
-
esac
|
|
82
|
-
}`;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Repo-hygiene block shared across Silk Suite hook files.
|
|
86
|
-
*
|
|
87
|
-
* @remarks
|
|
88
|
-
* Self-guarded against CI and needs no package manager: disables Git's `core.fileMode`
|
|
89
|
-
* tracking and marks tracked shell scripts executable.
|
|
90
|
-
*
|
|
91
|
-
* @returns The hygiene shell, with no surrounding markers or trailing newline.
|
|
92
|
-
*
|
|
93
|
-
* @since 0.5.0
|
|
94
|
-
* @public
|
|
95
|
-
*/
|
|
96
|
-
function savvyHooksHygiene() {
|
|
97
|
-
return `if ! { [ -n "$CI" ] || [ -n "$GITHUB_ACTIONS" ]; }; then
|
|
98
|
-
git config core.fileMode false
|
|
99
|
-
git ls-files -z '*.sh' | xargs -0 chmod +x 2>/dev/null || true
|
|
100
|
-
fi`;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Build a consumer's one-line tool section so every consumer calls the shared base
|
|
104
|
-
* helpers identically.
|
|
105
|
-
*
|
|
106
|
-
* @remarks
|
|
107
|
-
* The returned block's content is exactly `in_ci || pm_exec <command>` with `command`
|
|
108
|
-
* appended verbatim — it is not parsed, quoted, or interpolated, so shell tokens like
|
|
109
|
-
* `$ROOT` and `$1` survive into the generated literal.
|
|
110
|
-
*
|
|
111
|
-
* **Precondition:** a {@link SavvyBaseSection} block must precede this section in the same
|
|
112
|
-
* hook file so `in_ci` and `pm_exec` are defined. Consumers guarantee this by passing both
|
|
113
|
-
* to `ManagedSection.syncAll` in order:
|
|
114
|
-
*
|
|
115
|
-
* @example
|
|
116
|
-
* ```ts
|
|
117
|
-
* yield* sections.syncAll(".husky/commit-msg", [
|
|
118
|
-
* SavvyBaseSection.section(savvyBasePreamble()),
|
|
119
|
-
* savvyToolSection("savvy-commit", 'commitlint --config "$ROOT/lib/configs/commitlint.config.ts" --edit "$1"'),
|
|
120
|
-
* ]);
|
|
121
|
-
* ```
|
|
122
|
-
*
|
|
123
|
-
* @param toolName - Section identity; also drives the marker names (uppercased).
|
|
124
|
-
* @param command - The command passed verbatim to `pm_exec`, run only outside CI.
|
|
125
|
-
* @returns A shell `Section` (`commentStyle: hash`) for `toolName`.
|
|
126
|
-
*
|
|
127
|
-
* @since 0.5.0
|
|
128
|
-
* @public
|
|
129
|
-
*/
|
|
130
|
-
function savvyToolSection(toolName, command) {
|
|
131
|
-
return shellSection(toolName).section(`in_ci || pm_exec ${command}`);
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Section identity for the package-manager toolchain drift check.
|
|
135
|
-
*
|
|
136
|
-
* `toolName` is `"savvy-toolchain"`; pair with {@link savvyToolchainCheck}.
|
|
137
|
-
*
|
|
138
|
-
* @since 7.3.0
|
|
139
|
-
* @public
|
|
140
|
-
*/
|
|
141
|
-
const SavvyToolchainSection = shellSection("savvy-toolchain");
|
|
142
|
-
/**
|
|
143
|
-
* Package-manager drift check shared across Silk Suite hook files.
|
|
144
|
-
*
|
|
145
|
-
* @remarks
|
|
146
|
-
* Compares the running package manager's version against the repo's
|
|
147
|
-
* `devEngines.packageManager` pin and prints a warning on mismatch. **Warn only** —
|
|
148
|
-
* it never blocks the hook and never installs anything, so nobody mid-bisect or
|
|
149
|
-
* mid-rebase on an older pin is stranded.
|
|
150
|
-
*
|
|
151
|
-
* Deliberately self-contained: its homes are `.husky/post-checkout` and
|
|
152
|
-
* `.husky/post-merge`, which carry {@link SavvyHooksSection} but no
|
|
153
|
-
* {@link SavvyBaseSection}, so it defines its own root/CI/pin lookups rather than
|
|
154
|
-
* depending on `ROOT`, `in_ci` or `PM`. It honours the `name` recorded in the pin
|
|
155
|
-
* rather than assuming pnpm.
|
|
156
|
-
*
|
|
157
|
-
* Every input is treated as optional: no `git` root, no `jq`, no `devEngines` block,
|
|
158
|
-
* or a package manager that is not on `PATH` all mean "say nothing". Only an exact
|
|
159
|
-
* pin is comparable, so ranges (`^1.2.3`, `>=1 || <2`) and wildcards (`1.x`) are
|
|
160
|
-
* skipped, and the `+sha512…` integrity tail `devEngines` versions routinely carry is
|
|
161
|
-
* stripped before comparison. Skipped under CI, where the runtime action installs the
|
|
162
|
-
* pin by construction.
|
|
163
|
-
*
|
|
164
|
-
* @returns The drift-check shell, with no surrounding markers or trailing newline.
|
|
165
|
-
*
|
|
166
|
-
* @since 7.3.0
|
|
167
|
-
* @public
|
|
168
|
-
*/
|
|
169
|
-
function savvyToolchainCheck() {
|
|
170
|
-
return `if ! { [ -n "$CI" ] || [ -n "$GITHUB_ACTIONS" ]; }; then
|
|
171
|
-
toolchain_root=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
172
|
-
toolchain_pm=""
|
|
173
|
-
toolchain_pin=""
|
|
174
|
-
if [ -n "$toolchain_root" ] && [ -f "$toolchain_root/package.json" ] && command -v jq >/dev/null 2>&1; then
|
|
175
|
-
toolchain_pm=$(jq -r '.devEngines.packageManager.name // empty' "$toolchain_root/package.json" 2>/dev/null)
|
|
176
|
-
toolchain_pin=$(jq -r '.devEngines.packageManager.version // empty' "$toolchain_root/package.json" 2>/dev/null | cut -d'+' -f1)
|
|
177
|
-
fi
|
|
178
|
-
# Only an exact pin is comparable: drop ranges (^ ~ >= ||) and wildcards (x, *).
|
|
179
|
-
case "$toolchain_pin" in ""|[!0-9]*|*[!0-9A-Za-z.-]*|*x*|*X*) toolchain_pin="" ;; esac
|
|
180
|
-
if [ -n "$toolchain_pm" ] && [ -n "$toolchain_pin" ] && command -v "$toolchain_pm" >/dev/null 2>&1; then
|
|
181
|
-
toolchain_have=$("$toolchain_pm" --version 2>/dev/null | head -n 1 | tr -d '[:space:]')
|
|
182
|
-
# A manager that failed or answered with prose says nothing about drift.
|
|
183
|
-
case "$toolchain_have" in [!0-9]*|*[!0-9A-Za-z.-]*) toolchain_have="" ;; esac
|
|
184
|
-
if [ -n "$toolchain_have" ] && [ "$toolchain_have" != "$toolchain_pin" ]; then
|
|
185
|
-
printf '⚠ %s %s does not match %s, the version pinned in devEngines.packageManager.\\n' "$toolchain_pm" "$toolchain_have" "$toolchain_pin" >&2
|
|
186
|
-
printf ' Lockfiles written by this version may differ from CI. Fix: corepack use %s@%s\\n' "$toolchain_pm" "$toolchain_pin" >&2
|
|
187
|
-
fi
|
|
188
|
-
fi
|
|
189
|
-
unset toolchain_root toolchain_pm toolchain_pin toolchain_have
|
|
190
|
-
fi`;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
//#endregion
|
|
194
|
-
export { SavvyBaseSection, SavvyHooksSection, SavvyToolchainSection, savvyBasePreamble, savvyHooksHygiene, savvyToolSection, savvyToolchainCheck };
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { Effect, Schema } from "effect";
|
|
2
|
-
|
|
3
|
-
//#region src/schemas/VersioningSchemas.ts
|
|
4
|
-
/**
|
|
5
|
-
* Configuration for how private packages are handled during versioning.
|
|
6
|
-
*
|
|
7
|
-
* @remarks
|
|
8
|
-
* When set to `false`, private packages are completely ignored.
|
|
9
|
-
* When set to an object, `tag` and `version` control whether private packages
|
|
10
|
-
* receive git tags and version bumps respectively.
|
|
11
|
-
*
|
|
12
|
-
* @since 0.2.0
|
|
13
|
-
*/
|
|
14
|
-
const PrivatePackagesConfig = Schema.Union([Schema.Struct({
|
|
15
|
-
tag: Schema.optional(Schema.Boolean),
|
|
16
|
-
version: Schema.optional(Schema.Boolean)
|
|
17
|
-
}), Schema.Literal(false)]);
|
|
18
|
-
/**
|
|
19
|
-
* Snapshot release configuration for changesets.
|
|
20
|
-
*
|
|
21
|
-
* @remarks
|
|
22
|
-
* Controls how snapshot versions are generated.
|
|
23
|
-
* `useCalculatedVersion` prepends the calculated version to the snapshot tag.
|
|
24
|
-
* `prereleaseTemplate` is a custom template string for snapshot version format.
|
|
25
|
-
*
|
|
26
|
-
* @since 0.2.0
|
|
27
|
-
*/
|
|
28
|
-
const SnapshotConfig = Schema.Struct({
|
|
29
|
-
useCalculatedVersion: Schema.optional(Schema.Boolean),
|
|
30
|
-
prereleaseTemplate: Schema.optional(Schema.String)
|
|
31
|
-
});
|
|
32
|
-
/**
|
|
33
|
-
* Standard changesets configuration matching the `@changesets/config@4.0.0` spec.
|
|
34
|
-
*
|
|
35
|
-
* @remarks
|
|
36
|
-
* Represents the parsed `.changeset/config.json` file. All fields are optional
|
|
37
|
-
* to allow partial configs. Use {@link (SilkChangesetConfigFile:type)} when the Silk changelog
|
|
38
|
-
* adapter is detected.
|
|
39
|
-
*
|
|
40
|
-
* @since 0.1.0
|
|
41
|
-
*/
|
|
42
|
-
/** @public */
|
|
43
|
-
const ChangesetConfigFile = Schema.Struct({
|
|
44
|
-
changelog: Schema.optional(Schema.Union([
|
|
45
|
-
Schema.String,
|
|
46
|
-
Schema.Array(Schema.Unknown),
|
|
47
|
-
Schema.Literal(false)
|
|
48
|
-
])),
|
|
49
|
-
commit: Schema.optional(Schema.Union([
|
|
50
|
-
Schema.Boolean,
|
|
51
|
-
Schema.String,
|
|
52
|
-
Schema.Array(Schema.Unknown)
|
|
53
|
-
])),
|
|
54
|
-
fixed: Schema.optional(Schema.Array(Schema.Array(Schema.String))),
|
|
55
|
-
linked: Schema.optional(Schema.Array(Schema.Array(Schema.String))),
|
|
56
|
-
access: Schema.optional(Schema.Literals(["public", "restricted"])),
|
|
57
|
-
baseBranch: Schema.optional(Schema.String),
|
|
58
|
-
updateInternalDependencies: Schema.optional(Schema.Literals([
|
|
59
|
-
"patch",
|
|
60
|
-
"minor",
|
|
61
|
-
"major"
|
|
62
|
-
])),
|
|
63
|
-
ignore: Schema.optional(Schema.Array(Schema.String)),
|
|
64
|
-
privatePackages: Schema.optional(PrivatePackagesConfig),
|
|
65
|
-
prettier: Schema.optional(Schema.Boolean),
|
|
66
|
-
changedFilePatterns: Schema.optional(Schema.Array(Schema.String)),
|
|
67
|
-
bumpVersionsWithWorkspaceProtocolOnly: Schema.optional(Schema.Boolean),
|
|
68
|
-
snapshot: Schema.optional(SnapshotConfig)
|
|
69
|
-
});
|
|
70
|
-
/**
|
|
71
|
-
* Extended changeset config for repos using the `@savvy-web/changesets` changelog adapter.
|
|
72
|
-
*
|
|
73
|
-
* @remarks
|
|
74
|
-
* Extends {@link (ChangesetConfigFile:type)} with a `_isSilk` marker flag that is automatically
|
|
75
|
-
* set to `true`. Detected by {@link ChangesetConfigReader} when the `changelog` field
|
|
76
|
-
* references `@savvy-web/changesets`.
|
|
77
|
-
*
|
|
78
|
-
* @since 0.1.0
|
|
79
|
-
*/
|
|
80
|
-
/** @public */
|
|
81
|
-
const SilkChangesetConfigFile = Schema.Struct({
|
|
82
|
-
...ChangesetConfigFile.fields,
|
|
83
|
-
_isSilk: Schema.Boolean.pipe(Schema.withDecodingDefaultType(Effect.succeed(true)), Schema.withConstructorDefault(Effect.succeed(true)))
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
//#endregion
|
|
87
|
-
export { ChangesetConfigFile, SilkChangesetConfigFile };
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { ChangesetConfigFile, SilkChangesetConfigFile } from "./VersioningSchemas.js";
|
|
2
|
-
import { trimTrailingSlashes } from "../utils/TrailingSlash.js";
|
|
3
|
-
import { Effect, Equal, Function, Hash, Option, Schema } from "effect";
|
|
4
|
-
import { PublishConfig, PublishTarget, TagStyle, VersioningStrategy } from "@effected/workspaces";
|
|
5
|
-
|
|
6
|
-
//#region src/schemas/WorkspaceAnalysisSchemas.ts
|
|
7
|
-
const PublishProtocol = Schema.Literals(["npm", "jsr"]);
|
|
8
|
-
const PublishTargetShorthand = Schema.Literals([
|
|
9
|
-
"npm",
|
|
10
|
-
"github",
|
|
11
|
-
"jsr"
|
|
12
|
-
]);
|
|
13
|
-
const PublishTargetObject = Schema.Struct({
|
|
14
|
-
protocol: PublishProtocol.pipe(Schema.withDecodingDefaultType(Effect.succeed("npm")), Schema.withConstructorDefault(Effect.succeed("npm"))),
|
|
15
|
-
registry: Schema.optional(Schema.String),
|
|
16
|
-
directory: Schema.optional(Schema.String),
|
|
17
|
-
access: Schema.optional(Schema.Literals(["public", "restricted"])),
|
|
18
|
-
provenance: Schema.optional(Schema.Boolean),
|
|
19
|
-
tag: Schema.optional(Schema.String)
|
|
20
|
-
});
|
|
21
|
-
/**
|
|
22
|
-
* Silk-extended publishConfig schema.
|
|
23
|
-
*
|
|
24
|
-
* @remarks
|
|
25
|
-
* Extends the base PublishConfig from `@effected/workspaces` (which covers the
|
|
26
|
-
* npm standard fields — access, registry, directory, tag — and, as of kit
|
|
27
|
-
* round 3, `linkDirectory`) with the Silk `targets` extension for
|
|
28
|
-
* multi-registry publishing.
|
|
29
|
-
*
|
|
30
|
-
* @since 0.2.0
|
|
31
|
-
* @public
|
|
32
|
-
*/
|
|
33
|
-
var SilkPublishConfig = class extends PublishConfig.extend("SilkPublishConfig")({ targets: Schema.optional(Schema.Array(Schema.Union([PublishTargetShorthand, PublishTargetObject]))) }) {};
|
|
34
|
-
const KNOWN_REGISTRIES = {
|
|
35
|
-
npm: "https://registry.npmjs.org/",
|
|
36
|
-
github: "https://npm.pkg.github.com/",
|
|
37
|
-
jsr: "https://jsr.io/"
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* Compare registry URLs ignoring a trailing slash. `SilkPublishability` resolves
|
|
41
|
-
* targets from the bundler's `dist/prod/targets.json` binding, which writes
|
|
42
|
-
* registry endpoints WITHOUT a trailing slash (`https://registry.npmjs.org`),
|
|
43
|
-
* while `KNOWN_REGISTRIES` / `NPM_DEFAULT` use the trailing-slash form. Normalize
|
|
44
|
-
* both sides so `hasTarget`/`targetFor` match regardless of which form a target
|
|
45
|
-
* carries (binding-driven, placeholder, or access-branch fallback).
|
|
46
|
-
*/
|
|
47
|
-
const sameRegistry = (a, b) => trimTrailingSlashes(a) === trimTrailingSlashes(b);
|
|
48
|
-
/**
|
|
49
|
-
* The package's declared version. `current` is absent for a member whose manifest carries no
|
|
50
|
-
* `version` — legal for a private package and the ordinary shape for a private monorepo root,
|
|
51
|
-
* which `@effected/workspaces` discovers as a member rather than rejecting (its `missingVersion`
|
|
52
|
-
* failure kind was retired in 0.19.0). Such a package has no version to bump, tag or stamp.
|
|
53
|
-
*/
|
|
54
|
-
const WorkspaceVersion = Schema.Struct({ current: Schema.optional(Schema.String) });
|
|
55
|
-
/**
|
|
56
|
-
* A fully analyzed workspace with publish targets, versioning status,
|
|
57
|
-
* and release group membership.
|
|
58
|
-
*
|
|
59
|
-
* @since 0.2.0
|
|
60
|
-
* @public
|
|
61
|
-
*/
|
|
62
|
-
var AnalyzedWorkspace = class AnalyzedWorkspace extends Schema.TaggedClass()("AnalyzedWorkspace", {
|
|
63
|
-
name: Schema.String,
|
|
64
|
-
version: WorkspaceVersion,
|
|
65
|
-
path: Schema.String,
|
|
66
|
-
root: Schema.Boolean,
|
|
67
|
-
publishConfig: Schema.NullOr(SilkPublishConfig),
|
|
68
|
-
publishable: Schema.Boolean,
|
|
69
|
-
targets: Schema.Array(PublishTarget),
|
|
70
|
-
versioned: Schema.Boolean,
|
|
71
|
-
tagged: Schema.Boolean,
|
|
72
|
-
released: Schema.Boolean,
|
|
73
|
-
linked: Schema.Array(Schema.suspend(() => AnalyzedWorkspace)),
|
|
74
|
-
fixed: Schema.Array(Schema.suspend(() => AnalyzedWorkspace))
|
|
75
|
-
}) {
|
|
76
|
-
get isRoot() {
|
|
77
|
-
return this.root;
|
|
78
|
-
}
|
|
79
|
-
get isPublishable() {
|
|
80
|
-
return this.publishable;
|
|
81
|
-
}
|
|
82
|
-
get isReleasable() {
|
|
83
|
-
return this.released;
|
|
84
|
-
}
|
|
85
|
-
get isFixed() {
|
|
86
|
-
return this.fixed.length > 0;
|
|
87
|
-
}
|
|
88
|
-
get isLinked() {
|
|
89
|
-
return this.linked.length > 0;
|
|
90
|
-
}
|
|
91
|
-
publishesTo(registry) {
|
|
92
|
-
return this.targets.some((t) => sameRegistry(t.registry, registry));
|
|
93
|
-
}
|
|
94
|
-
hasTarget(shorthand) {
|
|
95
|
-
const registry = KNOWN_REGISTRIES[shorthand];
|
|
96
|
-
return registry !== void 0 && this.publishesTo(registry);
|
|
97
|
-
}
|
|
98
|
-
targetFor(registry) {
|
|
99
|
-
const found = this.targets.find((t) => sameRegistry(t.registry, registry));
|
|
100
|
-
return found ? Option.some(found) : Option.none();
|
|
101
|
-
}
|
|
102
|
-
[Equal.symbol](that) {
|
|
103
|
-
if (!(that instanceof AnalyzedWorkspace)) return false;
|
|
104
|
-
return this.name === that.name && this.path === that.path;
|
|
105
|
-
}
|
|
106
|
-
[Hash.symbol]() {
|
|
107
|
-
return Hash.optimize(Hash.combine(Hash.hash(this.name), Hash.hash(this.path)));
|
|
108
|
-
}
|
|
109
|
-
toString() {
|
|
110
|
-
return this.version.current === void 0 ? this.name : `${this.name}@${this.version.current}`;
|
|
111
|
-
}
|
|
112
|
-
toJSON() {
|
|
113
|
-
return {
|
|
114
|
-
_tag: "AnalyzedWorkspace",
|
|
115
|
-
name: this.name,
|
|
116
|
-
version: this.version,
|
|
117
|
-
path: this.path,
|
|
118
|
-
root: this.root,
|
|
119
|
-
publishable: this.publishable,
|
|
120
|
-
targets: this.targets,
|
|
121
|
-
versioned: this.versioned,
|
|
122
|
-
tagged: this.tagged,
|
|
123
|
-
released: this.released
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
static publishable(workspaces) {
|
|
127
|
-
return workspaces.filter((w) => w.publishable);
|
|
128
|
-
}
|
|
129
|
-
static releasable(workspaces) {
|
|
130
|
-
return workspaces.filter((w) => w.released);
|
|
131
|
-
}
|
|
132
|
-
static findByName;
|
|
133
|
-
/** Pretty-print an AnalyzedWorkspace instance. */
|
|
134
|
-
static pretty;
|
|
135
|
-
};
|
|
136
|
-
AnalyzedWorkspace.findByName = Function.dual(2, (workspaces, name) => {
|
|
137
|
-
const found = workspaces.find((w) => w.name === name);
|
|
138
|
-
return found ? Option.some(found) : Option.none();
|
|
139
|
-
});
|
|
140
|
-
AnalyzedWorkspace.pretty = Schema.toFormatter(AnalyzedWorkspace);
|
|
141
|
-
const PackageManagerInfo = Schema.Struct({
|
|
142
|
-
type: Schema.Literals([
|
|
143
|
-
"npm",
|
|
144
|
-
"pnpm",
|
|
145
|
-
"yarn",
|
|
146
|
-
"bun"
|
|
147
|
-
]),
|
|
148
|
-
version: Schema.optional(Schema.String)
|
|
149
|
-
});
|
|
150
|
-
/**
|
|
151
|
-
* Full workspace analysis result containing all analyzed workspaces
|
|
152
|
-
* and project-level configuration.
|
|
153
|
-
*
|
|
154
|
-
* @since 0.2.0
|
|
155
|
-
* @public
|
|
156
|
-
*/
|
|
157
|
-
var WorkspaceAnalysis = class WorkspaceAnalysis extends Schema.TaggedClass()("WorkspaceAnalysis", {
|
|
158
|
-
root: Schema.String,
|
|
159
|
-
runtime: Schema.Literals(["node", "bun"]),
|
|
160
|
-
packageManager: PackageManagerInfo,
|
|
161
|
-
workspaces: Schema.Array(AnalyzedWorkspace),
|
|
162
|
-
changesetConfig: Schema.NullOr(Schema.Union([SilkChangesetConfigFile, ChangesetConfigFile])),
|
|
163
|
-
versioning: Schema.NullOr(VersioningStrategy),
|
|
164
|
-
tagStrategy: Schema.NullOr(TagStyle)
|
|
165
|
-
}) {
|
|
166
|
-
findWorkspace(name) {
|
|
167
|
-
const found = this.workspaces.find((w) => w.name === name);
|
|
168
|
-
return found ? Option.some(found) : Option.none();
|
|
169
|
-
}
|
|
170
|
-
get rootWorkspace() {
|
|
171
|
-
const root = this.workspaces.find((w) => w.root);
|
|
172
|
-
return root ? Option.some(root) : Option.none();
|
|
173
|
-
}
|
|
174
|
-
get publishableWorkspaces() {
|
|
175
|
-
return this.workspaces.filter((w) => w.publishable);
|
|
176
|
-
}
|
|
177
|
-
get versionedWorkspaces() {
|
|
178
|
-
return this.workspaces.filter((w) => w.versioned);
|
|
179
|
-
}
|
|
180
|
-
get taggedWorkspaces() {
|
|
181
|
-
return this.workspaces.filter((w) => w.tagged);
|
|
182
|
-
}
|
|
183
|
-
get releasableWorkspaces() {
|
|
184
|
-
return this.workspaces.filter((w) => w.released);
|
|
185
|
-
}
|
|
186
|
-
get isSilk() {
|
|
187
|
-
if (this.changesetConfig == null) return false;
|
|
188
|
-
return "_isSilk" in this.changesetConfig && this.changesetConfig._isSilk === true;
|
|
189
|
-
}
|
|
190
|
-
get hasChangesets() {
|
|
191
|
-
return this.changesetConfig != null;
|
|
192
|
-
}
|
|
193
|
-
[Equal.symbol](that) {
|
|
194
|
-
if (!(that instanceof WorkspaceAnalysis)) return false;
|
|
195
|
-
return this.root === that.root;
|
|
196
|
-
}
|
|
197
|
-
[Hash.symbol]() {
|
|
198
|
-
return Hash.optimize(Hash.hash(this.root));
|
|
199
|
-
}
|
|
200
|
-
toString() {
|
|
201
|
-
return `WorkspaceAnalysis(${this.root}, ${this.workspaces.length} workspaces)`;
|
|
202
|
-
}
|
|
203
|
-
/** Pretty-print a WorkspaceAnalysis instance. */
|
|
204
|
-
static pretty;
|
|
205
|
-
};
|
|
206
|
-
WorkspaceAnalysis.pretty = Schema.toFormatter(WorkspaceAnalysis);
|
|
207
|
-
|
|
208
|
-
//#endregion
|
|
209
|
-
export { AnalyzedWorkspace, SilkPublishConfig, WorkspaceAnalysis };
|
package/utils/TrailingSlash.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
//#region src/utils/TrailingSlash.ts
|
|
2
|
-
/**
|
|
3
|
-
* Trim trailing slashes from a string.
|
|
4
|
-
*
|
|
5
|
-
* @remarks
|
|
6
|
-
* Trims trailing slashes with an index scan rather than `/\/+$/`. That regex is
|
|
7
|
-
* unanchored at the start, so the engine retries the match from every position
|
|
8
|
-
* and degrades to O(n²) on a string of many slashes (CodeQL `js/polynomial-redos`).
|
|
9
|
-
* Only a trailing run of slashes is removed; interior slash runs are untouched.
|
|
10
|
-
*/
|
|
11
|
-
const trimTrailingSlashes = (s) => {
|
|
12
|
-
let end = s.length;
|
|
13
|
-
while (end > 0 && s[end - 1] === "/") end -= 1;
|
|
14
|
-
return s.slice(0, end);
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
//#endregion
|
|
18
|
-
export { trimTrailingSlashes };
|