@optique/git 0.9.0-dev.1
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.
- package/LICENSE +20 -0
- package/README.md +272 -0
- package/dist/index.cjs +553 -0
- package/dist/index.d.cts +215 -0
- package/dist/index.d.ts +215 -0
- package/dist/index.js +489 -0
- package/package.json +76 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
import { message, text } from "@optique/core/message";
|
|
2
|
+
import { ensureNonEmptyString } from "@optique/core/nonempty";
|
|
3
|
+
import * as git from "isomorphic-git";
|
|
4
|
+
import { expandOid, listBranches, listRemotes, listTags, readObject, resolveRef } from "isomorphic-git";
|
|
5
|
+
import process from "node:process";
|
|
6
|
+
|
|
7
|
+
//#region src/index.ts
|
|
8
|
+
const METAVAR_BRANCH = "BRANCH";
|
|
9
|
+
const METAVAR_TAG = "TAG";
|
|
10
|
+
const METAVAR_REMOTE = "REMOTE";
|
|
11
|
+
let defaultFs = null;
|
|
12
|
+
let fsLoading = null;
|
|
13
|
+
async function getDefaultFs() {
|
|
14
|
+
if (defaultFs) return await defaultFs;
|
|
15
|
+
if (fsLoading) return await fsLoading;
|
|
16
|
+
fsLoading = (async () => {
|
|
17
|
+
const nodeFs = await import("node:fs/promises");
|
|
18
|
+
const { TextDecoder } = await import("node:util");
|
|
19
|
+
const decoder = new TextDecoder();
|
|
20
|
+
defaultFs = {
|
|
21
|
+
async readFile(path) {
|
|
22
|
+
const data = await nodeFs.readFile(path);
|
|
23
|
+
if (path.endsWith("/index") || path.endsWith(".idx")) return data;
|
|
24
|
+
return decoder.decode(data);
|
|
25
|
+
},
|
|
26
|
+
async writeFile(path, data) {
|
|
27
|
+
await nodeFs.writeFile(path, data);
|
|
28
|
+
},
|
|
29
|
+
async mkdir(path, options) {
|
|
30
|
+
await nodeFs.mkdir(path, options);
|
|
31
|
+
},
|
|
32
|
+
async rmdir(path, options) {
|
|
33
|
+
await nodeFs.rmdir(path, options);
|
|
34
|
+
},
|
|
35
|
+
async unlink(path) {
|
|
36
|
+
await nodeFs.unlink(path);
|
|
37
|
+
},
|
|
38
|
+
async readdir(path) {
|
|
39
|
+
const entries = await nodeFs.readdir(path, { withFileTypes: false });
|
|
40
|
+
return entries.filter((e) => typeof e === "string");
|
|
41
|
+
},
|
|
42
|
+
async lstat(path) {
|
|
43
|
+
return await nodeFs.lstat(path);
|
|
44
|
+
},
|
|
45
|
+
async stat(path) {
|
|
46
|
+
return await nodeFs.stat(path);
|
|
47
|
+
},
|
|
48
|
+
async readlink(path) {
|
|
49
|
+
return await nodeFs.readlink(path);
|
|
50
|
+
},
|
|
51
|
+
async symlink(target, path) {
|
|
52
|
+
await nodeFs.symlink(target, path, "file");
|
|
53
|
+
},
|
|
54
|
+
async chmod(path, mode) {
|
|
55
|
+
await nodeFs.chmod(path, mode);
|
|
56
|
+
},
|
|
57
|
+
async chown(path, uid, gid) {
|
|
58
|
+
await nodeFs.chown(path, uid, gid);
|
|
59
|
+
},
|
|
60
|
+
async rename(oldPath, newPath) {
|
|
61
|
+
await nodeFs.rename(oldPath, newPath);
|
|
62
|
+
},
|
|
63
|
+
async copyFile(srcPath, destPath) {
|
|
64
|
+
await nodeFs.copyFile(srcPath, destPath);
|
|
65
|
+
},
|
|
66
|
+
async exists(path) {
|
|
67
|
+
try {
|
|
68
|
+
await nodeFs.stat(path);
|
|
69
|
+
return true;
|
|
70
|
+
} catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
return defaultFs;
|
|
76
|
+
})();
|
|
77
|
+
return fsLoading;
|
|
78
|
+
}
|
|
79
|
+
function createAsyncValueParser(options, metavar, parseFn, suggestFn) {
|
|
80
|
+
return {
|
|
81
|
+
$mode: "async",
|
|
82
|
+
metavar,
|
|
83
|
+
async parse(input) {
|
|
84
|
+
const fs = options?.fs ?? await getDefaultFs();
|
|
85
|
+
const dir = options?.dir ?? (typeof process !== "undefined" ? process.cwd() : ".");
|
|
86
|
+
ensureNonEmptyString(metavar);
|
|
87
|
+
return parseFn(fs, dir, input);
|
|
88
|
+
},
|
|
89
|
+
format(value) {
|
|
90
|
+
return value;
|
|
91
|
+
},
|
|
92
|
+
async *suggest(prefix) {
|
|
93
|
+
const fs = options?.fs ?? await getDefaultFs();
|
|
94
|
+
const dir = options?.dir ?? (typeof process !== "undefined" ? process.cwd() : ".");
|
|
95
|
+
if (suggestFn) yield* suggestFn(fs, dir, prefix);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Creates a value parser that validates local branch names.
|
|
101
|
+
*
|
|
102
|
+
* This parser uses isomorphic-git to verify that the provided input
|
|
103
|
+
* matches an existing branch in the repository.
|
|
104
|
+
*
|
|
105
|
+
* @param options Configuration options for the parser.
|
|
106
|
+
* @returns A value parser that accepts existing branch names.
|
|
107
|
+
* @since 0.9.0
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ~~~~ typescript
|
|
111
|
+
* import { gitBranch } from "@optique/git";
|
|
112
|
+
* import { argument } from "@optique/core/primitives";
|
|
113
|
+
*
|
|
114
|
+
* const parser = argument(gitBranch());
|
|
115
|
+
* ~~~~
|
|
116
|
+
*/
|
|
117
|
+
function gitBranch(options) {
|
|
118
|
+
const metavar = options?.metavar ?? METAVAR_BRANCH;
|
|
119
|
+
return createAsyncValueParser(options, metavar, async (fs, dir, input) => {
|
|
120
|
+
try {
|
|
121
|
+
const branches = await git.listBranches({
|
|
122
|
+
fs,
|
|
123
|
+
dir
|
|
124
|
+
});
|
|
125
|
+
if (branches.includes(input)) return {
|
|
126
|
+
success: true,
|
|
127
|
+
value: input
|
|
128
|
+
};
|
|
129
|
+
return {
|
|
130
|
+
success: false,
|
|
131
|
+
error: message`Branch ${text(input)} does not exist. Available branches: ${branches.join(", ")}`
|
|
132
|
+
};
|
|
133
|
+
} catch {
|
|
134
|
+
return {
|
|
135
|
+
success: false,
|
|
136
|
+
error: message`Failed to list branches. Ensure ${text(dir)} is a valid git repository.`
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}, async function* suggestBranch(fs, dir, prefix) {
|
|
140
|
+
try {
|
|
141
|
+
const branches = await git.listBranches({
|
|
142
|
+
fs,
|
|
143
|
+
dir
|
|
144
|
+
});
|
|
145
|
+
for (const branch of branches) if (branch.startsWith(prefix)) yield {
|
|
146
|
+
kind: "literal",
|
|
147
|
+
text: branch
|
|
148
|
+
};
|
|
149
|
+
} catch {}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Creates a value parser that validates remote branch names.
|
|
154
|
+
*
|
|
155
|
+
* This parser uses isomorphic-git to verify that the provided input
|
|
156
|
+
* matches an existing branch on the specified remote.
|
|
157
|
+
*
|
|
158
|
+
* @param remote The remote name to validate against.
|
|
159
|
+
* @param options Configuration options for the parser.
|
|
160
|
+
* @returns A value parser that accepts existing remote branch names.
|
|
161
|
+
* @since 0.9.0
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ~~~~ typescript
|
|
165
|
+
* import { gitRemoteBranch } from "@optique/git";
|
|
166
|
+
* import { option } from "@optique/core/primitives";
|
|
167
|
+
*
|
|
168
|
+
* const parser = option("-b", "--branch", gitRemoteBranch("origin"));
|
|
169
|
+
* ~~~~
|
|
170
|
+
*/
|
|
171
|
+
function gitRemoteBranch(remote, options) {
|
|
172
|
+
const metavar = options?.metavar ?? METAVAR_BRANCH;
|
|
173
|
+
return createAsyncValueParser(options, metavar, async (fs, dir, input) => {
|
|
174
|
+
try {
|
|
175
|
+
const branches = await git.listBranches({
|
|
176
|
+
fs,
|
|
177
|
+
dir,
|
|
178
|
+
remote
|
|
179
|
+
});
|
|
180
|
+
if (branches.includes(input)) return {
|
|
181
|
+
success: true,
|
|
182
|
+
value: input
|
|
183
|
+
};
|
|
184
|
+
return {
|
|
185
|
+
success: false,
|
|
186
|
+
error: message`Remote branch ${text(input)} does not exist on remote ${text(remote)}. Available branches: ${branches.join(", ")}`
|
|
187
|
+
};
|
|
188
|
+
} catch {
|
|
189
|
+
return {
|
|
190
|
+
success: false,
|
|
191
|
+
error: message`Failed to list remote branches. Ensure remote ${text(remote)} exists.`
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}, async function* suggestRemoteBranch(fs, dir, prefix) {
|
|
195
|
+
try {
|
|
196
|
+
const branches = await git.listBranches({
|
|
197
|
+
fs,
|
|
198
|
+
dir,
|
|
199
|
+
remote
|
|
200
|
+
});
|
|
201
|
+
for (const branch of branches) if (branch.startsWith(prefix)) yield {
|
|
202
|
+
kind: "literal",
|
|
203
|
+
text: branch
|
|
204
|
+
};
|
|
205
|
+
} catch {}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Creates a value parser that validates tag names.
|
|
210
|
+
*
|
|
211
|
+
* This parser uses isomorphic-git to verify that the provided input
|
|
212
|
+
* matches an existing tag in the repository.
|
|
213
|
+
*
|
|
214
|
+
* @param options Configuration options for the parser.
|
|
215
|
+
* @returns A value parser that accepts existing tag names.
|
|
216
|
+
* @since 0.9.0
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ~~~~ typescript
|
|
220
|
+
* import { gitTag } from "@optique/git";
|
|
221
|
+
* import { option } from "@optique/core/primitives";
|
|
222
|
+
*
|
|
223
|
+
* const parser = option("-t", "--tag", gitTag());
|
|
224
|
+
* ~~~~
|
|
225
|
+
*/
|
|
226
|
+
function gitTag(options) {
|
|
227
|
+
const metavar = options?.metavar ?? METAVAR_TAG;
|
|
228
|
+
return createAsyncValueParser(options, metavar, async (fs, dir, input) => {
|
|
229
|
+
try {
|
|
230
|
+
const tags = await git.listTags({
|
|
231
|
+
fs,
|
|
232
|
+
dir
|
|
233
|
+
});
|
|
234
|
+
if (tags.includes(input)) return {
|
|
235
|
+
success: true,
|
|
236
|
+
value: input
|
|
237
|
+
};
|
|
238
|
+
return {
|
|
239
|
+
success: false,
|
|
240
|
+
error: message`Tag ${text(input)} does not exist. Available tags: ${tags.join(", ")}`
|
|
241
|
+
};
|
|
242
|
+
} catch {
|
|
243
|
+
return {
|
|
244
|
+
success: false,
|
|
245
|
+
error: message`Failed to list tags. Ensure ${text(dir)} is a valid git repository.`
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
}, async function* suggestTag(fs, dir, prefix) {
|
|
249
|
+
try {
|
|
250
|
+
const tags = await git.listTags({
|
|
251
|
+
fs,
|
|
252
|
+
dir
|
|
253
|
+
});
|
|
254
|
+
for (const tag of tags) if (tag.startsWith(prefix)) yield {
|
|
255
|
+
kind: "literal",
|
|
256
|
+
text: tag
|
|
257
|
+
};
|
|
258
|
+
} catch {}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Creates a value parser that validates remote names.
|
|
263
|
+
*
|
|
264
|
+
* This parser uses isomorphic-git to verify that the provided input
|
|
265
|
+
* matches an existing remote in the repository.
|
|
266
|
+
*
|
|
267
|
+
* @param options Configuration options for the parser.
|
|
268
|
+
* @returns A value parser that accepts existing remote names.
|
|
269
|
+
* @since 0.9.0
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ~~~~ typescript
|
|
273
|
+
* import { gitRemote } from "@optique/git";
|
|
274
|
+
* import { option } from "@optique/core/primitives";
|
|
275
|
+
*
|
|
276
|
+
* const parser = option("-r", "--remote", gitRemote());
|
|
277
|
+
* ~~~~
|
|
278
|
+
*/
|
|
279
|
+
function gitRemote(options) {
|
|
280
|
+
const metavar = options?.metavar ?? METAVAR_REMOTE;
|
|
281
|
+
return createAsyncValueParser(options, metavar, async (fs, dir, input) => {
|
|
282
|
+
try {
|
|
283
|
+
const remotes = await git.listRemotes({
|
|
284
|
+
fs,
|
|
285
|
+
dir
|
|
286
|
+
});
|
|
287
|
+
const remoteNames = [];
|
|
288
|
+
for (const r of remotes) if ("remote" in r && typeof r.remote === "string") remoteNames.push(r.remote);
|
|
289
|
+
if (remoteNames.includes(input)) return {
|
|
290
|
+
success: true,
|
|
291
|
+
value: input
|
|
292
|
+
};
|
|
293
|
+
return {
|
|
294
|
+
success: false,
|
|
295
|
+
error: message`Remote ${text(input)} does not exist. Available remotes: ${remoteNames.join(", ")}`
|
|
296
|
+
};
|
|
297
|
+
} catch {
|
|
298
|
+
return {
|
|
299
|
+
success: false,
|
|
300
|
+
error: message`Failed to list remotes. Ensure ${text(dir)} is a valid git repository.`
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
}, async function* suggestRemote(fs, dir, prefix) {
|
|
304
|
+
try {
|
|
305
|
+
const remotes = await git.listRemotes({
|
|
306
|
+
fs,
|
|
307
|
+
dir
|
|
308
|
+
});
|
|
309
|
+
for (const r of remotes) if ("remote" in r && typeof r.remote === "string" && r.remote.startsWith(prefix)) yield {
|
|
310
|
+
kind: "literal",
|
|
311
|
+
text: r.remote
|
|
312
|
+
};
|
|
313
|
+
} catch {}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Creates a value parser that validates commit SHAs.
|
|
318
|
+
*
|
|
319
|
+
* This parser uses isomorphic-git to verify that the provided input
|
|
320
|
+
* is a valid commit SHA (full or shortened) that exists in the repository.
|
|
321
|
+
*
|
|
322
|
+
* @param options Configuration options for the parser.
|
|
323
|
+
* @returns A value parser that accepts valid commit SHAs.
|
|
324
|
+
* @since 0.9.0
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* ~~~~ typescript
|
|
328
|
+
* import { gitCommit } from "@optique/git";
|
|
329
|
+
* import { option } from "@optique/core/primitives";
|
|
330
|
+
*
|
|
331
|
+
* const parser = option("-c", "--commit", gitCommit());
|
|
332
|
+
* ~~~~
|
|
333
|
+
*/
|
|
334
|
+
function gitCommit(options) {
|
|
335
|
+
const metavar = options?.metavar ?? "COMMIT";
|
|
336
|
+
return createAsyncValueParser(options, metavar, async (fs, dir, input) => {
|
|
337
|
+
try {
|
|
338
|
+
const oid = await git.expandOid({
|
|
339
|
+
fs,
|
|
340
|
+
dir,
|
|
341
|
+
oid: input
|
|
342
|
+
});
|
|
343
|
+
await git.readObject({
|
|
344
|
+
fs,
|
|
345
|
+
dir,
|
|
346
|
+
oid
|
|
347
|
+
});
|
|
348
|
+
return {
|
|
349
|
+
success: true,
|
|
350
|
+
value: oid
|
|
351
|
+
};
|
|
352
|
+
} catch {
|
|
353
|
+
return {
|
|
354
|
+
success: false,
|
|
355
|
+
error: message`Commit ${text(input)} does not exist. Provide a valid commit SHA.`
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
}, async function* suggestCommit(fs, dir, prefix) {
|
|
359
|
+
try {
|
|
360
|
+
const branches = await git.listBranches({
|
|
361
|
+
fs,
|
|
362
|
+
dir
|
|
363
|
+
});
|
|
364
|
+
const commits = [];
|
|
365
|
+
for (const branch of branches.slice(0, 10)) try {
|
|
366
|
+
const oid = await git.resolveRef({
|
|
367
|
+
fs,
|
|
368
|
+
dir,
|
|
369
|
+
ref: branch
|
|
370
|
+
});
|
|
371
|
+
if (oid.startsWith(prefix)) commits.push(oid);
|
|
372
|
+
} catch {}
|
|
373
|
+
for (const commit of [...new Set(commits)].slice(0, 10)) yield {
|
|
374
|
+
kind: "literal",
|
|
375
|
+
text: commit
|
|
376
|
+
};
|
|
377
|
+
} catch {}
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Creates a value parser that validates any git reference
|
|
382
|
+
* (branches, tags, or commits).
|
|
383
|
+
*
|
|
384
|
+
* This parser uses isomorphic-git to verify that the provided input
|
|
385
|
+
* resolves to a valid git reference (branch, tag, or commit SHA).
|
|
386
|
+
*
|
|
387
|
+
* @param options Configuration options for the parser.
|
|
388
|
+
* @returns A value parser that accepts branches, tags, or commit SHAs.
|
|
389
|
+
* @since 0.9.0
|
|
390
|
+
*
|
|
391
|
+
* @example
|
|
392
|
+
* ~~~~ typescript
|
|
393
|
+
* import { gitRef } from "@optique/git";
|
|
394
|
+
* import { option } from "@optique/core/primitives";
|
|
395
|
+
*
|
|
396
|
+
* const parser = option("--ref", gitRef());
|
|
397
|
+
* ~~~~
|
|
398
|
+
*/
|
|
399
|
+
function gitRef(options) {
|
|
400
|
+
const metavar = options?.metavar ?? "REF";
|
|
401
|
+
return createAsyncValueParser(options, metavar, async (fs, dir, input) => {
|
|
402
|
+
try {
|
|
403
|
+
const oid = await git.resolveRef({
|
|
404
|
+
fs,
|
|
405
|
+
dir,
|
|
406
|
+
ref: input
|
|
407
|
+
});
|
|
408
|
+
return {
|
|
409
|
+
success: true,
|
|
410
|
+
value: oid
|
|
411
|
+
};
|
|
412
|
+
} catch {
|
|
413
|
+
return {
|
|
414
|
+
success: false,
|
|
415
|
+
error: message`Reference ${text(input)} does not exist. Provide a valid branch, tag, or commit SHA.`
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
}, async function* suggestRef(fs, dir, prefix) {
|
|
419
|
+
try {
|
|
420
|
+
const branches = await git.listBranches({
|
|
421
|
+
fs,
|
|
422
|
+
dir
|
|
423
|
+
});
|
|
424
|
+
for (const branch of branches) if (branch.startsWith(prefix)) yield {
|
|
425
|
+
kind: "literal",
|
|
426
|
+
text: branch
|
|
427
|
+
};
|
|
428
|
+
const tags = await git.listTags({
|
|
429
|
+
fs,
|
|
430
|
+
dir
|
|
431
|
+
});
|
|
432
|
+
for (const tag of tags) if (tag.startsWith(prefix)) yield {
|
|
433
|
+
kind: "literal",
|
|
434
|
+
text: tag
|
|
435
|
+
};
|
|
436
|
+
} catch {}
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Creates a factory for git parsers with shared configuration.
|
|
441
|
+
*
|
|
442
|
+
* This function returns an object with methods for creating individual git
|
|
443
|
+
* parsers that share the same configuration (filesystem and directory).
|
|
444
|
+
*
|
|
445
|
+
* @param options Shared configuration options for all parsers.
|
|
446
|
+
* @returns An object with methods for creating individual git parsers.
|
|
447
|
+
* @since 0.9.0
|
|
448
|
+
*
|
|
449
|
+
* @example
|
|
450
|
+
* ~~~~ typescript
|
|
451
|
+
* import { createGitParsers } from "@optique/git";
|
|
452
|
+
*
|
|
453
|
+
* const git = createGitParsers({ dir: "/path/to/repo" });
|
|
454
|
+
*
|
|
455
|
+
* const branchParser = git.branch();
|
|
456
|
+
* const tagParser = git.tag();
|
|
457
|
+
* ~~~~
|
|
458
|
+
*/
|
|
459
|
+
function createGitParsers(options) {
|
|
460
|
+
return {
|
|
461
|
+
branch: (parserOptions) => gitBranch({
|
|
462
|
+
...options,
|
|
463
|
+
...parserOptions
|
|
464
|
+
}),
|
|
465
|
+
remoteBranch: (remote, parserOptions) => gitRemoteBranch(remote, {
|
|
466
|
+
...options,
|
|
467
|
+
...parserOptions
|
|
468
|
+
}),
|
|
469
|
+
tag: (parserOptions) => gitTag({
|
|
470
|
+
...options,
|
|
471
|
+
...parserOptions
|
|
472
|
+
}),
|
|
473
|
+
remote: (parserOptions) => gitRemote({
|
|
474
|
+
...options,
|
|
475
|
+
...parserOptions
|
|
476
|
+
}),
|
|
477
|
+
commit: (parserOptions) => gitCommit({
|
|
478
|
+
...options,
|
|
479
|
+
...parserOptions
|
|
480
|
+
}),
|
|
481
|
+
ref: (parserOptions) => gitRef({
|
|
482
|
+
...options,
|
|
483
|
+
...parserOptions
|
|
484
|
+
})
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
//#endregion
|
|
489
|
+
export { createGitParsers, expandOid, gitBranch, gitCommit, gitRef, gitRemote, gitRemoteBranch, gitTag, listBranches, listRemotes, listTags, readObject, resolveRef };
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@optique/git",
|
|
3
|
+
"version": "0.9.0-dev.1",
|
|
4
|
+
"description": "Git value parsers for Optique",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"CLI",
|
|
7
|
+
"command-line",
|
|
8
|
+
"commandline",
|
|
9
|
+
"parser",
|
|
10
|
+
"git",
|
|
11
|
+
"git-reference",
|
|
12
|
+
"branch",
|
|
13
|
+
"tag",
|
|
14
|
+
"commit"
|
|
15
|
+
],
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"author": {
|
|
18
|
+
"name": "Hong Minhee",
|
|
19
|
+
"email": "hong@minhee.org",
|
|
20
|
+
"url": "https://hongminhee.org/"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://optique.dev/",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/dahlia/optique.git",
|
|
26
|
+
"directory": "packages/git/"
|
|
27
|
+
},
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/dahlia/optique/issues"
|
|
30
|
+
},
|
|
31
|
+
"funding": [
|
|
32
|
+
"https://github.com/sponsors/dahlia"
|
|
33
|
+
],
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=20.0.0",
|
|
36
|
+
"bun": ">=1.2.0",
|
|
37
|
+
"deno": ">=2.3.0"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist/",
|
|
41
|
+
"package.json",
|
|
42
|
+
"README.md"
|
|
43
|
+
],
|
|
44
|
+
"type": "module",
|
|
45
|
+
"module": "./dist/index.js",
|
|
46
|
+
"main": "./dist/index.cjs",
|
|
47
|
+
"types": "./dist/index.d.ts",
|
|
48
|
+
"exports": {
|
|
49
|
+
".": {
|
|
50
|
+
"types": {
|
|
51
|
+
"import": "./dist/index.d.ts",
|
|
52
|
+
"require": "./dist/index.d.cts"
|
|
53
|
+
},
|
|
54
|
+
"import": "./dist/index.js",
|
|
55
|
+
"require": "./dist/index.cjs"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"sideEffects": false,
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"isomorphic-git": "^1.36.1",
|
|
61
|
+
"@optique/core": ""
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@types/node": "^20.19.9",
|
|
65
|
+
"tsdown": "^0.13.0",
|
|
66
|
+
"typescript": "^5.8.3"
|
|
67
|
+
},
|
|
68
|
+
"scripts": {
|
|
69
|
+
"build": "tsdown",
|
|
70
|
+
"prepublish": "tsdown",
|
|
71
|
+
"test": "tsdown && node --experimental-transform-types --test",
|
|
72
|
+
"test:bun": "tsdown && bun test",
|
|
73
|
+
"test:deno": "deno test",
|
|
74
|
+
"test-all": "tsdown && node --experimental-transform-types --test && bun test && deno test"
|
|
75
|
+
}
|
|
76
|
+
}
|