@doki-land/nifty 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/cli/nifty.mjs +2 -2
  2. package/package.json +8 -7
  3. package/src/cli/authArgs.ts +29 -29
  4. package/src/cli/bump-cmd.ts +15 -15
  5. package/src/cli/bump.ts +183 -94
  6. package/src/cli/change-logs-cmd.ts +26 -26
  7. package/src/cli/cli.ts +3 -3
  8. package/src/cli/commit-cmd.ts +77 -77
  9. package/src/cli/commit-lint-report.ts +44 -44
  10. package/src/cli/context.ts +9 -9
  11. package/src/cli/format-cmd.ts +6 -6
  12. package/src/cli/format.ts +15 -15
  13. package/src/cli/install-native-cmd.ts +4 -4
  14. package/src/cli/install-native.ts +24 -24
  15. package/src/cli/lint-cmd.ts +11 -11
  16. package/src/cli/lint.ts +49 -49
  17. package/src/cli/options.ts +16 -16
  18. package/src/cli/publish-cmd.ts +16 -16
  19. package/src/cli/publish.ts +38 -38
  20. package/src/cli/resolveNpm.ts +3 -3
  21. package/src/cli/retime-cmd.ts +18 -18
  22. package/src/cli/trust-cmd.ts +11 -11
  23. package/src/cli/trust.ts +26 -26
  24. package/src/cli/update-cmd.ts +5 -5
  25. package/src/cli/update.ts +12 -12
  26. package/src/cli/upload-cmd.ts +17 -17
  27. package/src/cli/upload.ts +132 -132
  28. package/src/cli/workspace.ts +49 -49
  29. package/src/config/authorMap.ts +4 -4
  30. package/src/config/defineConfig.ts +10 -8
  31. package/src/config/detectProject.ts +46 -46
  32. package/src/config/formatPresets.ts +26 -26
  33. package/src/config/loadConfig.ts +35 -35
  34. package/src/config/trustPayload.ts +7 -7
  35. package/src/config/types.ts +38 -38
  36. package/src/git.ts +14 -14
  37. package/src/github.ts +54 -54
  38. package/src/gitmoji.ts +18 -18
  39. package/src/native.ts +600 -600
  40. package/src/nifty.ts +30 -30
  41. package/src/types.ts +17 -17
package/src/git.ts CHANGED
@@ -2,60 +2,60 @@ import type { CommitRecord, RangeInfo, TagInfo } from "./types.js";
2
2
  import { loadNiftyNative, mapCommitRecord, mapRangeInfo, mapTagInfo, type GitExports } from "./native.js";
3
3
 
4
4
  export type ResolveRangeOptions = {
5
- version ? : string;
6
- fromRef ? : string;
7
- toRef ? : string;
5
+ version?: string;
6
+ fromRef?: string;
7
+ toRef?: string;
8
8
  };
9
9
 
10
10
  /**
11
11
  * Read-only git repository helpers (gix via Node-API, no `git` subprocess).
12
12
  */
13
13
  export class Git {
14
- constructor(private readonly wasm : GitExports){ }
14
+ constructor(private readonly wasm: GitExports) {}
15
15
 
16
- static open() : Git {
16
+ static open(): Git {
17
17
  const native = loadNiftyNative();
18
18
  return new Git(native.git);
19
19
  }
20
20
 
21
21
  /** Walk upward from `startPath` to find the working tree root containing `.git`. */
22
- discoverRoot(startPath : string) : string {
22
+ discoverRoot(startPath: string): string {
23
23
  return this.wasm["discover-root"](startPath);
24
24
  }
25
25
 
26
26
  /** List `v*` tags sorted by semver. */
27
- listVersionTags(repoRoot : string) : string[]{
27
+ listVersionTags(repoRoot: string): string[] {
28
28
  return this.wasm["list-version-tags"](repoRoot);
29
29
  }
30
30
 
31
- listTagInfos(repoRoot : string) : TagInfo[]{
31
+ listTagInfos(repoRoot: string): TagInfo[] {
32
32
  return this.wasm["list-tag-infos"](repoRoot).map(mapTagInfo);
33
33
  }
34
34
 
35
- formatTagList(repoRoot : string) : string {
35
+ formatTagList(repoRoot: string): string {
36
36
  return this.wasm["format-tag-list"](repoRoot);
37
37
  }
38
38
 
39
- resolveRange(repoRoot : string, options : ResolveRangeOptions = { }) : RangeInfo {
39
+ resolveRange(repoRoot: string, options: ResolveRangeOptions = {}): RangeInfo {
40
40
  return mapRangeInfo(
41
41
  this.wasm["resolve-range"](repoRoot, options.version, options.fromRef, options.toRef),
42
42
  );
43
43
  }
44
44
 
45
45
  /** Collect non-merge commits in `fromRef..toRef` (exclusive..inclusive). */
46
- collectCommits(repoRoot : string, fromRef : string | undefined, toRef : string) : CommitRecord[]{
46
+ collectCommits(repoRoot: string, fromRef: string | undefined, toRef: string): CommitRecord[] {
47
47
  return this.wasm["collect-commits"](repoRoot, fromRef, toRef).map(mapCommitRecord);
48
48
  }
49
49
 
50
- detectGithubRepo(repoRoot : string) : string | undefined {
50
+ detectGithubRepo(repoRoot: string): string | undefined {
51
51
  return this.wasm["detect-github-repo"](repoRoot);
52
52
  }
53
53
 
54
- parseGithubRemote(url : string) : string | undefined {
54
+ parseGithubRemote(url: string): string | undefined {
55
55
  return this.wasm["parse-github-remote"](url);
56
56
  }
57
57
  }
58
58
 
59
- export function createGit() : Git {
59
+ export function createGit(): Git {
60
60
  return Git.open();
61
61
  }
package/src/github.ts CHANGED
@@ -3,130 +3,130 @@ import type { GithubAuthor } from "./types.js";
3
3
  const USER_AGENT = "nifty-github";
4
4
  const ACCEPT = "application/vnd.github+json";
5
5
 
6
- function parseUserJson(body : Record<string, unknown>, fallbackLogin ? : string) : GithubAuthor {
6
+ function parseUserJson(body: Record<string, unknown>, fallbackLogin?: string): GithubAuthor {
7
7
  const id = typeof body.id === "number" ? BigInt(body.id) : undefined;
8
8
  const login = typeof body.login === "string" ? body.login : fallbackLogin;
9
- if(id === undefined && login === undefined){
9
+ if (id === undefined && login === undefined) {
10
10
  throw new Error("GitHub user response missing id and login");
11
11
  }
12
12
  return { id, login };
13
13
  }
14
14
 
15
- async function getJson(url : string, token ? : string) : Promise<Record<string, unknown>>{
16
- const headers : Record<string, string> = {
17
- Accept : ACCEPT,
18
- "User-Agent" : USER_AGENT,
15
+ async function getJson(url: string, token?: string): Promise<Record<string, unknown>> {
16
+ const headers: Record<string, string> = {
17
+ Accept: ACCEPT,
18
+ "User-Agent": USER_AGENT,
19
19
  };
20
- if(token ?.trim()){
20
+ if (token?.trim()) {
21
21
  headers.Authorization = `Bearer ${token.trim()}`;
22
22
  }
23
23
  const response = await fetch(url, { headers });
24
- if(response.status === 404){
24
+ if (response.status === 404) {
25
25
  throw new Error("GitHub resource not found");
26
26
  }
27
- if(!response.ok){
27
+ if (!response.ok) {
28
28
  throw new Error(`GitHub API error: ${response.status} ${response.statusText}`);
29
29
  }
30
- return(await response.json())as Record<string, unknown>;
30
+ return (await response.json()) as Record<string, unknown>;
31
31
  }
32
32
 
33
- function parseNoreplyEmail(email : string) : GithubAuthor | undefined {
33
+ function parseNoreplyEmail(email: string): GithubAuthor | undefined {
34
34
  const trimmed = email.trim();
35
35
  const suffix = "@users.noreply.github.com";
36
36
  const lower = trimmed.toLowerCase();
37
- if(!lower.endsWith(suffix)){
37
+ if (!lower.endsWith(suffix)) {
38
38
  return undefined;
39
39
  }
40
- const local = trimmed.slice(0, - suffix.length);
40
+ const local = trimmed.slice(0, -suffix.length);
41
41
  const plus = local.indexOf("+");
42
- if(plus>= 0){
42
+ if (plus >= 0) {
43
43
  const idPart = local.slice(0, plus);
44
44
  const login = local.slice(plus + 1);
45
- if(!login){
45
+ if (!login) {
46
46
  return undefined;
47
47
  }
48
- return { id : BigInt(idPart), login };
48
+ return { id: BigInt(idPart), login };
49
49
  }
50
- if(!local){
50
+ if (!local) {
51
51
  return undefined;
52
52
  }
53
- return { login : local };
53
+ return { login: local };
54
54
  }
55
55
 
56
- function loadAuthorMap(json : string) : Map<string, GithubAuthor>{
56
+ function loadAuthorMap(json: string): Map<string, GithubAuthor> {
57
57
  const map = new Map<string, GithubAuthor>();
58
- if(!json.trim()){
58
+ if (!json.trim()) {
59
59
  return map;
60
60
  }
61
- const parsed = JSON.parse(json)as Record<string, { id ? : number; login ? : string }>;
62
- for(const[email, entry]of Object.entries(parsed)){
63
- const author : GithubAuthor = { };
64
- if(typeof entry.id === "number"){
61
+ const parsed = JSON.parse(json) as Record<string, { id?: number; login?: string }>;
62
+ for (const [email, entry] of Object.entries(parsed)) {
63
+ const author: GithubAuthor = {};
64
+ if (typeof entry.id === "number") {
65
65
  author.id = BigInt(entry.id);
66
66
  }
67
- if(typeof entry.login === "string" && entry.login.trim()){
67
+ if (typeof entry.login === "string" && entry.login.trim()) {
68
68
  author.login = entry.login.trim();
69
69
  }
70
- if(author.id!== undefined || author.login!== undefined){
70
+ if (author.id !== undefined || author.login !== undefined) {
71
71
  map.set(email.trim().toLowerCase(), author);
72
72
  }
73
73
  }
74
74
  return map;
75
75
  }
76
76
 
77
- function mergeAuthors(existing : GithubAuthor, incoming : GithubAuthor) : GithubAuthor {
77
+ function mergeAuthors(existing: GithubAuthor, incoming: GithubAuthor): GithubAuthor {
78
78
  return {
79
- id : existing.id ?? incoming.id,
80
- login : existing.login ?? incoming.login,
79
+ id: existing.id ?? incoming.id,
80
+ login: existing.login ?? incoming.login,
81
81
  };
82
82
  }
83
83
 
84
- async function enrichAuthor(author : GithubAuthor, token ? : string, fetch = false) : Promise<GithubAuthor>{
85
- if(!fetch && author.id!== undefined && author.login!== undefined){
84
+ async function enrichAuthor(author: GithubAuthor, token?: string, fetch = false): Promise<GithubAuthor> {
85
+ if (!fetch && author.id !== undefined && author.login !== undefined) {
86
86
  return author;
87
87
  }
88
- if(!fetch && author.id!== undefined){
88
+ if (!fetch && author.id !== undefined) {
89
89
  return author;
90
90
  }
91
- if(author.login && (author.id === undefined || fetch)){
91
+ if (author.login && (author.id === undefined || fetch)) {
92
92
  const fetched = await userByLoginFetch(author.login, token);
93
93
  return mergeAuthors(author, fetched);
94
94
  }
95
95
  return author;
96
96
  }
97
97
 
98
- async function userByLoginFetch(login : string, token ? : string) : Promise<GithubAuthor>{
98
+ async function userByLoginFetch(login: string, token?: string): Promise<GithubAuthor> {
99
99
  const trimmed = login.trim();
100
- if(!trimmed){
100
+ if (!trimmed) {
101
101
  throw new Error("login must not be empty");
102
102
  }
103
103
  const body = await getJson(`https://api.github.com/users/${trimmed}`, token);
104
104
  return parseUserJson(body, trimmed);
105
105
  }
106
106
 
107
- async function searchUserByEmailFetch(email : string, token : string) : Promise<GithubAuthor | undefined>{
107
+ async function searchUserByEmailFetch(email: string, token: string): Promise<GithubAuthor | undefined> {
108
108
  const trimmed = email.trim();
109
109
  const auth = token.trim();
110
- if(!trimmed){
110
+ if (!trimmed) {
111
111
  throw new Error("email must not be empty");
112
112
  }
113
- if(!auth){
113
+ if (!auth) {
114
114
  throw new Error("GitHub token is required for email search");
115
115
  }
116
116
  const query = encodeURIComponent(`${trimmed} in:email`);
117
117
  const body = await getJson(`https://api.github.com/search/users?q=${query}`, auth);
118
118
  const items = body.items;
119
- if(!Array.isArray(items) || items.length === 0){
119
+ if (!Array.isArray(items) || items.length === 0) {
120
120
  return undefined;
121
121
  }
122
- const first = items[0]as Record<string, unknown>;
122
+ const first = items[0] as Record<string, unknown>;
123
123
  return parseUserJson(first);
124
124
  }
125
125
 
126
126
  export type LookupUserOptions = {
127
- authorMapJson ? : string;
128
- token ? : string;
129
- fetch ? : boolean;
127
+ authorMapJson?: string;
128
+ token?: string;
129
+ fetch?: boolean;
130
130
  };
131
131
 
132
132
  /**
@@ -134,43 +134,43 @@ export type LookupUserOptions = {
134
134
  * Rust equivalent: `nifty-github` crate.
135
135
  */
136
136
  export class Github {
137
- constructor(private readonly token ? : string){ }
137
+ constructor(private readonly token?: string) {}
138
138
 
139
- static open(token ? : string) : Github {
139
+ static open(token?: string): Github {
140
140
  return new Github(token);
141
141
  }
142
142
 
143
- async userByLogin(login : string, token ? : string) : Promise<GithubAuthor>{
143
+ async userByLogin(login: string, token?: string): Promise<GithubAuthor> {
144
144
  return userByLoginFetch(login, token ?? this.token);
145
145
  }
146
146
 
147
- async searchUserByEmail(email : string, token ? : string) : Promise<GithubAuthor | undefined>{
147
+ async searchUserByEmail(email: string, token?: string): Promise<GithubAuthor | undefined> {
148
148
  const auth = token ?? this.token;
149
- if(!auth){
149
+ if (!auth) {
150
150
  throw new Error("GitHub token is required for email search");
151
151
  }
152
152
  return searchUserByEmailFetch(email, auth);
153
153
  }
154
154
 
155
- async lookupUserByEmail(email : string, options : LookupUserOptions = { }) : Promise<GithubAuthor | undefined>{
155
+ async lookupUserByEmail(email: string, options: LookupUserOptions = {}): Promise<GithubAuthor | undefined> {
156
156
  const token = options.token ?? this.token;
157
157
  const fetch = options.fetch ?? false;
158
158
  const mapJson = options.authorMapJson ?? "{}";
159
159
 
160
160
  const fromNoreply = parseNoreplyEmail(email);
161
- if(fromNoreply){
161
+ if (fromNoreply) {
162
162
  return enrichAuthor(fromNoreply, token, fetch);
163
163
  }
164
164
 
165
165
  const map = loadAuthorMap(mapJson);
166
166
  const mapped = map.get(email.trim().toLowerCase());
167
- if(mapped){
167
+ if (mapped) {
168
168
  return enrichAuthor(mapped, token, fetch);
169
169
  }
170
170
 
171
- if(token){
171
+ if (token) {
172
172
  const found = await searchUserByEmailFetch(email, token);
173
- if(found){
173
+ if (found) {
174
174
  return enrichAuthor(found, token, fetch);
175
175
  }
176
176
  }
@@ -179,6 +179,6 @@ export class Github {
179
179
  }
180
180
  }
181
181
 
182
- export function createGithub(token ? : string) : Github {
182
+ export function createGithub(token?: string): Github {
183
183
  return Github.open(token);
184
184
  }
package/src/gitmoji.ts CHANGED
@@ -6,72 +6,72 @@ import { loadNiftyNative, type GitmojiExports } from "./native.js";
6
6
  */
7
7
  export class Gitmoji {
8
8
  constructor(
9
- private readonly wasm : GitmojiExports,
9
+ private readonly wasm: GitmojiExports,
10
10
  private readonly defaultAuthorMapJson = "{}",
11
- ){ }
11
+ ) {}
12
12
 
13
- static open(authorMapJson = "{}") : Gitmoji {
13
+ static open(authorMapJson = "{}"): Gitmoji {
14
14
  const native = loadNiftyNative();
15
15
  return new Gitmoji(native.gitmoji, authorMapJson);
16
16
  }
17
17
 
18
- knownGitmojis() : string[]{
18
+ knownGitmojis(): string[] {
19
19
  return this.wasm["known-gitmojis"]();
20
20
  }
21
21
 
22
- validateSubject(subject : string) : boolean {
22
+ validateSubject(subject: string): boolean {
23
23
  return this.wasm["validate-subject"](subject);
24
24
  }
25
25
 
26
- parseSubject(subject : string) : ParsedSubject {
26
+ parseSubject(subject: string): ParsedSubject {
27
27
  return this.wasm["parse-subject"](subject);
28
28
  }
29
29
 
30
- formatSubject(gitmoji : string, body : string) : string {
30
+ formatSubject(gitmoji: string, body: string): string {
31
31
  return this.wasm["format-subject"](gitmoji, body);
32
32
  }
33
33
 
34
- stripGitmoji(subject : string) : string {
34
+ stripGitmoji(subject: string): string {
35
35
  return this.wasm["strip-gitmoji"](subject);
36
36
  }
37
37
 
38
- leadingGitmoji(subject : string) : string | undefined {
38
+ leadingGitmoji(subject: string): string | undefined {
39
39
  return this.wasm["leading-gitmoji"](subject);
40
40
  }
41
41
 
42
- sectionForGitmoji(gitmoji ? : string) : ReleaseSection {
42
+ sectionForGitmoji(gitmoji?: string): ReleaseSection {
43
43
  return this.wasm["section-for-gitmoji"](gitmoji);
44
44
  }
45
45
 
46
- parseNoreplyEmail(email : string) : GithubAuthor | undefined {
46
+ parseNoreplyEmail(email: string): GithubAuthor | undefined {
47
47
  return this.wasm["parse-noreply-email"](email);
48
48
  }
49
49
 
50
- resolveGithubAuthor(email : string, authorMapJson = this.defaultAuthorMapJson) : GithubAuthor | undefined {
50
+ resolveGithubAuthor(email: string, authorMapJson = this.defaultAuthorMapJson): GithubAuthor | undefined {
51
51
  return this.wasm["resolve-github-author"](email, authorMapJson);
52
52
  }
53
53
 
54
- displayLogin(author : GithubAuthor) : string {
54
+ displayLogin(author: GithubAuthor): string {
55
55
  return this.wasm["display-login"](author);
56
56
  }
57
57
 
58
- profileUrl(author : GithubAuthor) : string {
58
+ profileUrl(author: GithubAuthor): string {
59
59
  return this.wasm["profile-url"](author);
60
60
  }
61
61
 
62
- avatarUrl(author : GithubAuthor) : string {
62
+ avatarUrl(author: GithubAuthor): string {
63
63
  return this.wasm["avatar-url"](author);
64
64
  }
65
65
 
66
- authorMention(email : string, authorName : string, authorMapJson = this.defaultAuthorMapJson) : string {
66
+ authorMention(email: string, authorName: string, authorMapJson = this.defaultAuthorMapJson): string {
67
67
  return this.wasm["author-mention"](email, authorName, authorMapJson);
68
68
  }
69
69
 
70
- commitBullet(body : string, email : string, authorName : string, authorMapJson = this.defaultAuthorMapJson) : string {
70
+ commitBullet(body: string, email: string, authorName: string, authorMapJson = this.defaultAuthorMapJson): string {
71
71
  return this.wasm["commit-bullet"](body, email, authorName, authorMapJson);
72
72
  }
73
73
  }
74
74
 
75
- export function createGitmoji() : Gitmoji {
75
+ export function createGitmoji(): Gitmoji {
76
76
  return Gitmoji.open();
77
77
  }