@qlover/fe-release 2.3.5 → 3.1.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.
Files changed (6) hide show
  1. package/dist/cli.cjs +2666 -1005
  2. package/dist/cli.js +2673 -1007
  3. package/dist/index.cjs +3072 -1403
  4. package/dist/index.d.ts +2354 -161
  5. package/dist/index.js +3078 -1404
  6. package/package.json +5 -4
package/dist/index.d.ts CHANGED
@@ -1,22 +1,393 @@
1
- import { FeScriptContextOptions, Shell, FeReleaseConfig, FeScriptContext } from '@qlover/scripts-context';
2
- import { AsyncExecutor, ExecutorContext, ExecutorPlugin } from '@qlover/fe-corekit';
3
- import { LoggerInterface } from '@qlover/logger';
4
- import { Env } from '@qlover/env-loader';
1
+ import { AsyncExecutor, ExecutorContext } from '@qlover/fe-corekit';
2
+ import { ScriptPlugin, ScriptContext, ScriptPluginProps, ScriptSharedInterface, ScriptContextInterface, FeReleaseConfig, ShellInterface } from '@qlover/scripts-context';
3
+ export { ScriptPlugin } from '@qlover/scripts-context';
5
4
  import { CommitField } from 'gitlog';
5
+ import { LoggerInterface } from '@qlover/logger';
6
6
  import { OptionValues } from 'commander';
7
7
 
8
+ /**
9
+ * @module PluginTuple
10
+ * @description Type-safe plugin tuple creation and handling
11
+ *
12
+ * This module provides utilities for creating and handling tuples that
13
+ * represent plugin configurations. It ensures type safety when working
14
+ * with plugin constructors and their parameters.
15
+ *
16
+ * Core Features:
17
+ * - Type-safe plugin class handling
18
+ * - Constructor parameter inference
19
+ * - Plugin tuple creation
20
+ *
21
+ * @example Basic usage
22
+ * ```typescript
23
+ * class MyPlugin extends ScriptPlugin {
24
+ * constructor(context: ScriptContext, config: { option: string }) {
25
+ * super(context);
26
+ * }
27
+ * }
28
+ *
29
+ * const pluginTuple = tuple(MyPlugin, { option: 'value' });
30
+ * // [MyPlugin, { option: 'value' }]
31
+ * ```
32
+ *
33
+ * @example Plugin name string
34
+ * ```typescript
35
+ * const pluginTuple = tuple('MyPlugin', { option: 'value' });
36
+ * // ['MyPlugin', { option: 'value' }]
37
+ * ```
38
+ */
39
+
40
+ /**
41
+ * Plugin class constructor type
42
+ *
43
+ * Represents a constructor for a class that extends ScriptPlugin.
44
+ * Supports generic constructor arguments.
45
+ *
46
+ * @template T - Array type for constructor arguments
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * class MyPlugin extends ScriptPlugin {
51
+ * constructor(context: ScriptContext, config: { option: string }) {
52
+ * super(context);
53
+ * }
54
+ * }
55
+ *
56
+ * const PluginCtor: PluginClass = MyPlugin;
57
+ * ```
58
+ */
59
+ type PluginClass<T extends unknown[] = any[]> = new (...args: T) => ScriptPlugin<ScriptContext<any>, ScriptPluginProps>;
60
+ /**
61
+ * Plugin constructor parameters type
62
+ *
63
+ * Extracts the constructor parameter types for a plugin class,
64
+ * excluding the first parameter (context). Uses TypeScript's
65
+ * conditional types and inference to extract parameter types.
66
+ *
67
+ * @template T - Plugin class type
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * class MyPlugin extends ScriptPlugin {
72
+ * constructor(
73
+ * context: ScriptContext,
74
+ * config: { option: string },
75
+ * extra: number
76
+ * ) {
77
+ * super(context);
78
+ * }
79
+ * }
80
+ *
81
+ * // Type: [{ option: string }, number]
82
+ * type Params = PluginConstructorParams<typeof MyPlugin>;
83
+ * ```
84
+ */
85
+ type PluginConstructorParams<T extends PluginClass> = T extends new (first: any, ...args: infer P) => unknown ? P : never;
86
+ /**
87
+ * Plugin configuration tuple type
88
+ *
89
+ * Represents a tuple containing a plugin class (or name) and its
90
+ * constructor arguments. Used for plugin registration and loading.
91
+ *
92
+ * @template T - Plugin class type
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * class MyPlugin extends ScriptPlugin {
97
+ * constructor(context: ScriptContext, config: { option: string }) {
98
+ * super(context);
99
+ * }
100
+ * }
101
+ *
102
+ * // Type: [typeof MyPlugin, { option: string }]
103
+ * type Tuple = PluginTuple<typeof MyPlugin>;
104
+ *
105
+ * // Type: [string, { option: string }]
106
+ * type StringTuple = PluginTuple<'MyPlugin'>;
107
+ * ```
108
+ */
109
+ type PluginTuple<T extends PluginClass> = [
110
+ T | string,
111
+ ...PluginConstructorParams<T>
112
+ ];
113
+ /**
114
+ * Creates a type-safe plugin configuration tuple
115
+ *
116
+ * Helper function for creating tuples that represent plugin
117
+ * configurations with proper type inference for constructor
118
+ * arguments.
119
+ *
120
+ * @template T - Plugin class type
121
+ * @param plugin - Plugin class or name
122
+ * @param args - Plugin constructor arguments
123
+ * @returns Plugin configuration tuple
124
+ *
125
+ * @example Class-based plugin
126
+ * ```typescript
127
+ * class MyPlugin extends ScriptPlugin {
128
+ * constructor(
129
+ * context: ScriptContext,
130
+ * config: { option: string },
131
+ * extra: number
132
+ * ) {
133
+ * super(context);
134
+ * }
135
+ * }
136
+ *
137
+ * const config = tuple(MyPlugin, { option: 'value' }, 42);
138
+ * // [MyPlugin, { option: 'value' }, 42]
139
+ * ```
140
+ *
141
+ * @example String-based plugin
142
+ * ```typescript
143
+ * const config = tuple('MyPlugin', { option: 'value' });
144
+ * // ['MyPlugin', { option: 'value' }]
145
+ * ```
146
+ */
147
+ declare function tuple<T extends PluginClass>(plugin: T | string, ...args: PluginConstructorParams<T>): PluginTuple<T>;
148
+
149
+ /**
150
+ * @module ReleaseTask
151
+ * @description Task orchestration for release process
152
+ *
153
+ * This module provides the core task orchestration for the release process,
154
+ * managing plugin loading, execution order, and context handling. It serves
155
+ * as the main entry point for executing release operations.
156
+ *
157
+ * Core Features:
158
+ * - Plugin management and execution
159
+ * - Release context initialization
160
+ * - Task execution control
161
+ * - Environment-based control
162
+ *
163
+ * Default Plugins:
164
+ * - Workspaces: Monorepo workspace management
165
+ * - Changelog: Version and changelog management
166
+ * - GithubPR: Pull request creation and management
167
+ *
168
+ * @example Basic usage
169
+ * ```typescript
170
+ * // Initialize and execute
171
+ * const task = new ReleaseTask({
172
+ * rootPath: '/path/to/project',
173
+ * sourceBranch: 'main'
174
+ * });
175
+ *
176
+ * await task.exec();
177
+ * ```
178
+ *
179
+ * @example Custom plugins
180
+ * ```typescript
181
+ * import { tuple } from '@qlover/fe-release';
182
+ *
183
+ * // Add custom plugin
184
+ * class CustomPlugin extends ScriptPlugin {
185
+ * async onExec() {
186
+ * // Custom release logic
187
+ * }
188
+ * }
189
+ *
190
+ * const task = new ReleaseTask({}, new AsyncExecutor(), [
191
+ * tuple(CustomPlugin, { option: 'value' })
192
+ * ]);
193
+ *
194
+ * await task.exec();
195
+ * ```
196
+ *
197
+ * @example Environment control
198
+ * ```typescript
199
+ * // Skip release
200
+ * process.env.FE_RELEASE = 'false';
201
+ *
202
+ * const task = new ReleaseTask();
203
+ * try {
204
+ * await task.exec();
205
+ * } catch (e) {
206
+ * // Handle "Skip Release" error
207
+ * }
208
+ * ```
209
+ */
210
+
211
+ /**
212
+ * Core task class for managing release operations
213
+ *
214
+ * Handles plugin orchestration, task execution, and context management
215
+ * for the release process. Supports both built-in and custom plugins.
216
+ *
217
+ * Features:
218
+ * - Plugin lifecycle management
219
+ * - Task execution control
220
+ * - Context initialization and access
221
+ * - Environment-based control
222
+ *
223
+ * @example Basic initialization
224
+ * ```typescript
225
+ * const task = new ReleaseTask({
226
+ * rootPath: '/path/to/project'
227
+ * });
228
+ * ```
229
+ *
230
+ * @example Custom executor
231
+ * ```typescript
232
+ * const executor = new AsyncExecutor({
233
+ * onError: (err) => console.error('Release failed:', err)
234
+ * });
235
+ *
236
+ * const task = new ReleaseTask({}, executor);
237
+ * ```
238
+ *
239
+ * @example Custom plugins
240
+ * ```typescript
241
+ * const task = new ReleaseTask(
242
+ * {}, // options
243
+ * new AsyncExecutor(),
244
+ * [
245
+ * tuple(CustomPlugin, { config: 'value' }),
246
+ * ...innerTuples // include default plugins
247
+ * ]
248
+ * );
249
+ * ```
250
+ */
8
251
  declare class ReleaseTask {
9
252
  private executor;
10
253
  private defaultTuples;
254
+ /**
255
+ * Release context instance
256
+ * @protected
257
+ */
11
258
  protected context: ReleaseContext;
12
- constructor(options?: ReleaseContextOptions, executor?: AsyncExecutor, defaultTuples?: PluginTuple<PluginClass>[]);
259
+ /**
260
+ * Creates a new ReleaseTask instance
261
+ *
262
+ * Initializes the release context and sets up plugin configuration.
263
+ * Supports custom executors and plugin configurations.
264
+ *
265
+ * @param options - Release context configuration
266
+ * @param executor - Custom async executor (optional)
267
+ * @param defaultTuples - Plugin configuration tuples (optional)
268
+ *
269
+ * @example
270
+ * ```typescript
271
+ * // Basic initialization
272
+ * const task = new ReleaseTask({
273
+ * rootPath: '/path/to/project',
274
+ * sourceBranch: 'main'
275
+ * });
276
+ *
277
+ * // With custom executor and plugins
278
+ * const task = new ReleaseTask(
279
+ * { rootPath: '/path/to/project' },
280
+ * new AsyncExecutor(),
281
+ * [tuple(CustomPlugin, { option: 'value' })]
282
+ * );
283
+ * ```
284
+ */
285
+ constructor(options?: Partial<ReleaseContextOptions>, executor?: AsyncExecutor, defaultTuples?: PluginTuple<PluginClass>[]);
286
+ /**
287
+ * Gets the current release context
288
+ *
289
+ * @returns Release context instance
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * const task = new ReleaseTask();
294
+ * const context = task.getContext();
295
+ *
296
+ * console.log(context.releaseEnv);
297
+ * console.log(context.sourceBranch);
298
+ * ```
299
+ */
13
300
  getContext(): ReleaseContext;
14
- usePlugins(externalTuples?: PluginTuple<PluginClass>[]): Promise<Plugin[]>;
301
+ /**
302
+ * Loads and configures plugins for the release task
303
+ *
304
+ * Combines default and external plugins, initializes them with
305
+ * the current context, and configures special cases like the
306
+ * Workspaces plugin.
307
+ *
308
+ * Plugin Loading Process:
309
+ * 1. Merge default and external plugins
310
+ * 2. Initialize plugins with context
311
+ * 3. Configure special plugins
312
+ * 4. Add plugins to executor
313
+ *
314
+ * @param externalTuples - Additional plugin configurations
315
+ * @returns Array of initialized plugins
316
+ *
317
+ * @example Basic usage
318
+ * ```typescript
319
+ * const task = new ReleaseTask();
320
+ * const plugins = await task.usePlugins();
321
+ * ```
322
+ *
323
+ * @example Custom plugins
324
+ * ```typescript
325
+ * const task = new ReleaseTask();
326
+ * const plugins = await task.usePlugins([
327
+ * tuple(CustomPlugin, { option: 'value' })
328
+ * ]);
329
+ * ```
330
+ */
331
+ usePlugins(externalTuples?: PluginTuple<PluginClass>[]): Promise<ScriptPlugin<ScriptContext<any>, ScriptPluginProps>[]>;
332
+ /**
333
+ * Executes the release task
334
+ *
335
+ * Internal method that runs the task through the executor.
336
+ * Preserves the context through the execution chain.
337
+ *
338
+ * @returns Execution result
339
+ * @internal
340
+ */
15
341
  run(): Promise<unknown>;
342
+ /**
343
+ * Main entry point for executing the release task
344
+ *
345
+ * Checks environment conditions, loads plugins, and executes
346
+ * the release process. Supports additional plugin configuration
347
+ * at execution time.
348
+ *
349
+ * Environment Control:
350
+ * - Checks FE_RELEASE environment variable
351
+ * - Skips release if FE_RELEASE=false
352
+ *
353
+ * @param externalTuples - Additional plugin configurations
354
+ * @returns Execution result
355
+ * @throws Error if release is skipped via environment variable
356
+ *
357
+ * @example Basic execution
358
+ * ```typescript
359
+ * const task = new ReleaseTask();
360
+ * await task.exec();
361
+ * ```
362
+ *
363
+ * @example With additional plugins
364
+ * ```typescript
365
+ * const task = new ReleaseTask();
366
+ * await task.exec([
367
+ * tuple(CustomPlugin, { option: 'value' })
368
+ * ]);
369
+ * ```
370
+ *
371
+ * @example Environment control
372
+ * ```typescript
373
+ * // Skip release
374
+ * process.env.FE_RELEASE = 'false';
375
+ *
376
+ * const task = new ReleaseTask();
377
+ * try {
378
+ * await task.exec();
379
+ * } catch (e) {
380
+ * if (e.message === 'Skip Release') {
381
+ * console.log('Release skipped via environment variable');
382
+ * }
383
+ * }
384
+ * ```
385
+ */
16
386
  exec(externalTuples?: PluginTuple<PluginClass>[]): Promise<unknown>;
17
387
  }
18
388
 
19
- interface WorkspacesProps {
389
+ type PackageJson$1 = Record<string, unknown>;
390
+ interface WorkspacesProps extends ScriptPluginProps {
20
391
  /**
21
392
  * Whether to skip workspaces
22
393
  *
@@ -74,7 +445,7 @@ interface WorkspaceValue {
74
445
  /**
75
446
  * The package.json of the workspace
76
447
  */
77
- packageJson: PackageJson;
448
+ packageJson: PackageJson$1;
78
449
  /**
79
450
  * The tag name of the workspace
80
451
  * @private
@@ -139,19 +510,88 @@ type ReleaseParamsConfig = {
139
510
  PRBody?: string;
140
511
  };
141
512
 
142
- interface GitBaseProps {
513
+ /**
514
+ * Base configuration for Git-related plugins
515
+ *
516
+ * Extends ScriptPluginProps with GitHub-specific configuration
517
+ * options for API access and timeouts.
518
+ *
519
+ * @example
520
+ * ```typescript
521
+ * const config: GitBaseProps = {
522
+ * tokenRef: 'CUSTOM_TOKEN',
523
+ * timeout: 5000
524
+ * };
525
+ * ```
526
+ */
527
+ interface GitBaseProps extends ScriptPluginProps {
143
528
  /**
144
- * The token for the GitHub API
529
+ * Environment variable name for GitHub API token
530
+ *
531
+ * The value of this environment variable will be used
532
+ * for GitHub API authentication.
533
+ *
534
+ * @default 'GITHUB_TOKEN'
145
535
  *
146
- * @default `GITHUB_TOKEN`
536
+ * @example
537
+ * ```typescript
538
+ * process.env.CUSTOM_TOKEN = 'ghp_123...';
539
+ * const config = { tokenRef: 'CUSTOM_TOKEN' };
540
+ * ```
147
541
  */
148
542
  tokenRef?: string;
149
543
  /**
150
- * The timeout for the GitHub API
544
+ * Timeout for GitHub API requests in milliseconds
545
+ *
546
+ * Controls how long to wait for GitHub API responses
547
+ * before timing out.
548
+ *
549
+ * @example
550
+ * ```typescript
551
+ * const config = { timeout: 5000 }; // 5 seconds
552
+ * ```
151
553
  */
152
554
  timeout?: number;
153
555
  }
154
556
 
557
+ /**
558
+ * @module GithubPR
559
+ * @description GitHub Pull Request and Release Management
560
+ *
561
+ * This module provides functionality for managing GitHub pull requests
562
+ * and releases as part of the release process. It handles PR creation,
563
+ * release publishing, and changelog management.
564
+ *
565
+ * Core Features:
566
+ * - Pull request creation and management
567
+ * - Release publishing
568
+ * - Changelog integration
569
+ * - Tag management
570
+ * - Label management
571
+ * - Auto-merge support
572
+ *
573
+ * @example Basic usage
574
+ * ```typescript
575
+ * const plugin = new GithubPR(context, {
576
+ * releasePR: true,
577
+ * autoGenerate: true
578
+ * });
579
+ *
580
+ * await plugin.exec();
581
+ * ```
582
+ *
583
+ * @example Release publishing
584
+ * ```typescript
585
+ * const plugin = new GithubPR(context, {
586
+ * releasePR: false,
587
+ * makeLatest: true,
588
+ * preRelease: false
589
+ * });
590
+ *
591
+ * await plugin.exec();
592
+ * ```
593
+ */
594
+
155
595
  interface GithubPRProps extends ReleaseParamsConfig, GitBaseProps {
156
596
  /**
157
597
  * Whether to dry run the creation of the pull request
@@ -238,30 +678,197 @@ interface GithubPRProps extends ReleaseParamsConfig, GitBaseProps {
238
678
  pushChangeLabels?: boolean;
239
679
  }
240
680
 
681
+ /**
682
+ * @module FeReleaseTypes
683
+ * @description Type definitions for the fe-release framework
684
+ *
685
+ * This module provides TypeScript type definitions for the fe-release framework,
686
+ * including interfaces for release context, configuration, execution context,
687
+ * and various utility types.
688
+ *
689
+ * Type Categories:
690
+ * - Execution Context: Types for task execution and return values
691
+ * - Configuration: Types for release and workspace configuration
692
+ * - Plugin Types: Interfaces for GitHub PR and workspace plugins
693
+ * - Utility Types: Helper types like DeepPartial and PackageJson
694
+ *
695
+ * Design Considerations:
696
+ * - Type safety for plugin configuration
697
+ * - Extensible context interfaces
698
+ * - Backward compatibility support
699
+ * - Clear deprecation markers
700
+ * - Generic type constraints
701
+ */
702
+
703
+ /**
704
+ * Extended execution context for release tasks
705
+ *
706
+ * Adds release-specific return value handling to the base executor context.
707
+ * Used to track and manage release task execution results.
708
+ *
709
+ * @example
710
+ * ```typescript
711
+ * const context: ExecutorReleaseContext = {
712
+ * returnValue: { githubToken: 'token123' },
713
+ * // ... other executor context properties
714
+ * };
715
+ * ```
716
+ */
241
717
  interface ExecutorReleaseContext extends ExecutorContext<ReleaseContext> {
242
718
  returnValue: ReleaseReturnValue;
243
719
  }
720
+ /**
721
+ * Return value type for release tasks
722
+ *
723
+ * Defines the structure of data returned from release task execution.
724
+ * Includes GitHub token and allows for additional custom properties.
725
+ *
726
+ * @example
727
+ * ```typescript
728
+ * const returnValue: ReleaseReturnValue = {
729
+ * githubToken: 'github_pat_123',
730
+ * customData: { version: '1.0.0' }
731
+ * };
732
+ * ```
733
+ */
244
734
  type ReleaseReturnValue = {
245
735
  githubToken?: string;
246
736
  [key: string]: unknown;
247
737
  };
738
+ /**
739
+ * Utility type for creating deep partial types
740
+ *
741
+ * Makes all properties in T optional recursively, useful for
742
+ * partial configuration objects and type-safe updates.
743
+ *
744
+ * @example
745
+ * ```typescript
746
+ * interface Config {
747
+ * deep: {
748
+ * nested: {
749
+ * value: string;
750
+ * }
751
+ * }
752
+ * }
753
+ *
754
+ * const partial: DeepPartial<Config> = {
755
+ * deep: {
756
+ * nested: {
757
+ * // All properties optional
758
+ * }
759
+ * }
760
+ * };
761
+ * ```
762
+ */
248
763
  type DeepPartial<T> = {
249
764
  [P in keyof T]?: DeepPartial<T[P]>;
250
765
  };
251
- interface ReleaseConfig {
766
+ /**
767
+ * Configuration interface for release process
768
+ *
769
+ * Extends shared script configuration with release-specific
770
+ * settings for GitHub PR and workspace management.
771
+ *
772
+ * @example
773
+ * ```typescript
774
+ * const config: ReleaseConfig = {
775
+ * githubPR: {
776
+ * owner: 'org',
777
+ * repo: 'repo',
778
+ * base: 'main'
779
+ * },
780
+ * workspaces: {
781
+ * packages: ['packages/*']
782
+ * }
783
+ * };
784
+ * ```
785
+ */
786
+ interface ReleaseConfig extends ScriptSharedInterface {
252
787
  githubPR?: GithubPRProps;
253
788
  workspaces?: WorkspacesProps;
254
789
  }
255
- interface ReleaseContextOptions<T extends ReleaseConfig = ReleaseConfig> extends Omit<FeScriptContextOptions<T>, 'constructor'> {
256
- shared?: SharedReleaseOptions;
790
+ /**
791
+ * Options interface for release context
792
+ *
793
+ * Extends script context interface with release-specific configuration.
794
+ * Uses generic type parameter for custom configuration extensions.
795
+ *
796
+ * @example
797
+ * ```typescript
798
+ * interface CustomConfig extends ReleaseConfig {
799
+ * custom: {
800
+ * feature: boolean;
801
+ * }
802
+ * }
803
+ *
804
+ * const options: ReleaseContextOptions<CustomConfig> = {
805
+ * custom: {
806
+ * feature: true
807
+ * }
808
+ * };
809
+ * ```
810
+ */
811
+ interface ReleaseContextOptions$1<T extends ReleaseConfig = ReleaseConfig> extends ScriptContextInterface<T> {
257
812
  }
813
+ /**
814
+ * Configuration for a single execution step
815
+ *
816
+ * Defines a labeled, optionally enabled task with async execution.
817
+ * Used for creating structured, trackable release steps.
818
+ *
819
+ * @example
820
+ * ```typescript
821
+ * const step: StepOption<string> = {
822
+ * label: 'Update version',
823
+ * enabled: true,
824
+ * task: async () => {
825
+ * // Version update logic
826
+ * return 'Version updated to 1.0.0';
827
+ * }
828
+ * };
829
+ * ```
830
+ */
258
831
  type StepOption<T> = {
259
832
  label: string;
260
833
  enabled?: boolean;
261
834
  task: () => Promise<T>;
262
835
  };
836
+ /**
837
+ * Type alias for package.json structure
838
+ *
839
+ * Represents the structure of a package.json file with flexible
840
+ * key-value pairs. Used for package metadata handling.
841
+ *
842
+ * @example
843
+ * ```typescript
844
+ * const pkg: PackageJson = {
845
+ * name: 'my-package',
846
+ * version: '1.0.0',
847
+ * dependencies: {
848
+ * // ...
849
+ * }
850
+ * };
851
+ * ```
852
+ */
263
853
  type PackageJson = Record<string, unknown>;
264
- interface TemplateContext extends SharedReleaseOptions, WorkspaceValue {
854
+ /**
855
+ * Context interface for template processing
856
+ *
857
+ * Combines release context options with workspace values and
858
+ * adds template-specific properties. Includes deprecated fields
859
+ * with migration guidance.
860
+ *
861
+ * @example
862
+ * ```typescript
863
+ * const context: TemplateContext = {
864
+ * publishPath: './dist',
865
+ * env: 'production', // Deprecated
866
+ * branch: 'main', // Deprecated
867
+ * // ... other properties from ReleaseContextOptions
868
+ * };
869
+ * ```
870
+ */
871
+ interface TemplateContext extends ReleaseContextOptions$1, WorkspaceValue {
265
872
  publishPath: string;
266
873
  /**
267
874
  * @deprecated use `releaseEnv` from `shared`
@@ -273,67 +880,70 @@ interface TemplateContext extends SharedReleaseOptions, WorkspaceValue {
273
880
  branch: string;
274
881
  }
275
882
 
276
- declare abstract class Plugin<Props = unknown> implements ExecutorPlugin<ReleaseContext> {
277
- protected context: ReleaseContext;
278
- readonly pluginName: string;
279
- protected props: Props;
280
- readonly onlyOne = true;
281
- constructor(context: ReleaseContext, pluginName: string, props?: Props);
282
- getInitialProps(props?: Props): Props;
283
- get logger(): LoggerInterface;
284
- get shell(): Shell;
285
- get options(): Props;
286
- getEnv(key: string, defaultValue?: string): string | undefined;
287
- enabled(_name: string, _context: ExecutorReleaseContext): boolean;
288
- getConfig<T>(keys?: string | string[], defaultValue?: T): T;
289
- setConfig(config: DeepPartial<Props>): void;
290
- onBefore?(_context: ExecutorReleaseContext): void | Promise<void>;
291
- onExec?(_context: ExecutorReleaseContext): void | Promise<void>;
292
- onSuccess?(_context: ExecutorReleaseContext): void | Promise<void>;
293
- onError?(_context: ExecutorReleaseContext): void | Promise<void>;
294
- /**
295
- * run a step
296
- *
297
- * this will log the step and return the result of the task
298
- *
299
- * @param label - the label of the step
300
- * @param task - the task to run
301
- * @returns the result of the task
302
- */
303
- step<T>({ label, task }: StepOption<T>): Promise<T>;
304
- }
305
-
306
- /**
307
- * Represents a class that extends Plugin.
308
- */
309
- type PluginClass<T extends unknown[] = any[]> = new (...args: T) => Plugin;
310
- /**
311
- * Represents the constructor parameters for a specific Plugin class, excluding the first parameter.
312
- * This assumes that the constructor parameters are known and can be inferred.
313
- */
314
- type PluginConstructorParams<T extends PluginClass> = T extends new (first: any, ...args: infer P) => unknown ? P : never;
315
- type PluginTuple<T extends PluginClass> = [
316
- T | string,
317
- ...PluginConstructorParams<T>
318
- ];
319
- declare function tuple<T extends PluginClass>(plugin: T | string, ...args: PluginConstructorParams<T>): PluginTuple<T>;
320
-
321
883
  /**
322
- * This is the shared options for the release.
884
+ * @module ReleaseContext
885
+ * @description Core context management for release operations
886
+ *
887
+ * This module provides the central context management for release operations,
888
+ * handling configuration, environment variables, workspace management, and
889
+ * package information. It extends the base ScriptContext with release-specific
890
+ * functionality.
891
+ *
892
+ * Core Features:
893
+ * - Environment variable management
894
+ * - Workspace configuration
895
+ * - Package.json access
896
+ * - Template context generation
897
+ * - Changeset CLI integration
898
+ *
899
+ * @example Basic usage
900
+ * ```typescript
901
+ * const context = new ReleaseContext('my-package', {
902
+ * rootPath: '/path/to/project',
903
+ * sourceBranch: 'main',
904
+ * releaseEnv: 'production'
905
+ * });
906
+ *
907
+ * // Access package info
908
+ * const version = context.getPkg('version');
909
+ *
910
+ * // Generate template context
911
+ * const templateData = context.getTemplateContext();
912
+ * ```
913
+ *
914
+ * @example Workspace management
915
+ * ```typescript
916
+ * // Set workspace configuration
917
+ * context.setWorkspaces([{
918
+ * name: 'package-a',
919
+ * version: '1.0.0',
920
+ * path: 'packages/a'
921
+ * }]);
922
+ *
923
+ * // Access workspace info
924
+ * const currentWorkspace = context.workspace;
925
+ * ```
323
926
  *
324
- * extends `FeReleaseConfig`
927
+ * @example Changeset integration
928
+ * ```typescript
929
+ * // Run changeset commands
930
+ * await context.runChangesetsCli('version', ['--snapshot', 'alpha']);
931
+ * ```
325
932
  */
326
- interface SharedReleaseOptions extends FeReleaseConfig {
933
+
934
+ interface ReleaseContextOptions extends ScriptContextInterface<ReleaseContextConfig> {
935
+ }
936
+ interface ReleaseContextConfig extends FeReleaseConfig, ScriptSharedInterface {
327
937
  /**
328
- * The source branch of the project
329
- *
330
- * default:
331
- * - first, get from `FE_RELEASE_SOURCE_BRANCH`
332
- * - second, get from `FE_RELEASE_BRANCH`
333
- * - `master`
334
- *
938
+ * The github PR of the project
939
+ * @private
940
+ */
941
+ githubPR?: GithubPRProps;
942
+ /**
943
+ * The workspaces of the project
944
+ * @private
335
945
  */
336
- sourceBranch?: string;
946
+ workspaces?: WorkspacesProps;
337
947
  /**
338
948
  * The environment of the project
339
949
  *
@@ -343,12 +953,6 @@ interface SharedReleaseOptions extends FeReleaseConfig {
343
953
  * - `development`
344
954
  */
345
955
  releaseEnv?: string;
346
- /**
347
- * The root path of the project
348
- *
349
- * @default `process.cwd()`
350
- */
351
- rootPath?: string;
352
956
  /**
353
957
  * Plugins
354
958
  */
@@ -366,79 +970,611 @@ interface SharedReleaseOptions extends FeReleaseConfig {
366
970
  */
367
971
  currentBranch?: string;
368
972
  }
369
-
370
- declare class ReleaseContext<T extends ReleaseConfig = ReleaseConfig> extends FeScriptContext<T> {
371
- protected readonly _env: Env;
973
+ /**
974
+ * Core context class for release operations
975
+ *
976
+ * Manages release-specific configuration, environment variables,
977
+ * workspace settings, and provides utilities for release operations.
978
+ *
979
+ * Features:
980
+ * - Automatic environment detection
981
+ * - Source branch management
982
+ * - Workspace configuration
983
+ * - Package.json access
984
+ * - Template context generation
985
+ * - Changeset CLI integration
986
+ *
987
+ * @example Basic initialization
988
+ * ```typescript
989
+ * const context = new ReleaseContext('my-package', {
990
+ * rootPath: '/path/to/project',
991
+ * sourceBranch: 'main'
992
+ * });
993
+ * ```
994
+ *
995
+ * @example Environment configuration
996
+ * ```typescript
997
+ * // With environment variables
998
+ * process.env.FE_RELEASE_ENV = 'staging';
999
+ * process.env.FE_RELEASE_BRANCH = 'develop';
1000
+ *
1001
+ * const context = new ReleaseContext('my-package', {});
1002
+ * // context.releaseEnv === 'staging'
1003
+ * // context.sourceBranch === 'develop'
1004
+ * ```
1005
+ */
1006
+ declare class ReleaseContext extends ScriptContext<ReleaseContextConfig> {
372
1007
  /**
373
- * Shared Config
1008
+ * Creates a new ReleaseContext instance
1009
+ *
1010
+ * Initializes the context with provided options and sets up
1011
+ * default values for required configuration:
1012
+ * - rootPath: Defaults to current working directory
1013
+ * - sourceBranch: Uses environment variables or default
1014
+ * - releaseEnv: Uses environment variables or 'development'
1015
+ *
1016
+ * Environment Variable Priority:
1017
+ * - sourceBranch: FE_RELEASE_BRANCH > FE_RELEASE_SOURCE_BRANCH > DEFAULT_SOURCE_BRANCH
1018
+ * - releaseEnv: FE_RELEASE_ENV > NODE_ENV > 'development'
1019
+ *
1020
+ * @param name - Unique identifier for this release context
1021
+ * @param options - Configuration options
1022
+ *
1023
+ * @example
1024
+ * ```typescript
1025
+ * const context = new ReleaseContext('web-app', {
1026
+ * rootPath: '/projects/web-app',
1027
+ * sourceBranch: 'main',
1028
+ * releaseEnv: 'production'
1029
+ * });
1030
+ * ```
1031
+ */
1032
+ constructor(name: string, options: Partial<ReleaseContextOptions>);
1033
+ /**
1034
+ * Gets the root path of the project
1035
+ *
1036
+ * @returns Absolute path to project root
1037
+ *
1038
+ * @example
1039
+ * ```typescript
1040
+ * const root = context.rootPath;
1041
+ * // '/path/to/project'
1042
+ * ```
374
1043
  */
375
- shared: SharedReleaseOptions;
376
- constructor(context: ReleaseContextOptions<T>);
377
- private getDefaultShreadOptions;
378
1044
  get rootPath(): string;
379
- get sourceBranch(): string;
380
- get releaseEnv(): string;
381
- get env(): Env;
382
- get workspaces(): WorkspaceValue[] | undefined;
383
- get workspace(): WorkspaceValue | undefined;
384
- setWorkspaces(workspaces: WorkspaceValue[]): void;
385
- setConfig(config: DeepPartial<ReleaseConfig>): void;
386
- getConfig<T = unknown>(key: string | string[], defaultValue?: T): T;
387
- setShared(shared: Partial<SharedReleaseOptions>): void;
388
- getPkg<T>(key?: string, defaultValue?: T): T;
389
- getTemplateContext(): TemplateContext;
390
- runChangesetsCli(name: string, args?: string[]): Promise<string>;
391
- }
392
-
393
- type ReleaseLabelCompare = (changedFilePath: string, packagePath: string) => boolean;
394
- interface ReleaseLabelOptions {
395
1045
  /**
396
- * The change packages label
1046
+ * Gets the source branch for the release
1047
+ *
1048
+ * @returns Branch name to use as source
1049
+ *
1050
+ * @example
1051
+ * ```typescript
1052
+ * const branch = context.sourceBranch;
1053
+ * // 'main' or custom branch name
1054
+ * ```
397
1055
  */
398
- changePackagesLabel: string;
1056
+ get sourceBranch(): string;
399
1057
  /**
400
- * The packages directories
1058
+ * Gets the release environment
1059
+ *
1060
+ * @returns Environment name (e.g., 'development', 'production')
1061
+ *
1062
+ * @example
1063
+ * ```typescript
1064
+ * const env = context.releaseEnv;
1065
+ * // 'development' or custom environment
1066
+ * ```
401
1067
  */
402
- packagesDirectories: string[];
403
- compare?: ReleaseLabelCompare;
404
- }
405
- declare class ReleaseLabel {
406
- private readonly options;
407
- constructor(options: ReleaseLabelOptions);
408
- compare(changedFilePath: string, packagePath: string): boolean;
409
- toChangeLabel(packagePath: string, label?: string): string;
410
- toChangeLabels(packages: string[], label?: string): string[];
411
- pick(changedFiles: Array<string> | Set<string>, packages?: string[]): string[];
412
- }
413
-
414
- type BaseCommit = {
415
- [key in CommitField]: string | undefined;
416
- };
417
- interface GitChangelogOptions {
1068
+ get releaseEnv(): string;
418
1069
  /**
419
- * start tag
1070
+ * Gets all configured workspaces
1071
+ *
1072
+ * @returns Array of workspace configurations or undefined
1073
+ *
1074
+ * @example
1075
+ * ```typescript
1076
+ * const allWorkspaces = context.workspaces;
1077
+ * // [{ name: 'pkg-a', version: '1.0.0', ... }]
1078
+ * ```
420
1079
  */
421
- from?: string;
1080
+ get workspaces(): WorkspaceValue[] | undefined;
422
1081
  /**
423
- * end tag
1082
+ * Gets the current active workspace
1083
+ *
1084
+ * @returns Current workspace configuration or undefined
1085
+ *
1086
+ * @example
1087
+ * ```typescript
1088
+ * const current = context.workspace;
1089
+ * // { name: 'pkg-a', version: '1.0.0', ... }
1090
+ * ```
424
1091
  */
425
- to?: string;
1092
+ get workspace(): WorkspaceValue | undefined;
426
1093
  /**
427
- * log directory
1094
+ * Sets the workspace configurations
1095
+ *
1096
+ * Updates the workspace list while preserving other workspace settings
1097
+ *
1098
+ * @param workspaces - Array of workspace configurations
1099
+ *
1100
+ * @example
1101
+ * ```typescript
1102
+ * context.setWorkspaces([{
1103
+ * name: 'pkg-a',
1104
+ * version: '1.0.0',
1105
+ * path: 'packages/a'
1106
+ * }]);
1107
+ * ```
428
1108
  */
429
- directory?: string;
1109
+ setWorkspaces(workspaces: WorkspaceValue[]): void;
430
1110
  /**
431
- * gitlog default fields
432
- * @default ["abbrevHash", "hash", "subject", "authorName", "authorDate"]
433
- */
434
- fileds?: CommitField[];
1111
+ * Gets package.json data for the current workspace
1112
+ *
1113
+ * Provides type-safe access to package.json fields with optional
1114
+ * path and default value support.
1115
+ *
1116
+ * @param key - Optional dot-notation path to specific field
1117
+ * @param defaultValue - Default value if field not found
1118
+ * @returns Package data of type T
1119
+ * @throws Error if package.json not found
1120
+ *
1121
+ * @example Basic usage
1122
+ * ```typescript
1123
+ * // Get entire package.json
1124
+ * const pkg = context.getPkg();
1125
+ *
1126
+ * // Get specific field
1127
+ * const version = context.getPkg<string>('version');
1128
+ *
1129
+ * // Get nested field with default
1130
+ * const script = context.getPkg<string>(
1131
+ * 'scripts.build',
1132
+ * 'echo "No build script"'
1133
+ * );
1134
+ * ```
1135
+ */
1136
+ getPkg<T>(key?: string, defaultValue?: T): T;
1137
+ /**
1138
+ * Generates template context for string interpolation
1139
+ *
1140
+ * Combines context options, workspace data, and specific paths
1141
+ * for use in template processing. Includes deprecated fields
1142
+ * for backward compatibility.
1143
+ *
1144
+ * @returns Combined template context
1145
+ *
1146
+ * @example
1147
+ * ```typescript
1148
+ * const context = releaseContext.getTemplateContext();
1149
+ * // {
1150
+ * // publishPath: 'packages/my-pkg',
1151
+ * // env: 'production', // deprecated
1152
+ * // branch: 'main', // deprecated
1153
+ * // releaseEnv: 'production', // use this instead
1154
+ * // sourceBranch: 'main', // use this instead
1155
+ * // ...other options
1156
+ * // }
1157
+ * ```
1158
+ */
1159
+ getTemplateContext(): TemplateContext;
1160
+ /**
1161
+ * Executes changeset CLI commands
1162
+ *
1163
+ * Automatically detects and uses appropriate package manager
1164
+ * (pnpm or npx) to run changeset commands.
1165
+ *
1166
+ * @param name - Changeset command name
1167
+ * @param args - Optional command arguments
1168
+ * @returns Command output
1169
+ *
1170
+ * @example Version bump
1171
+ * ```typescript
1172
+ * // Bump version with snapshot
1173
+ * await context.runChangesetsCli('version', ['--snapshot', 'alpha']);
1174
+ *
1175
+ * // Create new changeset
1176
+ * await context.runChangesetsCli('add');
1177
+ *
1178
+ * // Status check
1179
+ * await context.runChangesetsCli('status');
1180
+ * ```
1181
+ */
1182
+ runChangesetsCli(name: string, args?: string[]): Promise<string>;
1183
+ }
1184
+
1185
+ /**
1186
+ * @module ReleaseLabel
1187
+ * @description Release label management and file change detection
1188
+ *
1189
+ * This module provides utilities for managing release labels and detecting
1190
+ * which packages have changed based on file paths. It supports custom
1191
+ * comparison logic and label formatting.
1192
+ *
1193
+ * Core Features:
1194
+ * - File change detection
1195
+ * - Package path matching
1196
+ * - Label generation
1197
+ * - Custom comparison logic
1198
+ *
1199
+ * @example Basic usage
1200
+ * ```typescript
1201
+ * const label = new ReleaseLabel({
1202
+ * changePackagesLabel: 'changed:${name}',
1203
+ * packagesDirectories: ['packages/a', 'packages/b']
1204
+ * });
1205
+ *
1206
+ * // Find changed packages
1207
+ * const changed = label.pick(['packages/a/src/index.ts']);
1208
+ * // ['packages/a']
1209
+ *
1210
+ * // Generate labels
1211
+ * const labels = label.toChangeLabels(changed);
1212
+ * // ['changed:packages/a']
1213
+ * ```
1214
+ *
1215
+ * @example Custom comparison
1216
+ * ```typescript
1217
+ * const label = new ReleaseLabel({
1218
+ * changePackagesLabel: 'changed:${name}',
1219
+ * packagesDirectories: ['packages/a'],
1220
+ * compare: (file, pkg) => file.includes(pkg)
1221
+ * });
1222
+ *
1223
+ * const changed = label.pick(['src/packages/a/index.ts']);
1224
+ * // ['packages/a']
1225
+ * ```
1226
+ */
1227
+ /**
1228
+ * Function type for custom file path comparison
1229
+ *
1230
+ * Used to determine if a changed file belongs to a package.
1231
+ * Default implementation checks if the file path starts with
1232
+ * the package path.
1233
+ *
1234
+ * @param changedFilePath - Path of the changed file
1235
+ * @param packagePath - Path of the package to check against
1236
+ * @returns True if the file belongs to the package
1237
+ */
1238
+ type ReleaseLabelCompare = (changedFilePath: string, packagePath: string) => boolean;
1239
+ interface ReleaseLabelOptions {
1240
+ /**
1241
+ * The change packages label
1242
+ */
1243
+ changePackagesLabel: string;
1244
+ /**
1245
+ * The packages directories
1246
+ */
1247
+ packagesDirectories: string[];
1248
+ compare?: ReleaseLabelCompare;
1249
+ }
1250
+ /**
1251
+ * Core class for managing release labels and change detection
1252
+ *
1253
+ * Provides utilities for detecting changed packages and generating
1254
+ * appropriate labels. Supports custom comparison logic and label
1255
+ * formatting.
1256
+ *
1257
+ * Features:
1258
+ * - File change detection
1259
+ * - Package path matching
1260
+ * - Label generation
1261
+ * - Custom comparison logic
1262
+ *
1263
+ * @example Basic usage
1264
+ * ```typescript
1265
+ * const label = new ReleaseLabel({
1266
+ * changePackagesLabel: 'changed:${name}',
1267
+ * packagesDirectories: ['packages/a', 'packages/b']
1268
+ * });
1269
+ *
1270
+ * // Find changed packages
1271
+ * const changed = label.pick(['packages/a/src/index.ts']);
1272
+ *
1273
+ * // Generate labels
1274
+ * const labels = label.toChangeLabels(changed);
1275
+ * ```
1276
+ *
1277
+ * @example Custom comparison
1278
+ * ```typescript
1279
+ * const label = new ReleaseLabel({
1280
+ * changePackagesLabel: 'changed:${name}',
1281
+ * packagesDirectories: ['packages/a'],
1282
+ * compare: (file, pkg) => file.includes(pkg)
1283
+ * });
1284
+ *
1285
+ * const changed = label.pick(['src/packages/a/index.ts']);
1286
+ * ```
1287
+ */
1288
+ declare class ReleaseLabel {
1289
+ private readonly options;
1290
+ /**
1291
+ * Creates a new ReleaseLabel instance
1292
+ *
1293
+ * @param options - Configuration options for label management
1294
+ *
1295
+ * @example
1296
+ * ```typescript
1297
+ * const label = new ReleaseLabel({
1298
+ * // Label template with ${name} placeholder
1299
+ * changePackagesLabel: 'changed:${name}',
1300
+ *
1301
+ * // Package directories to monitor
1302
+ * packagesDirectories: ['packages/a', 'packages/b'],
1303
+ *
1304
+ * // Optional custom comparison logic
1305
+ * compare: (file, pkg) => file.includes(pkg)
1306
+ * });
1307
+ * ```
1308
+ */
1309
+ constructor(options: ReleaseLabelOptions);
1310
+ /**
1311
+ * Compares a changed file path against a package path
1312
+ *
1313
+ * Uses custom comparison function if provided, otherwise
1314
+ * checks if the file path starts with the package path.
1315
+ *
1316
+ * @param changedFilePath - Path of the changed file
1317
+ * @param packagePath - Path of the package to check against
1318
+ * @returns True if the file belongs to the package
1319
+ *
1320
+ * @example
1321
+ * ```typescript
1322
+ * // Default comparison
1323
+ * label.compare('packages/a/src/index.ts', 'packages/a');
1324
+ * // true
1325
+ *
1326
+ * // Custom comparison
1327
+ * const label = new ReleaseLabel({
1328
+ * ...options,
1329
+ * compare: (file, pkg) => file.includes(pkg)
1330
+ * });
1331
+ * label.compare('src/packages/a/index.ts', 'packages/a');
1332
+ * // true
1333
+ * ```
1334
+ */
1335
+ compare(changedFilePath: string, packagePath: string): boolean;
1336
+ /**
1337
+ * Generates a change label for a single package
1338
+ *
1339
+ * Replaces ${name} placeholder in the label template with
1340
+ * the package path.
1341
+ *
1342
+ * @param packagePath - Path of the package
1343
+ * @param label - Optional custom label template
1344
+ * @returns Formatted change label
1345
+ *
1346
+ * @example
1347
+ * ```typescript
1348
+ * // Default label template
1349
+ * label.toChangeLabel('packages/a');
1350
+ * // 'changed:packages/a'
1351
+ *
1352
+ * // Custom label template
1353
+ * label.toChangeLabel('packages/a', 'modified:${name}');
1354
+ * // 'modified:packages/a'
1355
+ * ```
1356
+ */
1357
+ toChangeLabel(packagePath: string, label?: string): string;
1358
+ /**
1359
+ * Generates change labels for multiple packages
1360
+ *
1361
+ * Maps each package path to a formatted change label.
1362
+ *
1363
+ * @param packages - Array of package paths
1364
+ * @param label - Optional custom label template
1365
+ * @returns Array of formatted change labels
1366
+ *
1367
+ * @example
1368
+ * ```typescript
1369
+ * // Default label template
1370
+ * label.toChangeLabels(['packages/a', 'packages/b']);
1371
+ * // ['changed:packages/a', 'changed:packages/b']
1372
+ *
1373
+ * // Custom label template
1374
+ * label.toChangeLabels(
1375
+ * ['packages/a', 'packages/b'],
1376
+ * 'modified:${name}'
1377
+ * );
1378
+ * // ['modified:packages/a', 'modified:packages/b']
1379
+ * ```
1380
+ */
1381
+ toChangeLabels(packages: string[], label?: string): string[];
1382
+ /**
1383
+ * Identifies packages affected by changed files
1384
+ *
1385
+ * Checks each changed file against package paths to determine
1386
+ * which packages have been modified.
1387
+ *
1388
+ * @param changedFiles - Array or Set of changed file paths
1389
+ * @param packages - Optional array of package paths to check
1390
+ * @returns Array of affected package paths
1391
+ *
1392
+ * @example
1393
+ * ```typescript
1394
+ * // Check against default packages
1395
+ * label.pick(['packages/a/src/index.ts']);
1396
+ * // ['packages/a']
1397
+ *
1398
+ * // Check specific packages
1399
+ * label.pick(
1400
+ * ['packages/a/index.ts', 'packages/b/test.ts'],
1401
+ * ['packages/a', 'packages/c']
1402
+ * );
1403
+ * // ['packages/a']
1404
+ *
1405
+ * // Using Set of files
1406
+ * label.pick(new Set(['packages/a/index.ts']));
1407
+ * // ['packages/a']
1408
+ * ```
1409
+ */
1410
+ pick(changedFiles: Array<string> | Set<string>, packages?: string[]): string[];
1411
+ }
1412
+
1413
+ /**
1414
+ * @module ChangeLog
1415
+ * @description Core interfaces for changelog generation
1416
+ *
1417
+ * This module provides the core interfaces and types for generating
1418
+ * changelogs from Git commit history. It includes types for commit
1419
+ * parsing, formatting, and changelog generation.
1420
+ *
1421
+ * Core Components:
1422
+ * - Commit data structures
1423
+ * - Changelog formatting
1424
+ * - Git log options
1425
+ * - Changelog generation
1426
+ *
1427
+ * @example Basic usage
1428
+ * ```typescript
1429
+ * class MyChangeLog implements ChangeLogInterface {
1430
+ * async getCommits(options?: GitChangelogOptions): Promise<CommitValue[]> {
1431
+ * // Implementation
1432
+ * }
1433
+ * }
1434
+ *
1435
+ * class MyFormatter implements ChangelogFormatter {
1436
+ * format(commits: CommitValue[]): string[] {
1437
+ * // Implementation
1438
+ * }
1439
+ * }
1440
+ * ```
1441
+ */
1442
+
1443
+ /**
1444
+ * Base commit type mapping Git commit fields
1445
+ *
1446
+ * Maps all available Git commit fields to optional string values.
1447
+ * Uses the CommitField type from gitlog package to ensure type safety.
1448
+ *
1449
+ * Available fields include:
1450
+ * - hash: Full commit hash
1451
+ * - abbrevHash: Abbreviated commit hash
1452
+ * - subject: Commit message subject
1453
+ * - authorName: Author's name
1454
+ * - authorDate: Author date
1455
+ * - And many more from gitlog.CommitField
1456
+ *
1457
+ * @example
1458
+ * ```typescript
1459
+ * const commit: BaseCommit = {
1460
+ * hash: 'abc123def456',
1461
+ * abbrevHash: 'abc123',
1462
+ * subject: 'feat: new feature',
1463
+ * authorName: 'John Doe',
1464
+ * authorDate: '2023-01-01'
1465
+ * };
1466
+ * ```
1467
+ */
1468
+ type BaseCommit = {
1469
+ [key in CommitField]: string | undefined;
1470
+ };
1471
+ /**
1472
+ * Configuration options for changelog generation
1473
+ *
1474
+ * Provides comprehensive options for controlling how changelogs
1475
+ * are generated from Git history, including commit range selection,
1476
+ * formatting, and filtering.
1477
+ *
1478
+ * @example Basic usage
1479
+ * ```typescript
1480
+ * const options: GitChangelogOptions = {
1481
+ * from: 'v1.0.0',
1482
+ * to: 'v2.0.0',
1483
+ * directory: 'packages/my-pkg',
1484
+ * noMerges: true
1485
+ * };
1486
+ * ```
1487
+ *
1488
+ * @example Custom formatting
1489
+ * ```typescript
1490
+ * const options: GitChangelogOptions = {
1491
+ * types: [
1492
+ * { type: 'feat', section: '### Features' },
1493
+ * { type: 'fix', section: '### Bug Fixes' }
1494
+ * ],
1495
+ * formatTemplate: '* ${commitlint.message} ${prLink}',
1496
+ * commitBody: true
1497
+ * };
1498
+ * ```
1499
+ */
1500
+ interface GitChangelogOptions {
1501
+ /**
1502
+ * Starting tag or commit reference
1503
+ *
1504
+ * Defines the start point for collecting commits.
1505
+ * Can be a tag name, commit hash, or branch name.
1506
+ *
1507
+ * @example
1508
+ * ```typescript
1509
+ * from: 'v1.0.0' // Start from v1.0.0 tag
1510
+ * from: 'abc123' // Start from specific commit
1511
+ * ```
1512
+ */
1513
+ from?: string;
1514
+ /**
1515
+ * Ending tag or commit reference
1516
+ *
1517
+ * Defines the end point for collecting commits.
1518
+ * Can be a tag name, commit hash, or branch name.
1519
+ *
1520
+ * @example
1521
+ * ```typescript
1522
+ * to: 'v2.0.0' // End at v2.0.0 tag
1523
+ * to: 'main' // End at main branch
1524
+ * ```
1525
+ */
1526
+ to?: string;
1527
+ /**
1528
+ * Directory to collect commits from
1529
+ *
1530
+ * Limits commit collection to changes in specified directory.
1531
+ * Useful for monorepo package-specific changelogs.
1532
+ *
1533
+ * @example
1534
+ * ```typescript
1535
+ * directory: 'packages/my-pkg' // Only changes in this directory
1536
+ * ```
1537
+ */
1538
+ directory?: string;
1539
+ /**
1540
+ * Git commit fields to include
1541
+ *
1542
+ * Specifies which Git commit fields to retrieve.
1543
+ * @default ["abbrevHash", "hash", "subject", "authorName", "authorDate"]
1544
+ *
1545
+ * @example
1546
+ * ```typescript
1547
+ * fields: ['hash', 'subject', 'authorName']
1548
+ * ```
1549
+ */
1550
+ fields?: CommitField[];
435
1551
  /**
436
- * not include merge commit
1552
+ * Whether to exclude merge commits
1553
+ *
1554
+ * When true, merge commits are filtered out from the changelog.
437
1555
  * @default true
1556
+ *
1557
+ * @example
1558
+ * ```typescript
1559
+ * noMerges: true // Exclude merge commits
1560
+ * noMerges: false // Include merge commits
1561
+ * ```
438
1562
  */
439
1563
  noMerges?: boolean;
440
1564
  /**
441
- * custom commit type
1565
+ * Commit type configurations
1566
+ *
1567
+ * Defines how different commit types should be handled and
1568
+ * formatted in the changelog.
1569
+ *
1570
+ * @example
1571
+ * ```typescript
1572
+ * types: [
1573
+ * { type: 'feat', section: '### Features' },
1574
+ * { type: 'fix', section: '### Bug Fixes' },
1575
+ * { type: 'chore', hidden: true } // Skip chore commits
1576
+ * ]
1577
+ * ```
442
1578
  */
443
1579
  types?: {
444
1580
  type: string;
@@ -446,115 +1582,1172 @@ interface GitChangelogOptions {
446
1582
  hidden?: boolean;
447
1583
  }[];
448
1584
  /**
449
- * custom commit format
1585
+ * Template for formatting commit entries
450
1586
  *
451
- * - support `CommitValue` properties
452
- * - add scopeHeader, commitLink, prLink
1587
+ * Supports variables from CommitValue properties and adds:
1588
+ * - ${scopeHeader}: Formatted scope
1589
+ * - ${commitLink}: Commit hash link
1590
+ * - ${prLink}: PR number link
453
1591
  *
454
1592
  * @default '\n- ${scopeHeader} ${commitlint.message} ${commitLink} ${prLink}'
1593
+ *
1594
+ * @example
1595
+ * ```typescript
1596
+ * formatTemplate: '* ${commitlint.message} (${commitLink})'
1597
+ * ```
455
1598
  */
456
1599
  formatTemplate?: string;
457
1600
  /**
458
- * whether to include commit body
1601
+ * Whether to include commit message body
1602
+ *
1603
+ * When true, includes the full commit message body
1604
+ * in the changelog entry.
1605
+ *
459
1606
  * @since 2.3.0
460
1607
  * @default false
1608
+ *
1609
+ * @example
1610
+ * ```typescript
1611
+ * commitBody: true // Include full commit message
1612
+ * ```
461
1613
  */
462
1614
  commitBody?: boolean;
463
1615
  }
1616
+ /**
1617
+ * Parsed conventional commit data
1618
+ *
1619
+ * Represents a commit message parsed according to the
1620
+ * conventional commit specification.
1621
+ *
1622
+ * Format: type(scope): message
1623
+ *
1624
+ * @example
1625
+ * ```typescript
1626
+ * const commit: Commitlint = {
1627
+ * type: 'feat',
1628
+ * scope: 'api',
1629
+ * message: 'add new endpoint',
1630
+ * body: 'Adds support for new API endpoint\n\nBREAKING CHANGE: API format changed'
1631
+ * };
1632
+ * ```
1633
+ */
464
1634
  interface Commitlint {
1635
+ /** Commit type (e.g., 'feat', 'fix') */
465
1636
  type?: string;
1637
+ /** Commit scope (e.g., 'api', 'core') */
466
1638
  scope?: string;
1639
+ /** Main commit message */
467
1640
  message: string;
468
1641
  /**
469
- * commit body, remove repeat title
1642
+ * Commit message body with title removed
470
1643
  * @since 2.3.0
471
1644
  */
472
1645
  body?: string;
473
1646
  }
1647
+ /**
1648
+ * Complete commit information
1649
+ *
1650
+ * Combines Git commit data, parsed conventional commit info,
1651
+ * and PR metadata into a single value object.
1652
+ *
1653
+ * @example
1654
+ * ```typescript
1655
+ * const commit: CommitValue = {
1656
+ * base: {
1657
+ * hash: 'abc123',
1658
+ * subject: 'feat(api): new endpoint (#123)'
1659
+ * },
1660
+ * commitlint: {
1661
+ * type: 'feat',
1662
+ * scope: 'api',
1663
+ * message: 'new endpoint'
1664
+ * },
1665
+ * commits: [],
1666
+ * prNumber: '123'
1667
+ * };
1668
+ * ```
1669
+ */
474
1670
  interface CommitValue {
475
- /**
476
- * git log base info
477
- */
1671
+ /** Raw Git commit information */
478
1672
  base: BaseCommit;
479
- /**
480
- * parsed commitlint info
481
- */
1673
+ /** Parsed conventional commit data */
482
1674
  commitlint: Commitlint;
483
- /**
484
- * parsed commitlint info
485
- */
1675
+ /** Sub-commits (for merge commits) */
486
1676
  commits: CommitValue[];
487
- /**
488
- * pr number
489
- */
1677
+ /** Associated pull request number */
490
1678
  prNumber?: string;
491
1679
  }
1680
+ /**
1681
+ * Interface for changelog formatting
1682
+ *
1683
+ * Defines the contract for classes that format commit data
1684
+ * into changelog entries.
1685
+ *
1686
+ * @example
1687
+ * ```typescript
1688
+ * class MarkdownFormatter implements ChangelogFormatter {
1689
+ * format(commits: CommitValue[]): string[] {
1690
+ * return commits.map(commit =>
1691
+ * `- ${commit.commitlint.message} (#${commit.prNumber})`
1692
+ * );
1693
+ * }
1694
+ * }
1695
+ * ```
1696
+ */
492
1697
  interface ChangelogFormatter {
1698
+ /**
1699
+ * Formats commits into changelog entries
1700
+ *
1701
+ * @param commits - Array of commits to format
1702
+ * @param options - Optional formatting options
1703
+ * @returns Array of formatted changelog lines
1704
+ */
493
1705
  format<Opt extends GitChangelogOptions>(commits: unknown[], options?: Opt): string[];
494
1706
  }
1707
+ /**
1708
+ * Interface for changelog generation
1709
+ *
1710
+ * Defines the contract for classes that generate changelogs
1711
+ * from Git history.
1712
+ *
1713
+ * @example
1714
+ * ```typescript
1715
+ * class GitChangelog implements ChangeLogInterface {
1716
+ * async getCommits(options?: GitChangelogOptions): Promise<CommitValue[]> {
1717
+ * // Get commits from Git and parse them
1718
+ * const commits = await gitlog(options);
1719
+ * return commits.map(commit => ({
1720
+ * base: commit,
1721
+ * commitlint: parseCommit(commit.subject),
1722
+ * commits: []
1723
+ * }));
1724
+ * }
1725
+ * }
1726
+ * ```
1727
+ */
495
1728
  interface ChangeLogInterface {
1729
+ /**
1730
+ * Retrieves and parses Git commits
1731
+ *
1732
+ * @param options - Optional Git log options
1733
+ * @returns Promise resolving to array of parsed commits
1734
+ */
496
1735
  getCommits(options?: GitChangelogOptions): Promise<CommitValue[]>;
497
1736
  }
498
1737
 
1738
+ /**
1739
+ * @module GitChangelog
1740
+ * @description Git-based changelog generation and commit parsing
1741
+ *
1742
+ * This module provides functionality for generating changelogs from Git
1743
+ * history, parsing commit messages according to conventional commit format,
1744
+ * and managing commit metadata.
1745
+ *
1746
+ * Core Features:
1747
+ * - Git log retrieval
1748
+ * - Conventional commit parsing
1749
+ * - Changelog generation
1750
+ * - Tag resolution
1751
+ * - PR number extraction
1752
+ *
1753
+ * @example Basic usage
1754
+ * ```typescript
1755
+ * const changelog = new GitChangelog({
1756
+ * shell,
1757
+ * logger,
1758
+ * directory: 'packages/my-pkg'
1759
+ * });
1760
+ *
1761
+ * // Get commits between tags
1762
+ * const commits = await changelog.getCommits({
1763
+ * from: 'v1.0.0',
1764
+ * to: 'v2.0.0'
1765
+ * });
1766
+ * ```
1767
+ *
1768
+ * @example Commit parsing
1769
+ * ```typescript
1770
+ * const changelog = new GitChangelog({ shell, logger });
1771
+ *
1772
+ * // Parse conventional commit
1773
+ * const commit = changelog.parseCommitlint(
1774
+ * 'feat(api): add new endpoint',
1775
+ * 'Detailed description\n\nBREAKING CHANGE: API format changed'
1776
+ * );
1777
+ * // {
1778
+ * // type: 'feat',
1779
+ * // scope: 'api',
1780
+ * // message: 'add new endpoint',
1781
+ * // body: ' Detailed description\n\n BREAKING CHANGE: API format changed'
1782
+ * // }
1783
+ * ```
1784
+ */
1785
+
1786
+ /**
1787
+ * Complete list of available Git commit fields
1788
+ *
1789
+ * These fields can be used when retrieving commit information
1790
+ * to specify which data should be included in the output.
1791
+ *
1792
+ * @example
1793
+ * ```typescript
1794
+ * const commits = await changelog.getGitLog({
1795
+ * fields: CHANGELOG_ALL_FIELDS
1796
+ * });
1797
+ * ```
1798
+ */
499
1799
  declare const CHANGELOG_ALL_FIELDS: CommitField[];
500
1800
  interface GitChangelogProps extends GitChangelogOptions {
501
- shell: Shell;
1801
+ shell: ShellInterface;
502
1802
  logger: LoggerInterface;
503
1803
  }
1804
+ /**
1805
+ * Core class for Git-based changelog generation
1806
+ *
1807
+ * Provides functionality for retrieving and parsing Git commit history,
1808
+ * generating changelogs, and managing commit metadata. Implements the
1809
+ * ChangeLogInterface for standardized changelog generation.
1810
+ *
1811
+ * Features:
1812
+ * - Git log retrieval with flexible options
1813
+ * - Conventional commit parsing
1814
+ * - Tag resolution and validation
1815
+ * - PR number extraction
1816
+ * - Commit body formatting
1817
+ *
1818
+ * @example Basic usage
1819
+ * ```typescript
1820
+ * const changelog = new GitChangelog({
1821
+ * shell,
1822
+ * logger,
1823
+ * directory: 'packages/my-pkg'
1824
+ * });
1825
+ *
1826
+ * // Get commits with parsed metadata
1827
+ * const commits = await changelog.getCommits({
1828
+ * from: 'v1.0.0',
1829
+ * to: 'v2.0.0',
1830
+ * noMerges: true
1831
+ * });
1832
+ * ```
1833
+ *
1834
+ * @example Custom commit parsing
1835
+ * ```typescript
1836
+ * const changelog = new GitChangelog({ shell, logger });
1837
+ *
1838
+ * // Create commit value from hash and message
1839
+ * const commit = changelog.toCommitValue(
1840
+ * 'abc1234',
1841
+ * 'feat(api): new endpoint (#123)'
1842
+ * );
1843
+ * // {
1844
+ * // base: { hash: 'abc1234', ... },
1845
+ * // commitlint: { type: 'feat', scope: 'api', ... },
1846
+ * // prNumber: '123'
1847
+ * // }
1848
+ * ```
1849
+ */
504
1850
  declare class GitChangelog implements ChangeLogInterface {
505
1851
  protected options: GitChangelogProps;
1852
+ /**
1853
+ * Creates a new GitChangelog instance
1854
+ *
1855
+ * @param options - Configuration options including shell and logger
1856
+ *
1857
+ * @example
1858
+ * ```typescript
1859
+ * const changelog = new GitChangelog({
1860
+ * shell: new Shell(),
1861
+ * logger: new Logger(),
1862
+ * directory: 'packages/my-pkg',
1863
+ * noMerges: true
1864
+ * });
1865
+ * ```
1866
+ */
506
1867
  constructor(options: GitChangelogProps);
507
1868
  /**
508
- * Get the git log
1869
+ * Retrieves Git commit history with specified options
509
1870
  *
510
- * @param options
511
- * @returns
1871
+ * Fetches commit information between specified tags or commits,
1872
+ * with support for filtering and field selection.
1873
+ *
1874
+ * @param options - Configuration options for Git log retrieval
1875
+ * @returns Array of commit objects with requested fields
1876
+ *
1877
+ * @example Basic usage
1878
+ * ```typescript
1879
+ * const commits = await changelog.getGitLog({
1880
+ * from: 'v1.0.0',
1881
+ * to: 'v2.0.0',
1882
+ * directory: 'packages/my-pkg',
1883
+ * noMerges: true
1884
+ * });
1885
+ * ```
1886
+ *
1887
+ * @example Custom fields
1888
+ * ```typescript
1889
+ * const commits = await changelog.getGitLog({
1890
+ * fields: ['hash', 'subject', 'authorName'],
1891
+ * directory: 'src'
1892
+ * });
1893
+ * ```
512
1894
  */
513
1895
  getGitLog(options?: GitChangelogOptions): Promise<BaseCommit[]>;
1896
+ /**
1897
+ * Retrieves and parses Git commits with metadata
1898
+ *
1899
+ * Gets commit history and enhances it with parsed conventional
1900
+ * commit information and PR metadata.
1901
+ *
1902
+ * @param options - Configuration options for Git log retrieval
1903
+ * @returns Array of enhanced commit objects with parsed metadata
1904
+ *
1905
+ * @example Basic usage
1906
+ * ```typescript
1907
+ * const commits = await changelog.getCommits({
1908
+ * from: 'v1.0.0',
1909
+ * to: 'v2.0.0'
1910
+ * });
1911
+ * // [
1912
+ * // {
1913
+ * // base: { hash: '...', subject: '...' },
1914
+ * // commitlint: { type: 'feat', scope: 'api', ... },
1915
+ * // commits: []
1916
+ * // }
1917
+ * // ]
1918
+ * ```
1919
+ *
1920
+ * @example Filtered commits
1921
+ * ```typescript
1922
+ * const commits = await changelog.getCommits({
1923
+ * directory: 'packages/my-pkg',
1924
+ * noMerges: true
1925
+ * });
1926
+ * ```
1927
+ */
514
1928
  getCommits(options?: GitChangelogOptions): Promise<CommitValue[]>;
1929
+ /**
1930
+ * Creates a base commit object from message and optional data
1931
+ *
1932
+ * Utility method to create a standardized commit object with
1933
+ * basic metadata. Used internally for commit value creation.
1934
+ *
1935
+ * @param message - Commit message
1936
+ * @param target - Optional additional commit data
1937
+ * @returns Base commit object
1938
+ * @protected
1939
+ *
1940
+ * @example
1941
+ * ```typescript
1942
+ * const commit = changelog.createBaseCommit(
1943
+ * 'feat: new feature',
1944
+ * {
1945
+ * hash: 'abc123',
1946
+ * authorName: 'John Doe'
1947
+ * }
1948
+ * );
1949
+ * ```
1950
+ */
515
1951
  protected createBaseCommit(message: string, target?: Partial<BaseCommit>): BaseCommit;
516
1952
  /**
517
- * Tabify the body
1953
+ * Indents each line of a text block
1954
+ *
1955
+ * Adds specified number of spaces to the start of each line
1956
+ * in a multi-line string. Used for formatting commit body text.
518
1957
  *
519
1958
  * @since 2.3.2
520
- * @param body
521
- * @param size
522
- * @returns
1959
+ * @param body - Text to indent
1960
+ * @param size - Number of spaces to add (default: 2)
1961
+ * @returns Indented text
1962
+ *
1963
+ * @example
1964
+ * ```typescript
1965
+ * const text = changelog.tabify(
1966
+ * 'Line 1\nLine 2\nLine 3',
1967
+ * 4
1968
+ * );
1969
+ * // ' Line 1\n Line 2\n Line 3'
1970
+ * ```
523
1971
  */
524
1972
  tabify(body: string, size?: number): string;
1973
+ /**
1974
+ * Parses a commit message into conventional commit format
1975
+ *
1976
+ * Extracts type, scope, message, and body from a commit message
1977
+ * following the conventional commit specification.
1978
+ *
1979
+ * Format: type(scope): message
1980
+ *
1981
+ * @param subject - Commit subject line
1982
+ * @param rawBody - Full commit message body
1983
+ * @returns Parsed conventional commit data
1984
+ *
1985
+ * @example Basic commit
1986
+ * ```typescript
1987
+ * const commit = changelog.parseCommitlint(
1988
+ * 'feat(api): add new endpoint'
1989
+ * );
1990
+ * // {
1991
+ * // type: 'feat',
1992
+ * // scope: 'api',
1993
+ * // message: 'add new endpoint'
1994
+ * // }
1995
+ * ```
1996
+ *
1997
+ * @example With body
1998
+ * ```typescript
1999
+ * const commit = changelog.parseCommitlint(
2000
+ * 'fix(core): memory leak',
2001
+ * 'Fixed memory leak in core module\n\nBREAKING CHANGE: API changed'
2002
+ * );
2003
+ * // {
2004
+ * // type: 'fix',
2005
+ * // scope: 'core',
2006
+ * // message: 'memory leak',
2007
+ * // body: ' Fixed memory leak in core module\n\n BREAKING CHANGE: API changed'
2008
+ * // }
2009
+ * ```
2010
+ */
525
2011
  parseCommitlint(subject: string, rawBody?: string): Commitlint;
2012
+ /**
2013
+ * Creates a complete commit value object from hash and message
2014
+ *
2015
+ * Combines commit hash, parsed conventional commit data, and
2016
+ * PR information into a single commit value object.
2017
+ *
2018
+ * @param hash - Commit hash
2019
+ * @param message - Full commit message
2020
+ * @returns Complete commit value object
2021
+ *
2022
+ * @example Basic commit
2023
+ * ```typescript
2024
+ * const commit = changelog.toCommitValue(
2025
+ * 'abc123',
2026
+ * 'feat(api): new endpoint'
2027
+ * );
2028
+ * // {
2029
+ * // base: {
2030
+ * // hash: 'abc123',
2031
+ * // abbrevHash: 'abc123',
2032
+ * // subject: 'feat(api): new endpoint'
2033
+ * // },
2034
+ * // commitlint: {
2035
+ * // type: 'feat',
2036
+ * // scope: 'api',
2037
+ * // message: 'new endpoint'
2038
+ * // },
2039
+ * // commits: []
2040
+ * // }
2041
+ * ```
2042
+ *
2043
+ * @example PR commit
2044
+ * ```typescript
2045
+ * const commit = changelog.toCommitValue(
2046
+ * 'def456',
2047
+ * 'fix(core): memory leak (#123)'
2048
+ * );
2049
+ * // {
2050
+ * // base: { hash: 'def456', ... },
2051
+ * // commitlint: { type: 'fix', ... },
2052
+ * // commits: [],
2053
+ * // prNumber: '123'
2054
+ * // }
2055
+ * ```
2056
+ */
526
2057
  toCommitValue(hash: string, message: string): CommitValue;
2058
+ /**
2059
+ * Resolves a Git tag or reference to a valid commit reference
2060
+ *
2061
+ * Attempts to resolve a tag name to a valid Git reference.
2062
+ * Falls back to root commit or HEAD if tag doesn't exist.
2063
+ *
2064
+ * @param tag - Tag name to resolve
2065
+ * @param fallback - Fallback value ('root' or 'HEAD')
2066
+ * @returns Resolved Git reference
2067
+ * @protected
2068
+ *
2069
+ * @example Basic tag resolution
2070
+ * ```typescript
2071
+ * const ref = await changelog.resolveTag('v1.0.0');
2072
+ * // 'v1.0.0' if tag exists
2073
+ * // 'HEAD' if tag doesn't exist
2074
+ * ```
2075
+ *
2076
+ * @example Root commit fallback
2077
+ * ```typescript
2078
+ * const ref = await changelog.resolveTag(
2079
+ * 'non-existent-tag',
2080
+ * 'root'
2081
+ * );
2082
+ * // First commit hash if tag doesn't exist
2083
+ * ```
2084
+ */
527
2085
  protected resolveTag(tag?: string, fallback?: string): Promise<string>;
528
2086
  }
529
2087
 
2088
+ /**
2089
+ * @module GitChangelogFormatter
2090
+ * @description Formats Git commits into readable changelog entries
2091
+ *
2092
+ * This module provides functionality for formatting Git commits into
2093
+ * a structured changelog format, with support for conventional commits,
2094
+ * PR links, and custom templates.
2095
+ *
2096
+ * Core Features:
2097
+ * - Conventional commit formatting
2098
+ * - PR and commit linking
2099
+ * - Type-based grouping
2100
+ * - Custom templates
2101
+ * - Markdown formatting
2102
+ *
2103
+ * @example Basic usage
2104
+ * ```typescript
2105
+ * const formatter = new GitChangelogFormatter({
2106
+ * shell,
2107
+ * repoUrl: 'https://github.com/org/repo',
2108
+ * types: [
2109
+ * { type: 'feat', section: '### Features' },
2110
+ * { type: 'fix', section: '### Bug Fixes' }
2111
+ * ]
2112
+ * });
2113
+ *
2114
+ * const changelog = formatter.format(commits);
2115
+ * // ### Features
2116
+ * // - **api:** new endpoint ([abc123](https://github.com/org/repo/commit/abc123)) (#123)
2117
+ * //
2118
+ * // ### Bug Fixes
2119
+ * // - **core:** fix memory leak ([def456](https://github.com/org/repo/commit/def456))
2120
+ * ```
2121
+ *
2122
+ * @example Custom template
2123
+ * ```typescript
2124
+ * const formatter = new GitChangelogFormatter({
2125
+ * shell,
2126
+ * formatTemplate: '* ${commitlint.message} ${prLink}',
2127
+ * types: [{ type: 'feat', section: '## New' }]
2128
+ * });
2129
+ *
2130
+ * const changelog = formatter.format(commits);
2131
+ * // ## New
2132
+ * // * add user authentication (#124)
2133
+ * ```
2134
+ */
2135
+
2136
+ /**
2137
+ * Configuration options for changelog formatting
2138
+ *
2139
+ * Extends GitChangelogOptions with repository URL support
2140
+ * for generating links to commits and pull requests.
2141
+ */
530
2142
  interface Options extends GitChangelogOptions {
2143
+ /**
2144
+ * Repository URL for generating links
2145
+ *
2146
+ * @example 'https://github.com/org/repo'
2147
+ */
531
2148
  repoUrl?: string;
532
2149
  }
2150
+ /**
2151
+ * Core class for formatting Git commits into changelog entries
2152
+ *
2153
+ * Implements ChangelogFormatter interface to provide standardized
2154
+ * changelog generation with support for:
2155
+ * - Conventional commit formatting
2156
+ * - Type-based grouping
2157
+ * - PR and commit linking
2158
+ * - Custom templates
2159
+ * - Markdown formatting
2160
+ *
2161
+ * @example Basic usage
2162
+ * ```typescript
2163
+ * const formatter = new GitChangelogFormatter({
2164
+ * shell,
2165
+ * repoUrl: 'https://github.com/org/repo',
2166
+ * types: [
2167
+ * { type: 'feat', section: '### Features' },
2168
+ * { type: 'fix', section: '### Bug Fixes' }
2169
+ * ]
2170
+ * });
2171
+ *
2172
+ * const changelog = formatter.format(commits);
2173
+ * ```
2174
+ *
2175
+ * @example Custom formatting
2176
+ * ```typescript
2177
+ * const formatter = new GitChangelogFormatter({
2178
+ * shell,
2179
+ * formatTemplate: '* ${commitlint.message}',
2180
+ * types: [{ type: 'feat', section: '## New' }],
2181
+ * commitBody: true // Include commit body
2182
+ * });
2183
+ * ```
2184
+ */
533
2185
  declare class GitChangelogFormatter implements ChangelogFormatter {
534
2186
  protected options: Options & {
535
- shell: Shell;
2187
+ shell: ShellInterface;
536
2188
  };
2189
+ /**
2190
+ * Creates a new GitChangelogFormatter instance
2191
+ *
2192
+ * @param options - Configuration options including shell interface
2193
+ *
2194
+ * @example
2195
+ * ```typescript
2196
+ * const formatter = new GitChangelogFormatter({
2197
+ * shell: new Shell(),
2198
+ * repoUrl: 'https://github.com/org/repo',
2199
+ * types: [
2200
+ * { type: 'feat', section: '### Features' }
2201
+ * ],
2202
+ * formatTemplate: '- ${commitlint.message}'
2203
+ * });
2204
+ * ```
2205
+ */
537
2206
  constructor(options: Options & {
538
- shell: Shell;
2207
+ shell: ShellInterface;
539
2208
  });
2209
+ /**
2210
+ * Formats an array of commits into changelog entries
2211
+ *
2212
+ * Groups commits by type and formats them according to the
2213
+ * configured template and options. Supports commit body
2214
+ * inclusion and type-based sections.
2215
+ *
2216
+ * @param commits - Array of commit values to format
2217
+ * @param options - Optional formatting options
2218
+ * @returns Array of formatted changelog lines
2219
+ *
2220
+ * @example Basic formatting
2221
+ * ```typescript
2222
+ * const changelog = formatter.format([
2223
+ * {
2224
+ * base: { hash: 'abc123' },
2225
+ * commitlint: {
2226
+ * type: 'feat',
2227
+ * scope: 'api',
2228
+ * message: 'new endpoint'
2229
+ * }
2230
+ * }
2231
+ * ]);
2232
+ * // [
2233
+ * // '### Features',
2234
+ * // '- **api:** new endpoint ([abc123](...))'
2235
+ * // ]
2236
+ * ```
2237
+ *
2238
+ * @example With commit body
2239
+ * ```typescript
2240
+ * const changelog = formatter.format(
2241
+ * [{
2242
+ * commitlint: {
2243
+ * type: 'fix',
2244
+ * message: 'memory leak',
2245
+ * body: 'Fixed memory allocation\nAdded cleanup'
2246
+ * }
2247
+ * }],
2248
+ * { commitBody: true }
2249
+ * );
2250
+ * // [
2251
+ * // '### Bug Fixes',
2252
+ * // '- memory leak',
2253
+ * // ' Fixed memory allocation',
2254
+ * // ' Added cleanup'
2255
+ * // ]
2256
+ * ```
2257
+ */
540
2258
  format(commits: CommitValue[], options?: Options): string[];
2259
+ /**
2260
+ * Formats a single commit into a changelog entry
2261
+ *
2262
+ * Applies the configured template to a commit, including
2263
+ * scope formatting, PR links, and commit hash links.
2264
+ *
2265
+ * @param commit - Commit value to format
2266
+ * @param options - Optional formatting options
2267
+ * @returns Formatted changelog entry
2268
+ *
2269
+ * @example Basic formatting
2270
+ * ```typescript
2271
+ * const entry = formatter.formatCommit({
2272
+ * base: { hash: 'abc123' },
2273
+ * commitlint: {
2274
+ * type: 'feat',
2275
+ * scope: 'api',
2276
+ * message: 'new endpoint'
2277
+ * }
2278
+ * });
2279
+ * // '- **api:** new endpoint ([abc123](...))'
2280
+ * ```
2281
+ *
2282
+ * @example With PR number
2283
+ * ```typescript
2284
+ * const entry = formatter.formatCommit({
2285
+ * base: { hash: 'def456' },
2286
+ * commitlint: {
2287
+ * message: 'fix bug'
2288
+ * },
2289
+ * prNumber: '123'
2290
+ * });
2291
+ * // '- fix bug ([def456](...)) (#123)'
2292
+ * ```
2293
+ */
541
2294
  formatCommit(commit: CommitValue, options?: Options): string;
2295
+ /**
2296
+ * Formats a target string as a Markdown link
2297
+ *
2298
+ * Creates a Markdown-formatted link with optional URL.
2299
+ * If no URL is provided, formats as a plain reference.
2300
+ *
2301
+ * @param target - Text to display
2302
+ * @param url - Optional URL for the link
2303
+ * @returns Formatted Markdown link
2304
+ *
2305
+ * @example With URL
2306
+ * ```typescript
2307
+ * const link = formatter.foramtLink('abc123', 'https://github.com/org/repo/commit/abc123');
2308
+ * // '([abc123](https://github.com/org/repo/commit/abc123))'
2309
+ * ```
2310
+ *
2311
+ * @example Without URL
2312
+ * ```typescript
2313
+ * const link = formatter.foramtLink('abc123');
2314
+ * // '(abc123)'
2315
+ * ```
2316
+ */
542
2317
  foramtLink(target: string, url?: string): string;
2318
+ /**
2319
+ * Formats a commit hash as a Markdown link
2320
+ *
2321
+ * @deprecated Use foramtLink instead
2322
+ * @param target - Commit hash to display
2323
+ * @param url - Optional URL to the commit
2324
+ * @returns Formatted Markdown link
2325
+ *
2326
+ * @example
2327
+ * ```typescript
2328
+ * const link = formatter.formatCommitLink(
2329
+ * 'abc123',
2330
+ * 'https://github.com/org/repo/commit/abc123'
2331
+ * );
2332
+ * // '([abc123](https://github.com/org/repo/commit/abc123))'
2333
+ * ```
2334
+ */
543
2335
  formatCommitLink(target: string, url?: string): string;
2336
+ /**
2337
+ * Formats a commit scope in Markdown
2338
+ *
2339
+ * Wraps the scope in bold syntax and adds a colon.
2340
+ *
2341
+ * @param scope - Scope to format
2342
+ * @returns Formatted scope in Markdown
2343
+ *
2344
+ * @example
2345
+ * ```typescript
2346
+ * const scope = formatter.formatScope('api');
2347
+ * // '**api:**'
2348
+ * ```
2349
+ */
544
2350
  formatScope(scope: string): string;
545
2351
  }
546
2352
 
2353
+ /**
2354
+ * @module GithubChangelog
2355
+ * @description GitHub-specific changelog generation
2356
+ *
2357
+ * This module extends the base changelog functionality with
2358
+ * GitHub-specific features like PR linking, commit filtering
2359
+ * by directory, and workspace-aware changelog generation.
2360
+ *
2361
+ * Core Features:
2362
+ * - PR-aware commit gathering
2363
+ * - Directory-based filtering
2364
+ * - GitHub link generation
2365
+ * - Workspace changelog transformation
2366
+ * - Markdown formatting
2367
+ *
2368
+ * @example Basic usage
2369
+ * ```typescript
2370
+ * const changelog = new GithubChangelog({
2371
+ * shell,
2372
+ * logger,
2373
+ * githubRootPath: 'https://github.com/org/repo'
2374
+ * }, githubManager);
2375
+ *
2376
+ * const commits = await changelog.getFullCommit({
2377
+ * from: 'v1.0.0',
2378
+ * directory: 'packages/pkg-a'
2379
+ * });
2380
+ * ```
2381
+ *
2382
+ * @example Workspace transformation
2383
+ * ```typescript
2384
+ * const workspaces = await changelog.transformWorkspace(
2385
+ * [{ name: 'pkg-a', path: 'packages/a' }],
2386
+ * context
2387
+ * );
2388
+ * // Adds formatted changelog to each workspace
2389
+ * ```
2390
+ */
2391
+
547
2392
  interface GithubChangelogProps extends GitChangelogProps {
548
2393
  mergePRcommit?: boolean;
549
2394
  githubRootPath?: string;
550
2395
  }
551
2396
 
2397
+ /**
2398
+ * @module PluginLoader
2399
+ * @description Dynamic plugin loading and instantiation
2400
+ *
2401
+ * This module provides utilities for dynamically loading and instantiating
2402
+ * plugins from various sources (ESM imports, file paths, package names).
2403
+ * It supports concurrent loading with limits and fallback mechanisms.
2404
+ *
2405
+ * Core Features:
2406
+ * - Dynamic ESM imports
2407
+ * - Fallback to CommonJS require
2408
+ * - Concurrent loading with limits
2409
+ * - Plugin instantiation with context
2410
+ *
2411
+ * @example Basic plugin loading
2412
+ * ```typescript
2413
+ * // Load plugin by name
2414
+ * const [name, Plugin] = await load('@scope/my-plugin');
2415
+ *
2416
+ * // Load and instantiate multiple plugins
2417
+ * const plugins = await loaderPluginsFromPluginTuples(
2418
+ * context,
2419
+ * [
2420
+ * tuple(MyPlugin, { option: 'value' }),
2421
+ * tuple('@scope/my-plugin', { option: 'value' })
2422
+ * ]
2423
+ * );
2424
+ * ```
2425
+ *
2426
+ * @example Custom concurrency
2427
+ * ```typescript
2428
+ * // Load plugins with custom concurrency limit
2429
+ * const plugins = await loaderPluginsFromPluginTuples(
2430
+ * context,
2431
+ * pluginTuples,
2432
+ * 3 // Max 3 concurrent loads
2433
+ * );
2434
+ * ```
2435
+ */
2436
+
2437
+ /**
2438
+ * Dynamically loads a plugin module
2439
+ *
2440
+ * Attempts to load a plugin using multiple strategies:
2441
+ * 1. Direct ESM import
2442
+ * 2. Import from current working directory
2443
+ * 3. Fallback to CommonJS require.resolve
2444
+ *
2445
+ * @template T - Plugin module type
2446
+ * @param pluginName - Plugin name or path to load
2447
+ * @returns Promise resolving to [plugin name, plugin module]
2448
+ * @throws If plugin cannot be loaded by any method
2449
+ *
2450
+ * @example Package import
2451
+ * ```typescript
2452
+ * const [name, Plugin] = await load('@scope/my-plugin');
2453
+ * const instance = new Plugin(context);
2454
+ * ```
2455
+ *
2456
+ * @example Local file import
2457
+ * ```typescript
2458
+ * const [name, Plugin] = await load('./plugins/MyPlugin');
2459
+ * const instance = new Plugin(context);
2460
+ * ```
2461
+ *
2462
+ * @example Error handling
2463
+ * ```typescript
2464
+ * try {
2465
+ * const [name, Plugin] = await load('non-existent');
2466
+ * } catch (error) {
2467
+ * console.error('Failed to load plugin:', error);
2468
+ * }
2469
+ * ```
2470
+ */
552
2471
  declare function load<T>(pluginName: string): Promise<[string, T]>;
553
- declare function loaderPluginsFromPluginTuples<T extends Plugin<unknown>>(context: ReleaseContext, pluginsTuples: PluginTuple<PluginClass>[], maxLimit?: number): Promise<T[]>;
2472
+ /**
2473
+ * Loads and instantiates multiple plugins concurrently
2474
+ *
2475
+ * Takes an array of plugin tuples and creates plugin instances
2476
+ * with the provided context. Supports both class-based and
2477
+ * string-based plugin specifications.
2478
+ *
2479
+ * Features:
2480
+ * - Concurrent loading with configurable limit
2481
+ * - Mixed plugin types (class/string)
2482
+ * - Automatic context injection
2483
+ * - Type-safe instantiation
2484
+ *
2485
+ * @template T - Plugin instance type
2486
+ * @param context - Release context for plugin initialization
2487
+ * @param pluginsTuples - Array of plugin configuration tuples
2488
+ * @param maxLimit - Maximum concurrent plugin loads (default: 5)
2489
+ * @returns Promise resolving to array of plugin instances
2490
+ *
2491
+ * @example Basic usage
2492
+ * ```typescript
2493
+ * const plugins = await loaderPluginsFromPluginTuples(
2494
+ * context,
2495
+ * [
2496
+ * tuple(MyPlugin, { option: 'value' }),
2497
+ * tuple('@scope/plugin', { option: 'value' })
2498
+ * ]
2499
+ * );
2500
+ * ```
2501
+ *
2502
+ * @example Custom concurrency
2503
+ * ```typescript
2504
+ * const plugins = await loaderPluginsFromPluginTuples(
2505
+ * context,
2506
+ * pluginTuples,
2507
+ * 3 // Load max 3 plugins at once
2508
+ * );
2509
+ * ```
2510
+ *
2511
+ * @example Type-safe loading
2512
+ * ```typescript
2513
+ * interface MyPlugin extends ScriptPlugin {
2514
+ * customMethod(): void;
2515
+ * }
2516
+ *
2517
+ * const plugins = await loaderPluginsFromPluginTuples<MyPlugin>(
2518
+ * context,
2519
+ * pluginTuples
2520
+ * );
2521
+ *
2522
+ * plugins.forEach(plugin => plugin.customMethod());
2523
+ * ```
2524
+ */
2525
+ declare function loaderPluginsFromPluginTuples<T extends ScriptPlugin<ScriptContext<any>, ScriptPluginProps>>(context: ReleaseContext, pluginsTuples: PluginTuple<PluginClass>[], maxLimit?: number): Promise<T[]>;
554
2526
 
2527
+ /**
2528
+ * @module Factory
2529
+ * @description Type-safe factory function for class and function instantiation
2530
+ *
2531
+ * This module provides a flexible factory function that can handle both
2532
+ * class constructors and factory functions with proper type inference.
2533
+ *
2534
+ * Core Features:
2535
+ * - Type-safe instantiation
2536
+ * - Support for both classes and functions
2537
+ * - Argument type inference
2538
+ * - Runtime constructor detection
2539
+ *
2540
+ * @example Basic usage
2541
+ * ```typescript
2542
+ * // Class-based
2543
+ * class MyClass {
2544
+ * constructor(name: string, value: number) {}
2545
+ * }
2546
+ *
2547
+ * const instance = factory(MyClass, 'test', 42);
2548
+ *
2549
+ * // Function-based
2550
+ * function createObject(config: { option: string }) {
2551
+ * return { ...config };
2552
+ * }
2553
+ *
2554
+ * const object = factory(createObject, { option: 'value' });
2555
+ * ```
2556
+ */
2557
+ /**
2558
+ * Combined type for class constructors and factory functions
2559
+ *
2560
+ * Represents either a class constructor or a factory function
2561
+ * with proper typing for arguments and return value.
2562
+ *
2563
+ * @template T - Return type
2564
+ * @template Args - Tuple type for arguments
2565
+ *
2566
+ * @example Class constructor
2567
+ * ```typescript
2568
+ * class MyClass {
2569
+ * constructor(name: string) {}
2570
+ * }
2571
+ *
2572
+ * const ctor: ConstructorType<MyClass, [string]> = MyClass;
2573
+ * ```
2574
+ *
2575
+ * @example Factory function
2576
+ * ```typescript
2577
+ * interface Config {
2578
+ * option: string;
2579
+ * }
2580
+ *
2581
+ * const factory: ConstructorType<Config, [string]> =
2582
+ * (option: string) => ({ option });
2583
+ * ```
2584
+ */
555
2585
  type ConstructorType<T, Args extends unknown[]> = (new (...args: Args) => T) | ((...args: Args) => T);
2586
+ /**
2587
+ * Creates instances from constructors or factory functions
2588
+ *
2589
+ * A flexible factory function that can handle both class constructors
2590
+ * and factory functions. It automatically detects the type at runtime
2591
+ * and uses the appropriate instantiation method.
2592
+ *
2593
+ * Features:
2594
+ * - Automatic constructor detection
2595
+ * - Type-safe argument passing
2596
+ * - Support for both classes and functions
2597
+ * - Generic type inference
2598
+ *
2599
+ * @template T - Return type
2600
+ * @template Args - Tuple type for arguments
2601
+ * @param Constructor - Class constructor or factory function
2602
+ * @param args - Arguments to pass to constructor/function
2603
+ * @returns Instance of type T
2604
+ *
2605
+ * @example Class instantiation
2606
+ * ```typescript
2607
+ * class Logger {
2608
+ * constructor(name: string, level: string) {
2609
+ * // Implementation
2610
+ * }
2611
+ * }
2612
+ *
2613
+ * const logger = factory(Logger, 'main', 'debug');
2614
+ * ```
2615
+ *
2616
+ * @example Factory function
2617
+ * ```typescript
2618
+ * interface Config {
2619
+ * name: string;
2620
+ * options: Record<string, unknown>;
2621
+ * }
2622
+ *
2623
+ * function createConfig(name: string, options = {}): Config {
2624
+ * return { name, options };
2625
+ * }
2626
+ *
2627
+ * const config = factory(createConfig, 'myConfig', { debug: true });
2628
+ * ```
2629
+ *
2630
+ * @example Generic types
2631
+ * ```typescript
2632
+ * class Container<T> {
2633
+ * constructor(value: T) {
2634
+ * // Implementation
2635
+ * }
2636
+ * }
2637
+ *
2638
+ * const container = factory<Container<string>, [string]>(
2639
+ * Container,
2640
+ * 'value'
2641
+ * );
2642
+ * ```
2643
+ */
556
2644
  declare function factory<T, Args extends unknown[]>(Constructor: ConstructorType<T, Args>, ...args: Args): T;
557
2645
 
2646
+ /**
2647
+ * @module CommanderArgs
2648
+ * @description Command-line argument processing utilities
2649
+ *
2650
+ * This module provides utilities for processing and transforming
2651
+ * command-line arguments from Commander.js into structured objects.
2652
+ * It supports dot notation for nested properties and common prefix
2653
+ * grouping.
2654
+ *
2655
+ * Core Features:
2656
+ * - Dot notation support
2657
+ * - Common prefix grouping
2658
+ * - Deep object creation
2659
+ * - Type-safe processing
2660
+ *
2661
+ * @example Basic usage
2662
+ * ```typescript
2663
+ * const args = {
2664
+ * verbose: true,
2665
+ * 'config.port': 3000,
2666
+ * 'config.host': 'localhost'
2667
+ * };
2668
+ *
2669
+ * const processed = reduceOptions(args);
2670
+ * // {
2671
+ * // verbose: true,
2672
+ * // config: {
2673
+ * // port: 3000,
2674
+ * // host: 'localhost'
2675
+ * // }
2676
+ * // }
2677
+ * ```
2678
+ *
2679
+ * @example With common prefix
2680
+ * ```typescript
2681
+ * const args = {
2682
+ * verbose: true,
2683
+ * port: 3000
2684
+ * };
2685
+ *
2686
+ * const processed = reduceOptions(args, 'options');
2687
+ * // {
2688
+ * // options: {
2689
+ * // verbose: true,
2690
+ * // port: 3000
2691
+ * // }
2692
+ * // }
2693
+ * ```
2694
+ */
2695
+
2696
+ /**
2697
+ * Processes Commander.js options into a structured object
2698
+ *
2699
+ * Takes raw options from Commander.js and transforms them into a
2700
+ * structured object, handling dot notation for nested properties
2701
+ * and optional common prefix grouping.
2702
+ *
2703
+ * Features:
2704
+ * - Dot notation parsing (e.g., 'config.port' → { config: { port: value } })
2705
+ * - Common prefix grouping (e.g., { port: 3000 } → { common: { port: 3000 } })
2706
+ * - Deep object creation with lodash/set
2707
+ * - Preserves value types
2708
+ *
2709
+ * @param opts - Raw options from Commander.js
2710
+ * @param commonKey - Optional prefix for non-nested properties
2711
+ * @returns Processed options object
2712
+ *
2713
+ * @example Basic dot notation
2714
+ * ```typescript
2715
+ * const args = {
2716
+ * 'server.port': 3000,
2717
+ * 'server.host': 'localhost',
2718
+ * verbose: true
2719
+ * };
2720
+ *
2721
+ * const result = reduceOptions(args);
2722
+ * // {
2723
+ * // server: {
2724
+ * // port: 3000,
2725
+ * // host: 'localhost'
2726
+ * // },
2727
+ * // verbose: true
2728
+ * // }
2729
+ * ```
2730
+ *
2731
+ * @example With common prefix
2732
+ * ```typescript
2733
+ * const args = {
2734
+ * 'config.debug': true,
2735
+ * port: 3000,
2736
+ * host: 'localhost'
2737
+ * };
2738
+ *
2739
+ * const result = reduceOptions(args, 'server');
2740
+ * // {
2741
+ * // config: {
2742
+ * // debug: true
2743
+ * // },
2744
+ * // server: {
2745
+ * // port: 3000,
2746
+ * // host: 'localhost'
2747
+ * // }
2748
+ * // }
2749
+ * ```
2750
+ */
558
2751
  declare function reduceOptions(opts: OptionValues, commonKey?: string): OptionValues;
559
2752
 
560
- export { CHANGELOG_ALL_FIELDS, type ConstructorType, type DeepPartial, type ExecutorReleaseContext, GitChangelog, GitChangelogFormatter, type GitChangelogProps, type GithubChangelogProps, type Options, type PackageJson, Plugin, type PluginClass, type PluginConstructorParams, type PluginTuple, type ReleaseConfig, ReleaseContext, type ReleaseContextOptions, ReleaseLabel, type ReleaseLabelCompare, type ReleaseLabelOptions, type ReleaseReturnValue, ReleaseTask, type StepOption, type TemplateContext, factory, load, loaderPluginsFromPluginTuples, reduceOptions, tuple };
2753
+ export { CHANGELOG_ALL_FIELDS, type ConstructorType, type DeepPartial, type ExecutorReleaseContext, GitChangelog, GitChangelogFormatter, type GitChangelogProps, type GithubChangelogProps, type Options, type PackageJson, type PluginClass, type PluginConstructorParams, type PluginTuple, type ReleaseConfig, ReleaseContext, type ReleaseContextOptions$1 as ReleaseContextOptions, ReleaseLabel, type ReleaseLabelCompare, type ReleaseLabelOptions, type ReleaseReturnValue, ReleaseTask, type StepOption, type TemplateContext, factory, load, loaderPluginsFromPluginTuples, reduceOptions, tuple };