@aneuhold/core-ts-lib 2.2.9 → 2.2.11
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/lib/index.d.ts +5 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -2
- package/lib/index.js.map +1 -1
- package/lib/index.ts +5 -2
- package/lib/services/ChangelogService/ChangelogFileService.d.ts +42 -0
- package/lib/services/ChangelogService/ChangelogFileService.d.ts.map +1 -0
- package/lib/services/ChangelogService/ChangelogFileService.js +65 -0
- package/lib/services/ChangelogService/ChangelogFileService.js.map +1 -0
- package/lib/services/ChangelogService/ChangelogFileService.ts +68 -0
- package/lib/services/ChangelogService/ChangelogGenerator.d.ts +58 -0
- package/lib/services/ChangelogService/ChangelogGenerator.d.ts.map +1 -0
- package/lib/services/ChangelogService/ChangelogGenerator.js +145 -0
- package/lib/services/ChangelogService/ChangelogGenerator.js.map +1 -0
- package/lib/services/ChangelogService/ChangelogGenerator.ts +188 -0
- package/lib/services/ChangelogService/ChangelogParser.d.ts +21 -0
- package/lib/services/ChangelogService/ChangelogParser.d.ts.map +1 -0
- package/lib/services/ChangelogService/ChangelogParser.js +76 -0
- package/lib/services/ChangelogService/ChangelogParser.js.map +1 -0
- package/lib/services/ChangelogService/ChangelogParser.ts +94 -0
- package/lib/services/ChangelogService/ChangelogService.d.ts +54 -0
- package/lib/services/ChangelogService/ChangelogService.d.ts.map +1 -0
- package/lib/services/ChangelogService/ChangelogService.js +201 -0
- package/lib/services/ChangelogService/ChangelogService.js.map +1 -0
- package/lib/services/ChangelogService/ChangelogService.ts +293 -0
- package/lib/services/ChangelogService/ChangelogValidator.d.ts +15 -0
- package/lib/services/ChangelogService/ChangelogValidator.d.ts.map +1 -0
- package/lib/services/ChangelogService/ChangelogValidator.js +44 -0
- package/lib/services/ChangelogService/ChangelogValidator.js.map +1 -0
- package/lib/services/ChangelogService/ChangelogValidator.ts +55 -0
- package/lib/services/ChangelogService/GitTagService.d.ts +29 -0
- package/lib/services/ChangelogService/GitTagService.d.ts.map +1 -0
- package/lib/services/ChangelogService/GitTagService.js +57 -0
- package/lib/services/ChangelogService/GitTagService.js.map +1 -0
- package/lib/services/ChangelogService/GitTagService.ts +60 -0
- package/lib/services/ChangelogService/RepositoryInfoService.d.ts +14 -0
- package/lib/services/ChangelogService/RepositoryInfoService.d.ts.map +1 -0
- package/lib/services/ChangelogService/RepositoryInfoService.js +55 -0
- package/lib/services/ChangelogService/RepositoryInfoService.js.map +1 -0
- package/lib/services/ChangelogService/RepositoryInfoService.ts +64 -0
- package/lib/services/ChangelogService/index.d.ts +2 -0
- package/lib/services/ChangelogService/index.d.ts.map +1 -0
- package/lib/services/ChangelogService/index.js +2 -0
- package/lib/services/ChangelogService/index.js.map +1 -0
- package/lib/services/ChangelogService/index.ts +1 -0
- package/lib/services/ChangelogService/types.d.ts +27 -0
- package/lib/services/ChangelogService/types.d.ts.map +1 -0
- package/lib/services/ChangelogService/types.js +3 -0
- package/lib/services/ChangelogService/types.js.map +1 -0
- package/lib/services/ChangelogService/types.ts +30 -0
- package/lib/services/DependencyService.d.ts +2 -9
- package/lib/services/DependencyService.d.ts.map +1 -1
- package/lib/services/DependencyService.js +2 -11
- package/lib/services/DependencyService.js.map +1 -1
- package/lib/services/DependencyService.ts +2 -11
- package/lib/services/PackageService/JsrPackageService.d.ts +81 -0
- package/lib/services/PackageService/JsrPackageService.d.ts.map +1 -0
- package/lib/services/{PackageService.js → PackageService/JsrPackageService.js} +70 -312
- package/lib/services/PackageService/JsrPackageService.js.map +1 -0
- package/lib/services/{PackageService.ts → PackageService/JsrPackageService.ts} +79 -372
- package/lib/services/PackageService/NpmPackageService.d.ts +45 -0
- package/lib/services/PackageService/NpmPackageService.d.ts.map +1 -0
- package/lib/services/PackageService/NpmPackageService.js +146 -0
- package/lib/services/PackageService/NpmPackageService.js.map +1 -0
- package/lib/services/PackageService/NpmPackageService.ts +178 -0
- package/lib/services/PackageService/PackageService.d.ts +77 -0
- package/lib/services/PackageService/PackageService.d.ts.map +1 -0
- package/lib/services/PackageService/PackageService.js +96 -0
- package/lib/services/PackageService/PackageService.js.map +1 -0
- package/lib/services/PackageService/PackageService.ts +108 -0
- package/lib/services/PackageService/PackageServiceUtils.d.ts +69 -0
- package/lib/services/PackageService/PackageServiceUtils.d.ts.map +1 -0
- package/lib/services/PackageService/PackageServiceUtils.js +185 -0
- package/lib/services/PackageService/PackageServiceUtils.js.map +1 -0
- package/lib/services/PackageService/PackageServiceUtils.ts +239 -0
- package/lib/services/StringService.d.ts +12 -0
- package/lib/services/StringService.d.ts.map +1 -1
- package/lib/services/StringService.js +56 -0
- package/lib/services/StringService.js.map +1 -1
- package/lib/services/StringService.ts +72 -0
- package/lib/types/VersionType.d.ts +9 -0
- package/lib/types/VersionType.d.ts.map +1 -0
- package/lib/types/VersionType.js +10 -0
- package/lib/types/VersionType.js.map +1 -0
- package/lib/types/VersionType.ts +8 -0
- package/package.json +7 -6
- package/lib/services/PackageService.d.ts +0 -159
- package/lib/services/PackageService.d.ts.map +0 -1
- package/lib/services/PackageService.js.map +0 -1
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import ErrorUtils from '../../utils/ErrorUtils.js';
|
|
2
|
+
import { DR } from '../DependencyRegistry.js';
|
|
3
|
+
import ChangelogFileService from './ChangelogFileService.js';
|
|
4
|
+
import ChangelogGenerator from './ChangelogGenerator.js';
|
|
5
|
+
import ChangelogParser from './ChangelogParser.js';
|
|
6
|
+
import ChangelogValidator from './ChangelogValidator.js';
|
|
7
|
+
import GitTagService from './GitTagService.js';
|
|
8
|
+
import RepositoryInfoService from './RepositoryInfoService.js';
|
|
9
|
+
import { CHANGELOG_FILENAME, type ChangelogVersionEntry } from './types.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A service for managing and validating changelog files in packages.
|
|
13
|
+
*
|
|
14
|
+
* This service handles the creation, validation, and maintenance of CHANGELOG.md
|
|
15
|
+
* files following the Keep a Changelog format.
|
|
16
|
+
*/
|
|
17
|
+
export default class ChangelogService {
|
|
18
|
+
/**
|
|
19
|
+
* Validates that a changelog exists and contains a valid entry for the specified version.
|
|
20
|
+
*
|
|
21
|
+
* @param version The version to validate in the changelog
|
|
22
|
+
* @param packagePath Optional path to the package directory (defaults to current working directory)
|
|
23
|
+
* @throws Error if validation fails
|
|
24
|
+
*/
|
|
25
|
+
static async validateChangelogForVersion(version: string, packagePath?: string): Promise<void> {
|
|
26
|
+
const workingDir = packagePath || process.cwd();
|
|
27
|
+
|
|
28
|
+
DR.logger.info(`Validating changelog for version ${version}...`);
|
|
29
|
+
|
|
30
|
+
const changelogExists = await ChangelogFileService.changelogExists(packagePath);
|
|
31
|
+
if (!changelogExists) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
`No ${CHANGELOG_FILENAME} file found in ${workingDir}. ` +
|
|
34
|
+
`Run changelog initialization to create one.`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const changelogContent = await ChangelogFileService.readChangelog(packagePath);
|
|
40
|
+
const versionEntries = ChangelogParser.parseChangelog(changelogContent);
|
|
41
|
+
|
|
42
|
+
const versionEntry = versionEntries.find((entry) => entry.version === version);
|
|
43
|
+
|
|
44
|
+
if (!versionEntry) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`No changelog entry found for version ${version}. ` +
|
|
47
|
+
`Please add an entry to ${CHANGELOG_FILENAME} before publishing.`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
ChangelogValidator.validateVersionEntry(versionEntry, version);
|
|
52
|
+
|
|
53
|
+
DR.logger.success(`Changelog validation passed for version ${version}`);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
const errorString = ErrorUtils.getErrorString(error);
|
|
56
|
+
DR.logger.error(`Changelog validation failed: ${errorString}`);
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Initializes a changelog file for the current package if one doesn't exist.
|
|
63
|
+
* If a changelog already exists, validates it against existing Git tags and
|
|
64
|
+
* updates the most recent entry if needed to match the current version.
|
|
65
|
+
*
|
|
66
|
+
* @param version The current version for the changelog
|
|
67
|
+
* @param packageName The name of the package
|
|
68
|
+
* @param packagePath Optional path to the package directory (defaults to current working directory)
|
|
69
|
+
*/
|
|
70
|
+
static async initializeChangelog(
|
|
71
|
+
version: string,
|
|
72
|
+
packageName: string,
|
|
73
|
+
packagePath?: string
|
|
74
|
+
): Promise<void> {
|
|
75
|
+
const workingDir = packagePath || process.cwd();
|
|
76
|
+
|
|
77
|
+
DR.logger.info(`Initializing changelog for ${packageName} version ${version}...`);
|
|
78
|
+
|
|
79
|
+
const changelogExists = await ChangelogFileService.changelogExists(packagePath);
|
|
80
|
+
|
|
81
|
+
if (changelogExists) {
|
|
82
|
+
// If it exists, validate against Git tags and update if necessary
|
|
83
|
+
const existingContent = await ChangelogFileService.readChangelog(packagePath);
|
|
84
|
+
await this.validateAndUpdateExistingChangelog(
|
|
85
|
+
version,
|
|
86
|
+
packageName,
|
|
87
|
+
existingContent,
|
|
88
|
+
workingDir
|
|
89
|
+
);
|
|
90
|
+
} else {
|
|
91
|
+
// Changelog doesn't exist, create a new one
|
|
92
|
+
DR.logger.info(`Creating new changelog file`);
|
|
93
|
+
const repositoryInfo = await RepositoryInfoService.getRepositoryInfo(workingDir);
|
|
94
|
+
const initialContent = ChangelogGenerator.createInitialChangelogContent(
|
|
95
|
+
version,
|
|
96
|
+
packageName,
|
|
97
|
+
repositoryInfo
|
|
98
|
+
);
|
|
99
|
+
await ChangelogFileService.createChangelog(initialContent, packagePath);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
DR.logger.success(`Changelog initialization completed for ${packageName}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Validates an existing changelog against Git tags and updates if necessary.
|
|
107
|
+
*
|
|
108
|
+
* @param currentVersion The current version
|
|
109
|
+
* @param packageName The package name
|
|
110
|
+
* @param existingContent The current changelog content
|
|
111
|
+
* @param workingDir The working directory
|
|
112
|
+
*/
|
|
113
|
+
private static async validateAndUpdateExistingChangelog(
|
|
114
|
+
currentVersion: string,
|
|
115
|
+
packageName: string,
|
|
116
|
+
existingContent: string,
|
|
117
|
+
workingDir: string
|
|
118
|
+
): Promise<void> {
|
|
119
|
+
const versionEntries = ChangelogParser.parseChangelog(existingContent);
|
|
120
|
+
|
|
121
|
+
if (versionEntries.length === 0) {
|
|
122
|
+
// No version entries exist, add the current version
|
|
123
|
+
DR.logger.info(
|
|
124
|
+
`Changelog exists but has no version entries - adding entry for ${currentVersion}`
|
|
125
|
+
);
|
|
126
|
+
await this.addVersionEntry(currentVersion, existingContent, packageName, workingDir);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Get existing Git tags for this package
|
|
131
|
+
const existingTags = GitTagService.getPackageTags(packageName, workingDir);
|
|
132
|
+
|
|
133
|
+
// Check which entries have corresponding tags and remove ones that don't (except most recent)
|
|
134
|
+
const mostRecentEntry = versionEntries[0];
|
|
135
|
+
const olderEntries = versionEntries.slice(1);
|
|
136
|
+
const validOlderEntries: ChangelogVersionEntry[] = [];
|
|
137
|
+
const removedVersions: string[] = [];
|
|
138
|
+
|
|
139
|
+
for (const entry of olderEntries) {
|
|
140
|
+
const expectedTag = GitTagService.getTagName(packageName, entry.version);
|
|
141
|
+
if (existingTags.includes(expectedTag)) {
|
|
142
|
+
validOlderEntries.push(entry);
|
|
143
|
+
} else {
|
|
144
|
+
removedVersions.push(entry.version);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// If we removed any older entries, we need to regenerate the changelog
|
|
149
|
+
if (removedVersions.length > 0) {
|
|
150
|
+
DR.logger.info(
|
|
151
|
+
`Removing changelog entries without corresponding Git tags: ${removedVersions.join(', ')}`
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
const validEntries = [mostRecentEntry, ...validOlderEntries];
|
|
155
|
+
const repositoryInfo = await RepositoryInfoService.getRepositoryInfo(workingDir);
|
|
156
|
+
const updatedContent = ChangelogGenerator.regenerateChangelogContent(
|
|
157
|
+
validEntries,
|
|
158
|
+
packageName,
|
|
159
|
+
repositoryInfo
|
|
160
|
+
);
|
|
161
|
+
await ChangelogFileService.writeChangelog(updatedContent, workingDir);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Now handle the most recent entry
|
|
165
|
+
const mostRecentTag = GitTagService.getTagName(packageName, mostRecentEntry.version);
|
|
166
|
+
const hasTagForMostRecent = existingTags.includes(mostRecentTag);
|
|
167
|
+
|
|
168
|
+
if (hasTagForMostRecent) {
|
|
169
|
+
// Most recent entry has a tag, so we need to add a new entry for current version
|
|
170
|
+
if (mostRecentEntry.version === currentVersion) {
|
|
171
|
+
DR.logger.info(
|
|
172
|
+
`Changelog already contains entry for version ${currentVersion} with corresponding tag - no changes made`
|
|
173
|
+
);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
DR.logger.info(
|
|
178
|
+
`Most recent changelog entry has a tag - adding new entry for version ${currentVersion}`
|
|
179
|
+
);
|
|
180
|
+
await this.addVersionEntry(currentVersion, existingContent, packageName, workingDir);
|
|
181
|
+
} else {
|
|
182
|
+
// Most recent entry doesn't have a tag
|
|
183
|
+
if (mostRecentEntry.version === currentVersion) {
|
|
184
|
+
DR.logger.info(
|
|
185
|
+
`Changelog already contains entry for version ${currentVersion} without tag - no changes made`
|
|
186
|
+
);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Update the most recent entry to match current version
|
|
191
|
+
DR.logger.info(
|
|
192
|
+
`Updating most recent changelog entry from ${mostRecentEntry.version} to ${currentVersion}`
|
|
193
|
+
);
|
|
194
|
+
await this.updateMostRecentVersionEntry(
|
|
195
|
+
currentVersion,
|
|
196
|
+
existingContent,
|
|
197
|
+
packageName,
|
|
198
|
+
workingDir
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Updates the most recent version entry in the changelog.
|
|
205
|
+
*
|
|
206
|
+
* @param newVersion The new version to update to
|
|
207
|
+
* @param existingContent The current changelog content
|
|
208
|
+
* @param packageName The package name
|
|
209
|
+
* @param workingDir The working directory
|
|
210
|
+
*/
|
|
211
|
+
private static async updateMostRecentVersionEntry(
|
|
212
|
+
newVersion: string,
|
|
213
|
+
existingContent: string,
|
|
214
|
+
packageName: string,
|
|
215
|
+
workingDir: string
|
|
216
|
+
): Promise<void> {
|
|
217
|
+
const versionEntries = ChangelogParser.parseChangelog(existingContent);
|
|
218
|
+
|
|
219
|
+
if (versionEntries.length === 0) {
|
|
220
|
+
throw new Error('No version entries found to update');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const mostRecentEntry = versionEntries[0];
|
|
224
|
+
const oldVersionPattern = `## 🔖 [${mostRecentEntry.version}]`;
|
|
225
|
+
const newVersionPattern = `## 🔖 [${newVersion}]`;
|
|
226
|
+
|
|
227
|
+
// Replace the version in the changelog content
|
|
228
|
+
let updatedContent = existingContent.replace(oldVersionPattern, newVersionPattern);
|
|
229
|
+
|
|
230
|
+
// Update version links if they exist
|
|
231
|
+
const repositoryInfo = await RepositoryInfoService.getRepositoryInfo(workingDir);
|
|
232
|
+
if (repositoryInfo) {
|
|
233
|
+
updatedContent = ChangelogGenerator.addVersionLinksToChangelog(
|
|
234
|
+
updatedContent,
|
|
235
|
+
repositoryInfo,
|
|
236
|
+
packageName
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
await ChangelogFileService.writeChangelog(updatedContent, workingDir);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Adds a new version entry to an existing changelog.
|
|
245
|
+
*
|
|
246
|
+
* @param version The version to add
|
|
247
|
+
* @param existingContent The current changelog content
|
|
248
|
+
* @param packageName The package name for generating version links
|
|
249
|
+
* @param packagePath The package directory path
|
|
250
|
+
*/
|
|
251
|
+
private static async addVersionEntry(
|
|
252
|
+
version: string,
|
|
253
|
+
existingContent: string,
|
|
254
|
+
packageName: string,
|
|
255
|
+
packagePath: string
|
|
256
|
+
): Promise<void> {
|
|
257
|
+
const currentDate = ChangelogGenerator.getCurrentDate();
|
|
258
|
+
const versionEntry = ChangelogGenerator.createVersionEntryContent(version, currentDate);
|
|
259
|
+
|
|
260
|
+
// Find the position after the header to insert the new version
|
|
261
|
+
const lines = existingContent.split('\n');
|
|
262
|
+
const headerEndIndex = lines.findIndex((line) => line.startsWith('## ') && line.includes('['));
|
|
263
|
+
|
|
264
|
+
let newContent: string;
|
|
265
|
+
if (headerEndIndex === -1) {
|
|
266
|
+
// No existing version entries, add after the header
|
|
267
|
+
const headerLines = lines.slice(0, lines.findIndex((line) => line.trim() === '') + 1);
|
|
268
|
+
newContent = [...headerLines, '', versionEntry, '', ...lines.slice(headerLines.length)].join(
|
|
269
|
+
'\n'
|
|
270
|
+
);
|
|
271
|
+
} else {
|
|
272
|
+
// Insert before the first existing version
|
|
273
|
+
newContent = [
|
|
274
|
+
...lines.slice(0, headerEndIndex),
|
|
275
|
+
versionEntry,
|
|
276
|
+
'',
|
|
277
|
+
...lines.slice(headerEndIndex)
|
|
278
|
+
].join('\n');
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Add version links if repository info is available
|
|
282
|
+
const repositoryInfo = await RepositoryInfoService.getRepositoryInfo(packagePath);
|
|
283
|
+
if (repositoryInfo) {
|
|
284
|
+
newContent = ChangelogGenerator.addVersionLinksToChangelog(
|
|
285
|
+
newContent,
|
|
286
|
+
repositoryInfo,
|
|
287
|
+
packageName
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
await ChangelogFileService.writeChangelog(newContent, packagePath);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ChangelogVersionEntry } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Service for validating changelog entries and content.
|
|
4
|
+
*/
|
|
5
|
+
export default class ChangelogValidator {
|
|
6
|
+
/**
|
|
7
|
+
* Validates that a version entry meets the requirements.
|
|
8
|
+
*
|
|
9
|
+
* @param versionEntry The version entry to validate
|
|
10
|
+
* @param version The version being validated (for error messages)
|
|
11
|
+
* @throws Error if validation fails
|
|
12
|
+
*/
|
|
13
|
+
static validateVersionEntry(versionEntry: ChangelogVersionEntry, version: string): void;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=ChangelogValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChangelogValidator.d.ts","sourceRoot":"","sources":["../../../src/services/ChangelogService/ChangelogValidator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGxD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAkB;IACrC;;;;;;OAMG;IACH,MAAM,CAAC,oBAAoB,CAAC,YAAY,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;CAwCxF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { REQUIRED_SECTION_TYPES } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Service for validating changelog entries and content.
|
|
4
|
+
*/
|
|
5
|
+
export default class ChangelogValidator {
|
|
6
|
+
/**
|
|
7
|
+
* Validates that a version entry meets the requirements.
|
|
8
|
+
*
|
|
9
|
+
* @param versionEntry The version entry to validate
|
|
10
|
+
* @param version The version being validated (for error messages)
|
|
11
|
+
* @throws Error if validation fails
|
|
12
|
+
*/
|
|
13
|
+
static validateVersionEntry(versionEntry, version) {
|
|
14
|
+
const { sections } = versionEntry;
|
|
15
|
+
if (sections.length === 0) {
|
|
16
|
+
throw new Error(`Version ${version} has no changelog sections. ` +
|
|
17
|
+
`At least one of the following sections is required: ${REQUIRED_SECTION_TYPES.join(', ')}`);
|
|
18
|
+
}
|
|
19
|
+
let hasValidSection = false;
|
|
20
|
+
const emptySections = [];
|
|
21
|
+
for (const section of sections) {
|
|
22
|
+
if (REQUIRED_SECTION_TYPES.includes(section.type)) {
|
|
23
|
+
if (section.content && section.content.trim().length > 0) {
|
|
24
|
+
hasValidSection = true;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
// Section exists but is empty
|
|
28
|
+
emptySections.push(section.type);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Fail if any section exists but is empty
|
|
33
|
+
if (emptySections.length > 0) {
|
|
34
|
+
throw new Error(`Version ${version} has empty changelog sections. ` +
|
|
35
|
+
`The following sections exist but have no content: ${emptySections.join(', ')}`);
|
|
36
|
+
}
|
|
37
|
+
// Fail if no section has meaningful content
|
|
38
|
+
if (!hasValidSection) {
|
|
39
|
+
throw new Error(`Version ${version} has no meaningful content in changelog sections. ` +
|
|
40
|
+
`At least one of the following sections must have content: ${REQUIRED_SECTION_TYPES.join(', ')}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=ChangelogValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChangelogValidator.js","sourceRoot":"","sources":["../../../src/services/ChangelogService/ChangelogValidator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAkB;IACrC;;;;;;OAMG;IACH,MAAM,CAAC,oBAAoB,CAAC,YAAmC,EAAE,OAAe;QAC9E,MAAM,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAC;QAElC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACb,WAAW,OAAO,8BAA8B;gBAC9C,uDAAuD,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7F,CAAC;QACJ,CAAC;QAED,IAAI,eAAe,GAAG,KAAK,CAAC;QAC5B,MAAM,aAAa,GAAa,EAAE,CAAC;QAEnC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,sBAAsB,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClD,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACzD,eAAe,GAAG,IAAI,CAAC;gBACzB,CAAC;qBAAM,CAAC;oBACN,8BAA8B;oBAC9B,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC;QACH,CAAC;QAED,0CAA0C;QAC1C,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,WAAW,OAAO,iCAAiC;gBACjD,qDAAqD,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClF,CAAC;QACJ,CAAC;QAED,4CAA4C;QAC5C,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,WAAW,OAAO,oDAAoD;gBACpE,6DAA6D,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACnG,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ChangelogVersionEntry } from './types.js';
|
|
2
|
+
import { REQUIRED_SECTION_TYPES } from './types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Service for validating changelog entries and content.
|
|
6
|
+
*/
|
|
7
|
+
export default class ChangelogValidator {
|
|
8
|
+
/**
|
|
9
|
+
* Validates that a version entry meets the requirements.
|
|
10
|
+
*
|
|
11
|
+
* @param versionEntry The version entry to validate
|
|
12
|
+
* @param version The version being validated (for error messages)
|
|
13
|
+
* @throws Error if validation fails
|
|
14
|
+
*/
|
|
15
|
+
static validateVersionEntry(versionEntry: ChangelogVersionEntry, version: string): void {
|
|
16
|
+
const { sections } = versionEntry;
|
|
17
|
+
|
|
18
|
+
if (sections.length === 0) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`Version ${version} has no changelog sections. ` +
|
|
21
|
+
`At least one of the following sections is required: ${REQUIRED_SECTION_TYPES.join(', ')}`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let hasValidSection = false;
|
|
26
|
+
const emptySections: string[] = [];
|
|
27
|
+
|
|
28
|
+
for (const section of sections) {
|
|
29
|
+
if (REQUIRED_SECTION_TYPES.includes(section.type)) {
|
|
30
|
+
if (section.content && section.content.trim().length > 0) {
|
|
31
|
+
hasValidSection = true;
|
|
32
|
+
} else {
|
|
33
|
+
// Section exists but is empty
|
|
34
|
+
emptySections.push(section.type);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Fail if any section exists but is empty
|
|
40
|
+
if (emptySections.length > 0) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Version ${version} has empty changelog sections. ` +
|
|
43
|
+
`The following sections exist but have no content: ${emptySections.join(', ')}`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Fail if no section has meaningful content
|
|
48
|
+
if (!hasValidSection) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
`Version ${version} has no meaningful content in changelog sections. ` +
|
|
51
|
+
`At least one of the following sections must have content: ${REQUIRED_SECTION_TYPES.join(', ')}`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service for handling Git tag operations related to changelog management.
|
|
3
|
+
*/
|
|
4
|
+
export default class GitTagService {
|
|
5
|
+
/**
|
|
6
|
+
* Gets Git tags for a specific package.
|
|
7
|
+
*
|
|
8
|
+
* @param packageName The package name
|
|
9
|
+
* @param workingDir The working directory
|
|
10
|
+
* @returns Array of Git tags for the package
|
|
11
|
+
*/
|
|
12
|
+
static getPackageTags(packageName: string, workingDir: string): string[];
|
|
13
|
+
/**
|
|
14
|
+
* Generates the expected Git tag name for a package version.
|
|
15
|
+
*
|
|
16
|
+
* @param packageName The package name
|
|
17
|
+
* @param version The version
|
|
18
|
+
* @returns The expected Git tag name
|
|
19
|
+
*/
|
|
20
|
+
static getTagName(packageName: string, version: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Converts package name to tag prefix (removes scope if present).
|
|
23
|
+
*
|
|
24
|
+
* @param packageName The package name
|
|
25
|
+
* @returns The tag prefix
|
|
26
|
+
*/
|
|
27
|
+
private static getTagPrefix;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=GitTagService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitTagService.d.ts","sourceRoot":"","sources":["../../../src/services/ChangelogService/GitTagService.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;IAChC;;;;;;OAMG;IACH,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAuBxE;;;;;;OAMG;IACH,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAK/D;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;CAG5B"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import ErrorUtils from '../../utils/ErrorUtils.js';
|
|
3
|
+
import { DR } from '../DependencyRegistry.js';
|
|
4
|
+
/**
|
|
5
|
+
* Service for handling Git tag operations related to changelog management.
|
|
6
|
+
*/
|
|
7
|
+
export default class GitTagService {
|
|
8
|
+
/**
|
|
9
|
+
* Gets Git tags for a specific package.
|
|
10
|
+
*
|
|
11
|
+
* @param packageName The package name
|
|
12
|
+
* @param workingDir The working directory
|
|
13
|
+
* @returns Array of Git tags for the package
|
|
14
|
+
*/
|
|
15
|
+
static getPackageTags(packageName, workingDir) {
|
|
16
|
+
try {
|
|
17
|
+
// Convert package name to tag prefix (remove scope if present)
|
|
18
|
+
const tagPrefix = this.getTagPrefix(packageName);
|
|
19
|
+
const tagPattern = `${tagPrefix}-v*`;
|
|
20
|
+
// Get all tags matching the pattern
|
|
21
|
+
const output = execSync(`git tag -l "${tagPattern}"`, {
|
|
22
|
+
cwd: workingDir,
|
|
23
|
+
encoding: 'utf-8'
|
|
24
|
+
});
|
|
25
|
+
return output
|
|
26
|
+
.trim()
|
|
27
|
+
.split('\n')
|
|
28
|
+
.filter((tag) => tag.length > 0);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
// If git command fails (e.g., not a git repo), return empty array
|
|
32
|
+
DR.logger.warn(`Failed to retrieve Git tags: ${ErrorUtils.getErrorString(error)}`);
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Generates the expected Git tag name for a package version.
|
|
38
|
+
*
|
|
39
|
+
* @param packageName The package name
|
|
40
|
+
* @param version The version
|
|
41
|
+
* @returns The expected Git tag name
|
|
42
|
+
*/
|
|
43
|
+
static getTagName(packageName, version) {
|
|
44
|
+
const tagPrefix = this.getTagPrefix(packageName);
|
|
45
|
+
return `${tagPrefix}-v${version}`;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Converts package name to tag prefix (removes scope if present).
|
|
49
|
+
*
|
|
50
|
+
* @param packageName The package name
|
|
51
|
+
* @returns The tag prefix
|
|
52
|
+
*/
|
|
53
|
+
static getTagPrefix(packageName) {
|
|
54
|
+
return packageName.replace(/^@[\w-]+\//, '');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=GitTagService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitTagService.js","sourceRoot":"","sources":["../../../src/services/ChangelogService/GitTagService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,UAAU,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;IAChC;;;;;;OAMG;IACH,MAAM,CAAC,cAAc,CAAC,WAAmB,EAAE,UAAkB;QAC3D,IAAI,CAAC;YACH,+DAA+D;YAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;YACjD,MAAM,UAAU,GAAG,GAAG,SAAS,KAAK,CAAC;YAErC,oCAAoC;YACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,UAAU,GAAG,EAAE;gBACpD,GAAG,EAAE,UAAU;gBACf,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YAEH,OAAO,MAAM;iBACV,IAAI,EAAE;iBACN,KAAK,CAAC,IAAI,CAAC;iBACX,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,kEAAkE;YAClE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,UAAU,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACnF,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,UAAU,CAAC,WAAmB,EAAE,OAAe;QACpD,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QACjD,OAAO,GAAG,SAAS,KAAK,OAAO,EAAE,CAAC;IACpC,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,YAAY,CAAC,WAAmB;QAC7C,OAAO,WAAW,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC;CACF"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import ErrorUtils from '../../utils/ErrorUtils.js';
|
|
3
|
+
import { DR } from '../DependencyRegistry.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Service for handling Git tag operations related to changelog management.
|
|
7
|
+
*/
|
|
8
|
+
export default class GitTagService {
|
|
9
|
+
/**
|
|
10
|
+
* Gets Git tags for a specific package.
|
|
11
|
+
*
|
|
12
|
+
* @param packageName The package name
|
|
13
|
+
* @param workingDir The working directory
|
|
14
|
+
* @returns Array of Git tags for the package
|
|
15
|
+
*/
|
|
16
|
+
static getPackageTags(packageName: string, workingDir: string): string[] {
|
|
17
|
+
try {
|
|
18
|
+
// Convert package name to tag prefix (remove scope if present)
|
|
19
|
+
const tagPrefix = this.getTagPrefix(packageName);
|
|
20
|
+
const tagPattern = `${tagPrefix}-v*`;
|
|
21
|
+
|
|
22
|
+
// Get all tags matching the pattern
|
|
23
|
+
const output = execSync(`git tag -l "${tagPattern}"`, {
|
|
24
|
+
cwd: workingDir,
|
|
25
|
+
encoding: 'utf-8'
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return output
|
|
29
|
+
.trim()
|
|
30
|
+
.split('\n')
|
|
31
|
+
.filter((tag) => tag.length > 0);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
// If git command fails (e.g., not a git repo), return empty array
|
|
34
|
+
DR.logger.warn(`Failed to retrieve Git tags: ${ErrorUtils.getErrorString(error)}`);
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Generates the expected Git tag name for a package version.
|
|
41
|
+
*
|
|
42
|
+
* @param packageName The package name
|
|
43
|
+
* @param version The version
|
|
44
|
+
* @returns The expected Git tag name
|
|
45
|
+
*/
|
|
46
|
+
static getTagName(packageName: string, version: string): string {
|
|
47
|
+
const tagPrefix = this.getTagPrefix(packageName);
|
|
48
|
+
return `${tagPrefix}-v${version}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Converts package name to tag prefix (removes scope if present).
|
|
53
|
+
*
|
|
54
|
+
* @param packageName The package name
|
|
55
|
+
* @returns The tag prefix
|
|
56
|
+
*/
|
|
57
|
+
private static getTagPrefix(packageName: string): string {
|
|
58
|
+
return packageName.replace(/^@[\w-]+\//, '');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RepositoryInfo } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Service for extracting repository information from package.json files.
|
|
4
|
+
*/
|
|
5
|
+
export default class RepositoryInfoService {
|
|
6
|
+
/**
|
|
7
|
+
* Extracts repository information from package.json
|
|
8
|
+
*
|
|
9
|
+
* @param packagePath Path to the package directory
|
|
10
|
+
* @returns Repository information or null if not found/invalid
|
|
11
|
+
*/
|
|
12
|
+
static getRepositoryInfo(packagePath?: string): Promise<RepositoryInfo | null>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=RepositoryInfoService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RepositoryInfoService.d.ts","sourceRoot":"","sources":["../../../src/services/ChangelogService/RepositoryInfoService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAqB;IACxC;;;;;OAKG;WACU,iBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAiDrF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { readFile } from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Service for extracting repository information from package.json files.
|
|
5
|
+
*/
|
|
6
|
+
export default class RepositoryInfoService {
|
|
7
|
+
/**
|
|
8
|
+
* Extracts repository information from package.json
|
|
9
|
+
*
|
|
10
|
+
* @param packagePath Path to the package directory
|
|
11
|
+
* @returns Repository information or null if not found/invalid
|
|
12
|
+
*/
|
|
13
|
+
static async getRepositoryInfo(packagePath) {
|
|
14
|
+
const workingDir = packagePath || process.cwd();
|
|
15
|
+
const packageJsonPath = path.join(workingDir, 'package.json');
|
|
16
|
+
try {
|
|
17
|
+
const packageJsonContent = await readFile(packageJsonPath, 'utf-8');
|
|
18
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
19
|
+
// Type guard to check if packageJson has the expected structure
|
|
20
|
+
if (typeof packageJson !== 'object' ||
|
|
21
|
+
packageJson === null ||
|
|
22
|
+
!('repository' in packageJson) ||
|
|
23
|
+
typeof packageJson.repository !== 'object' ||
|
|
24
|
+
packageJson.repository === null ||
|
|
25
|
+
!('url' in packageJson.repository) ||
|
|
26
|
+
typeof packageJson.repository.url !== 'string') {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const url = packageJson.repository.url;
|
|
30
|
+
// Handle different URL formats
|
|
31
|
+
let gitUrl = url;
|
|
32
|
+
if (gitUrl.startsWith('git+')) {
|
|
33
|
+
gitUrl = gitUrl.substring(4);
|
|
34
|
+
}
|
|
35
|
+
if (gitUrl.endsWith('.git')) {
|
|
36
|
+
gitUrl = gitUrl.substring(0, gitUrl.length - 4);
|
|
37
|
+
}
|
|
38
|
+
// Extract owner and repo from GitHub URL
|
|
39
|
+
const match = gitUrl.match(/github\.com[/:]([\w-]+)\/([\w-]+)/);
|
|
40
|
+
if (!match) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const [, owner, repo] = match;
|
|
44
|
+
return {
|
|
45
|
+
owner,
|
|
46
|
+
repo,
|
|
47
|
+
url: `https://github.com/${owner}/${repo}`
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=RepositoryInfoService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RepositoryInfoService.js","sourceRoot":"","sources":["../../../src/services/ChangelogService/RepositoryInfoService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAqB;IACxC;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,WAAoB;QACjD,MAAM,UAAU,GAAG,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAE9D,IAAI,CAAC;YACH,MAAM,kBAAkB,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;YACpE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAY,CAAC;YAE9D,gEAAgE;YAChE,IACE,OAAO,WAAW,KAAK,QAAQ;gBAC/B,WAAW,KAAK,IAAI;gBACpB,CAAC,CAAC,YAAY,IAAI,WAAW,CAAC;gBAC9B,OAAO,WAAW,CAAC,UAAU,KAAK,QAAQ;gBAC1C,WAAW,CAAC,UAAU,KAAK,IAAI;gBAC/B,CAAC,CAAC,KAAK,IAAI,WAAW,CAAC,UAAU,CAAC;gBAClC,OAAO,WAAW,CAAC,UAAU,CAAC,GAAG,KAAK,QAAQ,EAC9C,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,GAAG,GAAG,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC;YAEvC,+BAA+B;YAC/B,IAAI,MAAM,GAAG,GAAG,CAAC;YACjB,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9B,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC/B,CAAC;YACD,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5B,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAClD,CAAC;YAED,yCAAyC;YACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;YAChE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;YAE9B,OAAO;gBACL,KAAK;gBACL,IAAI;gBACJ,GAAG,EAAE,sBAAsB,KAAK,IAAI,IAAI,EAAE;aAC3C,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
|