@savvy-web/silk 2.0.0 → 2.1.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.
Files changed (159) hide show
  1. package/README.md +7 -5
  2. package/changesets-changelog.cjs +109 -61
  3. package/changesets-changelog.d.cts +1 -1
  4. package/changesets-changelog.d.ts +1 -1
  5. package/changesets-changelog.js +54099 -1
  6. package/changesets-markdownlint.cjs +109 -61
  7. package/changesets-markdownlint.d.cts +1 -1
  8. package/changesets-markdownlint.d.ts +1 -1
  9. package/changesets-markdownlint.js +54099 -1
  10. package/package.json +5 -4
  11. package/tsconfig/node/dist/tsconfig.tsbuildinfo +1 -1
  12. package/_virtual/_rolldown/runtime.cjs +0 -45
  13. package/_virtual/_rolldown/runtime.js +0 -45
  14. package/packages/silk-effects/dist/dev/pkg/_virtual/_rolldown/runtime.cjs +0 -15
  15. package/packages/silk-effects/dist/dev/pkg/_virtual/_rolldown/runtime.js +0 -14
  16. package/packages/silk-effects/dist/dev/pkg/changesets/api/categories.cjs +0 -247
  17. package/packages/silk-effects/dist/dev/pkg/changesets/api/categories.js +0 -247
  18. package/packages/silk-effects/dist/dev/pkg/changesets/api/changelog.cjs +0 -134
  19. package/packages/silk-effects/dist/dev/pkg/changesets/api/changelog.js +0 -134
  20. package/packages/silk-effects/dist/dev/pkg/changesets/api/dependency-table.cjs +0 -163
  21. package/packages/silk-effects/dist/dev/pkg/changesets/api/dependency-table.js +0 -163
  22. package/packages/silk-effects/dist/dev/pkg/changesets/api/linter.cjs +0 -170
  23. package/packages/silk-effects/dist/dev/pkg/changesets/api/linter.js +0 -170
  24. package/packages/silk-effects/dist/dev/pkg/changesets/api/transformer.cjs +0 -134
  25. package/packages/silk-effects/dist/dev/pkg/changesets/api/transformer.js +0 -134
  26. package/packages/silk-effects/dist/dev/pkg/changesets/categories/index.cjs +0 -317
  27. package/packages/silk-effects/dist/dev/pkg/changesets/categories/index.js +0 -299
  28. package/packages/silk-effects/dist/dev/pkg/changesets/categories/types.cjs +0 -65
  29. package/packages/silk-effects/dist/dev/pkg/changesets/categories/types.js +0 -65
  30. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/formatting.cjs +0 -114
  31. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/formatting.js +0 -113
  32. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/getDependencyReleaseLine.cjs +0 -118
  33. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/getDependencyReleaseLine.js +0 -118
  34. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/getReleaseLine.cjs +0 -122
  35. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/getReleaseLine.js +0 -122
  36. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/index.cjs +0 -97
  37. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/index.js +0 -97
  38. package/packages/silk-effects/dist/dev/pkg/changesets/constants.cjs +0 -43
  39. package/packages/silk-effects/dist/dev/pkg/changesets/constants.js +0 -42
  40. package/packages/silk-effects/dist/dev/pkg/changesets/errors.cjs +0 -386
  41. package/packages/silk-effects/dist/dev/pkg/changesets/errors.js +0 -371
  42. package/packages/silk-effects/dist/dev/pkg/changesets/index.cjs +0 -300
  43. package/packages/silk-effects/dist/dev/pkg/changesets/index.js +0 -179
  44. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/index.cjs +0 -34
  45. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/index.js +0 -29
  46. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/content-structure.cjs +0 -98
  47. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/content-structure.js +0 -98
  48. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/dependency-table-format.cjs +0 -170
  49. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/dependency-table-format.js +0 -170
  50. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/heading-hierarchy.cjs +0 -61
  51. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/heading-hierarchy.js +0 -61
  52. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/required-sections.cjs +0 -54
  53. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/required-sections.js +0 -54
  54. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/uncategorized-content.cjs +0 -54
  55. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/uncategorized-content.js +0 -54
  56. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/utils.cjs +0 -31
  57. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/utils.js +0 -30
  58. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/aggregate-dependency-tables.cjs +0 -47
  59. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/aggregate-dependency-tables.js +0 -47
  60. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/contributor-footnotes.cjs +0 -123
  61. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/contributor-footnotes.js +0 -123
  62. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/deduplicate-items.cjs +0 -32
  63. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/deduplicate-items.js +0 -32
  64. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/issue-link-refs.cjs +0 -59
  65. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/issue-link-refs.js +0 -59
  66. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/maintenance-note.cjs +0 -61
  67. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/maintenance-note.js +0 -61
  68. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/merge-sections.cjs +0 -43
  69. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/merge-sections.js +0 -43
  70. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/normalize-format.cjs +0 -47
  71. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/normalize-format.js +0 -47
  72. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/reorder-sections.cjs +0 -34
  73. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/reorder-sections.js +0 -34
  74. package/packages/silk-effects/dist/dev/pkg/changesets/remark/presets.cjs +0 -120
  75. package/packages/silk-effects/dist/dev/pkg/changesets/remark/presets.js +0 -119
  76. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/content-structure.cjs +0 -22
  77. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/content-structure.js +0 -22
  78. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/dependency-table-format.cjs +0 -40
  79. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/dependency-table-format.js +0 -40
  80. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/heading-hierarchy.cjs +0 -19
  81. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/heading-hierarchy.js +0 -19
  82. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/required-sections.cjs +0 -17
  83. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/required-sections.js +0 -17
  84. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/uncategorized-content.cjs +0 -31
  85. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/uncategorized-content.js +0 -31
  86. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/changeset.cjs +0 -148
  87. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/changeset.js +0 -145
  88. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/dependency-table.cjs +0 -203
  89. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/dependency-table.js +0 -198
  90. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/git.cjs +0 -69
  91. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/git.js +0 -68
  92. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/github.cjs +0 -177
  93. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/github.js +0 -174
  94. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/options.cjs +0 -183
  95. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/options.js +0 -181
  96. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/package-scope.cjs +0 -129
  97. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/package-scope.js +0 -127
  98. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/primitives.cjs +0 -72
  99. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/primitives.js +0 -71
  100. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/release-plan.cjs +0 -62
  101. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/release-plan.js +0 -56
  102. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/version-files.cjs +0 -154
  103. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/version-files.js +0 -150
  104. package/packages/silk-effects/dist/dev/pkg/changesets/services/branch-analyzer.cjs +0 -300
  105. package/packages/silk-effects/dist/dev/pkg/changesets/services/branch-analyzer.js +0 -294
  106. package/packages/silk-effects/dist/dev/pkg/changesets/services/changelog.cjs +0 -50
  107. package/packages/silk-effects/dist/dev/pkg/changesets/services/changelog.js +0 -49
  108. package/packages/silk-effects/dist/dev/pkg/changesets/services/config-inspector.cjs +0 -489
  109. package/packages/silk-effects/dist/dev/pkg/changesets/services/config-inspector.js +0 -481
  110. package/packages/silk-effects/dist/dev/pkg/changesets/services/deps-regen.cjs +0 -375
  111. package/packages/silk-effects/dist/dev/pkg/changesets/services/deps-regen.js +0 -371
  112. package/packages/silk-effects/dist/dev/pkg/changesets/services/github.cjs +0 -160
  113. package/packages/silk-effects/dist/dev/pkg/changesets/services/github.js +0 -157
  114. package/packages/silk-effects/dist/dev/pkg/changesets/services/maintenance-reason.cjs +0 -68
  115. package/packages/silk-effects/dist/dev/pkg/changesets/services/maintenance-reason.js +0 -66
  116. package/packages/silk-effects/dist/dev/pkg/changesets/services/markdown.cjs +0 -87
  117. package/packages/silk-effects/dist/dev/pkg/changesets/services/markdown.js +0 -85
  118. package/packages/silk-effects/dist/dev/pkg/changesets/services/release-planner.cjs +0 -352
  119. package/packages/silk-effects/dist/dev/pkg/changesets/services/release-planner.js +0 -348
  120. package/packages/silk-effects/dist/dev/pkg/changesets/utils/commit-parser.cjs +0 -81
  121. package/packages/silk-effects/dist/dev/pkg/changesets/utils/commit-parser.js +0 -80
  122. package/packages/silk-effects/dist/dev/pkg/changesets/utils/dep-diff.cjs +0 -111
  123. package/packages/silk-effects/dist/dev/pkg/changesets/utils/dep-diff.js +0 -111
  124. package/packages/silk-effects/dist/dev/pkg/changesets/utils/dependency-table.cjs +0 -351
  125. package/packages/silk-effects/dist/dev/pkg/changesets/utils/dependency-table.js +0 -347
  126. package/packages/silk-effects/dist/dev/pkg/changesets/utils/git.cjs +0 -51
  127. package/packages/silk-effects/dist/dev/pkg/changesets/utils/git.js +0 -51
  128. package/packages/silk-effects/dist/dev/pkg/changesets/utils/issue-refs.cjs +0 -102
  129. package/packages/silk-effects/dist/dev/pkg/changesets/utils/issue-refs.js +0 -101
  130. package/packages/silk-effects/dist/dev/pkg/changesets/utils/jsonpath.cjs +0 -178
  131. package/packages/silk-effects/dist/dev/pkg/changesets/utils/jsonpath.js +0 -175
  132. package/packages/silk-effects/dist/dev/pkg/changesets/utils/logger.cjs +0 -51
  133. package/packages/silk-effects/dist/dev/pkg/changesets/utils/logger.js +0 -50
  134. package/packages/silk-effects/dist/dev/pkg/changesets/utils/markdown-link.cjs +0 -59
  135. package/packages/silk-effects/dist/dev/pkg/changesets/utils/markdown-link.js +0 -57
  136. package/packages/silk-effects/dist/dev/pkg/changesets/utils/publishability.cjs +0 -50
  137. package/packages/silk-effects/dist/dev/pkg/changesets/utils/publishability.js +0 -50
  138. package/packages/silk-effects/dist/dev/pkg/changesets/utils/remark-pipeline.cjs +0 -81
  139. package/packages/silk-effects/dist/dev/pkg/changesets/utils/remark-pipeline.js +0 -79
  140. package/packages/silk-effects/dist/dev/pkg/changesets/utils/section-parser.cjs +0 -94
  141. package/packages/silk-effects/dist/dev/pkg/changesets/utils/section-parser.js +0 -94
  142. package/packages/silk-effects/dist/dev/pkg/changesets/utils/strip-frontmatter.cjs +0 -47
  143. package/packages/silk-effects/dist/dev/pkg/changesets/utils/strip-frontmatter.js +0 -46
  144. package/packages/silk-effects/dist/dev/pkg/changesets/utils/version-blocks.cjs +0 -110
  145. package/packages/silk-effects/dist/dev/pkg/changesets/utils/version-blocks.js +0 -108
  146. package/packages/silk-effects/dist/dev/pkg/changesets/utils/version-files.cjs +0 -336
  147. package/packages/silk-effects/dist/dev/pkg/changesets/utils/version-files.js +0 -336
  148. package/packages/silk-effects/dist/dev/pkg/changesets/vendor/github-info.cjs +0 -77
  149. package/packages/silk-effects/dist/dev/pkg/changesets/vendor/github-info.js +0 -77
  150. package/packages/silk-effects/dist/dev/pkg/errors/ChangesetConfigError.cjs +0 -21
  151. package/packages/silk-effects/dist/dev/pkg/errors/ChangesetConfigError.js +0 -21
  152. package/packages/silk-effects/dist/dev/pkg/schemas/VersioningSchemas.cjs +0 -101
  153. package/packages/silk-effects/dist/dev/pkg/schemas/VersioningSchemas.js +0 -99
  154. package/packages/silk-effects/dist/dev/pkg/services/ChangesetConfig.cjs +0 -81
  155. package/packages/silk-effects/dist/dev/pkg/services/ChangesetConfig.js +0 -80
  156. package/packages/silk-effects/dist/dev/pkg/services/ChangesetConfigReader.cjs +0 -109
  157. package/packages/silk-effects/dist/dev/pkg/services/ChangesetConfigReader.js +0 -108
  158. package/packages/silk-effects/dist/dev/pkg/services/SilkPublishability.cjs +0 -238
  159. package/packages/silk-effects/dist/dev/pkg/services/SilkPublishability.js +0 -236
@@ -1,481 +0,0 @@
1
- import { ChangesetConfigReader } from "../../services/ChangesetConfigReader.js";
2
- import { WorkspaceDiscovery } from "../../../../../../../node_modules/.pnpm/workspaces-effect@2.0.1_@effect_platform@0.96.2_effect@3.21.4__effect@3.21.4/node_modules/workspaces-effect/services/WorkspaceDiscovery.js";
3
- import { SilkPublishability, readTargetsBinding } from "../../services/SilkPublishability.js";
4
- import { ConfigurationError } from "../errors.js";
5
- import { ChangesetOptionsSchema } from "../schemas/options.js";
6
- import { globSync } from "../../../../../../../node_modules/.pnpm/tinyglobby@0.2.17/node_modules/tinyglobby/dist/index.js";
7
- import { Context, Effect, Layer, Schema } from "effect";
8
- import { FileSystem } from "@effect/platform";
9
- import { isAbsolute, join, relative, resolve } from "node:path";
10
-
11
- //#region ../silk-effects/dist/dev/pkg/changesets/services/config-inspector.js
12
- /**
13
- * `ConfigInspector` service — surface the project's `.changeset/config.json`
14
- * in a structured, validated form that agents and tooling can consume.
15
- *
16
- * @remarks
17
- * The inspector handles three responsibilities that the schemas alone cannot:
18
- *
19
- * 1. **Legacy normalization.** Configs from 0.8.x still use the flat
20
- * top-level `versionFiles[]` array. When that field is populated, the
21
- * inspector emits a one-line deprecation warning to stderr (naming the
22
- * config path and the required edit) and folds each legacy entry into
23
- * the equivalent `packages[entry.package].versionFiles` shape for
24
- * downstream consumers. Removed in 1.0.0.
25
- * 2. **Resolution against the workspace.** Each `packages` key must resolve
26
- * to a known workspace package via `WorkspaceDiscovery`. Unknown keys
27
- * surface as a {@link ConfigurationError}. The inspector returns the
28
- * package's absolute workspace directory alongside the resolved scope.
29
- * 3. **Overlap detection.** Cross-package validation rules that the schemas
30
- * cannot enforce:
31
- * - `additionalScopes` of two different packages must not overlap.
32
- * - `additionalScopes` of one package must not shadow another package's
33
- * workspace directory.
34
- * - Two `versionFiles` entries (within or across packages) must not
35
- * resolve to the same `(file, $.path)` tuple.
36
- *
37
- * Validation is performed eagerly on the first {@link ConfigInspectorShape.inspect}
38
- * call. The resolved state is cached internally per `cwd` so subsequent
39
- * {@link ConfigInspectorShape.classify} calls reuse it.
40
- *
41
- * @see {@link ConfigInspector} for the Effect service tag
42
- * @see {@link ConfigInspectorLive} for the production layer
43
- *
44
- */
45
- /** A `versionFiles` entry expanded to its absolute target paths. @public */
46
- const ResolvedVersionFileSchema = Schema.Struct({
47
- glob: Schema.String,
48
- paths: Schema.Array(Schema.String).annotations({ description: "JSONPath expressions to update (defaults to [\"$.version\"])." }),
49
- matchedFiles: Schema.Array(Schema.String)
50
- }).annotations({ identifier: "ResolvedVersionFile" });
51
- /** A package's resolved release surface. @public */
52
- const ResolvedPackageScopeSchema = Schema.Struct({
53
- name: Schema.String,
54
- workspaceDir: Schema.String,
55
- version: Schema.String,
56
- additionalScopes: Schema.Array(Schema.String),
57
- additionalScopeFiles: Schema.Array(Schema.String),
58
- versionFiles: Schema.Array(ResolvedVersionFileSchema)
59
- }).annotations({ identifier: "ResolvedPackageScope" });
60
- /** Structured representation of a resolved `.changeset/config.json`. @public */
61
- const InspectedConfigSchema = Schema.Struct({
62
- configPath: Schema.String,
63
- projectDir: Schema.String.annotations({ description: "Absolute project root (the directory containing .changeset/)." }),
64
- changelog: Schema.NullOr(Schema.String),
65
- baseBranch: Schema.String,
66
- access: Schema.Literal("public", "restricted"),
67
- ignore: Schema.Array(Schema.String),
68
- packages: Schema.Array(ResolvedPackageScopeSchema),
69
- legacyVersionFilesUsed: Schema.Boolean
70
- }).annotations({ identifier: "InspectedConfig" });
71
- /** Reason a path was attributed to a package (or left unmapped). @public */
72
- const ClassificationReasonSchema = Schema.Union(Schema.Literal("workspace"), Schema.Struct({
73
- kind: Schema.Literal("additionalScope"),
74
- glob: Schema.String
75
- }), Schema.Struct({
76
- kind: Schema.Literal("versionFile"),
77
- glob: Schema.String
78
- }), Schema.Null).annotations({ identifier: "ClassificationReason" });
79
- /** The result of classifying a single path against a resolved config. @public */
80
- const ClassificationSchema = Schema.Struct({
81
- path: Schema.String,
82
- package: Schema.NullOr(Schema.String),
83
- reason: ClassificationReasonSchema
84
- }).annotations({ identifier: "Classification" });
85
- /**
86
- * Base class for {@link ConfigInspector}.
87
- *
88
- * @privateRemarks
89
- * Effect's `Context.Tag` creates an anonymous base class that api-extractor
90
- * cannot follow without an explicit export. Do not delete.
91
- *
92
- * @internal
93
- */
94
- const ConfigInspectorBase = Context.Tag("ConfigInspector")();
95
- /**
96
- * Effect service tag for {@link ConfigInspectorShape}.
97
- *
98
- * @example
99
- * ```typescript
100
- * import { Effect } from "effect";
101
- * import { ConfigInspector, ConfigInspectorLive } from "@savvy-web/changesets";
102
- *
103
- * const program = Effect.gen(function* () {
104
- * const inspector = yield* ConfigInspector;
105
- * const config = yield* inspector.inspect(process.cwd());
106
- * return config.packages.map((p) => p.name);
107
- * });
108
- *
109
- * Effect.runPromise(program.pipe(Effect.provide(ConfigInspectorLive)));
110
- * ```
111
- *
112
- * @public
113
- */
114
- var ConfigInspector = class extends ConfigInspectorBase {};
115
- /**
116
- * Pull the changelog formatter ID and its options object out of the raw
117
- * `.changeset/config.json` shape (where `changelog` may be a tuple, a string,
118
- * or absent).
119
- */
120
- function extractChangelogOptions(config) {
121
- const { changelog } = config;
122
- if (Array.isArray(changelog)) return {
123
- changelogId: typeof changelog[0] === "string" ? changelog[0] : null,
124
- options: changelog[1] ?? {}
125
- };
126
- if (typeof changelog === "string") return {
127
- changelogId: changelog,
128
- options: {}
129
- };
130
- return {
131
- changelogId: null,
132
- options: {}
133
- };
134
- }
135
- /**
136
- * Normalize the deprecated top-level `versionFiles[]` array into the
137
- * equivalent `packages[entry.package].versionFiles` shape. Mutates a fresh
138
- * copy of the options; never the input.
139
- *
140
- * Returns the normalized options and a flag indicating whether normalization
141
- * happened (so the caller can emit a deprecation warning once per inspect).
142
- */
143
- function normalizeLegacyOptions(options, configPath) {
144
- const legacy = options.versionFiles;
145
- if (!Array.isArray(legacy) || legacy.length === 0) return {
146
- normalized: options,
147
- legacyUsed: false
148
- };
149
- console.warn(`[changesets] DEPRECATION: ${configPath} uses the top-level \`versionFiles\` array. Migrate to \`changelog[1].packages[<name>].versionFiles\`. Removed in 1.0.0.`);
150
- const existing = options.packages ?? {};
151
- const next = {};
152
- for (const [k, v] of Object.entries(existing)) next[k] = { ...v };
153
- for (const entry of legacy) {
154
- const ownerName = typeof entry.package === "string" ? entry.package : void 0;
155
- if (!ownerName) throw new ConfigurationError({
156
- field: "versionFiles",
157
- reason: `Legacy versionFiles entry { glob: ${JSON.stringify(entry.glob)} } in ${configPath} has no \`package\` field. Path-based owner inference is removed during the 0.9.0 migration — add an explicit \`package\` field, or migrate the entry to \`packages[<name>].versionFiles\`.`
158
- });
159
- if (!next[ownerName]) next[ownerName] = {};
160
- const slot = next[ownerName];
161
- const arr = Array.isArray(slot.versionFiles) ? slot.versionFiles.slice() : [];
162
- const cleaned = { glob: entry.glob };
163
- if (Array.isArray(entry.paths)) cleaned.paths = entry.paths;
164
- arr.push(cleaned);
165
- slot.versionFiles = arr;
166
- }
167
- const normalized = {
168
- ...options,
169
- packages: next
170
- };
171
- delete normalized.versionFiles;
172
- return {
173
- normalized,
174
- legacyUsed: true
175
- };
176
- }
177
- /**
178
- * Materialize a glob against `cwd` and return the matched file paths as
179
- * repo-relative strings. Honors negation patterns and ignores `node_modules`.
180
- */
181
- function materializeGlob(glob, cwd) {
182
- return globSync(glob, {
183
- cwd,
184
- ignore: ["**/node_modules/**"],
185
- dot: true
186
- });
187
- }
188
- /**
189
- * Determine whether `child` is the same directory as `parent` or sits inside
190
- * it. Both paths must be absolute.
191
- */
192
- function isInside(parent, child) {
193
- const rel = relative(parent, child);
194
- return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
195
- }
196
- /**
197
- * Build per-package resolved scopes by intersecting the (possibly normalized)
198
- * options with workspace info.
199
- */
200
- function buildResolvedScopes(params) {
201
- const { options, workspaces, projectDir, configPath } = params;
202
- const packages = options.packages ?? {};
203
- const workspacesByName = new Map(workspaces.map((w) => [w.name, w]));
204
- const scopes = [];
205
- for (const [pkgName, scope] of Object.entries(packages)) {
206
- const ws = workspacesByName.get(pkgName);
207
- if (!ws) throw new ConfigurationError({
208
- field: `packages["${pkgName}"]`,
209
- reason: `Unknown package "${pkgName}" in ${configPath}. Known workspace packages: ${workspaces.map((w) => w.name).join(", ") || "(none)"}.`
210
- });
211
- const additionalScopes = scope.additionalScopes ?? [];
212
- const additionalScopeFiles = additionalScopes.flatMap((g) => materializeGlob(g, projectDir));
213
- const resolvedVersionFiles = (scope.versionFiles ?? []).map((entry) => ({
214
- glob: entry.glob,
215
- paths: entry.paths ?? ["$.version"],
216
- matchedFiles: materializeGlob(entry.glob, projectDir).map((rel) => join(projectDir, rel))
217
- }));
218
- scopes.push({
219
- name: pkgName,
220
- workspaceDir: ws.path,
221
- version: ws.version,
222
- additionalScopes,
223
- additionalScopeFiles: additionalScopeFiles.map((rel) => join(projectDir, rel)),
224
- versionFiles: resolvedVersionFiles
225
- });
226
- }
227
- return scopes;
228
- }
229
- /**
230
- * Read a workspace package's raw package.json. A genuinely missing manifest
231
- * resolves to `null` so the caller can skip that package — a workspace
232
- * directory without a `package.json` is not a release surface. Any OTHER
233
- * failure (unreadable file, malformed JSON) is surfaced as a
234
- * {@link ConfigurationError} carrying the package path, rather than silently
235
- * dropping the package, which would cascade into wrong attribution.
236
- */
237
- function readRawPackageJson(fs, pkgDir) {
238
- const pkgJsonPath = join(pkgDir, "package.json");
239
- return fs.readFileString(pkgJsonPath).pipe(Effect.flatMap((content) => Effect.try(() => JSON.parse(content))), Effect.catchAll((err) => {
240
- if (err.reason === "NotFound") return Effect.succeed(null);
241
- return Effect.fail(new ConfigurationError({
242
- field: "workspace",
243
- reason: `Failed to read or parse ${pkgJsonPath}: ${err instanceof Error ? err.message : String(err)}`
244
- }));
245
- }));
246
- }
247
- /**
248
- * Build resolved scopes from the discovered workspace packages, keeping only
249
- * those that are a release surface (declare publishConfig that yields at least
250
- * one publish target). Used both when `.changeset/config.json` declares no
251
- * explicit `packages` record AND to augment an explicit record with the
252
- * remaining workspace packages it does not list (so the record annotates the
253
- * listed packages without shrinking the release surface). The changeset
254
- * `ignore` list is intentionally NOT consulted here — an ignored package still
255
- * declares publishConfig and remains a valid changeset target.
256
- */
257
- function buildFallbackScopes(fs, workspaces) {
258
- return Effect.forEach(workspaces, (ws) => Effect.gen(function* () {
259
- const raw = yield* readRawPackageJson(fs, ws.path);
260
- if (raw === null) return [];
261
- const binding = yield* readTargetsBinding(fs, ws.path);
262
- if (SilkPublishability.detect(ws.name, raw, binding).length === 0) return [];
263
- return [{
264
- name: ws.name,
265
- workspaceDir: ws.path,
266
- version: ws.version,
267
- additionalScopes: [],
268
- additionalScopeFiles: [],
269
- versionFiles: []
270
- }];
271
- })).pipe(Effect.map((nested) => nested.flat()));
272
- }
273
- /**
274
- * Cross-package validation: no overlap in `additionalScopes`, no shadowing
275
- * of another workspace package's directory (regardless of whether that
276
- * package is itself declared in `config.packages`), and no duplicate
277
- * `(file, JSONPath)` tuples in `versionFiles`.
278
- */
279
- function checkConflicts(scopes, allWorkspaces, projectDir, configPath) {
280
- const scopeOwner = /* @__PURE__ */ new Map();
281
- for (const s of scopes) for (const f of s.additionalScopeFiles) {
282
- const prev = scopeOwner.get(f);
283
- if (prev && prev !== s.name) throw new ConfigurationError({
284
- field: `packages["${s.name}"].additionalScopes`,
285
- reason: `Overlap in ${configPath}: file ${JSON.stringify(f)} is matched by both "${prev}" and "${s.name}". additionalScopes must not overlap between packages.`
286
- });
287
- scopeOwner.set(f, s.name);
288
- }
289
- for (const s of scopes) for (const f of s.additionalScopeFiles) for (const ws of allWorkspaces) {
290
- if (ws.name === s.name) continue;
291
- if (ws.path === projectDir) continue;
292
- if (isInside(ws.path, f)) throw new ConfigurationError({
293
- field: `packages["${s.name}"].additionalScopes`,
294
- reason: `Shadowing in ${configPath}: "${s.name}" claims ${JSON.stringify(f)} via additionalScopes, but that path is inside "${ws.name}"'s workspace directory (${ws.path}). A package's additionalScopes must not include another package's workspace files.`
295
- });
296
- }
297
- const seen = /* @__PURE__ */ new Map();
298
- for (const s of scopes) for (const vf of s.versionFiles) for (const file of vf.matchedFiles) for (const path of vf.paths) {
299
- const key = `${file}::${path}`;
300
- const prev = seen.get(key);
301
- if (prev && (prev.pkg !== s.name || prev.glob !== vf.glob)) throw new ConfigurationError({
302
- field: `packages["${s.name}"].versionFiles`,
303
- reason: `Conflict in ${configPath}: target (${JSON.stringify(file)}, ${path}) is claimed by both "${prev.pkg}" (glob ${JSON.stringify(prev.glob)}) and "${s.name}" (glob ${JSON.stringify(vf.glob)}). Two versionFiles entries must not resolve to the same (file, JSONPath) tuple.`
304
- });
305
- seen.set(key, {
306
- pkg: s.name,
307
- glob: vf.glob
308
- });
309
- }
310
- }
311
- /**
312
- * Build a `ConfigurationError` from a Schema `ParseError`. Captures the
313
- * original message verbatim so the user sees exactly what the schema
314
- * complained about.
315
- */
316
- function configErrorFromParseError(parseError, configPath) {
317
- return new ConfigurationError({
318
- field: "options",
319
- reason: `Invalid options in ${configPath}: ${String(parseError)}`
320
- });
321
- }
322
- /**
323
- * Build a {@link ConfigInspectorShape} that closes over already-resolved
324
- * service implementations. This keeps the public `inspect`/`classify`
325
- * signatures requirement-free (`R = never`) while still allowing the
326
- * implementation to use `ChangesetConfigReader` and `WorkspaceDiscovery`.
327
- *
328
- * Each shape carries a private cache keyed by absolute project dir so
329
- * repeat `inspect`/`classify` calls reuse the materialized state.
330
- */
331
- function makeShape(reader, discovery, fs) {
332
- const cache = /* @__PURE__ */ new Map();
333
- const inspect = (cwd) => Effect.gen(function* () {
334
- const projectDir = resolve(cwd);
335
- const cached = cache.get(projectDir);
336
- if (cached) return cached;
337
- const config = yield* reader.read(projectDir).pipe(Effect.mapError((err) => new ConfigurationError({
338
- field: "configFile",
339
- reason: err.message
340
- })));
341
- const configPath = join(projectDir, ".changeset", "config.json");
342
- const { changelogId, options: rawOptions } = extractChangelogOptions(config);
343
- const optionsRecord = typeof rawOptions === "object" && rawOptions !== null ? rawOptions : {};
344
- if (Array.isArray(optionsRecord.versionFiles) && typeof optionsRecord.packages === "object" && optionsRecord.packages !== null) return yield* Effect.fail(new ConfigurationError({
345
- field: "options",
346
- reason: `Configuration in ${configPath} declares both \`packages\` and the deprecated top-level \`versionFiles\` array. Migrate the legacy entries into \`packages[<name>].versionFiles\` and remove the top-level field.`
347
- }));
348
- let normalized;
349
- let legacyUsed;
350
- try {
351
- const result = normalizeLegacyOptions(optionsRecord, configPath);
352
- normalized = result.normalized;
353
- legacyUsed = result.legacyUsed;
354
- } catch (e) {
355
- if (e instanceof ConfigurationError) return yield* Effect.fail(e);
356
- throw e;
357
- }
358
- const decodedOptions = yield* Schema.decodeUnknown(ChangesetOptionsSchema)(normalized).pipe(Effect.mapError((parseError) => configErrorFromParseError(parseError, configPath)));
359
- const workspaces = (yield* discovery.listPackages(projectDir).pipe(Effect.mapError((err) => new ConfigurationError({
360
- field: "workspace",
361
- reason: `Workspace discovery failed for ${projectDir}: ${err.message}`
362
- })))).map((w) => ({
363
- name: w.name,
364
- path: w.path,
365
- version: w.version
366
- }));
367
- const hasExplicitPackages = Object.keys(decodedOptions.packages ?? {}).length > 0;
368
- let scopes;
369
- if (hasExplicitPackages) {
370
- let explicitScopes;
371
- try {
372
- explicitScopes = buildResolvedScopes({
373
- options: decodedOptions,
374
- workspaces,
375
- projectDir,
376
- configPath
377
- });
378
- checkConflicts(explicitScopes, workspaces, projectDir, configPath);
379
- } catch (e) {
380
- if (e instanceof ConfigurationError) return yield* Effect.fail(e);
381
- throw e;
382
- }
383
- const explicitNames = new Set(explicitScopes.map((s) => s.name));
384
- const discoveredScopes = yield* buildFallbackScopes(fs, workspaces.filter((w) => !explicitNames.has(w.name)));
385
- scopes = [...explicitScopes, ...discoveredScopes];
386
- } else scopes = yield* buildFallbackScopes(fs, workspaces);
387
- const inspected = {
388
- configPath,
389
- projectDir,
390
- changelog: changelogId,
391
- baseBranch: config.baseBranch ?? "main",
392
- access: config.access ?? "restricted",
393
- ignore: config.ignore ?? [],
394
- packages: scopes,
395
- legacyVersionFilesUsed: legacyUsed
396
- };
397
- cache.set(projectDir, inspected);
398
- return inspected;
399
- });
400
- const classify = (cwd, paths) => Effect.gen(function* () {
401
- const inspected = yield* inspect(cwd);
402
- return paths.map((p) => classifyOne(inspected, p));
403
- });
404
- return {
405
- inspect,
406
- classify
407
- };
408
- }
409
- /**
410
- * Classify a single path against an inspected config.
411
- */
412
- function classifyOne(inspected, path) {
413
- const abs = resolve(inspected.projectDir, path);
414
- let bestWorkspace = null;
415
- for (const s of inspected.packages) if (isInside(s.workspaceDir, abs)) {
416
- const depth = s.workspaceDir.length;
417
- if (!bestWorkspace || depth > bestWorkspace.depth) bestWorkspace = {
418
- pkg: s.name,
419
- depth
420
- };
421
- }
422
- if (bestWorkspace) return {
423
- path,
424
- package: bestWorkspace.pkg,
425
- reason: "workspace"
426
- };
427
- for (const s of inspected.packages) if (s.additionalScopeFiles.includes(abs)) {
428
- const glob = s.additionalScopes.find((g) => materializeGlob(g, inspected.projectDir).map((rel) => join(inspected.projectDir, rel)).includes(abs));
429
- return {
430
- path,
431
- package: s.name,
432
- reason: {
433
- kind: "additionalScope",
434
- glob: glob ?? s.additionalScopes[0] ?? ""
435
- }
436
- };
437
- }
438
- for (const s of inspected.packages) for (const vf of s.versionFiles) if (vf.matchedFiles.includes(abs)) return {
439
- path,
440
- package: s.name,
441
- reason: {
442
- kind: "versionFile",
443
- glob: vf.glob
444
- }
445
- };
446
- return {
447
- path,
448
- package: null,
449
- reason: null
450
- };
451
- }
452
- /**
453
- * Live layer for {@link ConfigInspector}.
454
- *
455
- * Requires {@link ChangesetConfigReader} and `WorkspaceDiscovery`
456
- * in the environment.
457
- *
458
- * @public
459
- */
460
- const ConfigInspectorLive = Layer.effect(ConfigInspector, Effect.gen(function* () {
461
- return makeShape(yield* ChangesetConfigReader, yield* WorkspaceDiscovery, yield* FileSystem.FileSystem);
462
- }));
463
- /**
464
- * Test factory — build a {@link ConfigInspector} that returns a fixed
465
- * {@link InspectedConfig} without touching the filesystem.
466
- *
467
- * Tests that need to exercise the inspect/classify logic against real files
468
- * should compose `ConfigInspectorLive` with test layers for
469
- * `ChangesetConfigReader` and `WorkspaceDiscovery` instead.
470
- *
471
- * @public
472
- */
473
- function makeConfigInspectorTest(fixed) {
474
- return Layer.succeed(ConfigInspector, {
475
- inspect: () => Effect.succeed(fixed),
476
- classify: (_cwd, paths) => Effect.succeed(paths.map((p) => classifyOne(fixed, p)))
477
- });
478
- }
479
-
480
- //#endregion
481
- export { ClassificationReasonSchema, ClassificationSchema, ConfigInspector, ConfigInspectorBase, ConfigInspectorLive, InspectedConfigSchema, ResolvedPackageScopeSchema, ResolvedVersionFileSchema, makeConfigInspectorTest };