@doki-land/nifty 0.0.3 → 0.0.5

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 (44) hide show
  1. package/cli/nifty.mjs +11 -11
  2. package/locales/en-US/cli.json +68 -68
  3. package/locales/locales.json +4 -4
  4. package/package.json +16 -20
  5. package/src/cli/authArgs.ts +52 -52
  6. package/src/cli/bump-cmd.ts +55 -55
  7. package/src/cli/bump.ts +237 -237
  8. package/src/cli/change-logs-cmd.ts +97 -97
  9. package/src/cli/cli.ts +47 -47
  10. package/src/cli/context.ts +36 -36
  11. package/src/cli/format-cmd.ts +23 -23
  12. package/src/cli/format.ts +28 -28
  13. package/src/cli/index.ts +9 -9
  14. package/src/cli/install-native-cmd.ts +22 -22
  15. package/src/cli/install-native.ts +80 -80
  16. package/src/cli/lint-cmd.ts +35 -35
  17. package/src/cli/lint.ts +102 -102
  18. package/src/cli/main.ts +1 -1
  19. package/src/cli/options.ts +40 -40
  20. package/src/cli/publish-cmd.ts +38 -38
  21. package/src/cli/publish.ts +95 -95
  22. package/src/cli/resolveNpm.ts +16 -16
  23. package/src/cli/retime-cmd.ts +62 -62
  24. package/src/cli/reword-cmd.ts +87 -87
  25. package/src/cli/trust-cmd.ts +38 -38
  26. package/src/cli/trust.ts +83 -83
  27. package/src/cli/update-cmd.ts +20 -20
  28. package/src/cli/update.ts +32 -32
  29. package/src/cli/upload-cmd.ts +44 -44
  30. package/src/cli/upload.ts +313 -313
  31. package/src/cli/workspace.ts +124 -124
  32. package/src/config/defineConfig.ts +12 -12
  33. package/src/config/detectProject.ts +189 -189
  34. package/src/config/index.ts +25 -25
  35. package/src/config/loadConfig.ts +129 -129
  36. package/src/config/types.ts +57 -57
  37. package/src/git.ts +61 -61
  38. package/src/github.ts +184 -184
  39. package/src/gitmoji.ts +77 -77
  40. package/src/index.ts +36 -36
  41. package/src/native.ts +665 -665
  42. package/src/nifty.ts +95 -95
  43. package/src/types.ts +40 -40
  44. package/README.md +0 -29
package/src/native.ts CHANGED
@@ -1,665 +1,665 @@
1
- import { createRequire } from "node:module";
2
- import type {
3
- CommitRecord,
4
- GithubAuthor,
5
- ParsedSubject,
6
- RangeInfo,
7
- ReleaseSection,
8
- TagInfo,
9
- } from "./types.js";
10
-
11
- export type GitmojiExports = {
12
- "known-gitmojis": () => string[];
13
- "validate-subject": (subject: string) => boolean;
14
- "parse-subject": (subject: string) => ParsedSubject;
15
- "format-subject": (gitmoji: string, body: string) => string;
16
- "strip-gitmoji": (subject: string) => string;
17
- "leading-gitmoji": (subject: string) => string | undefined;
18
- "section-for-gitmoji": (gitmoji: string | undefined) => ReleaseSection;
19
- "parse-noreply-email": (email: string) => GithubAuthor | undefined;
20
- "resolve-github-author": (email: string, authorMapJson: string) => GithubAuthor | undefined;
21
- "display-login": (author: GithubAuthor) => string;
22
- "profile-url": (author: GithubAuthor) => string;
23
- "avatar-url": (author: GithubAuthor) => string;
24
- "author-mention": (email: string, authorName: string, authorMapJson: string) => string;
25
- "commit-bullet": (body: string, email: string, authorName: string, authorMapJson: string) => string;
26
- };
27
-
28
- export type GitExports = {
29
- "discover-root": (startPath: string) => string;
30
- "list-version-tags": (repoRoot: string) => string[];
31
- "list-tag-infos": (repoRoot: string) => Array<{ name: string; "short-hash": string }>;
32
- "format-tag-list": (repoRoot: string) => string;
33
- "resolve-range": (
34
- repoRoot: string,
35
- version: string | undefined,
36
- fromRef: string | undefined,
37
- toRef: string | undefined,
38
- ) => { version: string; "from-ref"?: string; "to-ref": string };
39
- "collect-commits": (
40
- repoRoot: string,
41
- fromRef: string | undefined,
42
- toRef: string,
43
- ) => Array<{
44
- hash: string;
45
- email: string;
46
- author: string;
47
- subject: string;
48
- body: string;
49
- gitmoji?: string;
50
- section: string;
51
- }>;
52
- "detect-github-repo": (repoRoot: string) => string | undefined;
53
- "parse-github-remote": (url: string) => string | undefined;
54
- };
55
-
56
- export type PublishReport = {
57
- root: string;
58
- order: string[];
59
- published: string[];
60
- skipped: string[];
61
- skippedVersions: string[];
62
- };
63
-
64
- export type TrustReport = {
65
- root: string;
66
- configured: string[];
67
- skipped: string[];
68
- failed: string[];
69
- };
70
-
71
- export type RewordPlannedChange = {
72
- oldOid: string;
73
- oldSubject: string;
74
- newSubject: string;
75
- parentsRelinked: boolean;
76
- messageChanged: boolean;
77
- };
78
-
79
- export type RewordRewriteReport = {
80
- changes: RewordPlannedChange[];
81
- oldTip: string;
82
- newTip?: string;
83
- refName: string;
84
- dryRun: boolean;
85
- };
86
-
87
- export type HistoryExports = {
88
- "reword-export": (options: {
89
- cwd?: string;
90
- base: string;
91
- ref?: string;
92
- path: string;
93
- }) => { count: number; path: string };
94
- "reword-rewrite": (options: {
95
- cwd?: string;
96
- base: string;
97
- ref?: string;
98
- path: string;
99
- dryRun?: boolean;
100
- }) => RewordRewriteReport;
101
- "retime-range": (options: {
102
- cwd?: string;
103
- commit: string;
104
- startDate?: string;
105
- endDate?: string;
106
- branch?: string;
107
- tip?: string;
108
- }) => { branch: string; newTip: string; rewritten: number };
109
- "retime-root": (options: {
110
- cwd?: string;
111
- startDate?: string;
112
- endDate?: string;
113
- branch?: string;
114
- tip?: string;
115
- message?: string;
116
- }) => { branch: string; newTip: string; rewritten: number };
117
- "changelog-render": (options: {
118
- cwd?: string;
119
- version?: string;
120
- fromRef?: string;
121
- toRef?: string;
122
- write?: boolean;
123
- tags?: boolean;
124
- repo?: string;
125
- authorMap?: string;
126
- releasesDir?: string;
127
- }) => {
128
- notes: string;
129
- version: string;
130
- fromRef?: string;
131
- toRef: string;
132
- commitCount: number;
133
- writtenPath?: string;
134
- rangeLabel: string;
135
- };
136
- "changelog-lookup": (options: {
137
- cwd?: string;
138
- email?: string;
139
- login?: string;
140
- map?: string;
141
- githubToken?: string;
142
- fetch?: boolean;
143
- }) => GithubAuthor;
144
- };
145
-
146
- export type LintDiagnosticRecord = {
147
- rule: string;
148
- severity: "error" | "warning" | "info";
149
- message: string;
150
- subject?: string;
151
- hash?: string;
152
- path?: string;
153
- line?: number;
154
- };
155
-
156
- export type LintRunOptions = {
157
- cwd?: string;
158
- fromRef?: string;
159
- toRef?: string;
160
- subjects?: string[];
161
- rules?: Array<{ id: string; enabled?: boolean; severity?: "error" | "warning" | "info" }>;
162
- scanCargo?: boolean;
163
- };
164
-
165
- export type LintReportRecord = {
166
- diagnostics: LintDiagnosticRecord[];
167
- errorCount: number;
168
- warningCount: number;
169
- };
170
-
171
- export type LintExports = {
172
- run: (options: LintRunOptions) => LintReportRecord;
173
- check: (options: LintRunOptions) => LintReportRecord;
174
- };
175
-
176
- export type UpdaterExports = {
177
- run: (options: { cwd?: string; interactive?: boolean }) => void;
178
- };
179
-
180
- export type FormatReportRecord = {
181
- formatted: number;
182
- unchanged: number;
183
- errors: string[];
184
- };
185
-
186
- export type FormatterExports = {
187
- run: (options: { cwd?: string; check?: boolean }) => FormatReportRecord;
188
- };
189
-
190
- export type PublisherExports = {
191
- "publish-workspace": (options: {
192
- cwd?: string;
193
- dryRun?: boolean;
194
- refresh?: boolean;
195
- only?: string;
196
- packages?: string[];
197
- tag?: string;
198
- access?: string;
199
- npm?: string;
200
- otp?: string;
201
- totpSecret?: string;
202
- token?: string;
203
- }) => PublishReport;
204
- "trust-workspace": (options: {
205
- cwd?: string;
206
- dryRun?: boolean;
207
- refresh?: boolean;
208
- only?: string;
209
- packages?: string[];
210
- npm?: string;
211
- otp?: string;
212
- totpSecret?: string;
213
- token?: string;
214
- }) => TrustReport;
215
- };
216
-
217
- export type NiftyNative = {
218
- gitmoji: GitmojiExports;
219
- git: GitExports;
220
- history: HistoryExports;
221
- lint: LintExports;
222
- updater: UpdaterExports;
223
- formatter: FormatterExports;
224
- publisher: PublisherExports;
225
- };
226
-
227
- type NativeBinding = {
228
- gitmojiKnownGitmojis: () => string[];
229
- gitmojiValidateSubject: (subject: string) => boolean;
230
- gitmojiParseSubject: (subject: string) => ParsedSubject;
231
- gitmojiFormatSubject: (gitmoji: string, body: string) => string;
232
- gitmojiStripGitmoji: (subject: string) => string;
233
- gitmojiLeadingGitmoji: (subject: string) => string | null;
234
- gitmojiSectionForGitmoji: (gitmoji?: string | null) => string;
235
- gitmojiParseNoreplyEmail: (email: string) => GithubAuthor | null;
236
- gitmojiResolveGithubAuthor: (email: string, authorMapJson: string) => GithubAuthor | null;
237
- gitmojiDisplayLogin: (author: GithubAuthor) => string;
238
- gitmojiProfileUrl: (author: GithubAuthor) => string;
239
- gitmojiAvatarUrl: (author: GithubAuthor) => string;
240
- gitmojiAuthorMention: (email: string, authorName: string, authorMapJson: string) => string;
241
- gitmojiCommitBullet: (body: string, email: string, authorName: string, authorMapJson: string) => string;
242
- gitDiscoverRoot: (startPath: string) => string;
243
- gitListVersionTags: (repoRoot: string) => string[];
244
- gitListTagInfos: (repoRoot: string) => Array<{ name: string; shortHash: string }>;
245
- gitFormatTagList: (repoRoot: string) => string;
246
- gitResolveRange: (
247
- repoRoot: string,
248
- version?: string | null,
249
- fromRef?: string | null,
250
- toRef?: string | null,
251
- ) => { version: string; fromRef?: string; toRef: string };
252
- gitCollectCommits: (
253
- repoRoot: string,
254
- fromRef: string | null | undefined,
255
- toRef: string,
256
- ) => CommitRecord[];
257
- gitDetectGithubRepo: (repoRoot: string) => string | null;
258
- gitParseGithubRemote: (url: string) => string | null;
259
- publisherPublishWorkspace: (options: {
260
- cwd?: string | null;
261
- dryRun?: boolean | null;
262
- refresh?: boolean | null;
263
- tag?: string | null;
264
- access?: string | null;
265
- npm?: string | null;
266
- otp?: string | null;
267
- totpSecret?: string | null;
268
- token?: string | null;
269
- only?: string | null;
270
- packages?: string[] | null;
271
- }) => PublishReport;
272
- publisherTrustWorkspace: (options: {
273
- cwd?: string | null;
274
- dryRun?: boolean | null;
275
- refresh?: boolean | null;
276
- only?: string | null;
277
- packages?: string[] | null;
278
- npm?: string | null;
279
- otp?: string | null;
280
- totpSecret?: string | null;
281
- token?: string | null;
282
- }) => TrustReport;
283
- gitToolsRewordExport: (options: {
284
- cwd?: string | null;
285
- base: string;
286
- ref?: string | null;
287
- path: string;
288
- }) => { count: number; path: string };
289
- gitToolsRewordRewrite: (options: {
290
- cwd?: string | null;
291
- base: string;
292
- ref?: string | null;
293
- path: string;
294
- dryRun?: boolean | null;
295
- }) => {
296
- changes: Array<{
297
- oldOid: string;
298
- oldSubject: string;
299
- newSubject: string;
300
- parentsRelinked: boolean;
301
- messageChanged: boolean;
302
- }>;
303
- oldTip: string;
304
- newTip?: string | null;
305
- refName: string;
306
- dryRun: boolean;
307
- };
308
- gitToolsRetimeRange: (options: {
309
- cwd?: string | null;
310
- commit: string;
311
- startDate?: string | null;
312
- endDate?: string | null;
313
- branch?: string | null;
314
- tip?: string | null;
315
- }) => { branch: string; newTip: string; rewritten: number };
316
- gitToolsRetimeRoot: (options: {
317
- cwd?: string | null;
318
- startDate?: string | null;
319
- endDate?: string | null;
320
- branch?: string | null;
321
- tip?: string | null;
322
- message?: string | null;
323
- }) => { branch: string; newTip: string; rewritten: number };
324
- gitToolsChangelogRender: (options: {
325
- cwd?: string | null;
326
- version?: string | null;
327
- fromRef?: string | null;
328
- toRef?: string | null;
329
- write?: boolean | null;
330
- tags?: boolean | null;
331
- repo?: string | null;
332
- authorMap?: string | null;
333
- releasesDir?: string | null;
334
- }) => {
335
- notes: string;
336
- version: string;
337
- fromRef?: string | null;
338
- toRef: string;
339
- commitCount: number;
340
- writtenPath?: string | null;
341
- rangeLabel: string;
342
- };
343
- gitToolsChangelogLookup: (options: {
344
- cwd?: string | null;
345
- email?: string | null;
346
- login?: string | null;
347
- map?: string | null;
348
- githubToken?: string | null;
349
- fetch?: boolean | null;
350
- }) => GithubAuthor;
351
- lintRun: (options: {
352
- cwd?: string | null;
353
- fromRef?: string | null;
354
- toRef?: string | null;
355
- subjects?: string[] | null;
356
- rules?: Array<{ id: string; enabled?: boolean | null; severity?: string | null }> | null;
357
- scanCargo?: boolean | null;
358
- check?: boolean | null;
359
- }) => {
360
- diagnostics: Array<{
361
- rule: string;
362
- severity: string;
363
- message: string;
364
- subject?: string | null;
365
- hash?: string | null;
366
- path?: string | null;
367
- line?: number | null;
368
- }>;
369
- errorCount: number;
370
- warningCount: number;
371
- };
372
- lintCheck: (options: {
373
- cwd?: string | null;
374
- fromRef?: string | null;
375
- toRef?: string | null;
376
- subjects?: string[] | null;
377
- rules?: Array<{ id: string; enabled?: boolean | null; severity?: string | null }> | null;
378
- scanCargo?: boolean | null;
379
- check?: boolean | null;
380
- }) => {
381
- diagnostics: Array<{
382
- rule: string;
383
- severity: string;
384
- message: string;
385
- subject?: string | null;
386
- hash?: string | null;
387
- path?: string | null;
388
- line?: number | null;
389
- }>;
390
- errorCount: number;
391
- warningCount: number;
392
- };
393
- updaterRun: (options: { cwd?: string | null; interactive?: boolean | null }) => void;
394
- formatterRun: (options: { cwd?: string | null; check?: boolean | null }) => {
395
- formatted: number;
396
- unchanged: number;
397
- errors: string[];
398
- };
399
- };
400
-
401
- const PLATFORM_PACKAGES: Record<string, string> = {
402
- "win32-x64": "@doki-land/nifty-win32-x64",
403
- "linux-x64": "@doki-land/nifty-linux-x64",
404
- "linux-arm64": "@doki-land/nifty-linux-arm64",
405
- "darwin-x64": "@doki-land/nifty-darwin-x64",
406
- "darwin-arm64": "@doki-land/nifty-darwin-arm64",
407
- };
408
-
409
- function mapAuthor(raw: GithubAuthor | null | undefined): GithubAuthor | undefined {
410
- if (!raw) {
411
- return undefined;
412
- }
413
- return {
414
- id: raw.id !== undefined && raw.id !== null ? BigInt(raw.id) : undefined,
415
- login: raw.login ?? undefined,
416
- };
417
- }
418
-
419
- function mapLintOptions(options: LintRunOptions) {
420
- return {
421
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
422
- ...(options.fromRef !== undefined ? { fromRef: options.fromRef } : {}),
423
- ...(options.toRef !== undefined ? { toRef: options.toRef } : {}),
424
- ...(options.subjects !== undefined ? { subjects: options.subjects } : {}),
425
- ...(options.rules !== undefined ? { rules: options.rules } : {}),
426
- ...(options.scanCargo !== undefined ? { scanCargo: options.scanCargo } : {}),
427
- };
428
- }
429
-
430
- function mapLintReport(raw: {
431
- diagnostics: Array<{
432
- rule: string;
433
- severity: string;
434
- message: string;
435
- subject?: string | null;
436
- hash?: string | null;
437
- path?: string | null;
438
- line?: number | null;
439
- }>;
440
- errorCount: number;
441
- warningCount: number;
442
- }): LintReportRecord {
443
- return {
444
- errorCount: raw.errorCount,
445
- warningCount: raw.warningCount,
446
- diagnostics: raw.diagnostics.map((item) => ({
447
- rule: item.rule,
448
- severity: item.severity as LintDiagnosticRecord["severity"],
449
- message: item.message,
450
- subject: item.subject ?? undefined,
451
- hash: item.hash ?? undefined,
452
- path: item.path ?? undefined,
453
- line: item.line ?? undefined,
454
- })),
455
- };
456
- }
457
-
458
- function wrapBinding(binding: NativeBinding): NiftyNative {
459
- return {
460
- gitmoji: {
461
- "known-gitmojis": () => binding.gitmojiKnownGitmojis(),
462
- "validate-subject": (subject) => binding.gitmojiValidateSubject(subject),
463
- "parse-subject": (subject) => binding.gitmojiParseSubject(subject),
464
- "format-subject": (gitmoji, body) => binding.gitmojiFormatSubject(gitmoji, body),
465
- "strip-gitmoji": (subject) => binding.gitmojiStripGitmoji(subject),
466
- "leading-gitmoji": (subject) => binding.gitmojiLeadingGitmoji(subject) ?? undefined,
467
- "section-for-gitmoji": (gitmoji) => binding.gitmojiSectionForGitmoji(gitmoji) as ReleaseSection,
468
- "parse-noreply-email": (email) => mapAuthor(binding.gitmojiParseNoreplyEmail(email)),
469
- "resolve-github-author": (email, authorMapJson) =>
470
- mapAuthor(binding.gitmojiResolveGithubAuthor(email, authorMapJson)),
471
- "display-login": (author) => binding.gitmojiDisplayLogin(author),
472
- "profile-url": (author) => binding.gitmojiProfileUrl(author),
473
- "avatar-url": (author) => binding.gitmojiAvatarUrl(author),
474
- "author-mention": (email, authorName, authorMapJson) =>
475
- binding.gitmojiAuthorMention(email, authorName, authorMapJson),
476
- "commit-bullet": (body, email, authorName, authorMapJson) =>
477
- binding.gitmojiCommitBullet(body, email, authorName, authorMapJson),
478
- },
479
- git: {
480
- "discover-root": (startPath) => binding.gitDiscoverRoot(startPath),
481
- "list-version-tags": (repoRoot) => binding.gitListVersionTags(repoRoot),
482
- "list-tag-infos": (repoRoot) =>
483
- binding.gitListTagInfos(repoRoot).map((tag) => ({
484
- name: tag.name,
485
- "short-hash": tag.shortHash,
486
- })),
487
- "format-tag-list": (repoRoot) => binding.gitFormatTagList(repoRoot),
488
- "resolve-range": (repoRoot, version, fromRef, toRef) => {
489
- const range = binding.gitResolveRange(repoRoot, version, fromRef, toRef);
490
- return {
491
- version: range.version,
492
- "from-ref": range.fromRef,
493
- "to-ref": range.toRef,
494
- };
495
- },
496
- "collect-commits": (repoRoot, fromRef, toRef) => binding.gitCollectCommits(repoRoot, fromRef, toRef),
497
- "detect-github-repo": (repoRoot) => binding.gitDetectGithubRepo(repoRoot) ?? undefined,
498
- "parse-github-remote": (url) => binding.gitParseGithubRemote(url) ?? undefined,
499
- },
500
- history: {
501
- "reword-export": (options) =>
502
- binding.gitToolsRewordExport({
503
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
504
- base: options.base,
505
- ...(options.ref !== undefined ? { ref: options.ref } : {}),
506
- path: options.path,
507
- }),
508
- "reword-rewrite": (options) => {
509
- const report = binding.gitToolsRewordRewrite({
510
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
511
- base: options.base,
512
- ...(options.ref !== undefined ? { ref: options.ref } : {}),
513
- path: options.path,
514
- ...(options.dryRun !== undefined ? { dryRun: options.dryRun } : {}),
515
- });
516
- return {
517
- changes: report.changes,
518
- oldTip: report.oldTip,
519
- newTip: report.newTip ?? undefined,
520
- refName: report.refName,
521
- dryRun: report.dryRun,
522
- };
523
- },
524
- "retime-range": (options) =>
525
- binding.gitToolsRetimeRange({
526
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
527
- commit: options.commit,
528
- ...(options.startDate !== undefined ? { startDate: options.startDate } : {}),
529
- ...(options.endDate !== undefined ? { endDate: options.endDate } : {}),
530
- ...(options.branch !== undefined ? { branch: options.branch } : {}),
531
- ...(options.tip !== undefined ? { tip: options.tip } : {}),
532
- }),
533
- "retime-root": (options) =>
534
- binding.gitToolsRetimeRoot({
535
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
536
- ...(options.startDate !== undefined ? { startDate: options.startDate } : {}),
537
- ...(options.endDate !== undefined ? { endDate: options.endDate } : {}),
538
- ...(options.branch !== undefined ? { branch: options.branch } : {}),
539
- ...(options.tip !== undefined ? { tip: options.tip } : {}),
540
- ...(options.message !== undefined ? { message: options.message } : {}),
541
- }),
542
- "changelog-render": (options) => {
543
- const report = binding.gitToolsChangelogRender({
544
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
545
- ...(options.version !== undefined ? { version: options.version } : {}),
546
- ...(options.fromRef !== undefined ? { fromRef: options.fromRef } : {}),
547
- ...(options.toRef !== undefined ? { toRef: options.toRef } : {}),
548
- ...(options.write !== undefined ? { write: options.write } : {}),
549
- ...(options.tags !== undefined ? { tags: options.tags } : {}),
550
- ...(options.repo !== undefined ? { repo: options.repo } : {}),
551
- ...(options.authorMap !== undefined ? { authorMap: options.authorMap } : {}),
552
- ...(options.releasesDir !== undefined ? { releasesDir: options.releasesDir } : {}),
553
- });
554
- return {
555
- notes: report.notes,
556
- version: report.version,
557
- fromRef: report.fromRef ?? undefined,
558
- toRef: report.toRef,
559
- commitCount: report.commitCount,
560
- writtenPath: report.writtenPath ?? undefined,
561
- rangeLabel: report.rangeLabel,
562
- };
563
- },
564
- "changelog-lookup": (options) => {
565
- const author = binding.gitToolsChangelogLookup({
566
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
567
- ...(options.email !== undefined ? { email: options.email } : {}),
568
- ...(options.login !== undefined ? { login: options.login } : {}),
569
- ...(options.map !== undefined ? { map: options.map } : {}),
570
- ...(options.githubToken !== undefined ? { githubToken: options.githubToken } : {}),
571
- ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),
572
- });
573
- return mapAuthor(author) ?? {};
574
- },
575
- },
576
- lint: {
577
- run: (options) => mapLintReport(binding.lintRun(mapLintOptions(options))),
578
- check: (options) => mapLintReport(binding.lintCheck(mapLintOptions(options))),
579
- },
580
- updater: {
581
- run: (options) => {
582
- binding.updaterRun({
583
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
584
- ...(options.interactive !== undefined ? { interactive: options.interactive } : {}),
585
- });
586
- },
587
- },
588
- formatter: {
589
- run: (options) => binding.formatterRun({
590
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
591
- ...(options.check !== undefined ? { check: options.check } : {}),
592
- }),
593
- },
594
- publisher: {
595
- "publish-workspace": (options) =>
596
- binding.publisherPublishWorkspace({
597
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
598
- ...(options.dryRun !== undefined ? { dryRun: options.dryRun } : {}),
599
- ...(options.refresh !== undefined ? { refresh: options.refresh } : {}),
600
- ...(options.only !== undefined ? { only: options.only } : {}),
601
- ...(options.packages !== undefined ? { packages: options.packages } : {}),
602
- ...(options.tag !== undefined ? { tag: options.tag } : {}),
603
- ...(options.access !== undefined ? { access: options.access } : {}),
604
- ...(options.npm !== undefined ? { npm: options.npm } : {}),
605
- ...(options.otp !== undefined ? { otp: options.otp } : {}),
606
- ...(options.totpSecret !== undefined ? { totpSecret: options.totpSecret } : {}),
607
- ...(options.token !== undefined ? { token: options.token } : {}),
608
- }),
609
- "trust-workspace": (options) =>
610
- binding.publisherTrustWorkspace({
611
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
612
- ...(options.dryRun !== undefined ? { dryRun: options.dryRun } : {}),
613
- ...(options.refresh !== undefined ? { refresh: options.refresh } : {}),
614
- ...(options.only !== undefined ? { only: options.only } : {}),
615
- ...(options.packages !== undefined ? { packages: options.packages } : {}),
616
- ...(options.npm !== undefined ? { npm: options.npm } : {}),
617
- ...(options.otp !== undefined ? { otp: options.otp } : {}),
618
- ...(options.totpSecret !== undefined ? { totpSecret: options.totpSecret } : {}),
619
- ...(options.token !== undefined ? { token: options.token } : {}),
620
- }),
621
- },
622
- };
623
- }
624
-
625
- let cached: NiftyNative | undefined;
626
-
627
- /** Load the platform-specific Node-API binary from `@doki-land/nifty-<platform>`. */
628
- export function loadNiftyNative(): NiftyNative {
629
- if (cached) {
630
- return cached;
631
- }
632
- const key = `${process.platform}-${process.arch}`;
633
- const pkg = PLATFORM_PACKAGES[key];
634
- if (!pkg) {
635
- throw new Error(`Unsupported platform for Nifty native bindings: ${key}`);
636
- }
637
- const require = createRequire(import.meta.url);
638
- const binding = require(pkg).default as NativeBinding;
639
- cached = wrapBinding(binding);
640
- return cached;
641
- }
642
-
643
- export function mapTagInfo(raw: { name: string; "short-hash": string }): TagInfo {
644
- return { name: raw.name, shortHash: raw["short-hash"] };
645
- }
646
-
647
- export function mapRangeInfo(raw: { version: string; "from-ref"?: string; "to-ref": string }): RangeInfo {
648
- return {
649
- version: raw.version,
650
- fromRef: raw["from-ref"],
651
- toRef: raw["to-ref"],
652
- };
653
- }
654
-
655
- export function mapCommitRecord(raw: CommitRecord): CommitRecord {
656
- return {
657
- hash: raw.hash,
658
- email: raw.email,
659
- author: raw.author,
660
- subject: raw.subject,
661
- body: raw.body,
662
- gitmoji: raw.gitmoji,
663
- section: raw.section as ReleaseSection,
664
- };
665
- }
1
+ import { createRequire } from "node:module";
2
+ import type {
3
+ CommitRecord,
4
+ GithubAuthor,
5
+ ParsedSubject,
6
+ RangeInfo,
7
+ ReleaseSection,
8
+ TagInfo,
9
+ } from "./types.js";
10
+
11
+ export type GitmojiExports = {
12
+ "known-gitmojis": () => string[];
13
+ "validate-subject": (subject: string) => boolean;
14
+ "parse-subject": (subject: string) => ParsedSubject;
15
+ "format-subject": (gitmoji: string, body: string) => string;
16
+ "strip-gitmoji": (subject: string) => string;
17
+ "leading-gitmoji": (subject: string) => string | undefined;
18
+ "section-for-gitmoji": (gitmoji: string | undefined) => ReleaseSection;
19
+ "parse-noreply-email": (email: string) => GithubAuthor | undefined;
20
+ "resolve-github-author": (email: string, authorMapJson: string) => GithubAuthor | undefined;
21
+ "display-login": (author: GithubAuthor) => string;
22
+ "profile-url": (author: GithubAuthor) => string;
23
+ "avatar-url": (author: GithubAuthor) => string;
24
+ "author-mention": (email: string, authorName: string, authorMapJson: string) => string;
25
+ "commit-bullet": (body: string, email: string, authorName: string, authorMapJson: string) => string;
26
+ };
27
+
28
+ export type GitExports = {
29
+ "discover-root": (startPath: string) => string;
30
+ "list-version-tags": (repoRoot: string) => string[];
31
+ "list-tag-infos": (repoRoot: string) => Array<{ name: string; "short-hash": string }>;
32
+ "format-tag-list": (repoRoot: string) => string;
33
+ "resolve-range": (
34
+ repoRoot: string,
35
+ version: string | undefined,
36
+ fromRef: string | undefined,
37
+ toRef: string | undefined,
38
+ ) => { version: string; "from-ref"?: string; "to-ref": string };
39
+ "collect-commits": (
40
+ repoRoot: string,
41
+ fromRef: string | undefined,
42
+ toRef: string,
43
+ ) => Array<{
44
+ hash: string;
45
+ email: string;
46
+ author: string;
47
+ subject: string;
48
+ body: string;
49
+ gitmoji?: string;
50
+ section: string;
51
+ }>;
52
+ "detect-github-repo": (repoRoot: string) => string | undefined;
53
+ "parse-github-remote": (url: string) => string | undefined;
54
+ };
55
+
56
+ export type PublishReport = {
57
+ root: string;
58
+ order: string[];
59
+ published: string[];
60
+ skipped: string[];
61
+ skippedVersions: string[];
62
+ };
63
+
64
+ export type TrustReport = {
65
+ root: string;
66
+ configured: string[];
67
+ skipped: string[];
68
+ failed: string[];
69
+ };
70
+
71
+ export type RewordPlannedChange = {
72
+ oldOid: string;
73
+ oldSubject: string;
74
+ newSubject: string;
75
+ parentsRelinked: boolean;
76
+ messageChanged: boolean;
77
+ };
78
+
79
+ export type RewordRewriteReport = {
80
+ changes: RewordPlannedChange[];
81
+ oldTip: string;
82
+ newTip?: string;
83
+ refName: string;
84
+ dryRun: boolean;
85
+ };
86
+
87
+ export type HistoryExports = {
88
+ "reword-export": (options: {
89
+ cwd?: string;
90
+ base: string;
91
+ ref?: string;
92
+ path: string;
93
+ }) => { count: number; path: string };
94
+ "reword-rewrite": (options: {
95
+ cwd?: string;
96
+ base: string;
97
+ ref?: string;
98
+ path: string;
99
+ dryRun?: boolean;
100
+ }) => RewordRewriteReport;
101
+ "retime-range": (options: {
102
+ cwd?: string;
103
+ commit: string;
104
+ startDate?: string;
105
+ endDate?: string;
106
+ branch?: string;
107
+ tip?: string;
108
+ }) => { branch: string; newTip: string; rewritten: number };
109
+ "retime-root": (options: {
110
+ cwd?: string;
111
+ startDate?: string;
112
+ endDate?: string;
113
+ branch?: string;
114
+ tip?: string;
115
+ message?: string;
116
+ }) => { branch: string; newTip: string; rewritten: number };
117
+ "changelog-render": (options: {
118
+ cwd?: string;
119
+ version?: string;
120
+ fromRef?: string;
121
+ toRef?: string;
122
+ write?: boolean;
123
+ tags?: boolean;
124
+ repo?: string;
125
+ authorMap?: string;
126
+ releasesDir?: string;
127
+ }) => {
128
+ notes: string;
129
+ version: string;
130
+ fromRef?: string;
131
+ toRef: string;
132
+ commitCount: number;
133
+ writtenPath?: string;
134
+ rangeLabel: string;
135
+ };
136
+ "changelog-lookup": (options: {
137
+ cwd?: string;
138
+ email?: string;
139
+ login?: string;
140
+ map?: string;
141
+ githubToken?: string;
142
+ fetch?: boolean;
143
+ }) => GithubAuthor;
144
+ };
145
+
146
+ export type LintDiagnosticRecord = {
147
+ rule: string;
148
+ severity: "error" | "warning" | "info";
149
+ message: string;
150
+ subject?: string;
151
+ hash?: string;
152
+ path?: string;
153
+ line?: number;
154
+ };
155
+
156
+ export type LintRunOptions = {
157
+ cwd?: string;
158
+ fromRef?: string;
159
+ toRef?: string;
160
+ subjects?: string[];
161
+ rules?: Array<{ id: string; enabled?: boolean; severity?: "error" | "warning" | "info" }>;
162
+ scanCargo?: boolean;
163
+ };
164
+
165
+ export type LintReportRecord = {
166
+ diagnostics: LintDiagnosticRecord[];
167
+ errorCount: number;
168
+ warningCount: number;
169
+ };
170
+
171
+ export type LintExports = {
172
+ run: (options: LintRunOptions) => LintReportRecord;
173
+ check: (options: LintRunOptions) => LintReportRecord;
174
+ };
175
+
176
+ export type UpdaterExports = {
177
+ run: (options: { cwd?: string; interactive?: boolean }) => void;
178
+ };
179
+
180
+ export type FormatReportRecord = {
181
+ formatted: number;
182
+ unchanged: number;
183
+ errors: string[];
184
+ };
185
+
186
+ export type FormatterExports = {
187
+ run: (options: { cwd?: string; check?: boolean }) => FormatReportRecord;
188
+ };
189
+
190
+ export type PublisherExports = {
191
+ "publish-workspace": (options: {
192
+ cwd?: string;
193
+ dryRun?: boolean;
194
+ refresh?: boolean;
195
+ only?: string;
196
+ packages?: string[];
197
+ tag?: string;
198
+ access?: string;
199
+ npm?: string;
200
+ otp?: string;
201
+ totpSecret?: string;
202
+ token?: string;
203
+ }) => PublishReport;
204
+ "trust-workspace": (options: {
205
+ cwd?: string;
206
+ dryRun?: boolean;
207
+ refresh?: boolean;
208
+ only?: string;
209
+ packages?: string[];
210
+ npm?: string;
211
+ otp?: string;
212
+ totpSecret?: string;
213
+ token?: string;
214
+ }) => TrustReport;
215
+ };
216
+
217
+ export type NiftyNative = {
218
+ gitmoji: GitmojiExports;
219
+ git: GitExports;
220
+ history: HistoryExports;
221
+ lint: LintExports;
222
+ updater: UpdaterExports;
223
+ formatter: FormatterExports;
224
+ publisher: PublisherExports;
225
+ };
226
+
227
+ type NativeBinding = {
228
+ gitmojiKnownGitmojis: () => string[];
229
+ gitmojiValidateSubject: (subject: string) => boolean;
230
+ gitmojiParseSubject: (subject: string) => ParsedSubject;
231
+ gitmojiFormatSubject: (gitmoji: string, body: string) => string;
232
+ gitmojiStripGitmoji: (subject: string) => string;
233
+ gitmojiLeadingGitmoji: (subject: string) => string | null;
234
+ gitmojiSectionForGitmoji: (gitmoji?: string | null) => string;
235
+ gitmojiParseNoreplyEmail: (email: string) => GithubAuthor | null;
236
+ gitmojiResolveGithubAuthor: (email: string, authorMapJson: string) => GithubAuthor | null;
237
+ gitmojiDisplayLogin: (author: GithubAuthor) => string;
238
+ gitmojiProfileUrl: (author: GithubAuthor) => string;
239
+ gitmojiAvatarUrl: (author: GithubAuthor) => string;
240
+ gitmojiAuthorMention: (email: string, authorName: string, authorMapJson: string) => string;
241
+ gitmojiCommitBullet: (body: string, email: string, authorName: string, authorMapJson: string) => string;
242
+ gitDiscoverRoot: (startPath: string) => string;
243
+ gitListVersionTags: (repoRoot: string) => string[];
244
+ gitListTagInfos: (repoRoot: string) => Array<{ name: string; shortHash: string }>;
245
+ gitFormatTagList: (repoRoot: string) => string;
246
+ gitResolveRange: (
247
+ repoRoot: string,
248
+ version?: string | null,
249
+ fromRef?: string | null,
250
+ toRef?: string | null,
251
+ ) => { version: string; fromRef?: string; toRef: string };
252
+ gitCollectCommits: (
253
+ repoRoot: string,
254
+ fromRef: string | null | undefined,
255
+ toRef: string,
256
+ ) => CommitRecord[];
257
+ gitDetectGithubRepo: (repoRoot: string) => string | null;
258
+ gitParseGithubRemote: (url: string) => string | null;
259
+ publisherPublishWorkspace: (options: {
260
+ cwd?: string | null;
261
+ dryRun?: boolean | null;
262
+ refresh?: boolean | null;
263
+ tag?: string | null;
264
+ access?: string | null;
265
+ npm?: string | null;
266
+ otp?: string | null;
267
+ totpSecret?: string | null;
268
+ token?: string | null;
269
+ only?: string | null;
270
+ packages?: string[] | null;
271
+ }) => PublishReport;
272
+ publisherTrustWorkspace: (options: {
273
+ cwd?: string | null;
274
+ dryRun?: boolean | null;
275
+ refresh?: boolean | null;
276
+ only?: string | null;
277
+ packages?: string[] | null;
278
+ npm?: string | null;
279
+ otp?: string | null;
280
+ totpSecret?: string | null;
281
+ token?: string | null;
282
+ }) => TrustReport;
283
+ gitToolsRewordExport: (options: {
284
+ cwd?: string | null;
285
+ base: string;
286
+ ref?: string | null;
287
+ path: string;
288
+ }) => { count: number; path: string };
289
+ gitToolsRewordRewrite: (options: {
290
+ cwd?: string | null;
291
+ base: string;
292
+ ref?: string | null;
293
+ path: string;
294
+ dryRun?: boolean | null;
295
+ }) => {
296
+ changes: Array<{
297
+ oldOid: string;
298
+ oldSubject: string;
299
+ newSubject: string;
300
+ parentsRelinked: boolean;
301
+ messageChanged: boolean;
302
+ }>;
303
+ oldTip: string;
304
+ newTip?: string | null;
305
+ refName: string;
306
+ dryRun: boolean;
307
+ };
308
+ gitToolsRetimeRange: (options: {
309
+ cwd?: string | null;
310
+ commit: string;
311
+ startDate?: string | null;
312
+ endDate?: string | null;
313
+ branch?: string | null;
314
+ tip?: string | null;
315
+ }) => { branch: string; newTip: string; rewritten: number };
316
+ gitToolsRetimeRoot: (options: {
317
+ cwd?: string | null;
318
+ startDate?: string | null;
319
+ endDate?: string | null;
320
+ branch?: string | null;
321
+ tip?: string | null;
322
+ message?: string | null;
323
+ }) => { branch: string; newTip: string; rewritten: number };
324
+ gitToolsChangelogRender: (options: {
325
+ cwd?: string | null;
326
+ version?: string | null;
327
+ fromRef?: string | null;
328
+ toRef?: string | null;
329
+ write?: boolean | null;
330
+ tags?: boolean | null;
331
+ repo?: string | null;
332
+ authorMap?: string | null;
333
+ releasesDir?: string | null;
334
+ }) => {
335
+ notes: string;
336
+ version: string;
337
+ fromRef?: string | null;
338
+ toRef: string;
339
+ commitCount: number;
340
+ writtenPath?: string | null;
341
+ rangeLabel: string;
342
+ };
343
+ gitToolsChangelogLookup: (options: {
344
+ cwd?: string | null;
345
+ email?: string | null;
346
+ login?: string | null;
347
+ map?: string | null;
348
+ githubToken?: string | null;
349
+ fetch?: boolean | null;
350
+ }) => GithubAuthor;
351
+ lintRun: (options: {
352
+ cwd?: string | null;
353
+ fromRef?: string | null;
354
+ toRef?: string | null;
355
+ subjects?: string[] | null;
356
+ rules?: Array<{ id: string; enabled?: boolean | null; severity?: string | null }> | null;
357
+ scanCargo?: boolean | null;
358
+ check?: boolean | null;
359
+ }) => {
360
+ diagnostics: Array<{
361
+ rule: string;
362
+ severity: string;
363
+ message: string;
364
+ subject?: string | null;
365
+ hash?: string | null;
366
+ path?: string | null;
367
+ line?: number | null;
368
+ }>;
369
+ errorCount: number;
370
+ warningCount: number;
371
+ };
372
+ lintCheck: (options: {
373
+ cwd?: string | null;
374
+ fromRef?: string | null;
375
+ toRef?: string | null;
376
+ subjects?: string[] | null;
377
+ rules?: Array<{ id: string; enabled?: boolean | null; severity?: string | null }> | null;
378
+ scanCargo?: boolean | null;
379
+ check?: boolean | null;
380
+ }) => {
381
+ diagnostics: Array<{
382
+ rule: string;
383
+ severity: string;
384
+ message: string;
385
+ subject?: string | null;
386
+ hash?: string | null;
387
+ path?: string | null;
388
+ line?: number | null;
389
+ }>;
390
+ errorCount: number;
391
+ warningCount: number;
392
+ };
393
+ updaterRun: (options: { cwd?: string | null; interactive?: boolean | null }) => void;
394
+ formatterRun: (options: { cwd?: string | null; check?: boolean | null }) => {
395
+ formatted: number;
396
+ unchanged: number;
397
+ errors: string[];
398
+ };
399
+ };
400
+
401
+ const PLATFORM_PACKAGES: Record<string, string> = {
402
+ "win32-x64": "@doki-land/nifty-win32-x64",
403
+ "linux-x64": "@doki-land/nifty-linux-x64",
404
+ "linux-arm64": "@doki-land/nifty-linux-arm64",
405
+ "darwin-x64": "@doki-land/nifty-darwin-x64",
406
+ "darwin-arm64": "@doki-land/nifty-darwin-arm64",
407
+ };
408
+
409
+ function mapAuthor(raw: GithubAuthor | null | undefined): GithubAuthor | undefined {
410
+ if (!raw) {
411
+ return undefined;
412
+ }
413
+ return {
414
+ id: raw.id !== undefined && raw.id !== null ? BigInt(raw.id) : undefined,
415
+ login: raw.login ?? undefined,
416
+ };
417
+ }
418
+
419
+ function mapLintOptions(options: LintRunOptions) {
420
+ return {
421
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
422
+ ...(options.fromRef !== undefined ? { fromRef: options.fromRef } : {}),
423
+ ...(options.toRef !== undefined ? { toRef: options.toRef } : {}),
424
+ ...(options.subjects !== undefined ? { subjects: options.subjects } : {}),
425
+ ...(options.rules !== undefined ? { rules: options.rules } : {}),
426
+ ...(options.scanCargo !== undefined ? { scanCargo: options.scanCargo } : {}),
427
+ };
428
+ }
429
+
430
+ function mapLintReport(raw: {
431
+ diagnostics: Array<{
432
+ rule: string;
433
+ severity: string;
434
+ message: string;
435
+ subject?: string | null;
436
+ hash?: string | null;
437
+ path?: string | null;
438
+ line?: number | null;
439
+ }>;
440
+ errorCount: number;
441
+ warningCount: number;
442
+ }): LintReportRecord {
443
+ return {
444
+ errorCount: raw.errorCount,
445
+ warningCount: raw.warningCount,
446
+ diagnostics: raw.diagnostics.map((item) => ({
447
+ rule: item.rule,
448
+ severity: item.severity as LintDiagnosticRecord["severity"],
449
+ message: item.message,
450
+ subject: item.subject ?? undefined,
451
+ hash: item.hash ?? undefined,
452
+ path: item.path ?? undefined,
453
+ line: item.line ?? undefined,
454
+ })),
455
+ };
456
+ }
457
+
458
+ function wrapBinding(binding: NativeBinding): NiftyNative {
459
+ return {
460
+ gitmoji: {
461
+ "known-gitmojis": () => binding.gitmojiKnownGitmojis(),
462
+ "validate-subject": (subject) => binding.gitmojiValidateSubject(subject),
463
+ "parse-subject": (subject) => binding.gitmojiParseSubject(subject),
464
+ "format-subject": (gitmoji, body) => binding.gitmojiFormatSubject(gitmoji, body),
465
+ "strip-gitmoji": (subject) => binding.gitmojiStripGitmoji(subject),
466
+ "leading-gitmoji": (subject) => binding.gitmojiLeadingGitmoji(subject) ?? undefined,
467
+ "section-for-gitmoji": (gitmoji) => binding.gitmojiSectionForGitmoji(gitmoji) as ReleaseSection,
468
+ "parse-noreply-email": (email) => mapAuthor(binding.gitmojiParseNoreplyEmail(email)),
469
+ "resolve-github-author": (email, authorMapJson) =>
470
+ mapAuthor(binding.gitmojiResolveGithubAuthor(email, authorMapJson)),
471
+ "display-login": (author) => binding.gitmojiDisplayLogin(author),
472
+ "profile-url": (author) => binding.gitmojiProfileUrl(author),
473
+ "avatar-url": (author) => binding.gitmojiAvatarUrl(author),
474
+ "author-mention": (email, authorName, authorMapJson) =>
475
+ binding.gitmojiAuthorMention(email, authorName, authorMapJson),
476
+ "commit-bullet": (body, email, authorName, authorMapJson) =>
477
+ binding.gitmojiCommitBullet(body, email, authorName, authorMapJson),
478
+ },
479
+ git: {
480
+ "discover-root": (startPath) => binding.gitDiscoverRoot(startPath),
481
+ "list-version-tags": (repoRoot) => binding.gitListVersionTags(repoRoot),
482
+ "list-tag-infos": (repoRoot) =>
483
+ binding.gitListTagInfos(repoRoot).map((tag) => ({
484
+ name: tag.name,
485
+ "short-hash": tag.shortHash,
486
+ })),
487
+ "format-tag-list": (repoRoot) => binding.gitFormatTagList(repoRoot),
488
+ "resolve-range": (repoRoot, version, fromRef, toRef) => {
489
+ const range = binding.gitResolveRange(repoRoot, version, fromRef, toRef);
490
+ return {
491
+ version: range.version,
492
+ "from-ref": range.fromRef,
493
+ "to-ref": range.toRef,
494
+ };
495
+ },
496
+ "collect-commits": (repoRoot, fromRef, toRef) => binding.gitCollectCommits(repoRoot, fromRef, toRef),
497
+ "detect-github-repo": (repoRoot) => binding.gitDetectGithubRepo(repoRoot) ?? undefined,
498
+ "parse-github-remote": (url) => binding.gitParseGithubRemote(url) ?? undefined,
499
+ },
500
+ history: {
501
+ "reword-export": (options) =>
502
+ binding.gitToolsRewordExport({
503
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
504
+ base: options.base,
505
+ ...(options.ref !== undefined ? { ref: options.ref } : {}),
506
+ path: options.path,
507
+ }),
508
+ "reword-rewrite": (options) => {
509
+ const report = binding.gitToolsRewordRewrite({
510
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
511
+ base: options.base,
512
+ ...(options.ref !== undefined ? { ref: options.ref } : {}),
513
+ path: options.path,
514
+ ...(options.dryRun !== undefined ? { dryRun: options.dryRun } : {}),
515
+ });
516
+ return {
517
+ changes: report.changes,
518
+ oldTip: report.oldTip,
519
+ newTip: report.newTip ?? undefined,
520
+ refName: report.refName,
521
+ dryRun: report.dryRun,
522
+ };
523
+ },
524
+ "retime-range": (options) =>
525
+ binding.gitToolsRetimeRange({
526
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
527
+ commit: options.commit,
528
+ ...(options.startDate !== undefined ? { startDate: options.startDate } : {}),
529
+ ...(options.endDate !== undefined ? { endDate: options.endDate } : {}),
530
+ ...(options.branch !== undefined ? { branch: options.branch } : {}),
531
+ ...(options.tip !== undefined ? { tip: options.tip } : {}),
532
+ }),
533
+ "retime-root": (options) =>
534
+ binding.gitToolsRetimeRoot({
535
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
536
+ ...(options.startDate !== undefined ? { startDate: options.startDate } : {}),
537
+ ...(options.endDate !== undefined ? { endDate: options.endDate } : {}),
538
+ ...(options.branch !== undefined ? { branch: options.branch } : {}),
539
+ ...(options.tip !== undefined ? { tip: options.tip } : {}),
540
+ ...(options.message !== undefined ? { message: options.message } : {}),
541
+ }),
542
+ "changelog-render": (options) => {
543
+ const report = binding.gitToolsChangelogRender({
544
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
545
+ ...(options.version !== undefined ? { version: options.version } : {}),
546
+ ...(options.fromRef !== undefined ? { fromRef: options.fromRef } : {}),
547
+ ...(options.toRef !== undefined ? { toRef: options.toRef } : {}),
548
+ ...(options.write !== undefined ? { write: options.write } : {}),
549
+ ...(options.tags !== undefined ? { tags: options.tags } : {}),
550
+ ...(options.repo !== undefined ? { repo: options.repo } : {}),
551
+ ...(options.authorMap !== undefined ? { authorMap: options.authorMap } : {}),
552
+ ...(options.releasesDir !== undefined ? { releasesDir: options.releasesDir } : {}),
553
+ });
554
+ return {
555
+ notes: report.notes,
556
+ version: report.version,
557
+ fromRef: report.fromRef ?? undefined,
558
+ toRef: report.toRef,
559
+ commitCount: report.commitCount,
560
+ writtenPath: report.writtenPath ?? undefined,
561
+ rangeLabel: report.rangeLabel,
562
+ };
563
+ },
564
+ "changelog-lookup": (options) => {
565
+ const author = binding.gitToolsChangelogLookup({
566
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
567
+ ...(options.email !== undefined ? { email: options.email } : {}),
568
+ ...(options.login !== undefined ? { login: options.login } : {}),
569
+ ...(options.map !== undefined ? { map: options.map } : {}),
570
+ ...(options.githubToken !== undefined ? { githubToken: options.githubToken } : {}),
571
+ ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),
572
+ });
573
+ return mapAuthor(author) ?? {};
574
+ },
575
+ },
576
+ lint: {
577
+ run: (options) => mapLintReport(binding.lintRun(mapLintOptions(options))),
578
+ check: (options) => mapLintReport(binding.lintCheck(mapLintOptions(options))),
579
+ },
580
+ updater: {
581
+ run: (options) => {
582
+ binding.updaterRun({
583
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
584
+ ...(options.interactive !== undefined ? { interactive: options.interactive } : {}),
585
+ });
586
+ },
587
+ },
588
+ formatter: {
589
+ run: (options) => binding.formatterRun({
590
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
591
+ ...(options.check !== undefined ? { check: options.check } : {}),
592
+ }),
593
+ },
594
+ publisher: {
595
+ "publish-workspace": (options) =>
596
+ binding.publisherPublishWorkspace({
597
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
598
+ ...(options.dryRun !== undefined ? { dryRun: options.dryRun } : {}),
599
+ ...(options.refresh !== undefined ? { refresh: options.refresh } : {}),
600
+ ...(options.only !== undefined ? { only: options.only } : {}),
601
+ ...(options.packages !== undefined ? { packages: options.packages } : {}),
602
+ ...(options.tag !== undefined ? { tag: options.tag } : {}),
603
+ ...(options.access !== undefined ? { access: options.access } : {}),
604
+ ...(options.npm !== undefined ? { npm: options.npm } : {}),
605
+ ...(options.otp !== undefined ? { otp: options.otp } : {}),
606
+ ...(options.totpSecret !== undefined ? { totpSecret: options.totpSecret } : {}),
607
+ ...(options.token !== undefined ? { token: options.token } : {}),
608
+ }),
609
+ "trust-workspace": (options) =>
610
+ binding.publisherTrustWorkspace({
611
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
612
+ ...(options.dryRun !== undefined ? { dryRun: options.dryRun } : {}),
613
+ ...(options.refresh !== undefined ? { refresh: options.refresh } : {}),
614
+ ...(options.only !== undefined ? { only: options.only } : {}),
615
+ ...(options.packages !== undefined ? { packages: options.packages } : {}),
616
+ ...(options.npm !== undefined ? { npm: options.npm } : {}),
617
+ ...(options.otp !== undefined ? { otp: options.otp } : {}),
618
+ ...(options.totpSecret !== undefined ? { totpSecret: options.totpSecret } : {}),
619
+ ...(options.token !== undefined ? { token: options.token } : {}),
620
+ }),
621
+ },
622
+ };
623
+ }
624
+
625
+ let cached: NiftyNative | undefined;
626
+
627
+ /** Load the platform-specific Node-API binary from `@doki-land/nifty-<platform>`. */
628
+ export function loadNiftyNative(): NiftyNative {
629
+ if (cached) {
630
+ return cached;
631
+ }
632
+ const key = `${process.platform}-${process.arch}`;
633
+ const pkg = PLATFORM_PACKAGES[key];
634
+ if (!pkg) {
635
+ throw new Error(`Unsupported platform for Nifty native bindings: ${key}`);
636
+ }
637
+ const require = createRequire(import.meta.url);
638
+ const binding = require(pkg).default as NativeBinding;
639
+ cached = wrapBinding(binding);
640
+ return cached;
641
+ }
642
+
643
+ export function mapTagInfo(raw: { name: string; "short-hash": string }): TagInfo {
644
+ return { name: raw.name, shortHash: raw["short-hash"] };
645
+ }
646
+
647
+ export function mapRangeInfo(raw: { version: string; "from-ref"?: string; "to-ref": string }): RangeInfo {
648
+ return {
649
+ version: raw.version,
650
+ fromRef: raw["from-ref"],
651
+ toRef: raw["to-ref"],
652
+ };
653
+ }
654
+
655
+ export function mapCommitRecord(raw: CommitRecord): CommitRecord {
656
+ return {
657
+ hash: raw.hash,
658
+ email: raw.email,
659
+ author: raw.author,
660
+ subject: raw.subject,
661
+ body: raw.body,
662
+ gitmoji: raw.gitmoji,
663
+ section: raw.section as ReleaseSection,
664
+ };
665
+ }