better-commits 1.23.2 → 1.23.3

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 (68) hide show
  1. package/dist/branch.js +628 -19
  2. package/dist/chunk-GAAS3VS3.js +922 -0
  3. package/dist/chunk-H5CLUQIL.js +313 -0
  4. package/dist/index.js +1122 -41
  5. package/dist/init.js +44 -1
  6. package/package.json +12 -4
  7. package/readme.md +4 -2
  8. package/.better-commits.json +0 -52
  9. package/.github/workflows/publish.yml +0 -34
  10. package/.github/workflows/test.yml +0 -27
  11. package/.prettierignore +0 -5
  12. package/.prettierrc +0 -1
  13. package/dist/chunk-43H72S6V.js +0 -1
  14. package/dist/chunk-B7AGSPP3.js +0 -261
  15. package/src/args.test.ts +0 -128
  16. package/src/args.ts +0 -125
  17. package/src/branch-args.test.ts +0 -75
  18. package/src/branch-args.ts +0 -107
  19. package/src/branch-help.ts +0 -125
  20. package/src/branch.ts +0 -97
  21. package/src/default-config-template.ts +0 -258
  22. package/src/git.test.ts +0 -64
  23. package/src/git.ts +0 -72
  24. package/src/help.ts +0 -138
  25. package/src/index.test.ts +0 -7
  26. package/src/index.ts +0 -101
  27. package/src/init.test.ts +0 -123
  28. package/src/init.ts +0 -46
  29. package/src/prompts/autocomplete-multiselect.test.ts +0 -129
  30. package/src/prompts/autocomplete-multiselect.ts +0 -249
  31. package/src/prompts/branch-checkout.prompt.ts +0 -36
  32. package/src/prompts/branch-confirm.prompt.test.ts +0 -89
  33. package/src/prompts/branch-confirm.prompt.ts +0 -149
  34. package/src/prompts/branch-description.prompt.ts +0 -37
  35. package/src/prompts/branch-runnable.ts +0 -13
  36. package/src/prompts/branch-scope.prompt.ts +0 -59
  37. package/src/prompts/branch-ticket.prompt.ts +0 -41
  38. package/src/prompts/branch-type.prompt.ts +0 -46
  39. package/src/prompts/branch-user.prompt.ts +0 -50
  40. package/src/prompts/branch-version.prompt.ts +0 -41
  41. package/src/prompts/commit-body.prompt.ts +0 -51
  42. package/src/prompts/commit-confirm.prompt.ts +0 -123
  43. package/src/prompts/commit-footer.prompt.ts +0 -195
  44. package/src/prompts/commit-scope.prompt.ts +0 -91
  45. package/src/prompts/commit-status.prompt.ts +0 -66
  46. package/src/prompts/commit-ticket.prompt.ts +0 -82
  47. package/src/prompts/commit-title.prompt.ts +0 -98
  48. package/src/prompts/commit-type.prompt.ts +0 -96
  49. package/src/prompts/runnable.ts +0 -13
  50. package/src/utils/build-branch.test.ts +0 -159
  51. package/src/utils/build-branch.ts +0 -48
  52. package/src/utils/build-commit-string.test.ts +0 -273
  53. package/src/utils/build-commit-string.ts +0 -163
  54. package/src/utils/commit-title-size.ts +0 -24
  55. package/src/utils/infer.test.ts +0 -174
  56. package/src/utils/infer.ts +0 -160
  57. package/src/utils/messages.ts +0 -25
  58. package/src/utils/no-interactive-branch-validation.test.ts +0 -193
  59. package/src/utils/no-interactive-validation.test.ts +0 -174
  60. package/src/utils/no-interactive-validation.ts +0 -213
  61. package/src/utils.test.ts +0 -164
  62. package/src/utils.ts +0 -235
  63. package/src/valibot-consts.ts +0 -117
  64. package/src/valibot-state.test.ts +0 -57
  65. package/src/valibot-state.ts +0 -276
  66. package/tsconfig.json +0 -15
  67. package/tsup.config.ts +0 -12
  68. package/vitest.config.ts +0 -8
@@ -0,0 +1,313 @@
1
+ import {
2
+ BRANCH_STATE_ENTRIES,
3
+ COMMIT_STATE_ENTRIES,
4
+ CUSTOM_SCOPE_KEY,
5
+ flags
6
+ } from "./chunk-GAAS3VS3.js";
7
+
8
+ // src/utils/no-interactive-validation.ts
9
+ import * as v from "valibot";
10
+
11
+ // src/utils/commit-title-size.ts
12
+ function get_commit_title_size(val, options) {
13
+ const commit_scope_size = val.scope ? val.scope.length + 2 : 0;
14
+ const commit_type_size = val.type?.length ?? 0;
15
+ const commit_ticket_size = options.include_ticket ? val.ticket?.length ?? 0 : 0;
16
+ const title_size = val.title?.length ?? 0;
17
+ return commit_scope_size + commit_type_size + commit_ticket_size + title_size;
18
+ }
19
+
20
+ // src/utils/no-interactive-validation.ts
21
+ function format_allowed_values(values) {
22
+ const printable_values = values.map(
23
+ (value) => value === "" ? '"" (none)' : `"${value}"`
24
+ );
25
+ return printable_values.join(", ");
26
+ }
27
+ function create_strict_commit_state(config) {
28
+ const type_values = config.commit_type.options.map((option) => option.value);
29
+ const scope_values = config.commit_scope.options.map(
30
+ (option) => option.value
31
+ );
32
+ return v.pipe(
33
+ v.object(COMMIT_STATE_ENTRIES),
34
+ v.rawCheck(({ dataset, addIssue }) => {
35
+ if (!dataset.typed)
36
+ return;
37
+ const received = dataset.value.type ? `"${dataset.value.type}"` : "(empty)";
38
+ if (dataset.value.type && !type_values.includes(dataset.value.type)) {
39
+ addIssue({
40
+ message: `Invalid --type ${received}. Valid types: ${format_allowed_values(type_values)}.`
41
+ });
42
+ }
43
+ }),
44
+ v.rawCheck(({ dataset, addIssue }) => {
45
+ if (!dataset.typed)
46
+ return;
47
+ const received = dataset.value.scope ? `"${dataset.value.scope}"` : "(empty)";
48
+ if (dataset.value.scope && !config.commit_scope.custom_scope && !scope_values.includes(dataset.value.scope)) {
49
+ addIssue({
50
+ message: `Invalid --scope ${received}. Valid scopes: ${format_allowed_values(scope_values)}.`
51
+ });
52
+ }
53
+ }),
54
+ v.rawCheck(({ dataset, addIssue }) => {
55
+ if (!dataset.typed || dataset.value.title.trim())
56
+ return;
57
+ addIssue({
58
+ message: "Missing --title. Provide a non-empty commit title."
59
+ });
60
+ }),
61
+ v.rawCheck(({ dataset, addIssue }) => {
62
+ if (!dataset.typed)
63
+ return;
64
+ const size = get_commit_title_size(dataset.value, {
65
+ include_ticket: config.check_ticket.add_to_title
66
+ });
67
+ if (size > config.commit_title.max_size) {
68
+ addIssue({
69
+ message: `Title exceeds max width. Current size is ${size}, max is ${config.commit_title.max_size} (includes type, scope, and ticket when enabled).`
70
+ });
71
+ }
72
+ }),
73
+ v.rawCheck(({ dataset, addIssue }) => {
74
+ if (dataset.typed && config.commit_body.required && !dataset.value.body.trim()) {
75
+ addIssue({
76
+ message: "Missing --body. commit_body.required is enabled in config."
77
+ });
78
+ }
79
+ }),
80
+ v.rawCheck(({ dataset, addIssue }) => {
81
+ if (dataset.typed && dataset.value.closes && !dataset.value.ticket) {
82
+ addIssue({
83
+ message: 'Invalid footer values: --closes requires --ticket (for example: --ticket "ABC-123").'
84
+ });
85
+ }
86
+ }),
87
+ v.rawCheck(({ dataset, addIssue }) => {
88
+ if (dataset.typed && dataset.value.breaking_body && !dataset.value.breaking_title) {
89
+ addIssue({
90
+ message: "Invalid breaking change values: --breaking-body requires --breaking-title."
91
+ });
92
+ }
93
+ }),
94
+ v.rawCheck(({ dataset, addIssue }) => {
95
+ if (dataset.typed && dataset.value.deprecates_body && !dataset.value.deprecates_title) {
96
+ addIssue({
97
+ message: "Invalid deprecation values: --deprecates-body requires --deprecates-title."
98
+ });
99
+ }
100
+ })
101
+ );
102
+ }
103
+ function create_strict_branch_state(config) {
104
+ const type_values = config.commit_type.options.map((option) => option.value);
105
+ const scope_values = config.commit_scope.options.map(
106
+ (option) => option.value
107
+ );
108
+ return v.pipe(
109
+ v.object(BRANCH_STATE_ENTRIES),
110
+ v.rawCheck(({ dataset, addIssue }) => {
111
+ if (!dataset.typed)
112
+ return;
113
+ const received = dataset.value.type ? `"${dataset.value.type}"` : "(empty)";
114
+ if (dataset.value.type && !type_values.includes(dataset.value.type)) {
115
+ addIssue({
116
+ message: `Invalid --type ${received}. Valid types: ${format_allowed_values(type_values)}.`
117
+ });
118
+ }
119
+ }),
120
+ v.rawCheck(({ dataset, addIssue }) => {
121
+ if (!dataset.typed)
122
+ return;
123
+ const received = dataset.value.scope ? `"${dataset.value.scope}"` : "(empty)";
124
+ if (dataset.value.scope && !config.commit_scope.custom_scope && !scope_values.includes(dataset.value.scope)) {
125
+ addIssue({
126
+ message: `Invalid --scope ${received}. Valid scopes: ${format_allowed_values(scope_values)}.`
127
+ });
128
+ }
129
+ }),
130
+ v.rawCheck(({ dataset, addIssue }) => {
131
+ if (!dataset.typed || dataset.value.description.trim())
132
+ return;
133
+ addIssue({
134
+ message: "Missing --description. Provide a non-empty branch description."
135
+ });
136
+ }),
137
+ v.rawCheck(({ dataset, addIssue }) => {
138
+ if (!dataset.typed)
139
+ return;
140
+ const description = dataset.value.description.trim();
141
+ if (description.length > config.branch_description.max_length) {
142
+ addIssue({
143
+ message: `Description exceeds max length. Current length is ${description.length}, max is ${config.branch_description.max_length}.`
144
+ });
145
+ }
146
+ }),
147
+ v.rawCheck(({ dataset, addIssue }) => {
148
+ if (dataset.typed && config.branch_user.required && !dataset.value.user.trim()) {
149
+ addIssue({
150
+ message: "Missing --user. branch_user.required is enabled in config."
151
+ });
152
+ }
153
+ }),
154
+ v.rawCheck(({ dataset, addIssue }) => {
155
+ if (dataset.typed && config.branch_ticket.required && !dataset.value.ticket.trim()) {
156
+ addIssue({
157
+ message: "Missing --ticket. branch_ticket.required is enabled in config."
158
+ });
159
+ }
160
+ }),
161
+ v.rawCheck(({ dataset, addIssue }) => {
162
+ if (dataset.typed && config.branch_version.required && !dataset.value.version.trim()) {
163
+ addIssue({
164
+ message: "Missing --branch-version. branch_version.required is enabled in config."
165
+ });
166
+ }
167
+ })
168
+ );
169
+ }
170
+
171
+ // src/utils/infer.ts
172
+ import { execSync } from "child_process";
173
+ var REGEX_SLASH_TAG = /\/(\w+-\d+)/;
174
+ var REGEX_START_TAG = /^(\w+-\d+)/;
175
+ var REGEX_START_UND = /^([A-Z]+-[\[a-zA-Z\]\d]+)_/;
176
+ var REGEX_SLASH_UND = /\/([A-Z]+-[\[a-zA-Z\]\d]+)_/;
177
+ var REGEX_SLASH_NUM = /\/(\d+)/;
178
+ var REGEX_START_NUM = /^(\d+)/;
179
+ function infer_not_interactive(config) {
180
+ if (flags.interactive)
181
+ return;
182
+ let inferred_state = { ticket: "", type: "", scope: "" };
183
+ if (config.check_ticket.infer_ticket) {
184
+ const inferred_ticket = infer_ticket_from_git(
185
+ {
186
+ append_hashtag: config.check_ticket.append_hashtag,
187
+ prepend_hashtag: config.check_ticket.prepend_hashtag
188
+ },
189
+ flags.git_args
190
+ );
191
+ inferred_state.ticket = inferred_ticket;
192
+ }
193
+ const inferred_type = infer_type_from_git(
194
+ config.commit_type.options,
195
+ flags.git_args
196
+ );
197
+ inferred_state.type = inferred_type;
198
+ if (config.commit_scope.enable && config.commit_scope.infer_scope_from_branch) {
199
+ const inferred_scope = infer_scope_from_git(
200
+ config.commit_scope.options,
201
+ flags.git_args
202
+ );
203
+ inferred_state.scope = inferred_scope;
204
+ }
205
+ return inferred_state;
206
+ }
207
+ function infer_type_from_git(options, git_args) {
208
+ const branch = get_current_branch(git_args);
209
+ if (!branch)
210
+ return "";
211
+ return infer_type_from_branch(
212
+ branch,
213
+ options.map((option) => option.value)
214
+ );
215
+ }
216
+ function infer_ticket_from_git(options, git_args) {
217
+ const branch = get_current_branch(git_args);
218
+ if (!branch)
219
+ return "";
220
+ return infer_ticket_from_branch(branch, options);
221
+ }
222
+ function infer_scope_from_git(options, git_args) {
223
+ const branch = get_current_branch(git_args);
224
+ if (!branch)
225
+ return "";
226
+ return infer_scope_from_branch(branch, options);
227
+ }
228
+ function infer_ticket_from_branch(branch, options) {
229
+ const found = [
230
+ branch.match(REGEX_START_UND),
231
+ branch.match(REGEX_SLASH_UND),
232
+ branch.match(REGEX_SLASH_TAG),
233
+ branch.match(REGEX_SLASH_NUM),
234
+ branch.match(REGEX_START_TAG),
235
+ branch.match(REGEX_START_NUM)
236
+ ].filter((value) => value != null).map((value) => value && value.length >= 2 ? value[1] : "");
237
+ if (!found.length || !found[0])
238
+ return "";
239
+ return options.append_hashtag || options.prepend_hashtag === "Always" ? `#${found[0]}` : found[0];
240
+ }
241
+ function infer_type_from_branch(branch, types) {
242
+ const found = types.find((type) => {
243
+ const start_dash = new RegExp(`^${type}-`);
244
+ const between_dash = new RegExp(`-${type}-`);
245
+ const before_slash = new RegExp(`${type}/`);
246
+ const matches = [
247
+ branch.match(start_dash),
248
+ branch.match(between_dash),
249
+ branch.match(before_slash)
250
+ ].filter((value) => value != null);
251
+ return matches.length > 0;
252
+ });
253
+ return found ?? "";
254
+ }
255
+ function escape_regexp(value) {
256
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
257
+ }
258
+ function infer_scope_from_branch(branch, options) {
259
+ const scopes = options.map((option) => option.value).filter((scope) => scope && scope !== CUSTOM_SCOPE_KEY).sort((a, b) => b.length - a.length);
260
+ const found = scopes.find((scope) => {
261
+ const standalone_scope = new RegExp(
262
+ `(?:^|[/_-])${escape_regexp(scope)}(?=$|[/_-])`
263
+ );
264
+ return standalone_scope.test(branch);
265
+ });
266
+ return found ?? "";
267
+ }
268
+ function get_current_branch(git_args) {
269
+ try {
270
+ return execSync(`git ${git_args} branch --show-current`, {
271
+ stdio: "pipe"
272
+ }).toString().trim();
273
+ } catch {
274
+ return "";
275
+ }
276
+ }
277
+
278
+ // src/utils/messages.ts
279
+ import color from "picocolors";
280
+ function cache_message(message) {
281
+ return `${message} ${color.dim("\xB7 restored from cache")}`;
282
+ }
283
+ function inferred_message(message) {
284
+ return `${message} ${color.dim("\xB7 inferred from branch")}`;
285
+ }
286
+ function optional_message(message) {
287
+ return `${message} ${color.dim("\xB7 optional")}`;
288
+ }
289
+ function space_to_select_message(message) {
290
+ return `${message} ${color.dim("\xB7 <space> to select")}`;
291
+ }
292
+ function a_for_all_message(message) {
293
+ return `${message} ${color.dim("\xB7 <space> to select \xB7 <a> to select all")}`;
294
+ }
295
+ function dry_run_message(message) {
296
+ return `${message} ${color.dim("\xB7 dry run - changes will not be committed")}`;
297
+ }
298
+
299
+ export {
300
+ get_commit_title_size,
301
+ create_strict_commit_state,
302
+ create_strict_branch_state,
303
+ infer_not_interactive,
304
+ infer_type_from_git,
305
+ infer_ticket_from_git,
306
+ infer_scope_from_git,
307
+ cache_message,
308
+ inferred_message,
309
+ optional_message,
310
+ space_to_select_message,
311
+ a_for_all_message,
312
+ dry_run_message
313
+ };