@icebreakers/commitlint-config 1.0.3 → 1.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.
package/dist/index.cjs CHANGED
@@ -1,87 +1,392 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/index.ts
2
-
3
-
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/config.ts
4
2
 
5
3
 
6
4
  var _types = require('@commitlint/types');
7
5
 
8
- // ../../node_modules/.pnpm/defu@6.1.4/node_modules/defu/dist/defu.mjs
9
- function isPlainObject(value) {
10
- if (value === null || typeof value !== "object") {
11
- return false;
6
+ // src/constants.ts
7
+ var DEFAULT_PARSER_PRESET = "conventional-changelog-conventionalcommits";
8
+ var DEFAULT_HEADER_MAX_LENGTH = 100;
9
+ var DEFAULT_BODY_MAX_LINE_LENGTH = 100;
10
+ var DEFAULT_FOOTER_MAX_LINE_LENGTH = 100;
11
+ var DEFAULT_FULL_STOP = ".";
12
+ var DEFAULT_SUBJECT_FORBIDDEN_CASES = [
13
+ "sentence-case",
14
+ "start-case",
15
+ "pascal-case",
16
+ "upper-case"
17
+ ];
18
+ var DEFAULT_COMMIT_TYPES = [
19
+ {
20
+ value: "build",
21
+ title: "Builds",
22
+ description: "Changes that affect the build system or external dependencies (example scopes: pnpm, webpack, docker)",
23
+ emoji: "\u{1F6E0}"
24
+ },
25
+ {
26
+ value: "chore",
27
+ title: "Chores",
28
+ description: "Other changes that don't modify src or test files",
29
+ emoji: "\u267B\uFE0F"
30
+ },
31
+ {
32
+ value: "ci",
33
+ title: "Continuous Integrations",
34
+ description: "Changes to our CI configuration files and scripts (example scopes: GitHub Actions, Travis, Circle)",
35
+ emoji: "\u2699\uFE0F"
36
+ },
37
+ {
38
+ value: "docs",
39
+ title: "Documentation",
40
+ description: "Documentation only changes",
41
+ emoji: "\u{1F4DA}"
42
+ },
43
+ {
44
+ value: "feat",
45
+ title: "Features",
46
+ description: "A new feature",
47
+ emoji: "\u2728"
48
+ },
49
+ {
50
+ value: "fix",
51
+ title: "Bug Fixes",
52
+ description: "A bug fix",
53
+ emoji: "\u{1F41B}"
54
+ },
55
+ {
56
+ value: "perf",
57
+ title: "Performance Improvements",
58
+ description: "A code change that improves performance",
59
+ emoji: "\u{1F680}"
60
+ },
61
+ {
62
+ value: "refactor",
63
+ title: "Code Refactoring",
64
+ description: "A code change that neither fixes a bug nor adds a feature",
65
+ emoji: "\u{1F4E6}"
66
+ },
67
+ {
68
+ value: "revert",
69
+ title: "Reverts",
70
+ description: "Reverts a previous commit",
71
+ emoji: "\u{1F5D1}"
72
+ },
73
+ {
74
+ value: "style",
75
+ title: "Styles",
76
+ description: "Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)",
77
+ emoji: "\u{1F48E}"
78
+ },
79
+ {
80
+ value: "test",
81
+ title: "Tests",
82
+ description: "Adding missing tests or correcting existing tests",
83
+ emoji: "\u{1F6A8}"
12
84
  }
13
- const prototype = Object.getPrototypeOf(value);
14
- if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) {
15
- return false;
85
+ ];
86
+ var DEFAULT_TYPES = DEFAULT_COMMIT_TYPES.map((type) => type.value);
87
+ var DEFAULT_PROMPT_SCOPE_DESCRIPTION = "What is the scope of this change (e.g. component or file name)";
88
+ var DEFAULT_PROMPT_TYPE_DESCRIPTION = "Select the type of change that you're committing";
89
+ var DEFAULT_PROMPT_SUBJECT_DESCRIPTION = "Write a short, imperative tense description of the change";
90
+ var DEFAULT_PROMPT_BODY_DESCRIPTION = "Provide a longer description of the change";
91
+ var DEFAULT_PROMPT_IS_BREAKING_DESCRIPTION = "Are there any breaking changes?";
92
+ var DEFAULT_PROMPT_BREAKING_BODY_DESCRIPTION = "A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself";
93
+ var DEFAULT_PROMPT_BREAKING_DESCRIPTION = "Describe the breaking changes";
94
+ var DEFAULT_PROMPT_IS_ISSUE_AFFECTED_DESCRIPTION = "Does this change affect any open issues?";
95
+ var DEFAULT_PROMPT_ISSUES_BODY_DESCRIPTION = "If issues are closed, the commit requires a body. Please enter a longer description of the commit itself";
96
+ var DEFAULT_PROMPT_ISSUES_DESCRIPTION = 'Add issue references (e.g. "fix #123", "re #123".)';
97
+ var DEFAULT_EXTENDS = ["@commitlint/config-conventional"];
98
+
99
+ // src/utils.ts
100
+ function toArray(value) {
101
+ if (value === void 0) {
102
+ return [];
103
+ }
104
+ return Array.isArray(value) ? value : [value];
105
+ }
106
+ function unique(values) {
107
+ const seen = /* @__PURE__ */ new Set();
108
+ const result = [];
109
+ for (const value of values) {
110
+ if (!seen.has(value)) {
111
+ seen.add(value);
112
+ result.push(value);
113
+ }
16
114
  }
17
- if (Symbol.iterator in value) {
18
- return false;
115
+ return result;
116
+ }
117
+ function toTitleCase(value) {
118
+ return value.split(/[-_/]/g).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
119
+ }
120
+ function createDefaultCommitTypeDefinition(value) {
121
+ return {
122
+ value,
123
+ title: toTitleCase(value),
124
+ description: "Custom change type"
125
+ };
126
+ }
127
+ function mergeTypeDefinitions(defaults, overrides = []) {
128
+ const map = /* @__PURE__ */ new Map();
129
+ for (const definition of defaults) {
130
+ map.set(definition.value, definition);
19
131
  }
20
- if (Symbol.toStringTag in value) {
21
- return Object.prototype.toString.call(value) === "[object Module]";
132
+ for (const definition of overrides) {
133
+ map.set(definition.value, definition);
22
134
  }
23
- return true;
135
+ return map;
136
+ }
137
+ function isPlainObject(value) {
138
+ return Boolean(
139
+ value && typeof value === "object" && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]"
140
+ );
24
141
  }
25
- function _defu(baseObject, defaults, namespace = ".", merger) {
26
- if (!isPlainObject(defaults)) {
27
- return _defu(baseObject, {}, namespace, merger);
142
+ function mergeDeep(base, override) {
143
+ if (!override) {
144
+ return base;
28
145
  }
29
- const object = Object.assign({}, defaults);
30
- for (const key in baseObject) {
31
- if (key === "__proto__" || key === "constructor") {
146
+ const output = { ...base };
147
+ for (const [key, value] of Object.entries(override)) {
148
+ if (value === void 0) {
32
149
  continue;
33
150
  }
34
- const value = baseObject[key];
35
- if (value === null || value === void 0) {
151
+ const baseValue = output[key];
152
+ if (isPlainObject(baseValue) && isPlainObject(value)) {
153
+ output[key] = mergeDeep(baseValue, value);
36
154
  continue;
37
155
  }
38
- if (merger && merger(object, key, value, namespace)) {
156
+ if (Array.isArray(value)) {
157
+ output[key] = [...value];
39
158
  continue;
40
159
  }
41
- if (Array.isArray(value) && Array.isArray(object[key])) {
42
- object[key] = [...value, ...object[key]];
43
- } else if (isPlainObject(value) && isPlainObject(object[key])) {
44
- object[key] = _defu(
45
- value,
46
- object[key],
47
- (namespace ? `${namespace}.` : "") + key.toString(),
48
- merger
49
- );
50
- } else {
51
- object[key] = value;
52
- }
160
+ output[key] = value;
161
+ }
162
+ return output;
163
+ }
164
+ function removeUndefined(value) {
165
+ const entries = Object.entries(value).filter(([, item]) => item !== void 0);
166
+ return Object.fromEntries(entries);
167
+ }
168
+
169
+ // src/config.ts
170
+ function resolveExtends(entries) {
171
+ if (!entries) {
172
+ return [...DEFAULT_EXTENDS];
53
173
  }
54
- return object;
174
+ const values = toArray(entries);
175
+ return unique([...DEFAULT_EXTENDS, ...values]);
55
176
  }
56
- function createDefu(merger) {
57
- return (...arguments_) => (
58
- // eslint-disable-next-line unicorn/no-array-reduce
59
- arguments_.reduce((p, c) => _defu(p, c, "", merger), {})
177
+ function resolveTypeSettings(options) {
178
+ let severity = _types.RuleConfigSeverity.Error;
179
+ let condition = "always";
180
+ let overrides = [];
181
+ let values;
182
+ if (!options) {
183
+ values = [...DEFAULT_TYPES];
184
+ } else if (Array.isArray(options)) {
185
+ values = unique(options);
186
+ } else {
187
+ severity = _nullishCoalesce(options.severity, () => ( severity));
188
+ condition = _nullishCoalesce(options.condition, () => ( condition));
189
+ overrides = _nullishCoalesce(options.definitions, () => ( []));
190
+ const base = options.values ? toArray(options.values) : DEFAULT_TYPES;
191
+ const additions = options.add ? toArray(options.add) : [];
192
+ values = unique([...base, ...additions]);
193
+ }
194
+ if (values.length === 0) {
195
+ return {
196
+ definitions: [],
197
+ rule: [_types.RuleConfigSeverity.Disabled]
198
+ };
199
+ }
200
+ const definitionsMap = mergeTypeDefinitions(DEFAULT_COMMIT_TYPES, overrides);
201
+ const definitions = values.map(
202
+ (value) => _nullishCoalesce(definitionsMap.get(value), () => ( createDefaultCommitTypeDefinition(value)))
60
203
  );
204
+ return {
205
+ definitions,
206
+ rule: [severity, condition, values]
207
+ };
208
+ }
209
+ function asCaseArray(value) {
210
+ if (!value) {
211
+ return [];
212
+ }
213
+ return toArray(value);
61
214
  }
62
- var defu = createDefu();
63
- var defuFn = createDefu((object, key, currentValue) => {
64
- if (object[key] !== void 0 && typeof currentValue === "function") {
65
- object[key] = currentValue(object[key]);
66
- return true;
215
+ function resolveScopeRules(options) {
216
+ if (!options) {
217
+ return {};
218
+ }
219
+ const rules = {};
220
+ const values = Array.isArray(options) ? unique(options) : unique([
221
+ ...toArray(_nullishCoalesce(options.values, () => ( []))),
222
+ ...toArray(_nullishCoalesce(options.add, () => ( [])))
223
+ ]);
224
+ const baseSeverity = !Array.isArray(options) ? _nullishCoalesce(options.severity, () => ( _types.RuleConfigSeverity.Error)) : _types.RuleConfigSeverity.Error;
225
+ if (values.length > 0) {
226
+ rules["scope-enum"] = [baseSeverity, "always", values];
67
227
  }
68
- });
69
- var defuArrayFn = createDefu((object, key, currentValue) => {
70
- if (Array.isArray(object[key]) && typeof currentValue === "function") {
71
- object[key] = currentValue(object[key]);
72
- return true;
228
+ const allowEmpty = Array.isArray(options) ? true : _nullishCoalesce(options.allowEmpty, () => ( !options.required));
229
+ if (allowEmpty) {
230
+ rules["scope-empty"] = [_types.RuleConfigSeverity.Disabled];
231
+ } else {
232
+ rules["scope-empty"] = [baseSeverity, "never"];
73
233
  }
74
- });
234
+ if (!Array.isArray(options) && options.case) {
235
+ const scopeCaseValues = asCaseArray(options.case);
236
+ if (scopeCaseValues.length > 0) {
237
+ const caseSeverity = _nullishCoalesce(options.caseSeverity, () => ( baseSeverity));
238
+ rules["scope-case"] = [caseSeverity, "always", scopeCaseValues];
239
+ }
240
+ }
241
+ return rules;
242
+ }
243
+ function resolveSubjectRules(options) {
244
+ const rules = {};
245
+ const forbiddenCases = asCaseArray(_optionalChain([options, 'optionalAccess', _ => _.forbidden]));
246
+ const subjectCases = forbiddenCases.length > 0 ? forbiddenCases : DEFAULT_SUBJECT_FORBIDDEN_CASES;
247
+ const caseSeverity = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _2 => _2.caseSeverity]), () => ( _types.RuleConfigSeverity.Error));
248
+ rules["subject-case"] = [caseSeverity, "never", subjectCases];
249
+ if (_optionalChain([options, 'optionalAccess', _3 => _3.allowEmpty])) {
250
+ rules["subject-empty"] = [_types.RuleConfigSeverity.Disabled];
251
+ } else {
252
+ const emptySeverity = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _4 => _4.emptySeverity]), () => ( _types.RuleConfigSeverity.Error));
253
+ rules["subject-empty"] = [emptySeverity, "never"];
254
+ }
255
+ if (_optionalChain([options, 'optionalAccess', _5 => _5.fullStop]) === false) {
256
+ rules["subject-full-stop"] = [_types.RuleConfigSeverity.Disabled];
257
+ } else {
258
+ const fullStopSeverity = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _6 => _6.fullStopSeverity]), () => ( _types.RuleConfigSeverity.Error));
259
+ const fullStop = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _7 => _7.fullStop]), () => ( DEFAULT_FULL_STOP));
260
+ rules["subject-full-stop"] = [fullStopSeverity, "never", fullStop];
261
+ }
262
+ return rules;
263
+ }
264
+ function resolveHeaderRules(options) {
265
+ const severity = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _8 => _8.severity]), () => ( _types.RuleConfigSeverity.Error));
266
+ const maxLength = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _9 => _9.maxLength]), () => ( DEFAULT_HEADER_MAX_LENGTH));
267
+ return {
268
+ "header-max-length": [severity, "always", maxLength]
269
+ };
270
+ }
271
+ function createBaseRules() {
272
+ return {
273
+ "body-leading-blank": [_types.RuleConfigSeverity.Warning, "always"],
274
+ "body-max-line-length": [
275
+ _types.RuleConfigSeverity.Error,
276
+ "always",
277
+ DEFAULT_BODY_MAX_LINE_LENGTH
278
+ ],
279
+ "footer-leading-blank": [_types.RuleConfigSeverity.Warning, "always"],
280
+ "footer-max-line-length": [
281
+ _types.RuleConfigSeverity.Error,
282
+ "always",
283
+ DEFAULT_FOOTER_MAX_LINE_LENGTH
284
+ ],
285
+ "header-trim": [_types.RuleConfigSeverity.Error, "always"],
286
+ "type-case": [_types.RuleConfigSeverity.Error, "always", "lower-case"],
287
+ "type-empty": [_types.RuleConfigSeverity.Error, "never"]
288
+ };
289
+ }
290
+ function buildTypeEnum(definitions) {
291
+ return definitions.reduce(
292
+ (accumulator, definition) => {
293
+ accumulator[definition.value] = {
294
+ description: definition.description,
295
+ title: definition.title,
296
+ emoji: definition.emoji
297
+ };
298
+ return accumulator;
299
+ },
300
+ {}
301
+ );
302
+ }
303
+ function createBasePrompt(definitions) {
304
+ return {
305
+ questions: {
306
+ type: {
307
+ description: DEFAULT_PROMPT_TYPE_DESCRIPTION,
308
+ enum: buildTypeEnum(definitions)
309
+ },
310
+ scope: {
311
+ description: DEFAULT_PROMPT_SCOPE_DESCRIPTION
312
+ },
313
+ subject: {
314
+ description: DEFAULT_PROMPT_SUBJECT_DESCRIPTION
315
+ },
316
+ body: {
317
+ description: DEFAULT_PROMPT_BODY_DESCRIPTION
318
+ },
319
+ isBreaking: {
320
+ description: DEFAULT_PROMPT_IS_BREAKING_DESCRIPTION
321
+ },
322
+ breakingBody: {
323
+ description: DEFAULT_PROMPT_BREAKING_BODY_DESCRIPTION
324
+ },
325
+ breaking: {
326
+ description: DEFAULT_PROMPT_BREAKING_DESCRIPTION
327
+ },
328
+ isIssueAffected: {
329
+ description: DEFAULT_PROMPT_IS_ISSUE_AFFECTED_DESCRIPTION
330
+ },
331
+ issuesBody: {
332
+ description: DEFAULT_PROMPT_ISSUES_BODY_DESCRIPTION
333
+ },
334
+ issues: {
335
+ description: DEFAULT_PROMPT_ISSUES_DESCRIPTION
336
+ }
337
+ }
338
+ };
339
+ }
340
+ function resolvePrompt(definitions, overrides) {
341
+ const base = createBasePrompt(definitions);
342
+ return mergeDeep(base, overrides);
343
+ }
344
+ function createIcebreakerCommitlintConfig(options = {}) {
345
+ const extendsField = resolveExtends(options.extends);
346
+ const typeSettings = resolveTypeSettings(options.types);
347
+ const scopeRules = resolveScopeRules(options.scopes);
348
+ const subjectRules = resolveSubjectRules(options.subject);
349
+ const headerRules = resolveHeaderRules(options.header);
350
+ const baseRules = createBaseRules();
351
+ const rules = {
352
+ ...baseRules,
353
+ "type-enum": typeSettings.rule,
354
+ ...scopeRules,
355
+ ...subjectRules,
356
+ ...headerRules,
357
+ ...options.rules
358
+ };
359
+ const prompt = resolvePrompt(typeSettings.definitions, options.prompt);
360
+ return removeUndefined({
361
+ extends: extendsField,
362
+ formatter: options.formatter,
363
+ parserPreset: _nullishCoalesce(options.parserPreset, () => ( DEFAULT_PARSER_PRESET)),
364
+ rules,
365
+ ignores: options.ignores,
366
+ defaultIgnores: options.defaultIgnores,
367
+ plugins: options.plugins,
368
+ helpUrl: options.helpUrl,
369
+ prompt
370
+ });
371
+ }
75
372
 
76
373
  // src/index.ts
77
- function icebreaker(config) {
78
- return defu(config, {
79
- extends: ["@commitlint/config-conventional"]
80
- });
374
+
375
+ function createCommitlintConfig(options) {
376
+ return createIcebreakerCommitlintConfig(options);
377
+ }
378
+ function icebreaker(options) {
379
+ return createIcebreakerCommitlintConfig(options);
81
380
  }
82
381
 
83
382
 
84
383
 
85
384
 
86
385
 
87
- exports.RuleConfigCondition = _types.RuleConfigCondition; exports.RuleConfigSeverity = _types.RuleConfigSeverity; exports.TargetCaseType = _types.TargetCaseType; exports.icebreaker = icebreaker;
386
+
387
+
388
+
389
+
390
+
391
+
392
+ exports.DEFAULT_COMMIT_TYPES = DEFAULT_COMMIT_TYPES; exports.DEFAULT_EXTENDS = DEFAULT_EXTENDS; exports.DEFAULT_SUBJECT_FORBIDDEN_CASES = DEFAULT_SUBJECT_FORBIDDEN_CASES; exports.DEFAULT_TYPES = DEFAULT_TYPES; exports.RuleConfigCondition = _types.RuleConfigCondition; exports.RuleConfigSeverity = _types.RuleConfigSeverity; exports.TargetCaseType = _types.TargetCaseType; exports.createCommitlintConfig = createCommitlintConfig; exports.createIcebreakerCommitlintConfig = createIcebreakerCommitlintConfig; exports.icebreaker = icebreaker;
package/dist/index.d.cts CHANGED
@@ -1,6 +1,82 @@
1
- import { UserConfig } from '@commitlint/types';
2
- export { RuleConfigCondition, RuleConfigSeverity, TargetCaseType, UserConfig } from '@commitlint/types';
1
+ import { RuleConfigSeverity, RuleConfigCondition, TargetCaseType, UserConfig, UserPromptConfig } from '@commitlint/types';
2
+ export { RuleConfigCondition, RuleConfigSeverity, TargetCaseType } from '@commitlint/types';
3
3
 
4
- declare function icebreaker(config?: UserConfig): UserConfig;
4
+ interface CommitTypeDefinition {
5
+ value: string;
6
+ title: string;
7
+ description: string;
8
+ emoji?: string;
9
+ }
10
+ interface TypeRuleOptions {
11
+ /**
12
+ * Replace the default set of commit types.
13
+ */
14
+ values?: string | string[];
15
+ /**
16
+ * Extend the existing commit types without replacing them.
17
+ */
18
+ add?: string | string[];
19
+ /**
20
+ * Provide metadata for commit types, primarily used by the prompt.
21
+ */
22
+ definitions?: CommitTypeDefinition[];
23
+ severity?: RuleConfigSeverity;
24
+ condition?: RuleConfigCondition;
25
+ }
26
+ interface ScopeRuleOptions {
27
+ values?: string | string[];
28
+ add?: string | string[];
29
+ case?: TargetCaseType | TargetCaseType[];
30
+ /**
31
+ * Require scopes on every commit message. Equivalent to disallowing empty scopes.
32
+ */
33
+ required?: boolean;
34
+ /**
35
+ * Explicitly allow empty scopes. Takes precedence over `required` when set.
36
+ */
37
+ allowEmpty?: boolean;
38
+ severity?: RuleConfigSeverity;
39
+ caseSeverity?: RuleConfigSeverity;
40
+ }
41
+ interface SubjectRuleOptions {
42
+ forbidden?: TargetCaseType | TargetCaseType[];
43
+ caseSeverity?: RuleConfigSeverity;
44
+ /**
45
+ * Control the trailing character check. Set to `false` to disable the rule entirely.
46
+ */
47
+ fullStop?: string | false;
48
+ fullStopSeverity?: RuleConfigSeverity;
49
+ allowEmpty?: boolean;
50
+ emptySeverity?: RuleConfigSeverity;
51
+ }
52
+ interface HeaderRuleOptions {
53
+ maxLength?: number;
54
+ severity?: RuleConfigSeverity;
55
+ }
56
+ interface IcebreakerCommitlintOptions {
57
+ extends?: string | string[];
58
+ types?: TypeRuleOptions | string[];
59
+ scopes?: ScopeRuleOptions | string[];
60
+ subject?: SubjectRuleOptions;
61
+ header?: HeaderRuleOptions;
62
+ rules?: UserConfig['rules'];
63
+ parserPreset?: UserConfig['parserPreset'];
64
+ formatter?: UserConfig['formatter'];
65
+ ignores?: UserConfig['ignores'];
66
+ defaultIgnores?: UserConfig['defaultIgnores'];
67
+ plugins?: UserConfig['plugins'];
68
+ helpUrl?: UserConfig['helpUrl'];
69
+ prompt?: UserPromptConfig;
70
+ }
5
71
 
6
- export { icebreaker };
72
+ declare function createIcebreakerCommitlintConfig(options?: IcebreakerCommitlintOptions): UserConfig;
73
+
74
+ declare const DEFAULT_SUBJECT_FORBIDDEN_CASES: TargetCaseType[];
75
+ declare const DEFAULT_COMMIT_TYPES: CommitTypeDefinition[];
76
+ declare const DEFAULT_TYPES: string[];
77
+ declare const DEFAULT_EXTENDS: string[];
78
+
79
+ declare function createCommitlintConfig(options?: IcebreakerCommitlintOptions): UserConfig;
80
+ declare function icebreaker(options?: IcebreakerCommitlintOptions): UserConfig;
81
+
82
+ export { type CommitTypeDefinition, DEFAULT_COMMIT_TYPES, DEFAULT_EXTENDS, DEFAULT_SUBJECT_FORBIDDEN_CASES, DEFAULT_TYPES, type HeaderRuleOptions, type IcebreakerCommitlintOptions, type ScopeRuleOptions, type SubjectRuleOptions, type TypeRuleOptions, createCommitlintConfig, createIcebreakerCommitlintConfig, icebreaker };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,82 @@
1
- import { UserConfig } from '@commitlint/types';
2
- export { RuleConfigCondition, RuleConfigSeverity, TargetCaseType, UserConfig } from '@commitlint/types';
1
+ import { RuleConfigSeverity, RuleConfigCondition, TargetCaseType, UserConfig, UserPromptConfig } from '@commitlint/types';
2
+ export { RuleConfigCondition, RuleConfigSeverity, TargetCaseType } from '@commitlint/types';
3
3
 
4
- declare function icebreaker(config?: UserConfig): UserConfig;
4
+ interface CommitTypeDefinition {
5
+ value: string;
6
+ title: string;
7
+ description: string;
8
+ emoji?: string;
9
+ }
10
+ interface TypeRuleOptions {
11
+ /**
12
+ * Replace the default set of commit types.
13
+ */
14
+ values?: string | string[];
15
+ /**
16
+ * Extend the existing commit types without replacing them.
17
+ */
18
+ add?: string | string[];
19
+ /**
20
+ * Provide metadata for commit types, primarily used by the prompt.
21
+ */
22
+ definitions?: CommitTypeDefinition[];
23
+ severity?: RuleConfigSeverity;
24
+ condition?: RuleConfigCondition;
25
+ }
26
+ interface ScopeRuleOptions {
27
+ values?: string | string[];
28
+ add?: string | string[];
29
+ case?: TargetCaseType | TargetCaseType[];
30
+ /**
31
+ * Require scopes on every commit message. Equivalent to disallowing empty scopes.
32
+ */
33
+ required?: boolean;
34
+ /**
35
+ * Explicitly allow empty scopes. Takes precedence over `required` when set.
36
+ */
37
+ allowEmpty?: boolean;
38
+ severity?: RuleConfigSeverity;
39
+ caseSeverity?: RuleConfigSeverity;
40
+ }
41
+ interface SubjectRuleOptions {
42
+ forbidden?: TargetCaseType | TargetCaseType[];
43
+ caseSeverity?: RuleConfigSeverity;
44
+ /**
45
+ * Control the trailing character check. Set to `false` to disable the rule entirely.
46
+ */
47
+ fullStop?: string | false;
48
+ fullStopSeverity?: RuleConfigSeverity;
49
+ allowEmpty?: boolean;
50
+ emptySeverity?: RuleConfigSeverity;
51
+ }
52
+ interface HeaderRuleOptions {
53
+ maxLength?: number;
54
+ severity?: RuleConfigSeverity;
55
+ }
56
+ interface IcebreakerCommitlintOptions {
57
+ extends?: string | string[];
58
+ types?: TypeRuleOptions | string[];
59
+ scopes?: ScopeRuleOptions | string[];
60
+ subject?: SubjectRuleOptions;
61
+ header?: HeaderRuleOptions;
62
+ rules?: UserConfig['rules'];
63
+ parserPreset?: UserConfig['parserPreset'];
64
+ formatter?: UserConfig['formatter'];
65
+ ignores?: UserConfig['ignores'];
66
+ defaultIgnores?: UserConfig['defaultIgnores'];
67
+ plugins?: UserConfig['plugins'];
68
+ helpUrl?: UserConfig['helpUrl'];
69
+ prompt?: UserPromptConfig;
70
+ }
5
71
 
6
- export { icebreaker };
72
+ declare function createIcebreakerCommitlintConfig(options?: IcebreakerCommitlintOptions): UserConfig;
73
+
74
+ declare const DEFAULT_SUBJECT_FORBIDDEN_CASES: TargetCaseType[];
75
+ declare const DEFAULT_COMMIT_TYPES: CommitTypeDefinition[];
76
+ declare const DEFAULT_TYPES: string[];
77
+ declare const DEFAULT_EXTENDS: string[];
78
+
79
+ declare function createCommitlintConfig(options?: IcebreakerCommitlintOptions): UserConfig;
80
+ declare function icebreaker(options?: IcebreakerCommitlintOptions): UserConfig;
81
+
82
+ export { type CommitTypeDefinition, DEFAULT_COMMIT_TYPES, DEFAULT_EXTENDS, DEFAULT_SUBJECT_FORBIDDEN_CASES, DEFAULT_TYPES, type HeaderRuleOptions, type IcebreakerCommitlintOptions, type ScopeRuleOptions, type SubjectRuleOptions, type TypeRuleOptions, createCommitlintConfig, createIcebreakerCommitlintConfig, icebreaker };
package/dist/index.mjs CHANGED
@@ -1,87 +1,392 @@
1
- // src/index.ts
1
+ // src/config.ts
2
2
  import {
3
- RuleConfigCondition,
4
- RuleConfigSeverity,
5
- TargetCaseType
3
+ RuleConfigSeverity
6
4
  } from "@commitlint/types";
7
5
 
8
- // ../../node_modules/.pnpm/defu@6.1.4/node_modules/defu/dist/defu.mjs
9
- function isPlainObject(value) {
10
- if (value === null || typeof value !== "object") {
11
- return false;
6
+ // src/constants.ts
7
+ var DEFAULT_PARSER_PRESET = "conventional-changelog-conventionalcommits";
8
+ var DEFAULT_HEADER_MAX_LENGTH = 100;
9
+ var DEFAULT_BODY_MAX_LINE_LENGTH = 100;
10
+ var DEFAULT_FOOTER_MAX_LINE_LENGTH = 100;
11
+ var DEFAULT_FULL_STOP = ".";
12
+ var DEFAULT_SUBJECT_FORBIDDEN_CASES = [
13
+ "sentence-case",
14
+ "start-case",
15
+ "pascal-case",
16
+ "upper-case"
17
+ ];
18
+ var DEFAULT_COMMIT_TYPES = [
19
+ {
20
+ value: "build",
21
+ title: "Builds",
22
+ description: "Changes that affect the build system or external dependencies (example scopes: pnpm, webpack, docker)",
23
+ emoji: "\u{1F6E0}"
24
+ },
25
+ {
26
+ value: "chore",
27
+ title: "Chores",
28
+ description: "Other changes that don't modify src or test files",
29
+ emoji: "\u267B\uFE0F"
30
+ },
31
+ {
32
+ value: "ci",
33
+ title: "Continuous Integrations",
34
+ description: "Changes to our CI configuration files and scripts (example scopes: GitHub Actions, Travis, Circle)",
35
+ emoji: "\u2699\uFE0F"
36
+ },
37
+ {
38
+ value: "docs",
39
+ title: "Documentation",
40
+ description: "Documentation only changes",
41
+ emoji: "\u{1F4DA}"
42
+ },
43
+ {
44
+ value: "feat",
45
+ title: "Features",
46
+ description: "A new feature",
47
+ emoji: "\u2728"
48
+ },
49
+ {
50
+ value: "fix",
51
+ title: "Bug Fixes",
52
+ description: "A bug fix",
53
+ emoji: "\u{1F41B}"
54
+ },
55
+ {
56
+ value: "perf",
57
+ title: "Performance Improvements",
58
+ description: "A code change that improves performance",
59
+ emoji: "\u{1F680}"
60
+ },
61
+ {
62
+ value: "refactor",
63
+ title: "Code Refactoring",
64
+ description: "A code change that neither fixes a bug nor adds a feature",
65
+ emoji: "\u{1F4E6}"
66
+ },
67
+ {
68
+ value: "revert",
69
+ title: "Reverts",
70
+ description: "Reverts a previous commit",
71
+ emoji: "\u{1F5D1}"
72
+ },
73
+ {
74
+ value: "style",
75
+ title: "Styles",
76
+ description: "Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)",
77
+ emoji: "\u{1F48E}"
78
+ },
79
+ {
80
+ value: "test",
81
+ title: "Tests",
82
+ description: "Adding missing tests or correcting existing tests",
83
+ emoji: "\u{1F6A8}"
84
+ }
85
+ ];
86
+ var DEFAULT_TYPES = DEFAULT_COMMIT_TYPES.map((type) => type.value);
87
+ var DEFAULT_PROMPT_SCOPE_DESCRIPTION = "What is the scope of this change (e.g. component or file name)";
88
+ var DEFAULT_PROMPT_TYPE_DESCRIPTION = "Select the type of change that you're committing";
89
+ var DEFAULT_PROMPT_SUBJECT_DESCRIPTION = "Write a short, imperative tense description of the change";
90
+ var DEFAULT_PROMPT_BODY_DESCRIPTION = "Provide a longer description of the change";
91
+ var DEFAULT_PROMPT_IS_BREAKING_DESCRIPTION = "Are there any breaking changes?";
92
+ var DEFAULT_PROMPT_BREAKING_BODY_DESCRIPTION = "A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself";
93
+ var DEFAULT_PROMPT_BREAKING_DESCRIPTION = "Describe the breaking changes";
94
+ var DEFAULT_PROMPT_IS_ISSUE_AFFECTED_DESCRIPTION = "Does this change affect any open issues?";
95
+ var DEFAULT_PROMPT_ISSUES_BODY_DESCRIPTION = "If issues are closed, the commit requires a body. Please enter a longer description of the commit itself";
96
+ var DEFAULT_PROMPT_ISSUES_DESCRIPTION = 'Add issue references (e.g. "fix #123", "re #123".)';
97
+ var DEFAULT_EXTENDS = ["@commitlint/config-conventional"];
98
+
99
+ // src/utils.ts
100
+ function toArray(value) {
101
+ if (value === void 0) {
102
+ return [];
12
103
  }
13
- const prototype = Object.getPrototypeOf(value);
14
- if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) {
15
- return false;
104
+ return Array.isArray(value) ? value : [value];
105
+ }
106
+ function unique(values) {
107
+ const seen = /* @__PURE__ */ new Set();
108
+ const result = [];
109
+ for (const value of values) {
110
+ if (!seen.has(value)) {
111
+ seen.add(value);
112
+ result.push(value);
113
+ }
16
114
  }
17
- if (Symbol.iterator in value) {
18
- return false;
115
+ return result;
116
+ }
117
+ function toTitleCase(value) {
118
+ return value.split(/[-_/]/g).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
119
+ }
120
+ function createDefaultCommitTypeDefinition(value) {
121
+ return {
122
+ value,
123
+ title: toTitleCase(value),
124
+ description: "Custom change type"
125
+ };
126
+ }
127
+ function mergeTypeDefinitions(defaults, overrides = []) {
128
+ const map = /* @__PURE__ */ new Map();
129
+ for (const definition of defaults) {
130
+ map.set(definition.value, definition);
19
131
  }
20
- if (Symbol.toStringTag in value) {
21
- return Object.prototype.toString.call(value) === "[object Module]";
132
+ for (const definition of overrides) {
133
+ map.set(definition.value, definition);
22
134
  }
23
- return true;
135
+ return map;
24
136
  }
25
- function _defu(baseObject, defaults, namespace = ".", merger) {
26
- if (!isPlainObject(defaults)) {
27
- return _defu(baseObject, {}, namespace, merger);
137
+ function isPlainObject(value) {
138
+ return Boolean(
139
+ value && typeof value === "object" && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]"
140
+ );
141
+ }
142
+ function mergeDeep(base, override) {
143
+ if (!override) {
144
+ return base;
28
145
  }
29
- const object = Object.assign({}, defaults);
30
- for (const key in baseObject) {
31
- if (key === "__proto__" || key === "constructor") {
146
+ const output = { ...base };
147
+ for (const [key, value] of Object.entries(override)) {
148
+ if (value === void 0) {
32
149
  continue;
33
150
  }
34
- const value = baseObject[key];
35
- if (value === null || value === void 0) {
151
+ const baseValue = output[key];
152
+ if (isPlainObject(baseValue) && isPlainObject(value)) {
153
+ output[key] = mergeDeep(baseValue, value);
36
154
  continue;
37
155
  }
38
- if (merger && merger(object, key, value, namespace)) {
156
+ if (Array.isArray(value)) {
157
+ output[key] = [...value];
39
158
  continue;
40
159
  }
41
- if (Array.isArray(value) && Array.isArray(object[key])) {
42
- object[key] = [...value, ...object[key]];
43
- } else if (isPlainObject(value) && isPlainObject(object[key])) {
44
- object[key] = _defu(
45
- value,
46
- object[key],
47
- (namespace ? `${namespace}.` : "") + key.toString(),
48
- merger
49
- );
50
- } else {
51
- object[key] = value;
52
- }
160
+ output[key] = value;
161
+ }
162
+ return output;
163
+ }
164
+ function removeUndefined(value) {
165
+ const entries = Object.entries(value).filter(([, item]) => item !== void 0);
166
+ return Object.fromEntries(entries);
167
+ }
168
+
169
+ // src/config.ts
170
+ function resolveExtends(entries) {
171
+ if (!entries) {
172
+ return [...DEFAULT_EXTENDS];
53
173
  }
54
- return object;
174
+ const values = toArray(entries);
175
+ return unique([...DEFAULT_EXTENDS, ...values]);
55
176
  }
56
- function createDefu(merger) {
57
- return (...arguments_) => (
58
- // eslint-disable-next-line unicorn/no-array-reduce
59
- arguments_.reduce((p, c) => _defu(p, c, "", merger), {})
177
+ function resolveTypeSettings(options) {
178
+ let severity = RuleConfigSeverity.Error;
179
+ let condition = "always";
180
+ let overrides = [];
181
+ let values;
182
+ if (!options) {
183
+ values = [...DEFAULT_TYPES];
184
+ } else if (Array.isArray(options)) {
185
+ values = unique(options);
186
+ } else {
187
+ severity = options.severity ?? severity;
188
+ condition = options.condition ?? condition;
189
+ overrides = options.definitions ?? [];
190
+ const base = options.values ? toArray(options.values) : DEFAULT_TYPES;
191
+ const additions = options.add ? toArray(options.add) : [];
192
+ values = unique([...base, ...additions]);
193
+ }
194
+ if (values.length === 0) {
195
+ return {
196
+ definitions: [],
197
+ rule: [RuleConfigSeverity.Disabled]
198
+ };
199
+ }
200
+ const definitionsMap = mergeTypeDefinitions(DEFAULT_COMMIT_TYPES, overrides);
201
+ const definitions = values.map(
202
+ (value) => definitionsMap.get(value) ?? createDefaultCommitTypeDefinition(value)
60
203
  );
204
+ return {
205
+ definitions,
206
+ rule: [severity, condition, values]
207
+ };
61
208
  }
62
- var defu = createDefu();
63
- var defuFn = createDefu((object, key, currentValue) => {
64
- if (object[key] !== void 0 && typeof currentValue === "function") {
65
- object[key] = currentValue(object[key]);
66
- return true;
209
+ function asCaseArray(value) {
210
+ if (!value) {
211
+ return [];
67
212
  }
68
- });
69
- var defuArrayFn = createDefu((object, key, currentValue) => {
70
- if (Array.isArray(object[key]) && typeof currentValue === "function") {
71
- object[key] = currentValue(object[key]);
72
- return true;
213
+ return toArray(value);
214
+ }
215
+ function resolveScopeRules(options) {
216
+ if (!options) {
217
+ return {};
218
+ }
219
+ const rules = {};
220
+ const values = Array.isArray(options) ? unique(options) : unique([
221
+ ...toArray(options.values ?? []),
222
+ ...toArray(options.add ?? [])
223
+ ]);
224
+ const baseSeverity = !Array.isArray(options) ? options.severity ?? RuleConfigSeverity.Error : RuleConfigSeverity.Error;
225
+ if (values.length > 0) {
226
+ rules["scope-enum"] = [baseSeverity, "always", values];
227
+ }
228
+ const allowEmpty = Array.isArray(options) ? true : options.allowEmpty ?? !options.required;
229
+ if (allowEmpty) {
230
+ rules["scope-empty"] = [RuleConfigSeverity.Disabled];
231
+ } else {
232
+ rules["scope-empty"] = [baseSeverity, "never"];
233
+ }
234
+ if (!Array.isArray(options) && options.case) {
235
+ const scopeCaseValues = asCaseArray(options.case);
236
+ if (scopeCaseValues.length > 0) {
237
+ const caseSeverity = options.caseSeverity ?? baseSeverity;
238
+ rules["scope-case"] = [caseSeverity, "always", scopeCaseValues];
239
+ }
73
240
  }
74
- });
241
+ return rules;
242
+ }
243
+ function resolveSubjectRules(options) {
244
+ const rules = {};
245
+ const forbiddenCases = asCaseArray(options?.forbidden);
246
+ const subjectCases = forbiddenCases.length > 0 ? forbiddenCases : DEFAULT_SUBJECT_FORBIDDEN_CASES;
247
+ const caseSeverity = options?.caseSeverity ?? RuleConfigSeverity.Error;
248
+ rules["subject-case"] = [caseSeverity, "never", subjectCases];
249
+ if (options?.allowEmpty) {
250
+ rules["subject-empty"] = [RuleConfigSeverity.Disabled];
251
+ } else {
252
+ const emptySeverity = options?.emptySeverity ?? RuleConfigSeverity.Error;
253
+ rules["subject-empty"] = [emptySeverity, "never"];
254
+ }
255
+ if (options?.fullStop === false) {
256
+ rules["subject-full-stop"] = [RuleConfigSeverity.Disabled];
257
+ } else {
258
+ const fullStopSeverity = options?.fullStopSeverity ?? RuleConfigSeverity.Error;
259
+ const fullStop = options?.fullStop ?? DEFAULT_FULL_STOP;
260
+ rules["subject-full-stop"] = [fullStopSeverity, "never", fullStop];
261
+ }
262
+ return rules;
263
+ }
264
+ function resolveHeaderRules(options) {
265
+ const severity = options?.severity ?? RuleConfigSeverity.Error;
266
+ const maxLength = options?.maxLength ?? DEFAULT_HEADER_MAX_LENGTH;
267
+ return {
268
+ "header-max-length": [severity, "always", maxLength]
269
+ };
270
+ }
271
+ function createBaseRules() {
272
+ return {
273
+ "body-leading-blank": [RuleConfigSeverity.Warning, "always"],
274
+ "body-max-line-length": [
275
+ RuleConfigSeverity.Error,
276
+ "always",
277
+ DEFAULT_BODY_MAX_LINE_LENGTH
278
+ ],
279
+ "footer-leading-blank": [RuleConfigSeverity.Warning, "always"],
280
+ "footer-max-line-length": [
281
+ RuleConfigSeverity.Error,
282
+ "always",
283
+ DEFAULT_FOOTER_MAX_LINE_LENGTH
284
+ ],
285
+ "header-trim": [RuleConfigSeverity.Error, "always"],
286
+ "type-case": [RuleConfigSeverity.Error, "always", "lower-case"],
287
+ "type-empty": [RuleConfigSeverity.Error, "never"]
288
+ };
289
+ }
290
+ function buildTypeEnum(definitions) {
291
+ return definitions.reduce(
292
+ (accumulator, definition) => {
293
+ accumulator[definition.value] = {
294
+ description: definition.description,
295
+ title: definition.title,
296
+ emoji: definition.emoji
297
+ };
298
+ return accumulator;
299
+ },
300
+ {}
301
+ );
302
+ }
303
+ function createBasePrompt(definitions) {
304
+ return {
305
+ questions: {
306
+ type: {
307
+ description: DEFAULT_PROMPT_TYPE_DESCRIPTION,
308
+ enum: buildTypeEnum(definitions)
309
+ },
310
+ scope: {
311
+ description: DEFAULT_PROMPT_SCOPE_DESCRIPTION
312
+ },
313
+ subject: {
314
+ description: DEFAULT_PROMPT_SUBJECT_DESCRIPTION
315
+ },
316
+ body: {
317
+ description: DEFAULT_PROMPT_BODY_DESCRIPTION
318
+ },
319
+ isBreaking: {
320
+ description: DEFAULT_PROMPT_IS_BREAKING_DESCRIPTION
321
+ },
322
+ breakingBody: {
323
+ description: DEFAULT_PROMPT_BREAKING_BODY_DESCRIPTION
324
+ },
325
+ breaking: {
326
+ description: DEFAULT_PROMPT_BREAKING_DESCRIPTION
327
+ },
328
+ isIssueAffected: {
329
+ description: DEFAULT_PROMPT_IS_ISSUE_AFFECTED_DESCRIPTION
330
+ },
331
+ issuesBody: {
332
+ description: DEFAULT_PROMPT_ISSUES_BODY_DESCRIPTION
333
+ },
334
+ issues: {
335
+ description: DEFAULT_PROMPT_ISSUES_DESCRIPTION
336
+ }
337
+ }
338
+ };
339
+ }
340
+ function resolvePrompt(definitions, overrides) {
341
+ const base = createBasePrompt(definitions);
342
+ return mergeDeep(base, overrides);
343
+ }
344
+ function createIcebreakerCommitlintConfig(options = {}) {
345
+ const extendsField = resolveExtends(options.extends);
346
+ const typeSettings = resolveTypeSettings(options.types);
347
+ const scopeRules = resolveScopeRules(options.scopes);
348
+ const subjectRules = resolveSubjectRules(options.subject);
349
+ const headerRules = resolveHeaderRules(options.header);
350
+ const baseRules = createBaseRules();
351
+ const rules = {
352
+ ...baseRules,
353
+ "type-enum": typeSettings.rule,
354
+ ...scopeRules,
355
+ ...subjectRules,
356
+ ...headerRules,
357
+ ...options.rules
358
+ };
359
+ const prompt = resolvePrompt(typeSettings.definitions, options.prompt);
360
+ return removeUndefined({
361
+ extends: extendsField,
362
+ formatter: options.formatter,
363
+ parserPreset: options.parserPreset ?? DEFAULT_PARSER_PRESET,
364
+ rules,
365
+ ignores: options.ignores,
366
+ defaultIgnores: options.defaultIgnores,
367
+ plugins: options.plugins,
368
+ helpUrl: options.helpUrl,
369
+ prompt
370
+ });
371
+ }
75
372
 
76
373
  // src/index.ts
77
- function icebreaker(config) {
78
- return defu(config, {
79
- extends: ["@commitlint/config-conventional"]
80
- });
374
+ import { RuleConfigCondition, RuleConfigSeverity as RuleConfigSeverity2, TargetCaseType } from "@commitlint/types";
375
+ function createCommitlintConfig(options) {
376
+ return createIcebreakerCommitlintConfig(options);
377
+ }
378
+ function icebreaker(options) {
379
+ return createIcebreakerCommitlintConfig(options);
81
380
  }
82
381
  export {
382
+ DEFAULT_COMMIT_TYPES,
383
+ DEFAULT_EXTENDS,
384
+ DEFAULT_SUBJECT_FORBIDDEN_CASES,
385
+ DEFAULT_TYPES,
83
386
  RuleConfigCondition,
84
- RuleConfigSeverity,
387
+ RuleConfigSeverity2 as RuleConfigSeverity,
85
388
  TargetCaseType,
389
+ createCommitlintConfig,
390
+ createIcebreakerCommitlintConfig,
86
391
  icebreaker
87
392
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@icebreakers/commitlint-config",
3
3
  "type": "module",
4
- "version": "1.0.3",
4
+ "version": "1.1.0",
5
5
  "description": "icebreaker's commitlint config",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -29,8 +29,8 @@
29
29
  "dist"
30
30
  ],
31
31
  "dependencies": {
32
- "@commitlint/config-conventional": "^19.8.1",
33
- "@commitlint/types": "^19.8.1",
32
+ "@commitlint/config-conventional": "^20.0.0",
33
+ "@commitlint/types": "^20.0.0",
34
34
  "conventional-changelog-conventionalcommits": "^9.1.0"
35
35
  },
36
36
  "scripts": {