@finbheara/archive-client 0.0.0-stage → 0.1.0
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 +21 -0
- package/README.md +358 -2
- package/dist/chunks/index-hghdy980.js +75 -0
- package/dist/chunks/index-hne1wadw.js +57 -0
- package/dist/chunks/index-zr8tfjk0.js +2357 -0
- package/dist/cli.js +699 -0
- package/dist/config.js +21 -0
- package/dist/index.js +99 -0
- package/dist/tag.js +19 -0
- package/dist/types/assets.d.ts +40 -0
- package/dist/types/bytes.d.ts +3 -0
- package/dist/types/cli.d.ts +24 -0
- package/dist/types/comps.d.ts +127 -0
- package/dist/types/config.d.ts +16 -0
- package/dist/types/dancers-names.d.ts +5 -0
- package/dist/types/dancers.d.ts +138 -0
- package/dist/types/feises.d.ts +84 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/indexes.d.ts +31 -0
- package/dist/types/manager.d.ts +94 -0
- package/dist/types/people.d.ts +65 -0
- package/dist/types/pin.d.ts +8 -0
- package/dist/types/registrations.d.ts +60 -0
- package/dist/types/release.d.ts +70 -0
- package/dist/types/remote.d.ts +16 -0
- package/dist/types/results.d.ts +82 -0
- package/dist/types/schools.d.ts +42 -0
- package/dist/types/tag.d.ts +24 -0
- package/package.json +52 -5
package/dist/cli.js
ADDED
|
@@ -0,0 +1,699 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
import {
|
|
4
|
+
nameOrderOf,
|
|
5
|
+
openRelease2,
|
|
6
|
+
releases2
|
|
7
|
+
} from "./chunks/index-zr8tfjk0.js";
|
|
8
|
+
import"./chunks/index-hne1wadw.js";
|
|
9
|
+
import"./chunks/index-hghdy980.js";
|
|
10
|
+
|
|
11
|
+
var USAGE = `usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json]
|
|
12
|
+
|
|
13
|
+
config repo <owner/name> set the user-local repository the releases come from
|
|
14
|
+
list [--remote] the cached releases (size, files, indexes, the pin), and
|
|
15
|
+
with --remote the published tags
|
|
16
|
+
fetch [--release <spec>] [--assets results,majors,<file>...]
|
|
17
|
+
download, verify and cache a release (default: results)
|
|
18
|
+
pin <spec> the user-local pin: what a bare open (spec "pinned") opens
|
|
19
|
+
unpin remove the pin (a bare open is then "latest")
|
|
20
|
+
current the pin, and whether it is cached
|
|
21
|
+
add <dir> --tag <tag> add a release built locally (its MANIFEST.json and files)
|
|
22
|
+
to the cache under its tag
|
|
23
|
+
index [--release <spec>] [<name>...] [--force]
|
|
24
|
+
build the per-tag indexes (default: every one)
|
|
25
|
+
verify [--release <spec>] re-hash every cached file against its receipt
|
|
26
|
+
prune [--keep N] [--dry-run] remove all but the N newest cached releases (default 1)
|
|
27
|
+
and the pinned one
|
|
28
|
+
rm <tag> [--dry-run] remove one cached release (not the pinned one)
|
|
29
|
+
drop-indexes [<tag>] [--dry-run] remove the index files (of one release, or of every one)
|
|
30
|
+
feis [--release <spec>] [--platform <p>] [--code <c>] [--id <id>] [--name <glob>] [--year <y>]
|
|
31
|
+
the feises a query names
|
|
32
|
+
series [--release <spec>] <name|host code|feis id>
|
|
33
|
+
the series a name, a host code (fweb:ABC) or any feis id
|
|
34
|
+
names: its years, hosts, codes and next instance
|
|
35
|
+
school [--release <spec>] <print|school_id> [--region <code>]
|
|
36
|
+
a school print or id to the published schools
|
|
37
|
+
dancer [--release <spec>] <name> | --surname <s> | --like <glob> | --id <dancer_id>
|
|
38
|
+
[--order surname-first|given-first] [--school <print|id>]
|
|
39
|
+
[--yob <y> | --band <U10> [--year <y>] | --comp <competition>] [--as-of <date>]
|
|
40
|
+
[--rows] the dancers a name reaches, each with its evidence
|
|
41
|
+
(name level, age, school) and the arm; the results of
|
|
42
|
+
the one dancer where one answers (or --rows for each)
|
|
43
|
+
results [--release <spec>] [--dancer <id>] [--feis <id>] [--comp <competition>]
|
|
44
|
+
[--school <print|id>] [--year <y>] [--limit <n>]
|
|
45
|
+
the published result rows, prints and ids
|
|
46
|
+
majors [--release <spec>] [--event <e>] [--year <y>] [--comp <competition>] [--dancer <id>]
|
|
47
|
+
the majors: every event and its years; an event's
|
|
48
|
+
competitions; a competition's, an event's or a dancer's rows
|
|
49
|
+
teacher [--release <spec>] <name|TD number>
|
|
50
|
+
the staff lists' people: where they taught, the register,
|
|
51
|
+
where they sat
|
|
52
|
+
adjudicator [--release <spec>] <name|TD number>
|
|
53
|
+
the register's and the panels' people: the same answer
|
|
54
|
+
comp [--release <spec>] <feis> <code> [--year <y>] [--title <t>]
|
|
55
|
+
a feis's own comp code to the comp it names, through that
|
|
56
|
+
feis's syllabus (or the prior year's)
|
|
57
|
+
syllabus [--release <spec>] <feis> [year]
|
|
58
|
+
one feis-year's comps, in printed order
|
|
59
|
+
syllabus [--release <spec>] --for <series> [year]
|
|
60
|
+
a series' syllabus for a year: that year's where held,
|
|
61
|
+
else the newest, saying which and what it is read from
|
|
62
|
+
resolve comp [<feis> <code>] [--year <y>] [--title <t>]
|
|
63
|
+
resolve dancer [<name>] [--school <s>] [--comp <feis>/<code> | --yob <y> | --band <b> --year <y>]
|
|
64
|
+
[--order <o>] [--as-of <date>]
|
|
65
|
+
resolve registrations
|
|
66
|
+
JSONL out, one answer per line; with no positional the
|
|
67
|
+
questions are JSONL on stdin, one per line (a comp:
|
|
68
|
+
{feis, code, year?, title?}, a dancer: {name, school?, age?},
|
|
69
|
+
a registration: {name, school?, codes[], feis, year?})
|
|
70
|
+
|
|
71
|
+
<spec>: pinned (the default) | latest | a cut (42, 42.1) | a tag (archive-YYYY.MM.DD-N)`;
|
|
72
|
+
var VALUE = new Set([
|
|
73
|
+
"--cache",
|
|
74
|
+
"--repo",
|
|
75
|
+
"--release",
|
|
76
|
+
"--assets",
|
|
77
|
+
"--tag",
|
|
78
|
+
"--keep",
|
|
79
|
+
"--platform",
|
|
80
|
+
"--code",
|
|
81
|
+
"--id",
|
|
82
|
+
"--name",
|
|
83
|
+
"--year",
|
|
84
|
+
"--region",
|
|
85
|
+
"--order",
|
|
86
|
+
"--surname",
|
|
87
|
+
"--like",
|
|
88
|
+
"--school",
|
|
89
|
+
"--yob",
|
|
90
|
+
"--band",
|
|
91
|
+
"--comp",
|
|
92
|
+
"--as-of",
|
|
93
|
+
"--dancer",
|
|
94
|
+
"--feis",
|
|
95
|
+
"--limit",
|
|
96
|
+
"--event",
|
|
97
|
+
"--title",
|
|
98
|
+
"--for"
|
|
99
|
+
]);
|
|
100
|
+
function parseArgs(argv) {
|
|
101
|
+
const positional = [];
|
|
102
|
+
const flags = new Map;
|
|
103
|
+
const bools = new Set;
|
|
104
|
+
for (let i = 0;i < argv.length; i++) {
|
|
105
|
+
const a = argv[i];
|
|
106
|
+
if (a.startsWith("--")) {
|
|
107
|
+
const eq = a.indexOf("=");
|
|
108
|
+
if (eq !== -1)
|
|
109
|
+
flags.set(a.slice(0, eq), a.slice(eq + 1));
|
|
110
|
+
else if (VALUE.has(a)) {
|
|
111
|
+
const v = argv[i + 1];
|
|
112
|
+
if (v === undefined)
|
|
113
|
+
throw new Error(`${a} takes a value`);
|
|
114
|
+
flags.set(a, v);
|
|
115
|
+
i++;
|
|
116
|
+
} else
|
|
117
|
+
bools.add(a);
|
|
118
|
+
} else
|
|
119
|
+
positional.push(a);
|
|
120
|
+
}
|
|
121
|
+
return { positional, flags, bools };
|
|
122
|
+
}
|
|
123
|
+
var mb = (n) => `${(n / 1e6).toFixed(1)} MB`;
|
|
124
|
+
function printPlan(p, say) {
|
|
125
|
+
for (const k of p.keep)
|
|
126
|
+
say(`keep ${k.tag} (${k.why})`);
|
|
127
|
+
for (const r of p.remove)
|
|
128
|
+
say(`${p.dryRun ? "would remove" : "removed"} ${r.path} ${mb(r.bytes)} (${r.why})`);
|
|
129
|
+
say(`${p.dryRun ? "would free" : "freed"} ${mb(p.bytes)}${p.dryRun ? " (dry run: nothing removed)" : ""}`);
|
|
130
|
+
}
|
|
131
|
+
function printCached(c, say) {
|
|
132
|
+
say(`${c.pinned ? "*" : " "} ${c.tag} ${mb(c.bytes)} from ${c.source}`);
|
|
133
|
+
for (const f of c.files)
|
|
134
|
+
say(` ${f.name} ${mb(f.bytes)} verified: ${f.verified.length > 0 ? f.verified.join("+") : "none"}`);
|
|
135
|
+
for (const i of c.indexes)
|
|
136
|
+
say(` index/${i.name}.sqlite ${mb(i.bytes)} ${i.current === null ? "no builder" : i.current ? "current" : "stale"}`);
|
|
137
|
+
}
|
|
138
|
+
var span = (lo, hi) => lo === null ? "-" : lo === hi ? `${lo}` : `${lo}-${hi ?? "?"}`;
|
|
139
|
+
function printCandidate(c, say, pad = " ") {
|
|
140
|
+
say(`${pad}${c.dancer_id} ${c.display}${c.scope === "per-release" ? " [per-release id]" : ""} score ${c.score} name ${c.evidence.nameLevel} age ${c.evidence.age} school ${c.evidence.school}`);
|
|
141
|
+
say(`${pad} ${c.rows} rows ${span(c.year_lo, c.year_hi)} born ${span(c.birth.lo, c.birth.hi)} (${c.birth.source}) school ${c.school === null ? "-" : `${c.school.school_id ?? "(no id)"} "${c.school.print}" ${span(c.school.year_lo, c.school.year_hi)}`}`);
|
|
142
|
+
say(`${pad} prints ${c.prints.slice(0, 5).map((p) => `"${p.print}" (${p.rows}, ${p.level})`).join(", ")}${c.prints.length > 5 ? `, +${c.prints.length - 5} more` : ""}`);
|
|
143
|
+
}
|
|
144
|
+
function printDancers(a, say) {
|
|
145
|
+
say(`${a.arm} "${a.asked.name}" in ${a.tag} ${a.candidates.length} candidate(s)${a.refused !== undefined ? ` (refused: ${a.refused})` : ""}`);
|
|
146
|
+
if (a.age !== undefined)
|
|
147
|
+
say(` age asked: ${a.age.read ?? "(unread)"}${a.age.birth !== null ? ` born ${a.age.birth.from ?? "?"}-${a.age.birth.to ?? "?"}` : ""}${a.age.note !== undefined ? ` (${a.age.note})` : ""}`);
|
|
148
|
+
if (a.school !== undefined)
|
|
149
|
+
say(` school asked: ${a.school.arm} ${a.school.ids.join(", ") || "-"}`);
|
|
150
|
+
for (const c of a.candidates)
|
|
151
|
+
printCandidate(c, say);
|
|
152
|
+
if (a.preferred !== undefined)
|
|
153
|
+
say(` preferred (non-binding, the arm stands): ${a.preferred.dancer_id}, ${a.preferred.why}`);
|
|
154
|
+
for (const x of a.excluded.slice(0, 10)) {
|
|
155
|
+
const c = x.candidate;
|
|
156
|
+
say(` excluded (${x.why}) ${c.dancer_id} ${c.display} name ${c.evidence.nameLevel} born ${span(c.birth.lo, c.birth.hi)} school ${c.school?.school_id ?? "-"} ${c.rows} rows`);
|
|
157
|
+
}
|
|
158
|
+
if (a.excluded.length > 10)
|
|
159
|
+
say(` excluded: ${a.excluded.length - 10} more (--json lists them)`);
|
|
160
|
+
if (a.unlinked.length > 0)
|
|
161
|
+
say(` unlinked rows (no dancer id): ${a.unlinked.slice(0, 5).map((u) => `"${u.print}" (${u.rows})`).join(", ")}`);
|
|
162
|
+
}
|
|
163
|
+
function printResults(a, say) {
|
|
164
|
+
for (const r of a.rows)
|
|
165
|
+
say(` ${r.year ?? "?"} ${r.event} ${r.competition} ${r.title ?? "-"} [${r.age ?? "-"}] place ${r.place_printed}${r.competitors !== null ? `/${r.competitors}` : ""} "${r.name_printed}" ${r.dancer_id ?? "-"}${r.dancer_scope === "per-release" ? "*" : ""} "${r.school_printed}" ${r.school_id ?? "-"} ${r.address}`);
|
|
166
|
+
if (a.rows.some((r) => r.dancer_scope === "per-release"))
|
|
167
|
+
say(" * a feis-local dancer id: valid in this release only");
|
|
168
|
+
say(`${a.rows.length} row(s) from ${a.db} in ${a.tag}${a.truncated > 0 ? `, ${a.truncated} more past the limit` : ""}`);
|
|
169
|
+
}
|
|
170
|
+
function printStaff(a, say) {
|
|
171
|
+
say(`${a.arm} ${a.role} "${a.asked}" in ${a.tag}${a.refused !== undefined ? ` (refused: ${a.refused})` : ""}`);
|
|
172
|
+
for (const p of a.people) {
|
|
173
|
+
say(` ${[p.clrg !== null ? `TD ${p.clrg}` : null, p.judge_id !== null ? `judge id ${p.judge_id}` : null].filter((x) => x !== null).join(", ") || "(no number)"} by ${p.nameLevel} ${p.names.map((n) => `"${n}"`).join(", ")}`);
|
|
174
|
+
for (const t of p.taught)
|
|
175
|
+
say(` taught ${t.school_id} ${t.school ?? "?"} ${t.role ?? "-"}${t.credentials.length > 0 ? ` ${t.credentials.join("/")}` : ""} years ${t.years.join(",") || "-"}${t.former ? " former" : ""}${t.provisional ? " provisional" : ""}`);
|
|
176
|
+
for (const t of p.td_links)
|
|
177
|
+
say(` TD listed at ${t.school_id} ${t.school ?? "?"} (${t.via}, ${t.captured})`);
|
|
178
|
+
if (p.register.length > 0) {
|
|
179
|
+
const last = p.register[p.register.length - 1];
|
|
180
|
+
say(` register ${p.register.map((r) => r.year).join(",")} cat ${last?.cat} ${last?.region_code ?? last?.region} "${last?.name_printed}"`);
|
|
181
|
+
}
|
|
182
|
+
for (const s of p.sat)
|
|
183
|
+
say(` sat ${s.kind} ${s.event ?? "(no rows)"} ${s.year ?? "?"}: ${s.seats} seats, ${s.competitions} competitions`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async function schoolIdOf(rel, school) {
|
|
187
|
+
const a = await rel.schools.resolve(school);
|
|
188
|
+
if (a.arm !== "unique")
|
|
189
|
+
throw new Error(`school "${school}" is ${a.arm} in ${a.tag}${a.candidates.length > 0 ? `: ${a.candidates.map((c) => c.school_id).join(", ")}` : ""}`);
|
|
190
|
+
return a.candidates[0].school_id;
|
|
191
|
+
}
|
|
192
|
+
function printComp(a, say) {
|
|
193
|
+
const where = a.from !== undefined ? ` from ${a.from.year} (${a.from.feis_ids.join(", ")})` : "";
|
|
194
|
+
const check = a.check === undefined ? "" : a.check === "unchecked" ? " (title unchecked)" : ` (title ${a.check.agrees ? "agrees" : "differs"}: age ${a.check.age}, population ${a.check.population})`;
|
|
195
|
+
say(`${a.arm} ${a.asked.feis} ${a.asked.code} by ${a.source ?? "-"}${where}${a.syllabus_source !== null ? `, syllabus read from ${a.syllabus_source}` : ""} in ${a.tag}${check}${a.why !== undefined ? ` (${a.why})` : ""}`);
|
|
196
|
+
for (const c of a.candidates)
|
|
197
|
+
say(` ${c.competition} ${c.kind} ${c.level ?? "-"} ${c.age ?? "-"} ${c.population ?? "-"} ${c.canonical ?? "-"} "${c.title ?? ""}"`);
|
|
198
|
+
}
|
|
199
|
+
function jsonLines(text, check) {
|
|
200
|
+
const out = [];
|
|
201
|
+
for (const [i, l] of text.split(`
|
|
202
|
+
`).entries()) {
|
|
203
|
+
if (l.trim() === "")
|
|
204
|
+
continue;
|
|
205
|
+
let v;
|
|
206
|
+
try {
|
|
207
|
+
v = JSON.parse(l);
|
|
208
|
+
} catch (e) {
|
|
209
|
+
out.push({ line: i + 1, error: `not JSON: ${e.message}` });
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
if (v === null || typeof v !== "object" || Array.isArray(v)) {
|
|
213
|
+
out.push({ line: i + 1, error: "not a JSON object" });
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
const why = check(v);
|
|
217
|
+
out.push(why === null ? { line: i + 1, value: v } : { line: i + 1, error: why });
|
|
218
|
+
}
|
|
219
|
+
return out;
|
|
220
|
+
}
|
|
221
|
+
var checkComp = (q) => typeof q.feis !== "string" || q.feis.trim() === "" ? "a comp question needs feis" : q.code === undefined || q.code === null || String(q.code).trim() === "" ? "a comp question needs code" : null;
|
|
222
|
+
var checkDancer = (q) => typeof q.name !== "string" || q.name.trim() === "" ? "a dancer question needs name" : null;
|
|
223
|
+
var checkRegistration = (r) => typeof r.name !== "string" || r.name.trim() === "" ? "a registration row needs name" : typeof r.feis !== "string" || r.feis.trim() === "" ? "a registration row needs feis" : !Array.isArray(r.codes) ? "a registration row needs codes[]" : null;
|
|
224
|
+
async function resolveVerb(rel, what, args, p, say, stdin) {
|
|
225
|
+
const year = p.flags.has("--year") ? Number(p.flags.get("--year")) : undefined;
|
|
226
|
+
const emit = (v) => say(JSON.stringify(v));
|
|
227
|
+
let errors = 0;
|
|
228
|
+
const each = async (qs, answer) => {
|
|
229
|
+
for (const q of qs) {
|
|
230
|
+
if ("error" in q) {
|
|
231
|
+
errors++;
|
|
232
|
+
emit({ tag: rel.tag, line: q.line, error: q.error });
|
|
233
|
+
} else
|
|
234
|
+
emit(await answer(q.value));
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
switch (what) {
|
|
238
|
+
case "comp": {
|
|
239
|
+
const qs = args.length > 0 ? [
|
|
240
|
+
{
|
|
241
|
+
line: 0,
|
|
242
|
+
value: {
|
|
243
|
+
feis: args[0],
|
|
244
|
+
code: args[1] ?? "",
|
|
245
|
+
...year !== undefined ? { year } : {},
|
|
246
|
+
...p.flags.has("--title") ? { title: p.flags.get("--title") } : {}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
] : jsonLines(await stdin(), checkComp);
|
|
250
|
+
if (args.length > 0 && checkComp(qs[0].value) !== null)
|
|
251
|
+
throw new Error("resolve comp <feis> <code>");
|
|
252
|
+
let none = 0;
|
|
253
|
+
await each(qs, async (q) => {
|
|
254
|
+
const a = await rel.comps.resolve({ ...q, code: String(q.code) });
|
|
255
|
+
if (a.arm === "none")
|
|
256
|
+
none++;
|
|
257
|
+
return a;
|
|
258
|
+
});
|
|
259
|
+
return errors > 0 || args.length > 0 && none === 1 ? 1 : 0;
|
|
260
|
+
}
|
|
261
|
+
case "dancer": {
|
|
262
|
+
let qs;
|
|
263
|
+
if (args.length > 0) {
|
|
264
|
+
const comp = p.flags.get("--comp");
|
|
265
|
+
let age;
|
|
266
|
+
if (comp !== undefined)
|
|
267
|
+
age = { comp, ...year !== undefined ? { year } : {} };
|
|
268
|
+
else if (p.flags.has("--yob"))
|
|
269
|
+
age = { yob: Number(p.flags.get("--yob")) };
|
|
270
|
+
else if (p.flags.has("--band"))
|
|
271
|
+
age = { band: p.flags.get("--band"), year: year ?? null };
|
|
272
|
+
qs = [
|
|
273
|
+
{
|
|
274
|
+
line: 0,
|
|
275
|
+
value: {
|
|
276
|
+
name: args.join(" "),
|
|
277
|
+
...nameOrderOf(p.flags.get("--order")) !== undefined ? { order: nameOrderOf(p.flags.get("--order")) } : {},
|
|
278
|
+
...p.flags.has("--school") ? { school: p.flags.get("--school") } : {},
|
|
279
|
+
...age !== undefined ? { age } : {},
|
|
280
|
+
...p.flags.has("--as-of") ? { asOf: p.flags.get("--as-of") } : {}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
];
|
|
284
|
+
} else
|
|
285
|
+
qs = jsonLines(await stdin(), checkDancer);
|
|
286
|
+
let unavailable = 0;
|
|
287
|
+
await each(qs, async (q) => {
|
|
288
|
+
const a = await rel.registrations.dancer(q);
|
|
289
|
+
if (a.dancer.arm === "unavailable")
|
|
290
|
+
unavailable++;
|
|
291
|
+
return a;
|
|
292
|
+
});
|
|
293
|
+
return errors > 0 || unavailable > 0 ? 1 : 0;
|
|
294
|
+
}
|
|
295
|
+
case "registrations": {
|
|
296
|
+
const lines = jsonLines(await stdin(), checkRegistration);
|
|
297
|
+
const ok = lines.flatMap((l) => ("value" in l) ? [l.value] : []);
|
|
298
|
+
const answers = await rel.registrations.resolve(ok.map((r) => ({ ...r, codes: r.codes.map(String) })));
|
|
299
|
+
let k = 0;
|
|
300
|
+
await each(lines, async () => answers[k++]);
|
|
301
|
+
return errors > 0 ? 1 : 0;
|
|
302
|
+
}
|
|
303
|
+
default:
|
|
304
|
+
throw new Error("resolve comp|dancer|registrations");
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
async function main(argv, io = {}) {
|
|
308
|
+
const say = io.say ?? ((s) => console.log(s));
|
|
309
|
+
const log = io.log ?? ((s) => console.error(s));
|
|
310
|
+
let p;
|
|
311
|
+
try {
|
|
312
|
+
p = parseArgs(argv);
|
|
313
|
+
} catch (e) {
|
|
314
|
+
log(e.message);
|
|
315
|
+
return 2;
|
|
316
|
+
}
|
|
317
|
+
const [verb, ...rest] = p.positional;
|
|
318
|
+
const json = p.bools.has("--json");
|
|
319
|
+
const dryRun = p.bools.has("--dry-run");
|
|
320
|
+
const opts = {
|
|
321
|
+
...io.opts,
|
|
322
|
+
log,
|
|
323
|
+
...p.flags.has("--cache") ? { cache: p.flags.get("--cache") } : {},
|
|
324
|
+
...p.flags.has("--repo") ? { repo: p.flags.get("--repo") } : {}
|
|
325
|
+
};
|
|
326
|
+
const spec = p.flags.get("--release") ?? "pinned";
|
|
327
|
+
const m = releases2(opts);
|
|
328
|
+
const out = (v, text) => {
|
|
329
|
+
if (json)
|
|
330
|
+
say(JSON.stringify(v, null, 2));
|
|
331
|
+
else
|
|
332
|
+
text();
|
|
333
|
+
};
|
|
334
|
+
try {
|
|
335
|
+
switch (verb) {
|
|
336
|
+
case "config": {
|
|
337
|
+
if (rest[0] !== "repo" || rest[1] === undefined) {
|
|
338
|
+
out(m.readConfig(), () => say(JSON.stringify(m.readConfig())));
|
|
339
|
+
return rest.length === 0 ? 0 : 2;
|
|
340
|
+
}
|
|
341
|
+
const c = m.config({ repo: rest[1] });
|
|
342
|
+
out(c, () => say(`repo ${c.repo}`));
|
|
343
|
+
return 0;
|
|
344
|
+
}
|
|
345
|
+
case "list": {
|
|
346
|
+
const l = await m.list({ remote: p.bools.has("--remote") });
|
|
347
|
+
out(l, () => {
|
|
348
|
+
say(`cache ${l.root} repo ${l.repo ?? "(none)"} pin ${l.pin?.tag ?? "(none: latest)"}`);
|
|
349
|
+
for (const c of l.cached)
|
|
350
|
+
printCached(c, say);
|
|
351
|
+
if (l.cached.length === 0)
|
|
352
|
+
say(" (nothing cached)");
|
|
353
|
+
if (l.published !== undefined)
|
|
354
|
+
say(`published: ${l.published.length} tags, newest ${l.published.slice(0, 5).join(", ")}`);
|
|
355
|
+
});
|
|
356
|
+
return 0;
|
|
357
|
+
}
|
|
358
|
+
case "fetch": {
|
|
359
|
+
const assets = (p.flags.get("--assets") ?? "results").split(",").filter((a) => a !== "");
|
|
360
|
+
const rel = await m.fetch(spec, { assets });
|
|
361
|
+
const files = rel.receipt().files;
|
|
362
|
+
out({ tag: rel.tag, dir: rel.dir, files }, () => {
|
|
363
|
+
say(`${rel.tag} ${rel.dir}`);
|
|
364
|
+
for (const [name, f] of Object.entries(files))
|
|
365
|
+
say(` ${name} ${mb(f.bytes)} sha256 ${f.sha256.slice(0, 12)} verified: ${f.verified.join("+") || "none"}`);
|
|
366
|
+
});
|
|
367
|
+
rel.close();
|
|
368
|
+
return 0;
|
|
369
|
+
}
|
|
370
|
+
case "pin": {
|
|
371
|
+
if (rest[0] === undefined) {
|
|
372
|
+
log("pin <spec>");
|
|
373
|
+
return 2;
|
|
374
|
+
}
|
|
375
|
+
const pin = await m.pin(rest[0]);
|
|
376
|
+
out(pin, () => say(`pinned ${pin.tag} (from ${pin.source})`));
|
|
377
|
+
return 0;
|
|
378
|
+
}
|
|
379
|
+
case "unpin": {
|
|
380
|
+
const was = m.unpin();
|
|
381
|
+
out({ unpinned: was }, () => say(was ? "unpinned" : "no pin was set"));
|
|
382
|
+
return 0;
|
|
383
|
+
}
|
|
384
|
+
case "current": {
|
|
385
|
+
const c = m.current();
|
|
386
|
+
out(c, () => say(c.pin === null ? "no pin: a bare open is latest" : `pinned ${c.pin.tag}${c.cached ? "" : " (not cached)"}`));
|
|
387
|
+
return 0;
|
|
388
|
+
}
|
|
389
|
+
case "add": {
|
|
390
|
+
const tag = p.flags.get("--tag");
|
|
391
|
+
if (rest[0] === undefined || tag === undefined) {
|
|
392
|
+
log("add <dir> --tag <tag>");
|
|
393
|
+
return 2;
|
|
394
|
+
}
|
|
395
|
+
const rel = await m.add(rest[0], tag);
|
|
396
|
+
out({ tag: rel.tag, dir: rel.dir, files: rel.receipt().files }, () => say(`added ${rel.tag} at ${rel.dir}`));
|
|
397
|
+
return 0;
|
|
398
|
+
}
|
|
399
|
+
case "index": {
|
|
400
|
+
const r = await m.index(spec, rest, { force: p.bools.has("--force") });
|
|
401
|
+
out(r, () => {
|
|
402
|
+
for (const b of r.built)
|
|
403
|
+
say(`${r.tag} ${b.name} ${b.path}`);
|
|
404
|
+
});
|
|
405
|
+
return 0;
|
|
406
|
+
}
|
|
407
|
+
case "verify": {
|
|
408
|
+
const tag = (await m.fetch(spec, { assets: [] })).tag;
|
|
409
|
+
const bad = await m.verify(tag);
|
|
410
|
+
out({ tag, bad }, () => {
|
|
411
|
+
say(bad.length === 0 ? `${tag}: every cached file matches its receipt` : `${tag}: ${bad.length} differ`);
|
|
412
|
+
for (const b of bad)
|
|
413
|
+
say(` ${b.file}: want ${b.want}, got ${b.got}`);
|
|
414
|
+
});
|
|
415
|
+
return bad.length === 0 ? 0 : 1;
|
|
416
|
+
}
|
|
417
|
+
case "prune": {
|
|
418
|
+
const keep = p.flags.has("--keep") ? Number(p.flags.get("--keep")) : undefined;
|
|
419
|
+
const plan = m.prune({ ...keep !== undefined ? { keep } : {}, dryRun });
|
|
420
|
+
out(plan, () => printPlan(plan, say));
|
|
421
|
+
return 0;
|
|
422
|
+
}
|
|
423
|
+
case "rm": {
|
|
424
|
+
if (rest[0] === undefined) {
|
|
425
|
+
log("rm <tag>");
|
|
426
|
+
return 2;
|
|
427
|
+
}
|
|
428
|
+
const plan = m.remove(rest[0], { dryRun });
|
|
429
|
+
out(plan, () => printPlan(plan, say));
|
|
430
|
+
return 0;
|
|
431
|
+
}
|
|
432
|
+
case "drop-indexes": {
|
|
433
|
+
const plan = m.dropIndexes(rest[0], { dryRun });
|
|
434
|
+
out(plan, () => printPlan(plan, say));
|
|
435
|
+
return 0;
|
|
436
|
+
}
|
|
437
|
+
case "feis": {
|
|
438
|
+
const rel = await openRelease2(spec, { ...opts, assets: [] });
|
|
439
|
+
const year = p.flags.get("--year");
|
|
440
|
+
const a = await rel.feises.find({
|
|
441
|
+
...p.flags.has("--platform") ? { platform: p.flags.get("--platform") } : {},
|
|
442
|
+
...p.flags.has("--code") ? { code: p.flags.get("--code") } : {},
|
|
443
|
+
...p.flags.has("--id") ? { id: p.flags.get("--id") } : {},
|
|
444
|
+
...p.flags.has("--name") ? { name: p.flags.get("--name") } : {},
|
|
445
|
+
...year !== undefined ? { year: Number(year) } : {}
|
|
446
|
+
});
|
|
447
|
+
out(a, () => {
|
|
448
|
+
if (a.redirected !== undefined)
|
|
449
|
+
say(`(${a.redirected.from} is now ${a.redirected.to})`);
|
|
450
|
+
for (const f of a.feises)
|
|
451
|
+
say(`${f.feis_id} ${f.date_lo ?? "?"} ${f.name} [${f.regions.join(",") || "-"}] ${f.competitions} comps, ${f.rows} rows series ${f.instance_id ?? "-"}`);
|
|
452
|
+
say(`${a.feises.length} feis(es) in ${a.tag}`);
|
|
453
|
+
});
|
|
454
|
+
rel.close();
|
|
455
|
+
return a.feises.length > 0 ? 0 : 1;
|
|
456
|
+
}
|
|
457
|
+
case "series": {
|
|
458
|
+
if (rest[0] === undefined) {
|
|
459
|
+
log("series <name|host code|feis id>");
|
|
460
|
+
return 2;
|
|
461
|
+
}
|
|
462
|
+
const rel = await openRelease2(spec, { ...opts, assets: [] });
|
|
463
|
+
const a = await rel.feises.series(rest.join(" "));
|
|
464
|
+
out(a, () => {
|
|
465
|
+
say(`${a.arm} "${a.asked}" via ${a.via ?? "-"} in ${a.tag}${a.redirected !== undefined ? ` (${a.redirected.from} -> ${a.redirected.to})` : ""}${a.why !== undefined ? ` (${a.why})` : ""}`);
|
|
466
|
+
for (const c of a.candidates) {
|
|
467
|
+
say(` ${c.series_id} ${c.name} host ${c.hosts.join(",")} codes ${c.codes.join(",")}`);
|
|
468
|
+
for (const i of c.instances)
|
|
469
|
+
say(` ${i.year ?? "?"} ${i.date_lo ?? "?"} ${i.feis_ids.join(", ")}`);
|
|
470
|
+
}
|
|
471
|
+
if (a.arm === "unique")
|
|
472
|
+
say(` next: ${a.next === null ? `unknown (${a.next_why ?? ""})` : `${a.next.feis_id ?? "?"} ${a.next.date}`}`);
|
|
473
|
+
});
|
|
474
|
+
rel.close();
|
|
475
|
+
return a.arm === "none" ? 1 : 0;
|
|
476
|
+
}
|
|
477
|
+
case "school": {
|
|
478
|
+
if (rest[0] === undefined) {
|
|
479
|
+
log("school <print|school_id> [--region <code>]");
|
|
480
|
+
return 2;
|
|
481
|
+
}
|
|
482
|
+
const rel = await openRelease2(spec, { ...opts, assets: [] });
|
|
483
|
+
const region = p.flags.get("--region");
|
|
484
|
+
const a = await rel.schools.resolve(rest.join(" "), region !== undefined ? { region } : {});
|
|
485
|
+
out(a, () => {
|
|
486
|
+
say(`${a.arm} "${a.asked}" in ${a.tag}${a.refused !== undefined ? ` (refused: ${a.refused})` : ""}${a.redirected !== undefined ? ` (${a.redirected.from} -> ${a.redirected.to})` : ""}${a.region !== undefined ? ` (region ${a.region.asked}${a.region.narrowed ? " narrowed" : " did not narrow"})` : ""}`);
|
|
487
|
+
for (const c of a.candidates)
|
|
488
|
+
say(` ${c.school_id} ${c.display ?? "?"} by ${c.by} ${c.rows} rows regions ${c.regions.join(",") || "-"} prints ${c.prints.slice(0, 4).map((x) => `"${x}"`).join(", ")}`);
|
|
489
|
+
});
|
|
490
|
+
rel.close();
|
|
491
|
+
return a.arm === "none" ? 1 : 0;
|
|
492
|
+
}
|
|
493
|
+
case "dancer": {
|
|
494
|
+
const rel = await openRelease2(spec, { ...opts, assets: [] });
|
|
495
|
+
try {
|
|
496
|
+
const id = p.flags.get("--id");
|
|
497
|
+
if (id !== undefined) {
|
|
498
|
+
const d = await rel.dancers.get(Number(id));
|
|
499
|
+
const rows = d === null ? null : await rel.results.query({ dancer_id: d.dancer_id });
|
|
500
|
+
out({ dancer: d, results: rows }, () => {
|
|
501
|
+
if (d === null) {
|
|
502
|
+
say(`no dancer ${id} in ${rel.tag}`);
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
say(`${d.dancer_id} ${d.display}${d.scope === "per-release" ? " [per-release id]" : ""} ${d.kind ?? "-"} ${d.rows} rows ${span(d.year_lo, d.year_hi)} born ${span(d.birth.lo, d.birth.hi)} (${d.birth.source}${d.birth.conflict ? ", conflict" : ""}) ${d.genders} in ${d.tag}`);
|
|
506
|
+
say(` prints ${d.prints.map((x) => `"${x.print}" (${x.rows}, ${span(x.year_lo, x.year_hi)})`).join(", ")}`);
|
|
507
|
+
for (const s of d.schools)
|
|
508
|
+
say(` school ${s.school_id ?? "(no id)"} "${s.print}" ${s.rows} rows ${span(s.year_lo, s.year_hi)}`);
|
|
509
|
+
if (rows !== null)
|
|
510
|
+
printResults(rows, say);
|
|
511
|
+
});
|
|
512
|
+
return d === null ? 1 : 0;
|
|
513
|
+
}
|
|
514
|
+
const order = p.flags.get("--order");
|
|
515
|
+
const yob = p.flags.get("--yob");
|
|
516
|
+
const band = p.flags.get("--band");
|
|
517
|
+
const comp = p.flags.get("--comp");
|
|
518
|
+
const year = p.flags.get("--year");
|
|
519
|
+
const age = yob !== undefined ? { yob: Number(yob) } : band !== undefined ? { band, ...year !== undefined ? { year: Number(year) } : {} } : comp !== undefined ? { comp } : undefined;
|
|
520
|
+
const facets = {
|
|
521
|
+
...order !== undefined ? { order } : {},
|
|
522
|
+
...p.flags.has("--school") ? { school: p.flags.get("--school") } : {},
|
|
523
|
+
...age !== undefined ? { age } : {},
|
|
524
|
+
...p.flags.has("--as-of") ? { asOf: p.flags.get("--as-of") } : {},
|
|
525
|
+
...p.flags.has("--limit") ? { limit: Number(p.flags.get("--limit")) } : {}
|
|
526
|
+
};
|
|
527
|
+
const surname = p.flags.get("--surname");
|
|
528
|
+
const like = p.flags.get("--like");
|
|
529
|
+
if (surname === undefined && like === undefined && rest.length === 0) {
|
|
530
|
+
log("dancer <name> | --surname <s> | --like <glob> | --id <dancer_id>");
|
|
531
|
+
return 2;
|
|
532
|
+
}
|
|
533
|
+
const a = await rel.dancers.search(surname !== undefined ? { ...facets, surname } : like !== undefined ? { ...facets, like } : { ...facets, name: rest.join(" ") });
|
|
534
|
+
const each = p.bools.has("--rows") ? a.candidates : a.arm === "unique" ? a.candidates : [];
|
|
535
|
+
const trajectories = [];
|
|
536
|
+
for (const c of each)
|
|
537
|
+
trajectories.push(await rel.results.query({ dancer_id: c.dancer_id }));
|
|
538
|
+
out({ ...a, results: trajectories }, () => {
|
|
539
|
+
printDancers(a, say);
|
|
540
|
+
for (const t of trajectories) {
|
|
541
|
+
say(`results of ${t.asked.dancer_id}:`);
|
|
542
|
+
printResults(t, say);
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
return a.candidates.length === 0 ? 1 : 0;
|
|
546
|
+
} finally {
|
|
547
|
+
rel.close();
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
case "results": {
|
|
551
|
+
const rel = await openRelease2(spec, { ...opts, assets: [] });
|
|
552
|
+
try {
|
|
553
|
+
const q = {
|
|
554
|
+
...p.flags.has("--dancer") ? { dancer_id: Number(p.flags.get("--dancer")) } : {},
|
|
555
|
+
...p.flags.has("--feis") ? { feis: p.flags.get("--feis") } : {},
|
|
556
|
+
...p.flags.has("--comp") ? { competition: p.flags.get("--comp") } : {},
|
|
557
|
+
...p.flags.has("--school") ? { school_id: await schoolIdOf(rel, p.flags.get("--school")) } : {},
|
|
558
|
+
...p.flags.has("--year") ? { year: Number(p.flags.get("--year")) } : {},
|
|
559
|
+
...p.flags.has("--limit") ? { limit: Number(p.flags.get("--limit")) } : {}
|
|
560
|
+
};
|
|
561
|
+
const a = await rel.results.query(q);
|
|
562
|
+
out(a, () => printResults(a, say));
|
|
563
|
+
return a.rows.length === 0 ? 1 : 0;
|
|
564
|
+
} finally {
|
|
565
|
+
rel.close();
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
case "majors": {
|
|
569
|
+
const rel = await openRelease2(spec, { ...opts, assets: [] });
|
|
570
|
+
try {
|
|
571
|
+
const event = p.flags.get("--event");
|
|
572
|
+
const year = p.flags.get("--year");
|
|
573
|
+
const comp = p.flags.get("--comp");
|
|
574
|
+
const dancer = p.flags.get("--dancer");
|
|
575
|
+
if (comp !== undefined || dancer !== undefined || event !== undefined && p.bools.has("--rows")) {
|
|
576
|
+
const a = await rel.majors.results({
|
|
577
|
+
...comp !== undefined ? { competition: comp } : {},
|
|
578
|
+
...dancer !== undefined ? { dancer_id: Number(dancer) } : {},
|
|
579
|
+
...event !== undefined ? { feis: event } : {},
|
|
580
|
+
...year !== undefined ? { year: Number(year) } : {},
|
|
581
|
+
...p.flags.has("--limit") ? { limit: Number(p.flags.get("--limit")) } : {}
|
|
582
|
+
});
|
|
583
|
+
out(a, () => printResults(a, say));
|
|
584
|
+
return a.rows.length === 0 ? 1 : 0;
|
|
585
|
+
}
|
|
586
|
+
if (event !== undefined) {
|
|
587
|
+
const a = await rel.majors.competitions({
|
|
588
|
+
event,
|
|
589
|
+
...year !== undefined ? { year: Number(year) } : {}
|
|
590
|
+
});
|
|
591
|
+
out(a, () => {
|
|
592
|
+
for (const c of a.competitions)
|
|
593
|
+
say(` ${c.year ?? "?"} ${c.competition} ${c.comp_no ?? "-"} ${c.title ?? "-"} [${c.age ?? "-"}] ${c.gender ?? ""} ${c.rows} rows`);
|
|
594
|
+
say(`${a.competitions.length} competition(s) in ${a.tag}`);
|
|
595
|
+
});
|
|
596
|
+
return a.competitions.length === 0 ? 1 : 0;
|
|
597
|
+
}
|
|
598
|
+
const a = await rel.majors.events();
|
|
599
|
+
out(a, () => {
|
|
600
|
+
for (const e of a.events)
|
|
601
|
+
say(` ${e.event} ${e.years.length} year(s) ${span(e.years[0] ?? null, e.years[e.years.length - 1] ?? null)} ${e.competitions} comps ${e.rows} rows`);
|
|
602
|
+
say(`${a.events.length} event(s) in ${a.tag}`);
|
|
603
|
+
});
|
|
604
|
+
return 0;
|
|
605
|
+
} finally {
|
|
606
|
+
rel.close();
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
case "teacher":
|
|
610
|
+
case "adjudicator": {
|
|
611
|
+
if (rest.length === 0) {
|
|
612
|
+
log(`${verb} <name|TD number>`);
|
|
613
|
+
return 2;
|
|
614
|
+
}
|
|
615
|
+
const rel = await openRelease2(spec, { ...opts, assets: [] });
|
|
616
|
+
try {
|
|
617
|
+
const a = verb === "teacher" ? await rel.staff.teacher(rest.join(" ")) : await rel.staff.adjudicator(rest.join(" "));
|
|
618
|
+
out(a, () => printStaff(a, say));
|
|
619
|
+
return a.arm === "none" ? 1 : 0;
|
|
620
|
+
} finally {
|
|
621
|
+
rel.close();
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
case "comp": {
|
|
625
|
+
if (rest[0] === undefined || rest[1] === undefined) {
|
|
626
|
+
log("comp <feis> <code> [--year <y>] [--title <t>]");
|
|
627
|
+
return 2;
|
|
628
|
+
}
|
|
629
|
+
const rel = await openRelease2(spec, { ...opts, assets: [] });
|
|
630
|
+
const year = p.flags.get("--year");
|
|
631
|
+
const a = await rel.comps.resolve({
|
|
632
|
+
feis: rest[0],
|
|
633
|
+
code: rest[1],
|
|
634
|
+
...year !== undefined ? { year: Number(year) } : {},
|
|
635
|
+
...p.flags.has("--title") ? { title: p.flags.get("--title") } : {}
|
|
636
|
+
});
|
|
637
|
+
out(a, () => printComp(a, say));
|
|
638
|
+
rel.close();
|
|
639
|
+
return a.arm === "none" ? 1 : 0;
|
|
640
|
+
}
|
|
641
|
+
case "syllabus": {
|
|
642
|
+
const of = p.flags.get("--for");
|
|
643
|
+
if (of !== undefined) {
|
|
644
|
+
const y = rest[0] ?? p.flags.get("--year");
|
|
645
|
+
const rel = await openRelease2(spec, { ...opts, assets: [] });
|
|
646
|
+
const a = await rel.comps.syllabusFor(of, y !== undefined ? Number(y) : undefined);
|
|
647
|
+
out(a, () => {
|
|
648
|
+
say(`${a.arm} ${a.asked.series} asked ${a.asked.year ?? "-"} read ${a.year ?? "-"} (${a.held ? "held" : "not held"}) from ${a.source ?? "-"} series ${a.series_id ?? "-"} (years ${a.years.join(", ") || "-"}) in ${a.tag}`);
|
|
649
|
+
if (a.why !== undefined)
|
|
650
|
+
say(` ${a.why}`);
|
|
651
|
+
if (a.note !== undefined)
|
|
652
|
+
say(` note: ${a.note}`);
|
|
653
|
+
for (const c of a.entries)
|
|
654
|
+
say(` ${c.code} ${c.kind} ${c.level ?? "-"} ${c.age ?? "-"} ${c.population ?? "-"} ${c.canonical ?? "-"} "${c.title ?? ""}"`);
|
|
655
|
+
say(`${a.entries.length} comp(s), ${a.championships} championship(s)`);
|
|
656
|
+
});
|
|
657
|
+
rel.close();
|
|
658
|
+
return a.entries.length > 0 ? 0 : 1;
|
|
659
|
+
}
|
|
660
|
+
if (rest[0] === undefined) {
|
|
661
|
+
log("syllabus <feis> [year]");
|
|
662
|
+
return 2;
|
|
663
|
+
}
|
|
664
|
+
const rel = await openRelease2(spec, { ...opts, assets: [] });
|
|
665
|
+
const a = await rel.comps.syllabus(rest[0], rest[1] !== undefined ? Number(rest[1]) : undefined);
|
|
666
|
+
out(a, () => {
|
|
667
|
+
say(`${a.feis.asked} ${a.year ?? "?"} ${a.held ? `held: ${a.feis.feis_ids.join(", ")}` : "not held"} series ${a.feis.brand_id ?? "-"} (years ${a.years.join(", ") || "-"}) in ${a.tag}`);
|
|
668
|
+
for (const c of a.entries)
|
|
669
|
+
say(` ${c.code} ${c.kind} ${c.level ?? "-"} ${c.age ?? "-"} ${c.population ?? "-"} "${c.title ?? ""}"`);
|
|
670
|
+
say(`${a.entries.length} comp(s)`);
|
|
671
|
+
});
|
|
672
|
+
rel.close();
|
|
673
|
+
return a.held ? 0 : 1;
|
|
674
|
+
}
|
|
675
|
+
case "resolve": {
|
|
676
|
+
const rel = await openRelease2(spec, { ...opts, assets: [] });
|
|
677
|
+
try {
|
|
678
|
+
return await resolveVerb(rel, rest[0], rest.slice(1), p, say, io.stdin ?? (() => Bun.stdin.text()));
|
|
679
|
+
} finally {
|
|
680
|
+
rel.close();
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
default:
|
|
684
|
+
say(USAGE);
|
|
685
|
+
return verb === undefined || verb === "help" ? 0 : 2;
|
|
686
|
+
}
|
|
687
|
+
} catch (e) {
|
|
688
|
+
log(`idq ${verb}: ${e.message}`);
|
|
689
|
+
return 1;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
if (import.meta.main)
|
|
693
|
+
process.exit(await main(process.argv.slice(2)));
|
|
694
|
+
export {
|
|
695
|
+
USAGE,
|
|
696
|
+
jsonLines,
|
|
697
|
+
main,
|
|
698
|
+
parseArgs
|
|
699
|
+
};
|