@finbheara/archive-client 0.25.0 → 0.26.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/README.md +48 -2
- package/dist/chunks/{index-2ms980hc.js → index-8mwx3n9j.js} +298 -5
- package/dist/cli.js +83 -2
- package/dist/index.js +7 -1
- package/dist/types/feises.d.ts +9 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/release.d.ts +2 -0
- package/dist/types/upcoming.d.ts +138 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -95,6 +95,8 @@ c.features; // [{ feature: "dancers", state: "full" | "missing", missing: [...
|
|
|
95
95
|
| `teams` | `teams.results`, `teams.rosters`, `teams.resultRosters` | 260 |
|
|
96
96
|
| `teams.fields` | the fields `teams.results` (`age`, `gender`, `printed_status`) and `teams.rosters` (`dance`, `school_printed_as_of`, a member's `gender`) carry; absent, never refused, without it | 266 |
|
|
97
97
|
| `events` | `events.years` | 260 |
|
|
98
|
+
| `upcoming.feises` | `upcoming.feises`, and the `next` of `feises.series` (null with the reason without it) | 285 |
|
|
99
|
+
| `upcoming.fields`, `upcoming.entrants` | `upcoming.fields`, `upcoming.entrants` (285 and 290 carry the tables empty) | 291 |
|
|
98
100
|
| `tabs`, `panels` | `tabs.query`, `tabs.stream`; `panels.query` | 184 |
|
|
99
101
|
| `feis-panels` | `feisPanels.query` | 260 |
|
|
100
102
|
| `staff.adjudicators` | `staff.adjudicators` | 230 |
|
|
@@ -208,8 +210,11 @@ s.next; // the next scheduled instance where the release knows one, else n
|
|
|
208
210
|
A series is asked by any id of it (a feis, instance or brand id, a retired one followed), by a
|
|
209
211
|
host code with or without its year (held codes `<stem><yy>` whose two digits are their own year,
|
|
210
212
|
never a host id of digits alone, which is a sequence number), or by a name (a glob, or a plain word read as `*word*`). Two series answer `ambiguous` with both.
|
|
211
|
-
|
|
212
|
-
`
|
|
213
|
+
`next` is the series' earliest occurrence of the feis-index dated on or after the cut's day
|
|
214
|
+
(`rel.upcoming.feises`, state `upcoming`), under its brand id or one retired onto it: `{ feis_id,
|
|
215
|
+
date, date_hi, occurrence_id, name_printed, hosts, captured_id, series_basis }`, `feis_id` the
|
|
216
|
+
first listing's that names one. It is `null` with `next_why` where the feis-index lists none, and
|
|
217
|
+
on a release without `upcoming_feises` (feature `upcoming.feises`).
|
|
213
218
|
|
|
214
219
|
## Schools
|
|
215
220
|
|
|
@@ -648,6 +653,44 @@ every release the `teams` feature names, and `(await rel.capability("teams.field
|
|
|
648
653
|
a release has. The rows are read once per
|
|
649
654
|
release into the `teams` and `events` indexes.
|
|
650
655
|
|
|
656
|
+
## Upcoming feiseanna and their competitor lists
|
|
657
|
+
|
|
658
|
+
```ts
|
|
659
|
+
const o = await rel.upcoming.feises({ state: "upcoming", from: "2026-11-01" });
|
|
660
|
+
o.feises; // [{ occurrence_id, occurrence_ids, name_printed, date_lo, date_hi, year, hosts,
|
|
661
|
+
// feis_brand_id, feis_instance_id, series_basis, brand_candidates, captured_id, state }]
|
|
662
|
+
const f = await rel.upcoming.fields({ state: "pending" }); // state, feis, field_id, from, to
|
|
663
|
+
f.fields; // [{ field_id, feis_id, source, host_id, competition_code, count_only, occurrence_id,
|
|
664
|
+
// name_printed, date_lo, date_hi, year, feis_brand_id, comp, state,
|
|
665
|
+
// results_competitions, results_feis_ids, version, versions, captured_date, sha256,
|
|
666
|
+
// limits, entrants, stated_rows, printed_total }]
|
|
667
|
+
const e = await rel.upcoming.entrants({ field_id: "fweb:ABC26/101" }); // version: an older capture
|
|
668
|
+
e.entrants; // [{ name_printed, school_printed, school_id, yob, arm, candidates, flags,
|
|
669
|
+
// competitions, field_ids, captured_id, row_id, ... }]
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
`upcoming.feises` is every occurrence of the cut's feis-index the release holds no results of:
|
|
673
|
+
`upcoming` (dated on or after the cut's day) or `no-results` (before it), each with every
|
|
674
|
+
platform's or calendar's listing (`hosts`) and its feis series where one was named (`series_basis`
|
|
675
|
+
says how; `none` leaves `feis_brand_id` null, the unjoined ones).
|
|
676
|
+
|
|
677
|
+
A FIELD is one competition a competitor list names, `<feis_id>/<code>`, the same id on every cut. A later capture of the host is a new `version`
|
|
678
|
+
(a capture id; `versions` lists them), never a new field. `state` says how it stands on the cut:
|
|
679
|
+
`pending` (on the list), `results` (the release holds its results, `results_competitions` the
|
|
680
|
+
join), `passed` (its first day is before the cut's day and no result is held) or `withdrawn` (the
|
|
681
|
+
host's newest capture no longer lists it). `comp` is the competition reading of its code (`arm`,
|
|
682
|
+
`level`, `feis_level`, `age`, `population`, `kind`, `title`, `why`), null on a count list.
|
|
683
|
+
`limits` names what the capture cannot show (`registered-not-danced`, `paid-in-full-only`, ...).
|
|
684
|
+
|
|
685
|
+
`upcoming.entrants` answers a field's rows in one version, its current one by default. A
|
|
686
|
+
registrant carries the resolver's `arm` and `candidates`, NEVER A `dancer_id`: a list shows who
|
|
687
|
+
registered, not who danced, and a `unique` row's one candidate is read with its `flags`
|
|
688
|
+
(`initial-only`: a FeisWeb print is a surname and an initial). `count_only` marks a field read from
|
|
689
|
+
a registration-by-school page of the corpus `entrants/` part: its rows are schools' counts
|
|
690
|
+
(`level_counts`), with no names. A QuickFeis registrant list (`transcripts/*.registrationlist.jsonl`)
|
|
691
|
+
is not read into these tables yet. An unknown field or version answers no rows and says
|
|
692
|
+
why. On a release without the tables each call refuses by name.
|
|
693
|
+
|
|
651
694
|
## Teachers and adjudicators
|
|
652
695
|
|
|
653
696
|
```ts
|
|
@@ -816,6 +859,9 @@ is passed to the dancer resolver as asked (`rel.dancers`, above).
|
|
|
816
859
|
| --associations [--school <school_id>]]
|
|
817
860
|
idq teams [--release <spec>] [--event <e>] [--year <y>] [--rosters | --joins]
|
|
818
861
|
idq events [--release <spec>] [--event <e>] [--year <y>]
|
|
862
|
+
idq upcoming [--release <spec>] [--state <s,...>] [--feis <id>] [--from <date>] [--to <date>]
|
|
863
|
+
idq upcoming --entrants <field_id> [--version <capture id>]
|
|
864
|
+
idq upcoming --feises [--state upcoming|no-results] [--brand <series>] [--from <date>] [--to <date>]
|
|
819
865
|
idq teacher [--release <spec>] <name|TD number>
|
|
820
866
|
idq adjudicator [--release <spec>] <name|TD number>
|
|
821
867
|
idq comp [--release <spec>] <feis> <code> [--year y] [--title t]
|
|
@@ -201,6 +201,7 @@ var feisesIndex = {
|
|
|
201
201
|
}
|
|
202
202
|
};
|
|
203
203
|
var NO_CALENDAR2 = "the release holds a feis-year once its results are captured and carries no calendar of scheduled feiseanna";
|
|
204
|
+
var NO_UPCOMING2 = "the release's feis-index lists no occurrence of the series dated on or after the cut's day";
|
|
204
205
|
var globToLike = (g) => g.replace(/[\\%_]/g, (c) => `\\${c}`).replace(/\*/g, "%").replace(/\?/g, "_");
|
|
205
206
|
|
|
206
207
|
class FeisFinder2 {
|
|
@@ -296,6 +297,29 @@ class FeisFinder2 {
|
|
|
296
297
|
instances
|
|
297
298
|
};
|
|
298
299
|
}
|
|
300
|
+
async nextOf(brand) {
|
|
301
|
+
if ((await this.rel.capability("upcoming.feises")).state === "missing")
|
|
302
|
+
return { next: null, next_why: NO_CALENDAR2 };
|
|
303
|
+
const db = await this.rel.indexDb("feises");
|
|
304
|
+
const retired = db.query("SELECT old_id FROM redirect WHERE new_id = ? AND kind = 'brand' ORDER BY old_id").all(brand).map((r) => r.old_id);
|
|
305
|
+
let best = null;
|
|
306
|
+
for (const id of [brand, ...retired])
|
|
307
|
+
for (const o of (await this.rel.upcoming.feises({ state: "upcoming", brand: id })).feises) {
|
|
308
|
+
if (best !== null && (best.date < o.date_lo || best.date === o.date_lo && best.occurrence_id <= o.occurrence_id))
|
|
309
|
+
continue;
|
|
310
|
+
best = {
|
|
311
|
+
feis_id: o.hosts.find((h) => h.feis_id !== null)?.feis_id ?? null,
|
|
312
|
+
date: o.date_lo,
|
|
313
|
+
date_hi: o.date_hi,
|
|
314
|
+
occurrence_id: o.occurrence_id,
|
|
315
|
+
name_printed: o.name_printed,
|
|
316
|
+
hosts: o.hosts,
|
|
317
|
+
captured_id: o.captured_id,
|
|
318
|
+
series_basis: o.series_basis
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
return best === null ? { next: null, next_why: NO_UPCOMING2 } : { next: best };
|
|
322
|
+
}
|
|
299
323
|
async series(q) {
|
|
300
324
|
const asked = q.trim();
|
|
301
325
|
const answer = async (brands, via, more = {}) => {
|
|
@@ -314,8 +338,7 @@ class FeisFinder2 {
|
|
|
314
338
|
host: u?.host ?? null,
|
|
315
339
|
years: u?.years ?? [],
|
|
316
340
|
instances: u?.instances ?? [],
|
|
317
|
-
next: null,
|
|
318
|
-
...u !== null ? { next_why: NO_CALENDAR2 } : {},
|
|
341
|
+
...u !== null ? await this.nextOf(u.series_id) : { next: null },
|
|
319
342
|
candidates,
|
|
320
343
|
...arm === "ambiguous" ? { why: `${candidates.length} series answer "${asked}": ${brands.join(", ")}` } : {},
|
|
321
344
|
...more
|
|
@@ -3716,6 +3739,94 @@ var FEATURES2 = [
|
|
|
3716
3739
|
since: 260,
|
|
3717
3740
|
calls: "events.years (the events index)"
|
|
3718
3741
|
},
|
|
3742
|
+
{
|
|
3743
|
+
feature: "upcoming.feises",
|
|
3744
|
+
needs: [
|
|
3745
|
+
"occurrence_id",
|
|
3746
|
+
"occurrence_ids",
|
|
3747
|
+
"name_printed",
|
|
3748
|
+
"date_lo",
|
|
3749
|
+
"date_hi",
|
|
3750
|
+
"year",
|
|
3751
|
+
"hosts",
|
|
3752
|
+
"feis_brand_id",
|
|
3753
|
+
"feis_instance_id",
|
|
3754
|
+
"series_basis",
|
|
3755
|
+
"brand_candidates",
|
|
3756
|
+
"captured_id",
|
|
3757
|
+
"results_state"
|
|
3758
|
+
].map((c) => `results:upcoming_feises.${c}`),
|
|
3759
|
+
since: 285,
|
|
3760
|
+
calls: "upcoming.feises, the `next` of feises.series"
|
|
3761
|
+
},
|
|
3762
|
+
{
|
|
3763
|
+
feature: "upcoming.fields",
|
|
3764
|
+
needs: [
|
|
3765
|
+
"field_id",
|
|
3766
|
+
"feis_id",
|
|
3767
|
+
"source",
|
|
3768
|
+
"host_id",
|
|
3769
|
+
"competition_code",
|
|
3770
|
+
"count_only",
|
|
3771
|
+
"occurrence_id",
|
|
3772
|
+
"name_printed",
|
|
3773
|
+
"date_lo",
|
|
3774
|
+
"date_hi",
|
|
3775
|
+
"year",
|
|
3776
|
+
"feis_brand_id",
|
|
3777
|
+
"comp_arm",
|
|
3778
|
+
"comp_source",
|
|
3779
|
+
"comp_kind",
|
|
3780
|
+
"level",
|
|
3781
|
+
"feis_level",
|
|
3782
|
+
"age",
|
|
3783
|
+
"population",
|
|
3784
|
+
"comp_title",
|
|
3785
|
+
"comp_why",
|
|
3786
|
+
"state",
|
|
3787
|
+
"results_competitions",
|
|
3788
|
+
"results_feis_ids",
|
|
3789
|
+
"version",
|
|
3790
|
+
"versions",
|
|
3791
|
+
"captured_date",
|
|
3792
|
+
"sha256",
|
|
3793
|
+
"limits",
|
|
3794
|
+
"entrants",
|
|
3795
|
+
"stated_rows",
|
|
3796
|
+
"printed_total"
|
|
3797
|
+
].map((c) => `results:upcoming_fields.${c}`),
|
|
3798
|
+
since: 291,
|
|
3799
|
+
calls: "upcoming.fields (285 and 290 carry the table empty)"
|
|
3800
|
+
},
|
|
3801
|
+
{
|
|
3802
|
+
feature: "upcoming.entrants",
|
|
3803
|
+
needs: [
|
|
3804
|
+
"feis_id",
|
|
3805
|
+
"captured_id",
|
|
3806
|
+
"row_id",
|
|
3807
|
+
"source",
|
|
3808
|
+
"host_id",
|
|
3809
|
+
"row_kind",
|
|
3810
|
+
"count_only",
|
|
3811
|
+
"n",
|
|
3812
|
+
"name_printed",
|
|
3813
|
+
"school_printed",
|
|
3814
|
+
"school_id",
|
|
3815
|
+
"school_rung",
|
|
3816
|
+
"school_candidates",
|
|
3817
|
+
"competitions",
|
|
3818
|
+
"field_ids",
|
|
3819
|
+
"level_counts",
|
|
3820
|
+
"yob",
|
|
3821
|
+
"asked",
|
|
3822
|
+
"arm",
|
|
3823
|
+
"candidate_ids",
|
|
3824
|
+
"candidates",
|
|
3825
|
+
"flags"
|
|
3826
|
+
].map((c) => `results:upcoming_entrants.${c}`),
|
|
3827
|
+
since: 291,
|
|
3828
|
+
calls: "upcoming.entrants (285 and 290 carry the table empty)"
|
|
3829
|
+
},
|
|
3719
3830
|
{
|
|
3720
3831
|
feature: "staff",
|
|
3721
3832
|
needs: [
|
|
@@ -3815,14 +3926,14 @@ var FEATURES2 = [
|
|
|
3815
3926
|
}
|
|
3816
3927
|
];
|
|
3817
3928
|
async function hasNeed(probe, n) {
|
|
3818
|
-
const t = /^table:([A-Za-z_]
|
|
3929
|
+
const t = /^table:([A-Za-z_]\w*)(?:\.([A-Za-z_]\w*))?$/.exec(n);
|
|
3819
3930
|
if (t !== null) {
|
|
3820
3931
|
if (probe.tableColumns === undefined)
|
|
3821
3932
|
return false;
|
|
3822
3933
|
const cols = await probe.tableColumns(t[1]);
|
|
3823
3934
|
return t[2] === undefined ? cols.size > 0 : cols.has(t[2]);
|
|
3824
3935
|
}
|
|
3825
|
-
const m = /^(results|majors):([A-Za-z_]
|
|
3936
|
+
const m = /^(results|majors):([A-Za-z_]\w*)(?:\.([A-Za-z_]\w*))?$/.exec(n);
|
|
3826
3937
|
if (m === null)
|
|
3827
3938
|
return probe.publishes(n);
|
|
3828
3939
|
const cols = columnsOf2(await probe.db(m[1]), m[2]);
|
|
@@ -3839,6 +3950,186 @@ function needsRelease2(tag, c) {
|
|
|
3839
3950
|
return new Error(`archive-client: ${tag} is too old for ${c.feature} (${c.calls}): it lacks ${c.missing.join(", ")}. Open a release of cut ${c.since} or later`);
|
|
3840
3951
|
}
|
|
3841
3952
|
|
|
3953
|
+
var FIELD_STATES2 = ["pending", "results", "passed", "withdrawn"];
|
|
3954
|
+
var json = (s, empty) => typeof s === "string" && s !== "" ? JSON.parse(s) : empty;
|
|
3955
|
+
function fieldOf(r) {
|
|
3956
|
+
const countOnly = r.count_only === 1;
|
|
3957
|
+
return {
|
|
3958
|
+
field_id: r.field_id,
|
|
3959
|
+
feis_id: r.feis_id,
|
|
3960
|
+
source: r.source,
|
|
3961
|
+
host_id: r.host_id,
|
|
3962
|
+
competition_code: r.competition_code ?? null,
|
|
3963
|
+
count_only: countOnly,
|
|
3964
|
+
occurrence_id: r.occurrence_id ?? null,
|
|
3965
|
+
name_printed: r.name_printed,
|
|
3966
|
+
date_lo: r.date_lo ?? null,
|
|
3967
|
+
date_hi: r.date_hi ?? null,
|
|
3968
|
+
year: r.year,
|
|
3969
|
+
feis_brand_id: r.feis_brand_id ?? null,
|
|
3970
|
+
comp: r.comp_arm === null ? null : {
|
|
3971
|
+
arm: r.comp_arm,
|
|
3972
|
+
source: r.comp_source ?? null,
|
|
3973
|
+
kind: r.comp_kind ?? null,
|
|
3974
|
+
level: r.level ?? null,
|
|
3975
|
+
feis_level: r.feis_level ?? null,
|
|
3976
|
+
age: r.age ?? null,
|
|
3977
|
+
population: r.population ?? null,
|
|
3978
|
+
title: r.comp_title ?? null,
|
|
3979
|
+
why: r.comp_why ?? null
|
|
3980
|
+
},
|
|
3981
|
+
state: r.state,
|
|
3982
|
+
results_competitions: json(r.results_competitions, []),
|
|
3983
|
+
results_feis_ids: json(r.results_feis_ids, []),
|
|
3984
|
+
version: r.version,
|
|
3985
|
+
versions: json(r.versions, []),
|
|
3986
|
+
captured_date: r.captured_date,
|
|
3987
|
+
sha256: r.sha256,
|
|
3988
|
+
limits: json(r.limits, []),
|
|
3989
|
+
entrants: r.entrants,
|
|
3990
|
+
stated_rows: r.stated_rows ?? null,
|
|
3991
|
+
printed_total: json(r.printed_total, null)
|
|
3992
|
+
};
|
|
3993
|
+
}
|
|
3994
|
+
function entrantOf(r) {
|
|
3995
|
+
return {
|
|
3996
|
+
feis_id: r.feis_id,
|
|
3997
|
+
captured_id: r.captured_id,
|
|
3998
|
+
row_id: r.row_id,
|
|
3999
|
+
source: r.source,
|
|
4000
|
+
host_id: r.host_id,
|
|
4001
|
+
row_kind: r.row_kind,
|
|
4002
|
+
count_only: r.count_only === 1,
|
|
4003
|
+
n: r.n,
|
|
4004
|
+
name_printed: r.name_printed ?? null,
|
|
4005
|
+
school_printed: r.school_printed ?? null,
|
|
4006
|
+
school_id: r.school_id ?? null,
|
|
4007
|
+
school_rung: r.school_rung,
|
|
4008
|
+
school_candidates: json(r.school_candidates, []),
|
|
4009
|
+
competitions: json(r.competitions, []),
|
|
4010
|
+
field_ids: json(r.field_ids, []),
|
|
4011
|
+
level_counts: json(r.level_counts, null),
|
|
4012
|
+
yob: r.yob ?? null,
|
|
4013
|
+
asked: json(r.asked, null),
|
|
4014
|
+
arm: r.arm ?? null,
|
|
4015
|
+
candidates: json(r.candidates, []),
|
|
4016
|
+
flags: json(r.flags, [])
|
|
4017
|
+
};
|
|
4018
|
+
}
|
|
4019
|
+
function feisOf(r) {
|
|
4020
|
+
return {
|
|
4021
|
+
occurrence_id: r.occurrence_id,
|
|
4022
|
+
occurrence_ids: json(r.occurrence_ids, []),
|
|
4023
|
+
name_printed: r.name_printed,
|
|
4024
|
+
date_lo: r.date_lo,
|
|
4025
|
+
date_hi: r.date_hi ?? null,
|
|
4026
|
+
year: r.year,
|
|
4027
|
+
hosts: json(r.hosts, []),
|
|
4028
|
+
feis_brand_id: r.feis_brand_id ?? null,
|
|
4029
|
+
feis_instance_id: r.feis_instance_id ?? null,
|
|
4030
|
+
series_basis: r.series_basis,
|
|
4031
|
+
brand_candidates: json(r.brand_candidates, []),
|
|
4032
|
+
captured_id: r.captured_id,
|
|
4033
|
+
state: r.results_state
|
|
4034
|
+
};
|
|
4035
|
+
}
|
|
4036
|
+
|
|
4037
|
+
class UpcomingFinder2 {
|
|
4038
|
+
rel;
|
|
4039
|
+
constructor(rel) {
|
|
4040
|
+
this.rel = rel;
|
|
4041
|
+
}
|
|
4042
|
+
async db(feature) {
|
|
4043
|
+
await this.rel.fetch("results");
|
|
4044
|
+
await this.rel.require(feature);
|
|
4045
|
+
return this.rel.db("results");
|
|
4046
|
+
}
|
|
4047
|
+
async feises(q = {}) {
|
|
4048
|
+
const db = await this.db("upcoming.feises");
|
|
4049
|
+
const where = [];
|
|
4050
|
+
const args = [];
|
|
4051
|
+
if (q.state !== undefined) {
|
|
4052
|
+
where.push("results_state = ?");
|
|
4053
|
+
args.push(q.state);
|
|
4054
|
+
}
|
|
4055
|
+
if (q.brand !== undefined) {
|
|
4056
|
+
where.push("feis_brand_id = ?");
|
|
4057
|
+
args.push(q.brand);
|
|
4058
|
+
}
|
|
4059
|
+
if (q.from !== undefined) {
|
|
4060
|
+
where.push("date_lo >= ?");
|
|
4061
|
+
args.push(q.from);
|
|
4062
|
+
}
|
|
4063
|
+
if (q.to !== undefined) {
|
|
4064
|
+
where.push("date_lo <= ?");
|
|
4065
|
+
args.push(q.to);
|
|
4066
|
+
}
|
|
4067
|
+
const sql = `SELECT * FROM upcoming_feises${where.length > 0 ? ` WHERE ${where.join(" AND ")}` : ""} ORDER BY date_lo, occurrence_id`;
|
|
4068
|
+
const rows = db.query(sql).all(...args);
|
|
4069
|
+
return { tag: this.rel.tag, feises: rows.map(feisOf) };
|
|
4070
|
+
}
|
|
4071
|
+
async fields(q = {}) {
|
|
4072
|
+
const db = await this.db("upcoming.fields");
|
|
4073
|
+
const where = [];
|
|
4074
|
+
const args = [];
|
|
4075
|
+
if (q.state !== undefined) {
|
|
4076
|
+
const states = typeof q.state === "string" ? [q.state] : [...q.state];
|
|
4077
|
+
if (states.length === 0)
|
|
4078
|
+
return { tag: this.rel.tag, fields: [] };
|
|
4079
|
+
where.push(`state IN (${states.map(() => "?").join(", ")})`);
|
|
4080
|
+
args.push(...states);
|
|
4081
|
+
}
|
|
4082
|
+
if (q.feis !== undefined) {
|
|
4083
|
+
where.push("(feis_id = ? OR feis_brand_id = ? OR occurrence_id = ?)");
|
|
4084
|
+
args.push(q.feis, q.feis, q.feis);
|
|
4085
|
+
}
|
|
4086
|
+
if (q.field_id !== undefined) {
|
|
4087
|
+
where.push("field_id = ?");
|
|
4088
|
+
args.push(q.field_id);
|
|
4089
|
+
}
|
|
4090
|
+
if (q.from !== undefined) {
|
|
4091
|
+
where.push("date_lo >= ?");
|
|
4092
|
+
args.push(q.from);
|
|
4093
|
+
}
|
|
4094
|
+
if (q.to !== undefined) {
|
|
4095
|
+
where.push("date_lo <= ?");
|
|
4096
|
+
args.push(q.to);
|
|
4097
|
+
}
|
|
4098
|
+
const sql = `SELECT * FROM upcoming_fields${where.length > 0 ? ` WHERE ${where.join(" AND ")}` : ""} ORDER BY date_lo, feis_id, field_id`;
|
|
4099
|
+
const rows = db.query(sql).all(...args);
|
|
4100
|
+
return { tag: this.rel.tag, fields: rows.map(fieldOf) };
|
|
4101
|
+
}
|
|
4102
|
+
async entrants(q) {
|
|
4103
|
+
const [field] = (await this.fields({ field_id: q.field_id })).fields;
|
|
4104
|
+
const db = await this.db("upcoming.entrants");
|
|
4105
|
+
if (field === undefined)
|
|
4106
|
+
return {
|
|
4107
|
+
tag: this.rel.tag,
|
|
4108
|
+
field: null,
|
|
4109
|
+
version: null,
|
|
4110
|
+
entrants: [],
|
|
4111
|
+
why: `the release holds no field "${q.field_id}"`
|
|
4112
|
+
};
|
|
4113
|
+
const version = q.version ?? field.version;
|
|
4114
|
+
if (!field.versions.includes(version))
|
|
4115
|
+
return {
|
|
4116
|
+
tag: this.rel.tag,
|
|
4117
|
+
field,
|
|
4118
|
+
version,
|
|
4119
|
+
entrants: [],
|
|
4120
|
+
why: `${field.field_id} has no version ${version} (versions ${field.versions.join(", ")})`
|
|
4121
|
+
};
|
|
4122
|
+
const rows = db.query("SELECT * FROM upcoming_entrants WHERE feis_id = ? AND captured_id = ? ORDER BY row_id").all(field.feis_id, version).map(entrantOf).filter((e) => e.field_ids.includes(field.field_id));
|
|
4123
|
+
return {
|
|
4124
|
+
tag: this.rel.tag,
|
|
4125
|
+
field,
|
|
4126
|
+
version,
|
|
4127
|
+
entrants: rows,
|
|
4128
|
+
...rows.length === 0 ? { why: `${field.field_id} lists no row in version ${version}` } : {}
|
|
4129
|
+
};
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4132
|
+
|
|
3842
4133
|
function tagDir(root, tag) {
|
|
3843
4134
|
if (parseArchiveTag2(tag) === null)
|
|
3844
4135
|
throw new Error(`archive-client: "${tag}" is not a release tag (archive-YYYY.MM.DD[-N[.k]])`);
|
|
@@ -3895,6 +4186,7 @@ class Release2 {
|
|
|
3895
4186
|
registrations;
|
|
3896
4187
|
teams;
|
|
3897
4188
|
events;
|
|
4189
|
+
upcoming;
|
|
3898
4190
|
tabs;
|
|
3899
4191
|
panels;
|
|
3900
4192
|
feisPanels;
|
|
@@ -3920,6 +4212,7 @@ class Release2 {
|
|
|
3920
4212
|
this.registrations = new RegistrationResolver2(this, this.comps, opts.dancerResolver);
|
|
3921
4213
|
this.teams = new TeamFinder2(this);
|
|
3922
4214
|
this.events = new EventFinder2(this);
|
|
4215
|
+
this.upcoming = new UpcomingFinder2(this);
|
|
3923
4216
|
this.tabs = new TabFinder2(this);
|
|
3924
4217
|
this.panels = new PanelFinder2(this);
|
|
3925
4218
|
this.feisPanels = new FeisPanelFinder2(this);
|
|
@@ -4643,4 +4936,4 @@ function staleWarning2(answered, latest, floor, tags = [], command = "idq") {
|
|
|
4643
4936
|
return `answered from ${answered}. ${floorTag ?? `cut ${floor.cut}`} is required${why}: run \`${command} use ${floor.cut}\` to get it`;
|
|
4644
4937
|
}
|
|
4645
4938
|
|
|
4646
|
-
export { DATABASES2, planAsset2, sha256File2, unzstdTo2, NAME_LEVELS2, nameLevel2, NO_CALENDAR2, FeisFinder2, ADVANCEMENT_DANCES2, entryRank2, FEIS_LOCAL_ID_FLOOR2, ResultFinder2, MajorsFinder2, LINEAGE_FILE2, linksOfLineage2, releaseSchoolGraph2, readsSpanishNames2, SchoolResolver2, initialsOnly2, nameOrderOf, DancerResolver2, readPopulation2, syllabusSourceOf2, canonicalOf2, CompResolver2, TabFinder2, PanelFinder2, FeisPanelFinder2, StaffFinder2, TeamFinder2, EventFinder2, defaultBuilders2, indexPath2, indexKey2, isCurrent2, buildIndex2, ensureIndex2, listIndexes2, readPin2, youngest2, dancerResolverOf2, RegistrationResolver2, ghRemote2, httpsRemote2, fallbackRemote2, setRemote2, defaultRemote, columnsOf2, FEATURES2, capabilityOf2, needsRelease2, resolveTag2, Release2, openRelease2, openCached2, DEFAULT_KEEP2, ReleaseManager2, releases2, LOCAL_DIR2, localRoot2, newerThan2, incomplete2, releaseVersion2, pickBuild2, buildTag2, lacks, openBuild2, sweepBuilds2, LATEST_CHECK_MS2, LATEST_CHECK_BUDGET_MS2, latestCheckPath2, readLatestCheck2, latestCheck2, within, staleWarning2 };
|
|
4939
|
+
export { DATABASES2, planAsset2, sha256File2, unzstdTo2, NAME_LEVELS2, nameLevel2, NO_CALENDAR2, NO_UPCOMING2, FeisFinder2, ADVANCEMENT_DANCES2, entryRank2, FEIS_LOCAL_ID_FLOOR2, ResultFinder2, MajorsFinder2, LINEAGE_FILE2, linksOfLineage2, releaseSchoolGraph2, readsSpanishNames2, SchoolResolver2, initialsOnly2, nameOrderOf, DancerResolver2, readPopulation2, syllabusSourceOf2, canonicalOf2, CompResolver2, TabFinder2, PanelFinder2, FeisPanelFinder2, StaffFinder2, TeamFinder2, EventFinder2, defaultBuilders2, indexPath2, indexKey2, isCurrent2, buildIndex2, ensureIndex2, listIndexes2, readPin2, youngest2, dancerResolverOf2, RegistrationResolver2, ghRemote2, httpsRemote2, fallbackRemote2, setRemote2, defaultRemote, columnsOf2, FEATURES2, capabilityOf2, needsRelease2, FIELD_STATES2, UpcomingFinder2, resolveTag2, Release2, openRelease2, openCached2, DEFAULT_KEEP2, ReleaseManager2, releases2, LOCAL_DIR2, localRoot2, newerThan2, incomplete2, releaseVersion2, pickBuild2, buildTag2, lacks, openBuild2, sweepBuilds2, LATEST_CHECK_MS2, LATEST_CHECK_BUDGET_MS2, latestCheckPath2, readLatestCheck2, latestCheck2, within, staleWarning2 };
|
package/dist/cli.js
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
latestCheck2,
|
|
22
22
|
within,
|
|
23
23
|
staleWarning2
|
|
24
|
-
} from "./chunks/index-
|
|
24
|
+
} from "./chunks/index-8mwx3n9j.js";
|
|
25
25
|
import"./chunks/index-hghdy980.js";
|
|
26
26
|
|
|
27
27
|
var USAGE_HEADER = "usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json] [--live]";
|
|
@@ -360,6 +360,32 @@ var VERBS = [
|
|
|
360
360
|
" each event-year's dates and place"
|
|
361
361
|
]
|
|
362
362
|
},
|
|
363
|
+
{
|
|
364
|
+
verb: "upcoming",
|
|
365
|
+
value: [
|
|
366
|
+
"--release",
|
|
367
|
+
"--state",
|
|
368
|
+
"--feis",
|
|
369
|
+
"--from",
|
|
370
|
+
"--to",
|
|
371
|
+
"--entrants",
|
|
372
|
+
"--version",
|
|
373
|
+
"--brand"
|
|
374
|
+
],
|
|
375
|
+
bool: ["--feises"],
|
|
376
|
+
usage: [
|
|
377
|
+
" upcoming [--release <spec>] [--state pending,results,passed,withdrawn] [--feis <id>]",
|
|
378
|
+
" [--from <date>] [--to <date>]",
|
|
379
|
+
" the competitor lists' fields, each with its state, version",
|
|
380
|
+
" and competition reading; --feis a feis, series or",
|
|
381
|
+
" occurrence id",
|
|
382
|
+
" upcoming --entrants <field_id> [--version <capture id>]",
|
|
383
|
+
" a field's rows (default its current version): each",
|
|
384
|
+
" registrant's arm and candidates",
|
|
385
|
+
" upcoming --feises [--state upcoming|no-results] [--brand <series>] [--from <date>] [--to <date>]",
|
|
386
|
+
" the feis-index's occurrences the release holds no results of"
|
|
387
|
+
]
|
|
388
|
+
},
|
|
363
389
|
{
|
|
364
390
|
verb: "teacher",
|
|
365
391
|
value: ["--release"],
|
|
@@ -766,6 +792,7 @@ var ANSWERING = new Set([
|
|
|
766
792
|
"schools",
|
|
767
793
|
"teams",
|
|
768
794
|
"events",
|
|
795
|
+
"upcoming",
|
|
769
796
|
"teacher",
|
|
770
797
|
"adjudicator",
|
|
771
798
|
"comp",
|
|
@@ -1032,7 +1059,7 @@ async function main(argv, io = {}) {
|
|
|
1032
1059
|
say(` ${i.year ?? "?"} ${i.date_lo ?? "?"} ${i.feis_ids.join(", ")}`);
|
|
1033
1060
|
}
|
|
1034
1061
|
if (a.arm === "unique")
|
|
1035
|
-
say(` next: ${a.next === null ? `unknown (${a.next_why ?? ""})` : `${a.next.feis_id ?? "?"} ${a.next.date}`}`);
|
|
1062
|
+
say(` next: ${a.next === null ? `unknown (${a.next_why ?? ""})` : `${a.next.feis_id ?? "?"} ${a.next.date} ${a.next.occurrence_id} (${a.next.hosts.map((h) => h.source).join(",")}; ${a.next.series_basis})`}`);
|
|
1036
1063
|
});
|
|
1037
1064
|
rel.close();
|
|
1038
1065
|
return a.arm === "none" ? 1 : 0;
|
|
@@ -1433,6 +1460,60 @@ async function main(argv, io = {}) {
|
|
|
1433
1460
|
rel.close();
|
|
1434
1461
|
}
|
|
1435
1462
|
}
|
|
1463
|
+
case "upcoming": {
|
|
1464
|
+
const rel = await open(spec, { ...opts, assets: [] });
|
|
1465
|
+
try {
|
|
1466
|
+
const from = p.flags.get("--from");
|
|
1467
|
+
const to = p.flags.get("--to");
|
|
1468
|
+
const range = {
|
|
1469
|
+
...from !== undefined ? { from } : {},
|
|
1470
|
+
...to !== undefined ? { to } : {}
|
|
1471
|
+
};
|
|
1472
|
+
const state = p.flags.get("--state");
|
|
1473
|
+
const fieldId = p.flags.get("--entrants");
|
|
1474
|
+
if (fieldId !== undefined) {
|
|
1475
|
+
const version = p.flags.get("--version");
|
|
1476
|
+
const a = await rel.upcoming.entrants({
|
|
1477
|
+
field_id: fieldId,
|
|
1478
|
+
...version !== undefined ? { version } : {}
|
|
1479
|
+
});
|
|
1480
|
+
out(a, () => {
|
|
1481
|
+
for (const e of a.entrants)
|
|
1482
|
+
say(` ${e.arm ?? "-"} ${e.candidates.map((c) => c.dancer_id).join(",") || "-"} "${e.name_printed ?? ""}" ${e.school_id ?? "(no id)"} "${e.school_printed ?? ""}"${e.flags.length > 0 ? ` [${e.flags.join(",")}]` : ""}`);
|
|
1483
|
+
say(`${a.entrants.length} row(s) of ${a.field?.field_id ?? fieldId} version ${a.version ?? "-"}${a.why !== undefined ? ` (${a.why})` : ""} in ${a.tag}`);
|
|
1484
|
+
});
|
|
1485
|
+
return a.entrants.length === 0 ? 1 : 0;
|
|
1486
|
+
}
|
|
1487
|
+
if (p.bools.has("--feises")) {
|
|
1488
|
+
const brand = p.flags.get("--brand");
|
|
1489
|
+
const a = await rel.upcoming.feises({
|
|
1490
|
+
...state !== undefined ? { state } : {},
|
|
1491
|
+
...brand !== undefined ? { brand } : {},
|
|
1492
|
+
...range
|
|
1493
|
+
});
|
|
1494
|
+
out(a, () => {
|
|
1495
|
+
for (const f of a.feises)
|
|
1496
|
+
say(` ${f.date_lo} ${f.occurrence_id} "${f.name_printed}" ${f.feis_brand_id ?? "(no series)"} (${f.series_basis}) ${f.hosts.map((h) => h.feis_id ?? `${h.source}:${h.host_id}`).join(", ")} [${f.state}]`);
|
|
1497
|
+
say(`${a.feises.length} feis occurrence(s) in ${a.tag}`);
|
|
1498
|
+
});
|
|
1499
|
+
return a.feises.length === 0 ? 1 : 0;
|
|
1500
|
+
}
|
|
1501
|
+
const feis = p.flags.get("--feis");
|
|
1502
|
+
const a = await rel.upcoming.fields({
|
|
1503
|
+
...state !== undefined ? { state: state.split(",") } : {},
|
|
1504
|
+
...feis !== undefined ? { feis } : {},
|
|
1505
|
+
...range
|
|
1506
|
+
});
|
|
1507
|
+
out(a, () => {
|
|
1508
|
+
for (const f of a.fields)
|
|
1509
|
+
say(` ${f.date_lo ?? "?"} ${f.field_id} ${f.state} ${f.entrants} row(s) v${f.version} ${f.feis_brand_id ?? "(no series)"} ${f.comp === null ? "" : f.comp.arm === "none" ? "comp unread" : `${f.comp.level ?? "?"} ${f.comp.age ?? "?"} ${f.comp.population ?? ""}`}`);
|
|
1510
|
+
say(`${a.fields.length} field(s) in ${a.tag}`);
|
|
1511
|
+
});
|
|
1512
|
+
return a.fields.length === 0 ? 1 : 0;
|
|
1513
|
+
} finally {
|
|
1514
|
+
rel.close();
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1436
1517
|
case "teacher":
|
|
1437
1518
|
case "adjudicator": {
|
|
1438
1519
|
if (rest.length === 0) {
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
NAME_LEVELS2,
|
|
8
8
|
nameLevel2,
|
|
9
9
|
NO_CALENDAR2,
|
|
10
|
+
NO_UPCOMING2,
|
|
10
11
|
FeisFinder2,
|
|
11
12
|
ADVANCEMENT_DANCES2,
|
|
12
13
|
entryRank2,
|
|
@@ -49,6 +50,8 @@ import {
|
|
|
49
50
|
FEATURES2,
|
|
50
51
|
capabilityOf2,
|
|
51
52
|
needsRelease2,
|
|
53
|
+
FIELD_STATES2,
|
|
54
|
+
UpcomingFinder2,
|
|
52
55
|
resolveTag2,
|
|
53
56
|
Release2,
|
|
54
57
|
openRelease2,
|
|
@@ -71,7 +74,7 @@ import {
|
|
|
71
74
|
readLatestCheck2,
|
|
72
75
|
latestCheck2,
|
|
73
76
|
staleWarning2
|
|
74
|
-
} from "./chunks/index-
|
|
77
|
+
} from "./chunks/index-8mwx3n9j.js";
|
|
75
78
|
import {
|
|
76
79
|
cacheRoot2,
|
|
77
80
|
repoOf2
|
|
@@ -95,6 +98,7 @@ export {
|
|
|
95
98
|
EventFinder2 as EventFinder,
|
|
96
99
|
FEATURES2 as FEATURES,
|
|
97
100
|
FEIS_LOCAL_ID_FLOOR2 as FEIS_LOCAL_ID_FLOOR,
|
|
101
|
+
FIELD_STATES2 as FIELD_STATES,
|
|
98
102
|
FeisFinder2 as FeisFinder,
|
|
99
103
|
FeisPanelFinder2 as FeisPanelFinder,
|
|
100
104
|
LATEST_CHECK_BUDGET_MS2 as LATEST_CHECK_BUDGET_MS,
|
|
@@ -104,6 +108,7 @@ export {
|
|
|
104
108
|
MajorsFinder2 as MajorsFinder,
|
|
105
109
|
NAME_LEVELS2 as NAME_LEVELS,
|
|
106
110
|
NO_CALENDAR2 as NO_CALENDAR,
|
|
111
|
+
NO_UPCOMING2 as NO_UPCOMING,
|
|
107
112
|
PanelFinder2 as PanelFinder,
|
|
108
113
|
RegistrationResolver2 as RegistrationResolver,
|
|
109
114
|
Release2 as Release,
|
|
@@ -113,6 +118,7 @@ export {
|
|
|
113
118
|
StaffFinder2 as StaffFinder,
|
|
114
119
|
TabFinder2 as TabFinder,
|
|
115
120
|
TeamFinder2 as TeamFinder,
|
|
121
|
+
UpcomingFinder2 as UpcomingFinder,
|
|
116
122
|
buildIndex2 as buildIndex,
|
|
117
123
|
buildTag2 as buildTag,
|
|
118
124
|
cacheRoot2 as cacheRoot,
|
package/dist/types/feises.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { IndexBuilder } from "./indexes.js";
|
|
2
2
|
import type { Release } from "./release.js";
|
|
3
|
+
import type { UpcomingHost } from "./upcoming.js";
|
|
3
4
|
export interface Feis {
|
|
4
5
|
feis_id: string;
|
|
5
6
|
source: string;
|
|
@@ -53,6 +54,12 @@ export interface Series {
|
|
|
53
54
|
export interface SeriesNext {
|
|
54
55
|
feis_id: string | null;
|
|
55
56
|
date: string;
|
|
57
|
+
date_hi: string | null;
|
|
58
|
+
occurrence_id: string;
|
|
59
|
+
name_printed: string;
|
|
60
|
+
hosts: UpcomingHost[];
|
|
61
|
+
captured_id: string;
|
|
62
|
+
series_basis: string;
|
|
56
63
|
}
|
|
57
64
|
export interface SeriesAnswer {
|
|
58
65
|
tag: string;
|
|
@@ -74,6 +81,7 @@ export interface SeriesAnswer {
|
|
|
74
81
|
why?: string;
|
|
75
82
|
}
|
|
76
83
|
export declare const NO_CALENDAR = "the release holds a feis-year once its results are captured and carries no calendar of scheduled feiseanna";
|
|
84
|
+
export declare const NO_UPCOMING = "the release's feis-index lists no occurrence of the series dated on or after the cut's day";
|
|
77
85
|
export declare class FeisFinder {
|
|
78
86
|
private readonly rel;
|
|
79
87
|
constructor(rel: Release);
|
|
@@ -88,5 +96,6 @@ export declare class FeisFinder {
|
|
|
88
96
|
find(q: FeisQuery): Promise<FeisAnswer>;
|
|
89
97
|
codeStem(token: string, stem: string): Promise<string[]>;
|
|
90
98
|
seriesOf(brand: string): Promise<Series>;
|
|
99
|
+
nextOf(brand: string): Promise<Pick<SeriesAnswer, "next" | "next_why">>;
|
|
91
100
|
series(q: string): Promise<SeriesAnswer>;
|
|
92
101
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { NAME_LEVELS, type NameLevel, nameLevel } from "./dancers-names.js";
|
|
|
5
5
|
export { ADVANCEMENT_DANCES, type DancerGrades, type DancerLevelAnswer, type DancerLevelQuery, type LevelRange, } from "./dancer-level.js";
|
|
6
6
|
export { type Comp, type CompAnswer, type CompDance, type CompKind, type CompQuery, CompResolver, type CompSource, type FeisPlace, type SyllabusAnswer, type SyllabusForAnswer, type SyllabusSource, type TitleCheck, canonicalOf, syllabusSourceOf, } from "./comps.js";
|
|
7
7
|
export { type ClientOptions, cacheRoot, repoOf } from "./config.js";
|
|
8
|
-
export { type Feis, type FeisAnswer, FeisFinder, type FeisQuery, NO_CALENDAR, type Series, type SeriesAnswer, type SeriesInstance, type SeriesNext, } from "./feises.js";
|
|
8
|
+
export { type Feis, type FeisAnswer, FeisFinder, type FeisQuery, NO_CALENDAR, NO_UPCOMING, type Series, type SeriesAnswer, type SeriesInstance, type SeriesNext, } from "./feises.js";
|
|
9
9
|
export { type IndexBuilder, type IndexFile, buildIndex, defaultBuilders, ensureIndex, indexKey, indexPath, isCurrent, listIndexes, } from "./indexes.js";
|
|
10
10
|
export { type CutVersion, LOCAL_DIR, type LocalBuild, type PickedBuild, buildTag, incomplete, localRoot, newerThan, openBuild, pickBuild, releaseVersion, sweepBuilds, } from "./local.js";
|
|
11
11
|
export { type CachedRelease, DEFAULT_KEEP, type ReleaseList, ReleaseManager, type RemovalPlan, type UseResult, releases, } from "./manager.js";
|
|
@@ -24,4 +24,5 @@ export { type Capability, FEATURES, type Feature, type SchemaProbe, capabilityOf
|
|
|
24
24
|
export { type EntryRow, type StreamQuery, type StreamRow, type StreamScope, entryRank, } from "./stream.js";
|
|
25
25
|
export { type FeisPanelSeat, FeisPanelFinder, PanelFinder, type PanelSeat, type RegisterRow, type TabAnswer, TabFinder, type TabQuery, type TabRow, type TabStreamQuery, } from "./tabs.js";
|
|
26
26
|
export { EventFinder, type EventYear, type EventYearQuery, type ResultRoster, type RosterMember, type RosterTeam, TeamFinder, type TeamResult, } from "./teams.js";
|
|
27
|
+
export { type EntrantCandidate, FIELD_STATES, type FieldComp, type FieldState, type UpcomingEntrant, type UpcomingEntrantAnswer, type UpcomingEntrantQuery, type UpcomingFeis, type UpcomingFeisAnswer, type UpcomingFeisQuery, type UpcomingFeisState, type UpcomingField, type UpcomingFieldAnswer, type UpcomingFieldQuery, UpcomingFinder, type UpcomingHost, } from "./upcoming.js";
|
|
27
28
|
export { ARCHIVE_TAG, type ArchiveTag, type ReleaseSpec, compareTagsNewestFirst, cutOf, parseArchiveTag, parseReleaseSpec, pickTag, renderArchiveTag, } from "./tag.js";
|
package/dist/types/release.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { type SchoolReaderChoice, SchoolResolver } from "./schools.js";
|
|
|
14
14
|
import { FeisPanelFinder, PanelFinder, TabFinder } from "./tabs.js";
|
|
15
15
|
import { type ReleaseSpec } from "./tag.js";
|
|
16
16
|
import { EventFinder, TeamFinder } from "./teams.js";
|
|
17
|
+
import { UpcomingFinder } from "./upcoming.js";
|
|
17
18
|
export interface OpenOptions extends ClientOptions {
|
|
18
19
|
assets?: readonly string[];
|
|
19
20
|
remote?: Remote;
|
|
@@ -45,6 +46,7 @@ export declare class Release {
|
|
|
45
46
|
readonly registrations: RegistrationResolver;
|
|
46
47
|
readonly teams: TeamFinder;
|
|
47
48
|
readonly events: EventFinder;
|
|
49
|
+
readonly upcoming: UpcomingFinder;
|
|
48
50
|
readonly tabs: TabFinder;
|
|
49
51
|
readonly panels: PanelFinder;
|
|
50
52
|
readonly feisPanels: FeisPanelFinder;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { Release } from "./release.js";
|
|
2
|
+
export type FieldState = "pending" | "results" | "passed" | "withdrawn";
|
|
3
|
+
export declare const FIELD_STATES: readonly FieldState[];
|
|
4
|
+
export type UpcomingFeisState = "upcoming" | "no-results";
|
|
5
|
+
export interface UpcomingHost {
|
|
6
|
+
source: string;
|
|
7
|
+
host_id: string;
|
|
8
|
+
feis_id: string | null;
|
|
9
|
+
series: string | null;
|
|
10
|
+
name_printed: string | null;
|
|
11
|
+
date_lo: string | null;
|
|
12
|
+
date_hi: string | null;
|
|
13
|
+
url: string | null;
|
|
14
|
+
}
|
|
15
|
+
export interface UpcomingFeis {
|
|
16
|
+
occurrence_id: string;
|
|
17
|
+
occurrence_ids: string[];
|
|
18
|
+
name_printed: string;
|
|
19
|
+
date_lo: string;
|
|
20
|
+
date_hi: string | null;
|
|
21
|
+
year: number;
|
|
22
|
+
hosts: UpcomingHost[];
|
|
23
|
+
feis_brand_id: string | null;
|
|
24
|
+
feis_instance_id: string | null;
|
|
25
|
+
series_basis: string;
|
|
26
|
+
brand_candidates: string[];
|
|
27
|
+
captured_id: string;
|
|
28
|
+
state: UpcomingFeisState;
|
|
29
|
+
}
|
|
30
|
+
export interface FieldComp {
|
|
31
|
+
arm: "unique" | "ambiguous" | "none";
|
|
32
|
+
source: string | null;
|
|
33
|
+
kind: string | null;
|
|
34
|
+
level: string | null;
|
|
35
|
+
feis_level: number | null;
|
|
36
|
+
age: string | null;
|
|
37
|
+
population: string | null;
|
|
38
|
+
title: string | null;
|
|
39
|
+
why: string | null;
|
|
40
|
+
}
|
|
41
|
+
export interface UpcomingField {
|
|
42
|
+
field_id: string;
|
|
43
|
+
feis_id: string;
|
|
44
|
+
source: string;
|
|
45
|
+
host_id: string;
|
|
46
|
+
competition_code: string | null;
|
|
47
|
+
count_only: boolean;
|
|
48
|
+
occurrence_id: string | null;
|
|
49
|
+
name_printed: string;
|
|
50
|
+
date_lo: string | null;
|
|
51
|
+
date_hi: string | null;
|
|
52
|
+
year: number;
|
|
53
|
+
feis_brand_id: string | null;
|
|
54
|
+
comp: FieldComp | null;
|
|
55
|
+
state: FieldState;
|
|
56
|
+
results_competitions: string[];
|
|
57
|
+
results_feis_ids: string[];
|
|
58
|
+
version: string;
|
|
59
|
+
versions: string[];
|
|
60
|
+
captured_date: string;
|
|
61
|
+
sha256: string;
|
|
62
|
+
limits: string[];
|
|
63
|
+
entrants: number;
|
|
64
|
+
stated_rows: number | null;
|
|
65
|
+
printed_total: unknown;
|
|
66
|
+
}
|
|
67
|
+
export interface EntrantCandidate {
|
|
68
|
+
dancer_id: number;
|
|
69
|
+
scope: string;
|
|
70
|
+
kind: string | null;
|
|
71
|
+
score: number;
|
|
72
|
+
name: string | null;
|
|
73
|
+
age: string | null;
|
|
74
|
+
school: string | null;
|
|
75
|
+
}
|
|
76
|
+
export interface UpcomingEntrant {
|
|
77
|
+
feis_id: string;
|
|
78
|
+
captured_id: string;
|
|
79
|
+
row_id: string;
|
|
80
|
+
source: string;
|
|
81
|
+
host_id: string;
|
|
82
|
+
row_kind: string;
|
|
83
|
+
count_only: boolean;
|
|
84
|
+
n: number;
|
|
85
|
+
name_printed: string | null;
|
|
86
|
+
school_printed: string | null;
|
|
87
|
+
school_id: string | null;
|
|
88
|
+
school_rung: string;
|
|
89
|
+
school_candidates: string[];
|
|
90
|
+
competitions: string[];
|
|
91
|
+
field_ids: string[];
|
|
92
|
+
level_counts: Record<string, number> | null;
|
|
93
|
+
yob: number | null;
|
|
94
|
+
asked: Record<string, unknown> | null;
|
|
95
|
+
arm: "unique" | "ambiguous" | "none" | null;
|
|
96
|
+
candidates: EntrantCandidate[];
|
|
97
|
+
flags: string[];
|
|
98
|
+
}
|
|
99
|
+
export interface UpcomingFeisQuery {
|
|
100
|
+
state?: UpcomingFeisState;
|
|
101
|
+
brand?: string;
|
|
102
|
+
from?: string;
|
|
103
|
+
to?: string;
|
|
104
|
+
}
|
|
105
|
+
export interface UpcomingFieldQuery {
|
|
106
|
+
state?: FieldState | readonly FieldState[];
|
|
107
|
+
feis?: string;
|
|
108
|
+
field_id?: string;
|
|
109
|
+
from?: string;
|
|
110
|
+
to?: string;
|
|
111
|
+
}
|
|
112
|
+
export interface UpcomingEntrantQuery {
|
|
113
|
+
field_id: string;
|
|
114
|
+
version?: string;
|
|
115
|
+
}
|
|
116
|
+
export interface UpcomingFeisAnswer {
|
|
117
|
+
tag: string;
|
|
118
|
+
feises: UpcomingFeis[];
|
|
119
|
+
}
|
|
120
|
+
export interface UpcomingFieldAnswer {
|
|
121
|
+
tag: string;
|
|
122
|
+
fields: UpcomingField[];
|
|
123
|
+
}
|
|
124
|
+
export interface UpcomingEntrantAnswer {
|
|
125
|
+
tag: string;
|
|
126
|
+
field: UpcomingField | null;
|
|
127
|
+
version: string | null;
|
|
128
|
+
entrants: UpcomingEntrant[];
|
|
129
|
+
why?: string;
|
|
130
|
+
}
|
|
131
|
+
export declare class UpcomingFinder {
|
|
132
|
+
private readonly rel;
|
|
133
|
+
constructor(rel: Release);
|
|
134
|
+
private db;
|
|
135
|
+
feises(q?: UpcomingFeisQuery): Promise<UpcomingFeisAnswer>;
|
|
136
|
+
fields(q?: UpcomingFieldQuery): Promise<UpcomingFieldAnswer>;
|
|
137
|
+
entrants(q: UpcomingEntrantQuery): Promise<UpcomingEntrantAnswer>;
|
|
138
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finbheara/archive-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Open a versioned release of an Irish dance results archive: download, verify, decompress and cache it by tag, keep the cache, and resolve feises and schools against it",
|
|
5
5
|
"keywords": ["irish-dance", "results", "release", "cache", "sqlite"],
|
|
6
6
|
"license": "MIT",
|