@doki-land/nifty 0.0.0 → 0.0.2

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 (42) hide show
  1. package/cli/nifty.mjs +11 -11
  2. package/locales/en-US/cli.json +64 -0
  3. package/locales/locales.json +4 -0
  4. package/package.json +22 -19
  5. package/src/cli/authArgs.ts +52 -52
  6. package/src/cli/bump-cmd.ts +55 -0
  7. package/src/cli/bump.ts +237 -237
  8. package/src/cli/change-logs-cmd.ts +97 -0
  9. package/src/cli/cli.ts +45 -0
  10. package/src/cli/context.ts +36 -26
  11. package/src/cli/index.ts +9 -8
  12. package/src/cli/install-native-cmd.ts +22 -0
  13. package/src/cli/install-native.ts +80 -0
  14. package/src/cli/lint-cmd.ts +33 -0
  15. package/src/cli/lint.ts +113 -109
  16. package/src/cli/main.ts +1 -64
  17. package/src/cli/options.ts +40 -0
  18. package/src/cli/publish-cmd.ts +34 -0
  19. package/src/cli/publish.ts +95 -85
  20. package/src/cli/resolveNpm.ts +16 -16
  21. package/src/cli/retime-cmd.ts +62 -0
  22. package/src/cli/reword-cmd.ts +87 -0
  23. package/src/cli/trust-cmd.ts +38 -0
  24. package/src/cli/trust.ts +83 -77
  25. package/src/cli/update-cmd.ts +20 -0
  26. package/src/cli/update.ts +185 -182
  27. package/src/cli/upload-cmd.ts +44 -0
  28. package/src/cli/upload.ts +313 -280
  29. package/src/cli/workspace.ts +124 -124
  30. package/src/config/defineConfig.ts +12 -12
  31. package/src/config/detectProject.ts +189 -189
  32. package/src/config/index.ts +25 -25
  33. package/src/config/loadConfig.ts +129 -129
  34. package/src/config/types.ts +57 -43
  35. package/src/git.ts +61 -61
  36. package/src/github.ts +184 -184
  37. package/src/gitmoji.ts +77 -77
  38. package/src/index.ts +36 -36
  39. package/src/native.ts +507 -277
  40. package/src/nifty.ts +95 -95
  41. package/src/types.ts +40 -40
  42. package/Readme.md +0 -30
package/src/native.ts CHANGED
@@ -1,277 +1,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
- };
62
-
63
- export type TrustReport = {
64
- root: string;
65
- configured: string[];
66
- skipped: string[];
67
- failed: string[];
68
- };
69
-
70
- export type PublisherExports = {
71
- "publish-workspace": (options: {
72
- cwd?: string;
73
- dryRun?: boolean;
74
- tag?: string;
75
- access?: string;
76
- npm?: string;
77
- otp?: string;
78
- totpSecret?: string;
79
- token?: string;
80
- }) => PublishReport;
81
- "trust-workspace": (options: {
82
- cwd?: string;
83
- dryRun?: boolean;
84
- only?: string;
85
- npm?: string;
86
- otp?: string;
87
- totpSecret?: string;
88
- token?: string;
89
- }) => TrustReport;
90
- };
91
-
92
- export type NiftyNative = {
93
- gitmoji: GitmojiExports;
94
- git: GitExports;
95
- publisher: PublisherExports;
96
- };
97
-
98
- type NativeBinding = {
99
- gitmojiKnownGitmojis: () => string[];
100
- gitmojiValidateSubject: (subject: string) => boolean;
101
- gitmojiParseSubject: (subject: string) => ParsedSubject;
102
- gitmojiFormatSubject: (gitmoji: string, body: string) => string;
103
- gitmojiStripGitmoji: (subject: string) => string;
104
- gitmojiLeadingGitmoji: (subject: string) => string | null;
105
- gitmojiSectionForGitmoji: (gitmoji?: string | null) => string;
106
- gitmojiParseNoreplyEmail: (email: string) => GithubAuthor | null;
107
- gitmojiResolveGithubAuthor: (email: string, authorMapJson: string) => GithubAuthor | null;
108
- gitmojiDisplayLogin: (author: GithubAuthor) => string;
109
- gitmojiProfileUrl: (author: GithubAuthor) => string;
110
- gitmojiAvatarUrl: (author: GithubAuthor) => string;
111
- gitmojiAuthorMention: (email: string, authorName: string, authorMapJson: string) => string;
112
- gitmojiCommitBullet: (body: string, email: string, authorName: string, authorMapJson: string) => string;
113
- gitDiscoverRoot: (startPath: string) => string;
114
- gitListVersionTags: (repoRoot: string) => string[];
115
- gitListTagInfos: (repoRoot: string) => Array<{ name: string; shortHash: string }>;
116
- gitFormatTagList: (repoRoot: string) => string;
117
- gitResolveRange: (
118
- repoRoot: string,
119
- version?: string | null,
120
- fromRef?: string | null,
121
- toRef?: string | null,
122
- ) => { version: string; fromRef?: string; toRef: string };
123
- gitCollectCommits: (
124
- repoRoot: string,
125
- fromRef: string | null | undefined,
126
- toRef: string,
127
- ) => CommitRecord[];
128
- gitDetectGithubRepo: (repoRoot: string) => string | null;
129
- gitParseGithubRemote: (url: string) => string | null;
130
- publisherPublishWorkspace: (options: {
131
- cwd?: string | null;
132
- dryRun?: boolean | null;
133
- tag?: string | null;
134
- access?: string | null;
135
- npm?: string | null;
136
- otp?: string | null;
137
- totpSecret?: string | null;
138
- token?: string | null;
139
- }) => PublishReport;
140
- publisherTrustWorkspace: (options: {
141
- cwd?: string | null;
142
- dryRun?: boolean | null;
143
- only?: string | null;
144
- npm?: string | null;
145
- otp?: string | null;
146
- totpSecret?: string | null;
147
- token?: string | null;
148
- }) => TrustReport;
149
- };
150
-
151
- const PLATFORM_PACKAGES: Record<string, string> = {
152
- "win32-x64": "@doki-land/nifty-win32-x64",
153
- "linux-x64": "@doki-land/nifty-linux-x64",
154
- "linux-arm64": "@doki-land/nifty-linux-arm64",
155
- "darwin-x64": "@doki-land/nifty-darwin-x64",
156
- "darwin-arm64": "@doki-land/nifty-darwin-arm64",
157
- };
158
-
159
- function mapAuthor(raw: GithubAuthor | null | undefined): GithubAuthor | undefined {
160
- if (!raw) {
161
- return undefined;
162
- }
163
- return {
164
- id: raw.id !== undefined && raw.id !== null ? BigInt(raw.id) : undefined,
165
- login: raw.login ?? undefined,
166
- };
167
- }
168
-
169
- function wrapBinding(binding: NativeBinding): NiftyNative {
170
- return {
171
- gitmoji: {
172
- "known-gitmojis": () => binding.gitmojiKnownGitmojis(),
173
- "validate-subject": (subject) => binding.gitmojiValidateSubject(subject),
174
- "parse-subject": (subject) => binding.gitmojiParseSubject(subject),
175
- "format-subject": (gitmoji, body) => binding.gitmojiFormatSubject(gitmoji, body),
176
- "strip-gitmoji": (subject) => binding.gitmojiStripGitmoji(subject),
177
- "leading-gitmoji": (subject) => binding.gitmojiLeadingGitmoji(subject) ?? undefined,
178
- "section-for-gitmoji": (gitmoji) => binding.gitmojiSectionForGitmoji(gitmoji) as ReleaseSection,
179
- "parse-noreply-email": (email) => mapAuthor(binding.gitmojiParseNoreplyEmail(email)),
180
- "resolve-github-author": (email, authorMapJson) =>
181
- mapAuthor(binding.gitmojiResolveGithubAuthor(email, authorMapJson)),
182
- "display-login": (author) => binding.gitmojiDisplayLogin(author),
183
- "profile-url": (author) => binding.gitmojiProfileUrl(author),
184
- "avatar-url": (author) => binding.gitmojiAvatarUrl(author),
185
- "author-mention": (email, authorName, authorMapJson) =>
186
- binding.gitmojiAuthorMention(email, authorName, authorMapJson),
187
- "commit-bullet": (body, email, authorName, authorMapJson) =>
188
- binding.gitmojiCommitBullet(body, email, authorName, authorMapJson),
189
- },
190
- git: {
191
- "discover-root": (startPath) => binding.gitDiscoverRoot(startPath),
192
- "list-version-tags": (repoRoot) => binding.gitListVersionTags(repoRoot),
193
- "list-tag-infos": (repoRoot) =>
194
- binding.gitListTagInfos(repoRoot).map((tag) => ({
195
- name: tag.name,
196
- "short-hash": tag.shortHash,
197
- })),
198
- "format-tag-list": (repoRoot) => binding.gitFormatTagList(repoRoot),
199
- "resolve-range": (repoRoot, version, fromRef, toRef) => {
200
- const range = binding.gitResolveRange(repoRoot, version, fromRef, toRef);
201
- return {
202
- version: range.version,
203
- "from-ref": range.fromRef,
204
- "to-ref": range.toRef,
205
- };
206
- },
207
- "collect-commits": (repoRoot, fromRef, toRef) => binding.gitCollectCommits(repoRoot, fromRef, toRef),
208
- "detect-github-repo": (repoRoot) => binding.gitDetectGithubRepo(repoRoot) ?? undefined,
209
- "parse-github-remote": (url) => binding.gitParseGithubRemote(url) ?? undefined,
210
- },
211
- publisher: {
212
- "publish-workspace": (options) =>
213
- binding.publisherPublishWorkspace({
214
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
215
- ...(options.dryRun !== undefined ? { dryRun: options.dryRun } : {}),
216
- ...(options.tag !== undefined ? { tag: options.tag } : {}),
217
- ...(options.access !== undefined ? { access: options.access } : {}),
218
- ...(options.npm !== undefined ? { npm: options.npm } : {}),
219
- ...(options.otp !== undefined ? { otp: options.otp } : {}),
220
- ...(options.totpSecret !== undefined ? { totpSecret: options.totpSecret } : {}),
221
- ...(options.token !== undefined ? { token: options.token } : {}),
222
- }),
223
- "trust-workspace": (options) =>
224
- binding.publisherTrustWorkspace({
225
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
226
- ...(options.dryRun !== undefined ? { dryRun: options.dryRun } : {}),
227
- ...(options.only !== undefined ? { only: options.only } : {}),
228
- ...(options.npm !== undefined ? { npm: options.npm } : {}),
229
- ...(options.otp !== undefined ? { otp: options.otp } : {}),
230
- ...(options.totpSecret !== undefined ? { totpSecret: options.totpSecret } : {}),
231
- ...(options.token !== undefined ? { token: options.token } : {}),
232
- }),
233
- },
234
- };
235
- }
236
-
237
- let cached: NiftyNative | undefined;
238
-
239
- /** Load the platform-specific Node-API binary from `@doki-land/nifty-<platform>`. */
240
- export function loadNiftyNative(): NiftyNative {
241
- if (cached) {
242
- return cached;
243
- }
244
- const key = `${process.platform}-${process.arch}`;
245
- const pkg = PLATFORM_PACKAGES[key];
246
- if (!pkg) {
247
- throw new Error(`Unsupported platform for Nifty native bindings: ${key}`);
248
- }
249
- const require = createRequire(import.meta.url);
250
- const binding = require(pkg).default as NativeBinding;
251
- cached = wrapBinding(binding);
252
- return cached;
253
- }
254
-
255
- export function mapTagInfo(raw: { name: string; "short-hash": string }): TagInfo {
256
- return { name: raw.name, shortHash: raw["short-hash"] };
257
- }
258
-
259
- export function mapRangeInfo(raw: { version: string; "from-ref"?: string; "to-ref": string }): RangeInfo {
260
- return {
261
- version: raw.version,
262
- fromRef: raw["from-ref"],
263
- toRef: raw["to-ref"],
264
- };
265
- }
266
-
267
- export function mapCommitRecord(raw: CommitRecord): CommitRecord {
268
- return {
269
- hash: raw.hash,
270
- email: raw.email,
271
- author: raw.author,
272
- subject: raw.subject,
273
- body: raw.body,
274
- gitmoji: raw.gitmoji,
275
- section: raw.section as ReleaseSection,
276
- };
277
- }
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
+ }