@doki-land/nifty 0.0.2 → 0.0.4

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/README.md +29 -0
  2. package/cli/nifty.mjs +11 -11
  3. package/locales/en-US/cli.json +68 -64
  4. package/locales/locales.json +4 -4
  5. package/package.json +20 -16
  6. package/src/cli/authArgs.ts +52 -52
  7. package/src/cli/bump-cmd.ts +55 -55
  8. package/src/cli/bump.ts +237 -237
  9. package/src/cli/change-logs-cmd.ts +97 -97
  10. package/src/cli/cli.ts +47 -45
  11. package/src/cli/context.ts +36 -36
  12. package/src/cli/format-cmd.ts +23 -0
  13. package/src/cli/format.ts +28 -0
  14. package/src/cli/index.ts +9 -9
  15. package/src/cli/install-native-cmd.ts +22 -22
  16. package/src/cli/install-native.ts +80 -80
  17. package/src/cli/lint-cmd.ts +35 -33
  18. package/src/cli/lint.ts +102 -113
  19. package/src/cli/main.ts +1 -1
  20. package/src/cli/options.ts +40 -40
  21. package/src/cli/publish-cmd.ts +38 -34
  22. package/src/cli/publish.ts +95 -95
  23. package/src/cli/resolveNpm.ts +16 -16
  24. package/src/cli/retime-cmd.ts +62 -62
  25. package/src/cli/reword-cmd.ts +87 -87
  26. package/src/cli/trust-cmd.ts +38 -38
  27. package/src/cli/trust.ts +83 -83
  28. package/src/cli/update-cmd.ts +20 -20
  29. package/src/cli/update.ts +32 -185
  30. package/src/cli/upload-cmd.ts +44 -44
  31. package/src/cli/upload.ts +313 -313
  32. package/src/cli/workspace.ts +124 -124
  33. package/src/config/defineConfig.ts +12 -12
  34. package/src/config/detectProject.ts +189 -189
  35. package/src/config/index.ts +25 -25
  36. package/src/config/loadConfig.ts +129 -129
  37. package/src/config/types.ts +57 -57
  38. package/src/git.ts +61 -61
  39. package/src/github.ts +184 -184
  40. package/src/gitmoji.ts +77 -77
  41. package/src/index.ts +36 -36
  42. package/src/native.ts +665 -507
  43. package/src/nifty.ts +95 -95
  44. package/src/types.ts +40 -40
package/src/native.ts CHANGED
@@ -1,507 +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 PublisherExports = {
147
- "publish-workspace": (options: {
148
- cwd?: string;
149
- dryRun?: boolean;
150
- refresh?: boolean;
151
- tag?: string;
152
- access?: string;
153
- npm?: string;
154
- otp?: string;
155
- totpSecret?: string;
156
- token?: string;
157
- }) => PublishReport;
158
- "trust-workspace": (options: {
159
- cwd?: string;
160
- dryRun?: boolean;
161
- refresh?: boolean;
162
- only?: string;
163
- packages?: string[];
164
- npm?: string;
165
- otp?: string;
166
- totpSecret?: string;
167
- token?: string;
168
- }) => TrustReport;
169
- };
170
-
171
- export type NiftyNative = {
172
- gitmoji: GitmojiExports;
173
- git: GitExports;
174
- history: HistoryExports;
175
- publisher: PublisherExports;
176
- };
177
-
178
- type NativeBinding = {
179
- gitmojiKnownGitmojis: () => string[];
180
- gitmojiValidateSubject: (subject: string) => boolean;
181
- gitmojiParseSubject: (subject: string) => ParsedSubject;
182
- gitmojiFormatSubject: (gitmoji: string, body: string) => string;
183
- gitmojiStripGitmoji: (subject: string) => string;
184
- gitmojiLeadingGitmoji: (subject: string) => string | null;
185
- gitmojiSectionForGitmoji: (gitmoji?: string | null) => string;
186
- gitmojiParseNoreplyEmail: (email: string) => GithubAuthor | null;
187
- gitmojiResolveGithubAuthor: (email: string, authorMapJson: string) => GithubAuthor | null;
188
- gitmojiDisplayLogin: (author: GithubAuthor) => string;
189
- gitmojiProfileUrl: (author: GithubAuthor) => string;
190
- gitmojiAvatarUrl: (author: GithubAuthor) => string;
191
- gitmojiAuthorMention: (email: string, authorName: string, authorMapJson: string) => string;
192
- gitmojiCommitBullet: (body: string, email: string, authorName: string, authorMapJson: string) => string;
193
- gitDiscoverRoot: (startPath: string) => string;
194
- gitListVersionTags: (repoRoot: string) => string[];
195
- gitListTagInfos: (repoRoot: string) => Array<{ name: string; shortHash: string }>;
196
- gitFormatTagList: (repoRoot: string) => string;
197
- gitResolveRange: (
198
- repoRoot: string,
199
- version?: string | null,
200
- fromRef?: string | null,
201
- toRef?: string | null,
202
- ) => { version: string; fromRef?: string; toRef: string };
203
- gitCollectCommits: (
204
- repoRoot: string,
205
- fromRef: string | null | undefined,
206
- toRef: string,
207
- ) => CommitRecord[];
208
- gitDetectGithubRepo: (repoRoot: string) => string | null;
209
- gitParseGithubRemote: (url: string) => string | null;
210
- publisherPublishWorkspace: (options: {
211
- cwd?: string | null;
212
- dryRun?: boolean | null;
213
- refresh?: boolean | null;
214
- tag?: string | null;
215
- access?: string | null;
216
- npm?: string | null;
217
- otp?: string | null;
218
- totpSecret?: string | null;
219
- token?: string | null;
220
- }) => PublishReport;
221
- publisherTrustWorkspace: (options: {
222
- cwd?: string | null;
223
- dryRun?: boolean | null;
224
- refresh?: boolean | null;
225
- only?: string | null;
226
- packages?: string[] | null;
227
- npm?: string | null;
228
- otp?: string | null;
229
- totpSecret?: string | null;
230
- token?: string | null;
231
- }) => TrustReport;
232
- gitToolsRewordExport: (options: {
233
- cwd?: string | null;
234
- base: string;
235
- ref?: string | null;
236
- path: string;
237
- }) => { count: number; path: string };
238
- gitToolsRewordRewrite: (options: {
239
- cwd?: string | null;
240
- base: string;
241
- ref?: string | null;
242
- path: string;
243
- dryRun?: boolean | null;
244
- }) => {
245
- changes: Array<{
246
- oldOid: string;
247
- oldSubject: string;
248
- newSubject: string;
249
- parentsRelinked: boolean;
250
- messageChanged: boolean;
251
- }>;
252
- oldTip: string;
253
- newTip?: string | null;
254
- refName: string;
255
- dryRun: boolean;
256
- };
257
- gitToolsRetimeRange: (options: {
258
- cwd?: string | null;
259
- commit: string;
260
- startDate?: string | null;
261
- endDate?: string | null;
262
- branch?: string | null;
263
- tip?: string | null;
264
- }) => { branch: string; newTip: string; rewritten: number };
265
- gitToolsRetimeRoot: (options: {
266
- cwd?: string | null;
267
- startDate?: string | null;
268
- endDate?: string | null;
269
- branch?: string | null;
270
- tip?: string | null;
271
- message?: string | null;
272
- }) => { branch: string; newTip: string; rewritten: number };
273
- gitToolsChangelogRender: (options: {
274
- cwd?: string | null;
275
- version?: string | null;
276
- fromRef?: string | null;
277
- toRef?: string | null;
278
- write?: boolean | null;
279
- tags?: boolean | null;
280
- repo?: string | null;
281
- authorMap?: string | null;
282
- releasesDir?: string | null;
283
- }) => {
284
- notes: string;
285
- version: string;
286
- fromRef?: string | null;
287
- toRef: string;
288
- commitCount: number;
289
- writtenPath?: string | null;
290
- rangeLabel: string;
291
- };
292
- gitToolsChangelogLookup: (options: {
293
- cwd?: string | null;
294
- email?: string | null;
295
- login?: string | null;
296
- map?: string | null;
297
- githubToken?: string | null;
298
- fetch?: boolean | null;
299
- }) => GithubAuthor;
300
- };
301
-
302
- const PLATFORM_PACKAGES: Record<string, string> = {
303
- "win32-x64": "@doki-land/nifty-win32-x64",
304
- "linux-x64": "@doki-land/nifty-linux-x64",
305
- "linux-arm64": "@doki-land/nifty-linux-arm64",
306
- "darwin-x64": "@doki-land/nifty-darwin-x64",
307
- "darwin-arm64": "@doki-land/nifty-darwin-arm64",
308
- };
309
-
310
- function mapAuthor(raw: GithubAuthor | null | undefined): GithubAuthor | undefined {
311
- if (!raw) {
312
- return undefined;
313
- }
314
- return {
315
- id: raw.id !== undefined && raw.id !== null ? BigInt(raw.id) : undefined,
316
- login: raw.login ?? undefined,
317
- };
318
- }
319
-
320
- function wrapBinding(binding: NativeBinding): NiftyNative {
321
- return {
322
- gitmoji: {
323
- "known-gitmojis": () => binding.gitmojiKnownGitmojis(),
324
- "validate-subject": (subject) => binding.gitmojiValidateSubject(subject),
325
- "parse-subject": (subject) => binding.gitmojiParseSubject(subject),
326
- "format-subject": (gitmoji, body) => binding.gitmojiFormatSubject(gitmoji, body),
327
- "strip-gitmoji": (subject) => binding.gitmojiStripGitmoji(subject),
328
- "leading-gitmoji": (subject) => binding.gitmojiLeadingGitmoji(subject) ?? undefined,
329
- "section-for-gitmoji": (gitmoji) => binding.gitmojiSectionForGitmoji(gitmoji) as ReleaseSection,
330
- "parse-noreply-email": (email) => mapAuthor(binding.gitmojiParseNoreplyEmail(email)),
331
- "resolve-github-author": (email, authorMapJson) =>
332
- mapAuthor(binding.gitmojiResolveGithubAuthor(email, authorMapJson)),
333
- "display-login": (author) => binding.gitmojiDisplayLogin(author),
334
- "profile-url": (author) => binding.gitmojiProfileUrl(author),
335
- "avatar-url": (author) => binding.gitmojiAvatarUrl(author),
336
- "author-mention": (email, authorName, authorMapJson) =>
337
- binding.gitmojiAuthorMention(email, authorName, authorMapJson),
338
- "commit-bullet": (body, email, authorName, authorMapJson) =>
339
- binding.gitmojiCommitBullet(body, email, authorName, authorMapJson),
340
- },
341
- git: {
342
- "discover-root": (startPath) => binding.gitDiscoverRoot(startPath),
343
- "list-version-tags": (repoRoot) => binding.gitListVersionTags(repoRoot),
344
- "list-tag-infos": (repoRoot) =>
345
- binding.gitListTagInfos(repoRoot).map((tag) => ({
346
- name: tag.name,
347
- "short-hash": tag.shortHash,
348
- })),
349
- "format-tag-list": (repoRoot) => binding.gitFormatTagList(repoRoot),
350
- "resolve-range": (repoRoot, version, fromRef, toRef) => {
351
- const range = binding.gitResolveRange(repoRoot, version, fromRef, toRef);
352
- return {
353
- version: range.version,
354
- "from-ref": range.fromRef,
355
- "to-ref": range.toRef,
356
- };
357
- },
358
- "collect-commits": (repoRoot, fromRef, toRef) => binding.gitCollectCommits(repoRoot, fromRef, toRef),
359
- "detect-github-repo": (repoRoot) => binding.gitDetectGithubRepo(repoRoot) ?? undefined,
360
- "parse-github-remote": (url) => binding.gitParseGithubRemote(url) ?? undefined,
361
- },
362
- history: {
363
- "reword-export": (options) =>
364
- binding.gitToolsRewordExport({
365
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
366
- base: options.base,
367
- ...(options.ref !== undefined ? { ref: options.ref } : {}),
368
- path: options.path,
369
- }),
370
- "reword-rewrite": (options) => {
371
- const report = binding.gitToolsRewordRewrite({
372
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
373
- base: options.base,
374
- ...(options.ref !== undefined ? { ref: options.ref } : {}),
375
- path: options.path,
376
- ...(options.dryRun !== undefined ? { dryRun: options.dryRun } : {}),
377
- });
378
- return {
379
- changes: report.changes,
380
- oldTip: report.oldTip,
381
- newTip: report.newTip ?? undefined,
382
- refName: report.refName,
383
- dryRun: report.dryRun,
384
- };
385
- },
386
- "retime-range": (options) =>
387
- binding.gitToolsRetimeRange({
388
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
389
- commit: options.commit,
390
- ...(options.startDate !== undefined ? { startDate: options.startDate } : {}),
391
- ...(options.endDate !== undefined ? { endDate: options.endDate } : {}),
392
- ...(options.branch !== undefined ? { branch: options.branch } : {}),
393
- ...(options.tip !== undefined ? { tip: options.tip } : {}),
394
- }),
395
- "retime-root": (options) =>
396
- binding.gitToolsRetimeRoot({
397
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
398
- ...(options.startDate !== undefined ? { startDate: options.startDate } : {}),
399
- ...(options.endDate !== undefined ? { endDate: options.endDate } : {}),
400
- ...(options.branch !== undefined ? { branch: options.branch } : {}),
401
- ...(options.tip !== undefined ? { tip: options.tip } : {}),
402
- ...(options.message !== undefined ? { message: options.message } : {}),
403
- }),
404
- "changelog-render": (options) => {
405
- const report = binding.gitToolsChangelogRender({
406
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
407
- ...(options.version !== undefined ? { version: options.version } : {}),
408
- ...(options.fromRef !== undefined ? { fromRef: options.fromRef } : {}),
409
- ...(options.toRef !== undefined ? { toRef: options.toRef } : {}),
410
- ...(options.write !== undefined ? { write: options.write } : {}),
411
- ...(options.tags !== undefined ? { tags: options.tags } : {}),
412
- ...(options.repo !== undefined ? { repo: options.repo } : {}),
413
- ...(options.authorMap !== undefined ? { authorMap: options.authorMap } : {}),
414
- ...(options.releasesDir !== undefined ? { releasesDir: options.releasesDir } : {}),
415
- });
416
- return {
417
- notes: report.notes,
418
- version: report.version,
419
- fromRef: report.fromRef ?? undefined,
420
- toRef: report.toRef,
421
- commitCount: report.commitCount,
422
- writtenPath: report.writtenPath ?? undefined,
423
- rangeLabel: report.rangeLabel,
424
- };
425
- },
426
- "changelog-lookup": (options) => {
427
- const author = binding.gitToolsChangelogLookup({
428
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
429
- ...(options.email !== undefined ? { email: options.email } : {}),
430
- ...(options.login !== undefined ? { login: options.login } : {}),
431
- ...(options.map !== undefined ? { map: options.map } : {}),
432
- ...(options.githubToken !== undefined ? { githubToken: options.githubToken } : {}),
433
- ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),
434
- });
435
- return mapAuthor(author) ?? {};
436
- },
437
- },
438
- publisher: {
439
- "publish-workspace": (options) =>
440
- binding.publisherPublishWorkspace({
441
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
442
- ...(options.dryRun !== undefined ? { dryRun: options.dryRun } : {}),
443
- ...(options.refresh !== undefined ? { refresh: options.refresh } : {}),
444
- ...(options.tag !== undefined ? { tag: options.tag } : {}),
445
- ...(options.access !== undefined ? { access: options.access } : {}),
446
- ...(options.npm !== undefined ? { npm: options.npm } : {}),
447
- ...(options.otp !== undefined ? { otp: options.otp } : {}),
448
- ...(options.totpSecret !== undefined ? { totpSecret: options.totpSecret } : {}),
449
- ...(options.token !== undefined ? { token: options.token } : {}),
450
- }),
451
- "trust-workspace": (options) =>
452
- binding.publisherTrustWorkspace({
453
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
454
- ...(options.dryRun !== undefined ? { dryRun: options.dryRun } : {}),
455
- ...(options.refresh !== undefined ? { refresh: options.refresh } : {}),
456
- ...(options.only !== undefined ? { only: options.only } : {}),
457
- ...(options.packages !== undefined ? { packages: options.packages } : {}),
458
- ...(options.npm !== undefined ? { npm: options.npm } : {}),
459
- ...(options.otp !== undefined ? { otp: options.otp } : {}),
460
- ...(options.totpSecret !== undefined ? { totpSecret: options.totpSecret } : {}),
461
- ...(options.token !== undefined ? { token: options.token } : {}),
462
- }),
463
- },
464
- };
465
- }
466
-
467
- let cached: NiftyNative | undefined;
468
-
469
- /** Load the platform-specific Node-API binary from `@doki-land/nifty-<platform>`. */
470
- export function loadNiftyNative(): NiftyNative {
471
- if (cached) {
472
- return cached;
473
- }
474
- const key = `${process.platform}-${process.arch}`;
475
- const pkg = PLATFORM_PACKAGES[key];
476
- if (!pkg) {
477
- throw new Error(`Unsupported platform for Nifty native bindings: ${key}`);
478
- }
479
- const require = createRequire(import.meta.url);
480
- const binding = require(pkg).default as NativeBinding;
481
- cached = wrapBinding(binding);
482
- return cached;
483
- }
484
-
485
- export function mapTagInfo(raw: { name: string; "short-hash": string }): TagInfo {
486
- return { name: raw.name, shortHash: raw["short-hash"] };
487
- }
488
-
489
- export function mapRangeInfo(raw: { version: string; "from-ref"?: string; "to-ref": string }): RangeInfo {
490
- return {
491
- version: raw.version,
492
- fromRef: raw["from-ref"],
493
- toRef: raw["to-ref"],
494
- };
495
- }
496
-
497
- export function mapCommitRecord(raw: CommitRecord): CommitRecord {
498
- return {
499
- hash: raw.hash,
500
- email: raw.email,
501
- author: raw.author,
502
- subject: raw.subject,
503
- body: raw.body,
504
- gitmoji: raw.gitmoji,
505
- section: raw.section as ReleaseSection,
506
- };
507
- }
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
+ }