@savvy-web/silk-effects 4.0.1 → 4.2.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/changesets/services/config-inspector.js +7 -16
- package/changesets/utils/version-files.js +25 -17
- package/index.d.ts +48 -17
- package/lint/handlers/PackageJson.js +19 -9
- package/lint/handlers/PnpmWorkspace.js +35 -15
- package/lint/utils/Workspace.js +1 -1
- package/package.json +9 -10
- package/services/SilkPublishability.js +4 -23
- package/tsdoc-metadata.json +1 -1
|
@@ -5,7 +5,7 @@ import { SilkPublishability, readTargetsBinding } from "../../services/SilkPubli
|
|
|
5
5
|
import { Context, Effect, FileSystem, Layer, Path, Result, Schema } from "effect";
|
|
6
6
|
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
7
7
|
import { GlobPattern, GlobPatternOptions } from "@effected/glob";
|
|
8
|
-
import {
|
|
8
|
+
import { compileAndExpand } from "@effected/walker";
|
|
9
9
|
import { WorkspaceDiscovery } from "@effected/workspaces";
|
|
10
10
|
|
|
11
11
|
//#region src/changesets/services/config-inspector.ts
|
|
@@ -172,23 +172,13 @@ function normalizeLegacyOptions(options, configPath) {
|
|
|
172
172
|
/** Match dotfiles, mirroring the former tinyglobby `dot: true` behavior. */
|
|
173
173
|
const GLOB_OPTIONS = GlobPatternOptions.make({ dot: true });
|
|
174
174
|
/**
|
|
175
|
-
* Compile `glob` via `@effected/glob`, folding a compile-guard trip
|
|
176
|
-
* (over-length pattern, brace-expansion budget, nesting depth) into a
|
|
177
|
-
* {@link ConfigurationError} naming the offending glob on the typed channel.
|
|
178
|
-
*/
|
|
179
|
-
function compileGlob(glob) {
|
|
180
|
-
return GlobPattern.compile(glob, GLOB_OPTIONS).pipe(Effect.mapError((error) => new ConfigurationError({
|
|
181
|
-
field: "glob",
|
|
182
|
-
reason: `Invalid glob pattern ${JSON.stringify(glob)}: ${error.message}`
|
|
183
|
-
})));
|
|
184
|
-
}
|
|
185
175
|
/**
|
|
186
176
|
* Pure attribution helper: does `glob` (under this service's `dot: true`
|
|
187
177
|
* semantics) match the repo-relative POSIX path `rel`? An uncompilable
|
|
188
178
|
* pattern matches nothing.
|
|
189
179
|
*/
|
|
190
180
|
function globMatchesRel(glob, rel) {
|
|
191
|
-
const result =
|
|
181
|
+
const result = GlobPattern.compileResult(glob, GLOB_OPTIONS);
|
|
192
182
|
return Result.isSuccess(result) && result.success.matches(rel);
|
|
193
183
|
}
|
|
194
184
|
/**
|
|
@@ -204,13 +194,14 @@ function globMatchesRel(glob, rel) {
|
|
|
204
194
|
* module already speaks POSIX-relative match paths).
|
|
205
195
|
*/
|
|
206
196
|
function materializeGlob(glob, cwd) {
|
|
207
|
-
return
|
|
197
|
+
return compileAndExpand(glob, {
|
|
208
198
|
cwd,
|
|
209
|
-
onUnreadable: "skip"
|
|
199
|
+
onUnreadable: "skip",
|
|
200
|
+
glob: GLOB_OPTIONS
|
|
210
201
|
}).pipe(Effect.mapError((error) => new ConfigurationError({
|
|
211
202
|
field: "glob",
|
|
212
|
-
reason: `Failed to materialize glob ${JSON.stringify(glob)}: ${error.message}`
|
|
213
|
-
})), Effect.provide(Path.layer))
|
|
203
|
+
reason: error.stage === "compile" ? `Invalid glob pattern ${JSON.stringify(glob)}: ${error.cause.message}` : `Failed to materialize glob ${JSON.stringify(glob)}: ${error.cause.message}`
|
|
204
|
+
})), Effect.provide(Path.layer));
|
|
214
205
|
}
|
|
215
206
|
/**
|
|
216
207
|
* Determine whether `child` is the same directory as `parent` or sits inside
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { LegacyVersionFilesSchema } from "../schemas/version-files.js";
|
|
2
2
|
import { jsonPathGet, jsonPathResolve, parseJsonPath } from "./jsonpath.js";
|
|
3
|
-
import { Effect,
|
|
3
|
+
import { Effect, Path, Schema } from "effect";
|
|
4
4
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { join, relative, resolve } from "node:path";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { GlobPatternOptions } from "@effected/glob";
|
|
7
|
+
import { compileAndExpand } from "@effected/walker";
|
|
8
8
|
import { Jsonc, JsoncEdit, JsoncFormattingOptions, JsoncModifier } from "@effected/jsonc";
|
|
9
9
|
|
|
10
10
|
//#region src/changesets/utils/version-files.ts
|
|
@@ -405,19 +405,29 @@ var VersionFiles = class VersionFiles {
|
|
|
405
405
|
}
|
|
406
406
|
};
|
|
407
407
|
/**
|
|
408
|
+
* Match dotfiles, matching `ConfigInspector`'s glob dialect.
|
|
409
|
+
*
|
|
410
|
+
* @remarks
|
|
411
|
+
* This module previously compiled with minimatch DEFAULTS while
|
|
412
|
+
* `ConfigInspector` compiled with `dot: true`, so a wildcard segment matching
|
|
413
|
+
* a dotted directory was attributed to a package but never materialized (or
|
|
414
|
+
* the reverse). The two paths must agree: attribution and materialization
|
|
415
|
+
* answer the same question about the same glob.
|
|
416
|
+
*/
|
|
417
|
+
const GLOB_OPTIONS = GlobPatternOptions.make({ dot: true });
|
|
418
|
+
/**
|
|
408
419
|
* Expand a glob pattern against the filesystem, returning matching FILE paths
|
|
409
420
|
* relative to `cwd` (POSIX separators), sorted by relative path.
|
|
410
421
|
*
|
|
411
422
|
* @remarks
|
|
412
|
-
* The walk is `@effected/walker`'s `
|
|
423
|
+
* The walk is `@effected/walker`'s `compileAndExpand` (literal fast path,
|
|
413
424
|
* `enumerationPrefix` bounding, `node_modules`/`.git` pruning), with
|
|
414
425
|
* `onUnreadable: "skip"` preserving this module's silent-skip policy for
|
|
415
|
-
* unreadable directories. Matching semantics are
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
* paths and node-bound absolute paths throughout.
|
|
426
|
+
* unreadable directories. Matching semantics are {@link GLOB_OPTIONS} —
|
|
427
|
+
* wildcards DO match dotfiles, aligning this module with `ConfigInspector`. An
|
|
428
|
+
* uncompilable pattern expands to no matches. The `Path` requirement is
|
|
429
|
+
* satisfied internally with the core POSIX `Path.layer` — this module already
|
|
430
|
+
* speaks POSIX relative match paths and node-bound absolute paths throughout.
|
|
421
431
|
*
|
|
422
432
|
* @param source - The glob pattern, repo-relative
|
|
423
433
|
* @param cwd - Absolute directory the pattern is resolved against
|
|
@@ -426,13 +436,11 @@ var VersionFiles = class VersionFiles {
|
|
|
426
436
|
* @internal
|
|
427
437
|
*/
|
|
428
438
|
function expandGlob(source, cwd) {
|
|
429
|
-
return
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
})
|
|
435
|
-
})), Effect.provide(Path.layer));
|
|
439
|
+
return compileAndExpand(source, {
|
|
440
|
+
cwd,
|
|
441
|
+
onUnreadable: "skip",
|
|
442
|
+
glob: GLOB_OPTIONS
|
|
443
|
+
}).pipe(Effect.catch((error) => error.stage === "compile" ? Effect.succeed([]) : Effect.fail(error)), Effect.provide(Path.layer));
|
|
436
444
|
}
|
|
437
445
|
/**
|
|
438
446
|
* Read the `version` field from a `package.json` in the given directory.
|
package/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Plugin } from "unified";
|
|
|
3
3
|
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
4
4
|
import { PackageManagerDetector, PublishConfig, PublishTarget, PublishabilityDetector, WorkspaceDiscovery, WorkspaceDiscoveryFailure, WorkspacePackage, WorkspaceRoot, WorkspaceSnapshotAtFailure, WorkspaceSnapshotWorktreeFailure, WorkspaceSnapshots, WorkspaceStateSnapshot, WorkspacesOptions } from "@effected/workspaces";
|
|
5
5
|
import { Git } from "@effected/git";
|
|
6
|
-
import {
|
|
6
|
+
import { GlobExpansionError } from "@effected/walker";
|
|
7
7
|
//#endregion
|
|
8
8
|
//#region src/changesets/categories/types.d.ts
|
|
9
9
|
/**
|
|
@@ -287,7 +287,7 @@ declare class Categories {
|
|
|
287
287
|
static isValidHeading(heading: string): boolean;
|
|
288
288
|
}
|
|
289
289
|
//#endregion
|
|
290
|
-
//#region ../../node_modules/.pnpm/@changesets+types@7.0.0-next.
|
|
290
|
+
//#region ../../node_modules/.pnpm/@changesets+types@7.0.0-next.7/node_modules/@changesets/types/dist/index.d.mts
|
|
291
291
|
//#region src/index.d.ts
|
|
292
292
|
type MaybePromise<T> = T | Promise<T>;
|
|
293
293
|
type VersionType$1 = "major" | "minor" | "patch" | "none";
|
|
@@ -360,10 +360,13 @@ type Config = {
|
|
|
360
360
|
* The formatter to use to format changesets and changelogs. Set `false` to disable formatting.
|
|
361
361
|
* The default value of `"auto"` will auto-detect the formatter based on the project's configuration files.
|
|
362
362
|
*/
|
|
363
|
-
format: "auto" | "prettier" | "oxfmt" | "deno" | "dprint" | false;
|
|
364
|
-
|
|
363
|
+
format: "auto" | "prettier" | "oxfmt" | "deno" | "dprint" | false;
|
|
364
|
+
/** Features enabled for Private packages */
|
|
365
|
+
privatePackages: PrivatePackages;
|
|
366
|
+
/** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */
|
|
365
367
|
updateInternalDependencies: "patch" | "minor";
|
|
366
|
-
ignore: ReadonlyArray<string>;
|
|
368
|
+
ignore: ReadonlyArray<string>;
|
|
369
|
+
/** This is supposed to be used with pnpm's `link-workspace-packages: false` and Berry's `enableTransparentWorkspaces: false` */
|
|
367
370
|
bumpVersionsWithWorkspaceProtocolOnly?: boolean;
|
|
368
371
|
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: Required<ExperimentalOptions>;
|
|
369
372
|
snapshot: {
|
|
@@ -4928,7 +4931,7 @@ declare class VersionFiles {
|
|
|
4928
4931
|
* @param cwd - Project root directory
|
|
4929
4932
|
* @returns Effect of `[filePath, config]` tuples
|
|
4930
4933
|
*/
|
|
4931
|
-
static resolveGlobs(configs: readonly LegacyVersionFileConfig[], cwd: string): Effect.Effect<Array<[string, LegacyVersionFileConfig]>,
|
|
4934
|
+
static resolveGlobs(configs: readonly LegacyVersionFileConfig[], cwd: string): Effect.Effect<Array<[string, LegacyVersionFileConfig]>, GlobExpansionError, FileSystem.FileSystem>;
|
|
4932
4935
|
/**
|
|
4933
4936
|
* Detect indentation from file content.
|
|
4934
4937
|
*
|
|
@@ -5030,7 +5033,7 @@ declare class VersionFiles {
|
|
|
5030
5033
|
name: string;
|
|
5031
5034
|
version: string;
|
|
5032
5035
|
path: string;
|
|
5033
|
-
}>): Effect.Effect<VersionFileUpdate[],
|
|
5036
|
+
}>): Effect.Effect<VersionFileUpdate[], GlobExpansionError, FileSystem.FileSystem>;
|
|
5034
5037
|
/**
|
|
5035
5038
|
* Apply version-file updates from the resolved (post-`ConfigInspector`)
|
|
5036
5039
|
* representation. Each {@link ResolvedPackageScope} already names the
|
|
@@ -5174,7 +5177,7 @@ interface TokenTypeMap {
|
|
|
5174
5177
|
chunkString: 'chunkString';
|
|
5175
5178
|
}
|
|
5176
5179
|
//#endregion
|
|
5177
|
-
//#region ../../node_modules/.pnpm/markdownlint@0.41.1/node_modules/markdownlint/lib/markdownlint.d.mts
|
|
5180
|
+
//#region ../../node_modules/.pnpm/markdownlint@0.41.1_supports-color@8.1.1/node_modules/markdownlint/lib/markdownlint.d.mts
|
|
5178
5181
|
/**
|
|
5179
5182
|
* Function to implement rule logic.
|
|
5180
5183
|
*/
|
|
@@ -5447,7 +5450,7 @@ type Rule$2 = {
|
|
|
5447
5450
|
*/
|
|
5448
5451
|
type RuleConfiguration = boolean | any;
|
|
5449
5452
|
//#endregion
|
|
5450
|
-
//#region ../../node_modules/.pnpm/markdownlint@0.41.1/node_modules/markdownlint/lib/exports.d.mts
|
|
5453
|
+
//#region ../../node_modules/.pnpm/markdownlint@0.41.1_supports-color@8.1.1/node_modules/markdownlint/lib/exports.d.mts
|
|
5451
5454
|
type Rule$1 = Rule$2;
|
|
5452
5455
|
//#endregion
|
|
5453
5456
|
//#region src/changesets/markdownlint/rules/content-structure.d.ts
|
|
@@ -7281,7 +7284,7 @@ declare class Markdown {
|
|
|
7281
7284
|
/**
|
|
7282
7285
|
* Handler for package.json files.
|
|
7283
7286
|
*
|
|
7284
|
-
* Sorts fields with
|
|
7287
|
+
* Sorts fields with @effected/package-json and formats with Biome.
|
|
7285
7288
|
*
|
|
7286
7289
|
* @example
|
|
7287
7290
|
* ```typescript
|
|
@@ -7350,12 +7353,20 @@ declare class PackageJson {
|
|
|
7350
7353
|
* Sort the keys of a package.json document string.
|
|
7351
7354
|
*
|
|
7352
7355
|
* @remarks
|
|
7353
|
-
* Pure transform over the file contents using
|
|
7354
|
-
*
|
|
7355
|
-
* `
|
|
7356
|
+
* Pure transform over the file contents using `@effected/package-json`'s
|
|
7357
|
+
* `PackageJsonFormat.formatToString` — the tolerant text path, which sorts
|
|
7358
|
+
* canonically without decoding through the strict `Package` schema (so a
|
|
7359
|
+
* private or version-less root is sorted rather than rejected). Byte-verified
|
|
7360
|
+
* identical to the previous `sort-package-json` output on this repo's
|
|
7361
|
+
* manifests. Used by the `savvy lint fmt package-json` subcommand so the CLI
|
|
7362
|
+
* does not depend on a sorter directly.
|
|
7363
|
+
*
|
|
7364
|
+
* Unparseable content is returned UNCHANGED rather than throwing: a formatter
|
|
7365
|
+
* must not mangle a file it cannot read, and the surrounding Biome pass
|
|
7366
|
+
* reports the syntax error.
|
|
7356
7367
|
*
|
|
7357
7368
|
* @param content - The raw package.json file contents
|
|
7358
|
-
* @returns The sorted package.json file contents
|
|
7369
|
+
* @returns The sorted package.json file contents, or `content` if unparseable
|
|
7359
7370
|
*/
|
|
7360
7371
|
static sortContent(content: string): string;
|
|
7361
7372
|
/**
|
|
@@ -7433,6 +7444,26 @@ declare class PnpmWorkspace {
|
|
|
7433
7444
|
* @returns Sorted content
|
|
7434
7445
|
*/
|
|
7435
7446
|
static sortContent(content: PnpmWorkspaceContent): PnpmWorkspaceContent;
|
|
7447
|
+
/**
|
|
7448
|
+
* Stringify sorted workspace content to the repo's canonical YAML byte format.
|
|
7449
|
+
*
|
|
7450
|
+
* @remarks
|
|
7451
|
+
* The single source of truth for pnpm-workspace.yaml formatting. Both
|
|
7452
|
+
* {@link create} and the `savvy lint fmt pnpm-workspace` CLI subcommand route
|
|
7453
|
+
* through here so the two paths cannot drift.
|
|
7454
|
+
*
|
|
7455
|
+
* {@link DEFAULT_STRINGIFY_OPTIONS} produces the repo's byte format directly.
|
|
7456
|
+
* The former Prettier post-process — which existed only to re-indent block
|
|
7457
|
+
* sequences and re-quote scalars — is gone: `indentSequences` and
|
|
7458
|
+
* `quoteStyle` now express both, so there is no second printer to drift from.
|
|
7459
|
+
*
|
|
7460
|
+
* Still `async` for source compatibility with existing callers; it performs
|
|
7461
|
+
* no asynchronous work and can become synchronous in the next major.
|
|
7462
|
+
*
|
|
7463
|
+
* @param content - Sorted pnpm-workspace.yaml content
|
|
7464
|
+
* @returns The formatted YAML source
|
|
7465
|
+
*/
|
|
7466
|
+
static formatContent(content: PnpmWorkspaceContent): Promise<string>;
|
|
7436
7467
|
/**
|
|
7437
7468
|
* Create a handler that returns a CLI command to sort/format pnpm-workspace.yaml.
|
|
7438
7469
|
*
|
|
@@ -10238,9 +10269,9 @@ declare const SilkPublishabilityDetectorLive: Layer.Layer<PublishabilityDetector
|
|
|
10238
10269
|
*
|
|
10239
10270
|
* @remarks Requires `FileSystem` and {@link ChangesetConfig} at build.
|
|
10240
10271
|
* The kit's `detect` contract no longer receives the workspace root, so the changeset
|
|
10241
|
-
* lookups
|
|
10242
|
-
*
|
|
10243
|
-
*
|
|
10272
|
+
* lookups read it from `pkg.workspaceRoot` — the discovery root the package was found
|
|
10273
|
+
* against, never a filesystem marker walk, which could escape an unmarked root and read
|
|
10274
|
+
* the wrong `.changeset/config.json`.
|
|
10244
10275
|
*
|
|
10245
10276
|
* @since 0.4.0
|
|
10246
10277
|
* @public
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { Command } from "../utils/Command.js";
|
|
2
2
|
import { Filter } from "../utils/Filter.js";
|
|
3
3
|
import { isWorkspacePackagePath } from "../utils/Workspace.js";
|
|
4
|
+
import { Result } from "effect";
|
|
4
5
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
5
|
-
import
|
|
6
|
+
import { PackageJsonFormat } from "@effected/package-json";
|
|
6
7
|
|
|
7
8
|
//#region src/lint/handlers/PackageJson.ts
|
|
8
9
|
/**
|
|
9
10
|
* Handler for package.json files.
|
|
10
11
|
*
|
|
11
|
-
* Sorts fields with
|
|
12
|
+
* Sorts fields with @effected/package-json and formats with Biome.
|
|
12
13
|
*/
|
|
13
14
|
/**
|
|
14
15
|
* Handler for package.json files.
|
|
15
16
|
*
|
|
16
|
-
* Sorts fields with
|
|
17
|
+
* Sorts fields with @effected/package-json and formats with Biome.
|
|
17
18
|
*
|
|
18
19
|
* @example
|
|
19
20
|
* ```typescript
|
|
@@ -91,15 +92,24 @@ var PackageJson = class PackageJson {
|
|
|
91
92
|
* Sort the keys of a package.json document string.
|
|
92
93
|
*
|
|
93
94
|
* @remarks
|
|
94
|
-
* Pure transform over the file contents using
|
|
95
|
-
*
|
|
96
|
-
* `
|
|
95
|
+
* Pure transform over the file contents using `@effected/package-json`'s
|
|
96
|
+
* `PackageJsonFormat.formatToString` — the tolerant text path, which sorts
|
|
97
|
+
* canonically without decoding through the strict `Package` schema (so a
|
|
98
|
+
* private or version-less root is sorted rather than rejected). Byte-verified
|
|
99
|
+
* identical to the previous `sort-package-json` output on this repo's
|
|
100
|
+
* manifests. Used by the `savvy lint fmt package-json` subcommand so the CLI
|
|
101
|
+
* does not depend on a sorter directly.
|
|
102
|
+
*
|
|
103
|
+
* Unparseable content is returned UNCHANGED rather than throwing: a formatter
|
|
104
|
+
* must not mangle a file it cannot read, and the surrounding Biome pass
|
|
105
|
+
* reports the syntax error.
|
|
97
106
|
*
|
|
98
107
|
* @param content - The raw package.json file contents
|
|
99
|
-
* @returns The sorted package.json file contents
|
|
108
|
+
* @returns The sorted package.json file contents, or `content` if unparseable
|
|
100
109
|
*/
|
|
101
110
|
static sortContent(content) {
|
|
102
|
-
|
|
111
|
+
const result = PackageJsonFormat.formatToString(content);
|
|
112
|
+
return Result.isSuccess(result) ? result.success : content;
|
|
103
113
|
}
|
|
104
114
|
/**
|
|
105
115
|
* Create a handler with custom options.
|
|
@@ -116,7 +126,7 @@ var PackageJson = class PackageJson {
|
|
|
116
126
|
if (filtered.length === 0) return [];
|
|
117
127
|
if (!skipSort) for (const filepath of filtered) {
|
|
118
128
|
const content = readFileSync(filepath, "utf-8");
|
|
119
|
-
const sorted =
|
|
129
|
+
const sorted = PackageJson.sortContent(content);
|
|
120
130
|
if (sorted !== content) writeFileSync(filepath, sorted, "utf-8");
|
|
121
131
|
}
|
|
122
132
|
if (skipFormat) return [];
|
|
@@ -2,7 +2,6 @@ import { Command } from "../utils/Command.js";
|
|
|
2
2
|
import { Effect, Result } from "effect";
|
|
3
3
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { Yaml, YamlStringifyOptions } from "@effected/yaml";
|
|
5
|
-
import { format, resolveConfig } from "prettier";
|
|
6
5
|
|
|
7
6
|
//#region src/lint/handlers/PnpmWorkspace.ts
|
|
8
7
|
/**
|
|
@@ -14,18 +13,21 @@ import { format, resolveConfig } from "prettier";
|
|
|
14
13
|
* Default YAML stringify options for consistent formatting.
|
|
15
14
|
*
|
|
16
15
|
* @remarks
|
|
17
|
-
* `lineWidth: 0` disables line wrapping,
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* and on hostile synthetic shapes (
|
|
24
|
-
* sequences of maps)
|
|
16
|
+
* `lineWidth: 0` disables line wrapping, `indentSequences: true` indents block
|
|
17
|
+
* sequences one level under their key, and `quoteStyle: "double"` selects the
|
|
18
|
+
* quote character for plain scalars that require quoting. Together these
|
|
19
|
+
* reproduce the v3 `yaml.stringify(..., { indent: 2, lineWidth: 0,
|
|
20
|
+
* singleQuote: false })` byte format directly — probed byte-identical to the
|
|
21
|
+
* previous Prettier-normalized output on this repo's real
|
|
22
|
+
* `pnpm-workspace.yaml` and on hostile synthetic shapes (scoped package keys,
|
|
23
|
+
* block scalars, nested sequences of maps), which is what let the Prettier
|
|
24
|
+
* post-process be removed.
|
|
25
25
|
*/
|
|
26
26
|
const DEFAULT_STRINGIFY_OPTIONS = new YamlStringifyOptions({
|
|
27
27
|
indent: 2,
|
|
28
|
-
lineWidth: 0
|
|
28
|
+
lineWidth: 0,
|
|
29
|
+
indentSequences: true,
|
|
30
|
+
quoteStyle: "double"
|
|
29
31
|
});
|
|
30
32
|
/**
|
|
31
33
|
* Handler for pnpm-workspace.yaml.
|
|
@@ -101,6 +103,28 @@ var PnpmWorkspace = class PnpmWorkspace {
|
|
|
101
103
|
return result;
|
|
102
104
|
}
|
|
103
105
|
/**
|
|
106
|
+
* Stringify sorted workspace content to the repo's canonical YAML byte format.
|
|
107
|
+
*
|
|
108
|
+
* @remarks
|
|
109
|
+
* The single source of truth for pnpm-workspace.yaml formatting. Both
|
|
110
|
+
* {@link create} and the `savvy lint fmt pnpm-workspace` CLI subcommand route
|
|
111
|
+
* through here so the two paths cannot drift.
|
|
112
|
+
*
|
|
113
|
+
* {@link DEFAULT_STRINGIFY_OPTIONS} produces the repo's byte format directly.
|
|
114
|
+
* The former Prettier post-process — which existed only to re-indent block
|
|
115
|
+
* sequences and re-quote scalars — is gone: `indentSequences` and
|
|
116
|
+
* `quoteStyle` now express both, so there is no second printer to drift from.
|
|
117
|
+
*
|
|
118
|
+
* Still `async` for source compatibility with existing callers; it performs
|
|
119
|
+
* no asynchronous work and can become synchronous in the next major.
|
|
120
|
+
*
|
|
121
|
+
* @param content - Sorted pnpm-workspace.yaml content
|
|
122
|
+
* @returns The formatted YAML source
|
|
123
|
+
*/
|
|
124
|
+
static async formatContent(content) {
|
|
125
|
+
return Effect.runSync(Yaml.stringify(content, DEFAULT_STRINGIFY_OPTIONS));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
104
128
|
* Create a handler that returns a CLI command to sort/format pnpm-workspace.yaml.
|
|
105
129
|
*
|
|
106
130
|
* @remarks
|
|
@@ -139,11 +163,7 @@ var PnpmWorkspace = class PnpmWorkspace {
|
|
|
139
163
|
let parsed = parseResult.success;
|
|
140
164
|
if (!skipSort) parsed = PnpmWorkspace.sortContent(parsed);
|
|
141
165
|
if (!skipSort || !skipFormat) {
|
|
142
|
-
writeFileSync(filepath, await
|
|
143
|
-
...await resolveConfig(filepath),
|
|
144
|
-
filepath,
|
|
145
|
-
parser: "yaml"
|
|
146
|
-
}), "utf-8");
|
|
166
|
+
writeFileSync(filepath, await PnpmWorkspace.formatContent(parsed), "utf-8");
|
|
147
167
|
return [];
|
|
148
168
|
}
|
|
149
169
|
return [];
|
package/lint/utils/Workspace.js
CHANGED
|
@@ -27,7 +27,7 @@ let cachedPaths = UNRESOLVED;
|
|
|
27
27
|
*/
|
|
28
28
|
function getWorkspaceRoot() {
|
|
29
29
|
if (cachedRoot !== UNRESOLVED) return cachedRoot;
|
|
30
|
-
cachedRoot = findWorkspaceRootSync(nodeSyncOps);
|
|
30
|
+
cachedRoot = findWorkspaceRootSync(process.cwd(), nodeSyncOps);
|
|
31
31
|
return cachedRoot;
|
|
32
32
|
}
|
|
33
33
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@savvy-web/silk-effects",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Shared Effect library for Silk Suite conventions",
|
|
6
6
|
"homepage": "https://github.com/savvy-web/systems/tree/main/packages/silk-effects",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"@changesets/config": "^4.0.0-next.6",
|
|
34
34
|
"@changesets/get-github-info": "^1.0.0-next.3",
|
|
35
35
|
"@changesets/get-release-plan": "^5.0.0-next.7",
|
|
36
|
-
"@effected/git": "^0.4.
|
|
37
|
-
"@effected/glob": "^0.
|
|
38
|
-
"@effected/jsonc": "^0.
|
|
39
|
-
"@effected/package-json": "^0.
|
|
40
|
-
"@effected/walker": "^0.
|
|
41
|
-
"@effected/workspaces": "^0.
|
|
42
|
-
"@effected/yaml": "^0.
|
|
36
|
+
"@effected/git": "^0.4.1",
|
|
37
|
+
"@effected/glob": "^0.2.0",
|
|
38
|
+
"@effected/jsonc": "^0.5.0",
|
|
39
|
+
"@effected/package-json": "^0.4.1",
|
|
40
|
+
"@effected/walker": "^0.3.1",
|
|
41
|
+
"@effected/workspaces": "^0.5.2",
|
|
42
|
+
"@effected/yaml": "^0.5.0",
|
|
43
43
|
"@manypkg/get-packages": "^3.1.0",
|
|
44
44
|
"mdast-util-heading-range": "^4.0.0",
|
|
45
45
|
"mdast-util-to-string": "^4.0.0",
|
|
@@ -48,13 +48,12 @@
|
|
|
48
48
|
"remark-parse": "^11.0.0",
|
|
49
49
|
"remark-stringify": "^11.0.0",
|
|
50
50
|
"shell-quote": "^1.10.0",
|
|
51
|
-
"sort-package-json": "^4.0.0",
|
|
52
51
|
"unified": "^11.0.5",
|
|
53
52
|
"unified-lint-rule": "^3.0.1",
|
|
54
53
|
"unist-util-visit": "^5.1.0",
|
|
55
54
|
"yaml-lint": "^1.7.0"
|
|
56
55
|
},
|
|
57
56
|
"peerDependencies": {
|
|
58
|
-
"effect": "4.0.0-beta.
|
|
57
|
+
"effect": "4.0.0-beta.99"
|
|
59
58
|
}
|
|
60
59
|
}
|
|
@@ -244,34 +244,15 @@ const SilkPublishabilityDetectorLive = Layer.effect(PublishabilityDetector, Effe
|
|
|
244
244
|
}) };
|
|
245
245
|
}));
|
|
246
246
|
/**
|
|
247
|
-
* The workspace root a package was discovered against, derived from its own
|
|
248
|
-
* coordinates: `relativePath` is the package directory relative to the
|
|
249
|
-
* discovery root (POSIX, `"."` for the root package), so ascending one level
|
|
250
|
-
* per path segment from `pkg.path` lands exactly on that root.
|
|
251
|
-
*
|
|
252
|
-
* @remarks
|
|
253
|
-
* Derivation is deliberate — probing the filesystem for workspace markers
|
|
254
|
-
* (`WorkspaceRoot.find`) can walk PAST the intended root when that root
|
|
255
|
-
* carries no marker (a fixture tree, a bare directory) and land on an
|
|
256
|
-
* enclosing workspace, silently swapping in that outer root's
|
|
257
|
-
* `.changeset/config.json` and dropping the ignore/mode gating (the #209
|
|
258
|
-
* regression class). The discovery root needs no probing: whoever built the
|
|
259
|
-
* `WorkspacePackage` already knew it.
|
|
260
|
-
*/
|
|
261
|
-
const packageRoot = (pkg) => {
|
|
262
|
-
const segments = pkg.relativePath.split("/").filter((segment) => segment !== "" && segment !== ".");
|
|
263
|
-
return segments.length === 0 ? pkg.path : join(pkg.path, ...segments.map(() => ".."));
|
|
264
|
-
};
|
|
265
|
-
/**
|
|
266
247
|
* Ignore-aware override of `PublishabilityDetector`. `detect` short-circuits to `[]`
|
|
267
248
|
* for changeset-ignored packages, then dispatches on `ChangesetConfig.mode`:
|
|
268
249
|
* `none` → `[]`; `silk` → `SilkPublishability.detect`; `vanilla` → the library default.
|
|
269
250
|
*
|
|
270
251
|
* @remarks Requires `FileSystem` and {@link ChangesetConfig} at build.
|
|
271
252
|
* The kit's `detect` contract no longer receives the workspace root, so the changeset
|
|
272
|
-
* lookups
|
|
273
|
-
*
|
|
274
|
-
*
|
|
253
|
+
* lookups read it from `pkg.workspaceRoot` — the discovery root the package was found
|
|
254
|
+
* against, never a filesystem marker walk, which could escape an unmarked root and read
|
|
255
|
+
* the wrong `.changeset/config.json`.
|
|
275
256
|
*
|
|
276
257
|
* @since 0.4.0
|
|
277
258
|
* @public
|
|
@@ -281,7 +262,7 @@ const PublishabilityDetectorAdaptiveLive = Layer.effect(PublishabilityDetector,
|
|
|
281
262
|
const config = yield* ChangesetConfig;
|
|
282
263
|
const vanilla = yield* Effect.provide(PublishabilityDetector, PublishabilityDetector.layer);
|
|
283
264
|
return { detect: (pkg) => Effect.gen(function* () {
|
|
284
|
-
const root =
|
|
265
|
+
const root = pkg.workspaceRoot;
|
|
285
266
|
if (yield* config.isIgnored(pkg.name, root)) return [];
|
|
286
267
|
const mode = yield* config.mode(root);
|
|
287
268
|
if (mode === "none") return [];
|