@mark1russell7/site-pages 0.2.12 → 0.2.14

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 CHANGED
@@ -166,7 +166,7 @@ Two fields of a stamp change the age rule:
166
166
  - `"study": true` marks a fixed study. The data has no age limit, and the rule 3 does not apply. The run names the method or the run, the date and the engine version. The stamp line tells in plain words that the page is a fixed study of that version. A page with a claim about the current engine is not a fixed study.
167
167
  - `"limit"` sets a longer age limit: `{ "days": 7, "reason": "The scan is weekly.", "workflow": ".github/workflows/scan.yml" }`. The stamp line shows the limit and the reason. The schedule of that workflow must meet the limit, or the gate fails. A limit with no schedule fails. A limit over 14 days (`MAX_LIMIT_DAYS_WITHOUT_RULING`) also needs a `ruling`, a public https link for that site.
168
168
 
169
- When npm does not answer, the gate prints the rule 3 under `Not run` and does not fail. A workflow turns the gate on with the input `data-stamps` of `reusable-pages.yml`. The gate then runs from the template commit, so it needs no install.
169
+ When npm does not answer, the gate prints the rule 3 under `Not run` and does not fail. A workflow turns the gate on with the input `data-stamps` of `reusable-pages.yml`. A site with its own Pages workflow uses the action `data-stamps` of the template. The gate then runs from the template commit, so it needs no install.
170
170
 
171
171
  `renderDataStamp(stamp)` gives the line that the page shows with its data: the run, its date, its engine versions and the run in flight.
172
172
 
@@ -191,7 +191,7 @@ The command merges four sources by version:
191
191
  1. **The changelogs of Changesets.** Each `## 1.2.3` section of a `CHANGELOG.md` gives a version and its changes. Each change has its commit, the first sentence of its text, and the packages that list it.
192
192
  2. **The GitHub releases.** Each release gives a version (from its tag), a date and a link. When no changelog has the version, the list items of the release text are the changes.
193
193
  3. **The git tags.** The tags `1.2.3`, `v1.2.3` and `name@1.2.3` give the date of a version.
194
- 4. **npm.** The publication time of each version of `--packages` is the last source of a date.
194
+ 4. **npm.** The publication time of each version of `--packages` is the last source of a date. Each stable version of the group, or of the only package, is also a release. So a publication with no changelog heading stays on the list. With `--group`, a version of another package that the group does not have is a release with the name of its package, for example `viewer@0.4.1`.
195
195
 
196
196
  The date of a version comes from the git tag, else from the GitHub release, else from npm. Else it comes from the commit that added the version heading to the changelog. A version without a date gets the date of the next version, and the command writes a warning.
197
197
 
@@ -342,6 +342,9 @@ The functions of the command are also in the package:
342
342
  | --- | --- |
343
343
  | `readReleases(options)` | The releases of a repository on disk, with GitHub and npm |
344
344
  | `mergeReleases(sources)` | The releases from sources that the caller reads |
345
+ | `releaseReading(listed, sources, now)` | The versions that the changelog, the package or npm name and a list does not show, and the version in flight. Use it for a list that a site keeps itself |
346
+ | `versionCommitTime(repoDir, file)` | The time of the commit that set the version of a `package.json`, for the version in flight |
347
+ | `changelogVersions(markdown)` | The versions of the headings of a changelog |
345
348
  | `readStatusBoard(options)` | The status data of a repository on disk, with GitHub |
346
349
  | `githubReleases`, `githubOpenWork`, `npmPublishTimes` | The data of one source. After an error, each function gives `{ available: false, reason }`. It does not throw. |
347
350
  | `renderReleasesPage(releases, options)`, `renderStatusPage(data, options)` | The HTML of a page |
@@ -432,6 +435,8 @@ The theme `auto` removes `data-theme`, and the CSS of the site then obeys `prefe
432
435
 
433
436
  The file `kpi.json` at the root of a site holds the measures of the project, in the format `kpi/1`. A reader outside the site takes the numbers from this file.
434
437
 
438
+ A count that the build reads from the source is true at the commit of the build. Use `commitTime()` from `@mark1russell7/site-pages/vite` for its `at`.
439
+
435
440
  ```ts
436
441
  import { defineConfig } from "vite";
437
442
  import { siteKpi } from "@mark1russell7/site-pages/vite";
@@ -1,4 +1,4 @@
1
- import { C as readKpi, D as headingDate, E as headCommit, F as versionOfTag, M as compareVersions, N as kindOf, O as isShallow, P as parseVersion, T as gitTagDates, _ as KPI_FILE, d as escapeHtml, f as inlineMarkdown, h as plural, j as npmPublishTimes, k as originRepository, m as listText, p as link, y as KpiError } from "./freshness.js";
1
+ import { A as originRepository, C as readKpi, D as headCommit, E as gitTagDates, F as kindOf, I as parseVersion, L as versionOfTag, N as npmPublishTimes, O as headingDate, P as compareVersions, _ as KPI_FILE, d as escapeHtml, f as inlineMarkdown, h as plural, k as isShallow, m as listText, p as link, y as KpiError } from "./freshness.js";
2
2
  import { stripTypeScriptTypes } from "node:module";
3
3
  import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
4
4
  import { basename, dirname, isAbsolute, join, posix, resolve } from "node:path";
@@ -135,6 +135,10 @@ function releaseBodyEntries(body) {
135
135
  function headingAnchor(heading) {
136
136
  return heading.toLowerCase().trim().replace(/[^\p{L}\p{N}\s_-]/gu, "").replace(/\s/g, "-");
137
137
  }
138
+ /** This function gives the versions of the headings of a changelog, in the order of the file. Another heading is not a version. */
139
+ function changelogVersions(markdown) {
140
+ return parseChangelog(markdown).map((section) => section.version);
141
+ }
138
142
  // src/data/github.ts
139
143
  /** The GraphQL endpoint of GitHub. */
140
144
  const GITHUB_GRAPHQL = "https://api.github.com/graphql";
@@ -467,8 +471,10 @@ function stepKind(version, previous) {
467
471
  * version of a package is the kind `first`.
468
472
  * - A version with a prerelease part is not a release. npm also keeps the placeholder
469
473
  * `0.0.0-bootstrap.0` of a new package.
474
+ * - With `label`, each version has the name of its package, also when the times name one package.
475
+ * - With `keep`, the function gives only the versions that `keep` accepts. The kind still comes from each version of the package.
470
476
  */
471
- function npmReleases(times, group) {
477
+ function npmReleases(times, group, options = {}) {
472
478
  const stable = times.filter((time) => (!group || time.name === group) && parseVersion(time.version)?.prerelease.length === 0);
473
479
  const byPackage = /* @__PURE__ */ new Map();
474
480
  for (const time of stable) {
@@ -483,13 +489,14 @@ function npmReleases(times, group) {
483
489
  shortNames.set(name, short);
484
490
  shortCount.set(short, (shortCount.get(short) ?? 0) + 1);
485
491
  }
486
- const several = byPackage.size > 1;
492
+ const several = options.label ?? byPackage.size > 1;
487
493
  const releases = [];
488
494
  for (const [name, list] of byPackage) {
489
495
  list.sort((a, b) => compareVersions(a.version, b.version));
490
496
  const short = shortNames.get(name) ?? name;
491
497
  const label = (shortCount.get(short) ?? 0) > 1 ? name : short;
492
498
  list.forEach((time, index) => {
499
+ if (options.keep && !options.keep(time.version)) return;
493
500
  releases.push({
494
501
  version: several ? `${label}@${time.version}` : time.version,
495
502
  date: time.date,
@@ -508,13 +515,34 @@ function npmReleases(times, group) {
508
515
  }
509
516
  return releases.sort((a, b) => Date.parse(b.date) - Date.parse(a.date) || a.version.localeCompare(b.version));
510
517
  }
518
+ /** The npm package whose versions a release list shows: the group, or else the only package of the npm times. */
519
+ function npmLine(times, group) {
520
+ if (group) return group;
521
+ const names = new Set(times.map((time) => time.name));
522
+ return names.size === 1 ? [...names][0] : void 0;
523
+ }
524
+ /**
525
+ * This function adds the lines of their own to the list of a group. A package of the group can have a version that the
526
+ * group does not have. The list names that version with its package, because a reader looks for the package by its name.
527
+ */
528
+ function withOwnLines(list, times, group) {
529
+ if (!group) return list;
530
+ const versions = new Set(list.map((release) => release.version));
531
+ const own = npmReleases(times.filter((time) => time.name !== group), void 0, {
532
+ label: true,
533
+ keep: (version) => !versions.has(version)
534
+ });
535
+ return own.length === 0 ? list : [...list, ...own].sort((a, b) => Date.parse(b.date) - Date.parse(a.date));
536
+ }
511
537
  /**
512
538
  * This function merges the release sources into one entry for each version, the newest first.
513
539
  *
514
540
  * - The versions: the changelog of `group`, or else each changelog version and each GitHub release.
541
+ * - The versions also include each stable npm version of the group, or of the only npm package. A publication with no changelog heading is still a release.
515
542
  * - The date: the git tag, else the GitHub release, else npm, else the commit of the changelog heading.
516
543
  * - The changes: the changelog entries, else the list items of the GitHub release text.
517
544
  * - Without a changelog version and without a GitHub release, each npm version of each package is a release.
545
+ * - With `group`, a version of another package that the group does not have is a release with the name of its package.
518
546
  *
519
547
  * @throws ReleaseDataError when `group` has no changelog and other changelogs exist
520
548
  */
@@ -545,8 +573,10 @@ function mergeReleases(sources) {
545
573
  for (const { sections } of parsed) for (const section of sections) versions.add(section.version);
546
574
  for (const [version, list] of githubByVersion) if (list.some((entry) => inGroup(entry.package))) versions.add(version);
547
575
  }
576
+ if (versions.size === 0) return withOwnLines(npmReleases(sources.npm ?? [], group), sources.npm ?? [], group);
577
+ const line = npmLine(sources.npm ?? [], group);
578
+ for (const time of sources.npm ?? []) if (time.name === line && parseVersion(time.version)?.prerelease.length === 0) versions.add(time.version);
548
579
  const ordered = [...versions].sort((a, b) => compareVersions(b, a));
549
- if (ordered.length === 0) return npmReleases(sources.npm ?? [], group);
550
580
  const changelogChanges = /* @__PURE__ */ new Map();
551
581
  const changelogOf = /* @__PURE__ */ new Map();
552
582
  const groupFirst = groupChangelog ? [groupChangelog, ...parsed.filter((entry) => entry !== groupChangelog)] : parsed;
@@ -595,12 +625,16 @@ function mergeReleases(sources) {
595
625
  }
596
626
  }
597
627
  const oldest = ordered[ordered.length - 1];
598
- return ordered.map((version) => {
628
+ return withOwnLines(ordered.map((version) => {
599
629
  const github = githubByVersion.get(version) ?? [];
600
630
  let changes = changelogChanges.get(version);
601
631
  if (!changes) {
602
632
  changes = /* @__PURE__ */ new Map();
603
633
  for (const { release, package: packageName } of github) for (const entry of releaseBodyEntries(release.body)) addChange(changes, entry, packageName ?? (group || null));
634
+ if (changes.size === 0 && line !== void 0 && npmByVersion.get(version)?.some((time) => time.name === line)) addChange(changes, {
635
+ commit: null,
636
+ text: `Version ${version} of \`${line}\` on npm.`
637
+ }, line);
604
638
  }
605
639
  const links = [];
606
640
  const githubRelease = github.find((entry) => entry.package === group) ?? github.find((entry) => entry.package === null) ?? github[0];
@@ -633,7 +667,42 @@ function mergeReleases(sources) {
633
667
  changes: sortedChanges(changes),
634
668
  links
635
669
  };
636
- });
670
+ }), sources.npm ?? [], group);
671
+ }
672
+ /** The time that a release can take. After this time, a version with no tag is a failed release. */
673
+ const IN_FLIGHT_MS = 864e5;
674
+ /**
675
+ * This function reads a release list against its sources. An old list and a list with a missing middle version both give
676
+ * a gap. A version in flight gives no gap, because its release has not ended. After 1 day it gives a gap, so a failed
677
+ * release shows. The check covers one line of versions, so give the plain versions of one package. It does not read a
678
+ * page: a page that does not show its list has no gap here.
679
+ *
680
+ * @param listed - The versions of the list.
681
+ * @param sources - The sources that name the versions.
682
+ * @param now - The time of the check, in milliseconds.
683
+ */
684
+ function releaseReading(listed, sources, now = Date.now()) {
685
+ const { current, tags, versionAt } = sources;
686
+ const inFlight = current !== void 0 && tags !== void 0 && versionAt !== void 0 && !tags.includes(current) && now - Date.parse(versionAt) < IN_FLIGHT_MS ? current : void 0;
687
+ const shown = new Set(listed);
688
+ const gaps = /* @__PURE__ */ new Map();
689
+ const add = (version, source) => {
690
+ if (shown.has(version) || version === inFlight) return;
691
+ const gap = gaps.get(version) ?? {
692
+ version,
693
+ sources: []
694
+ };
695
+ gap.sources.push(source);
696
+ gaps.set(version, gap);
697
+ };
698
+ for (const version of sources.changelog ?? []) add(version, "changelog");
699
+ if (sources.current !== void 0) add(sources.current, "current");
700
+ for (const version of sources.npm ?? []) if (parseVersion(version)?.prerelease.length === 0) add(version, "npm");
701
+ const ordered = [...gaps.values()].sort((a, b) => compareVersions(b.version, a.version));
702
+ return inFlight === void 0 ? { gaps: ordered } : {
703
+ gaps: ordered,
704
+ inFlight
705
+ };
637
706
  }
638
707
  /** The default patterns of the changelog files: the first pattern that finds a file wins. */
639
708
  const DEFAULT_CHANGELOGS = ["packages/*/CHANGELOG.md", "CHANGELOG.md"];
@@ -2302,6 +2371,6 @@ async function runCli(argv, io) {
2302
2371
  throw error;
2303
2372
  }
2304
2373
  }
2305
- export { parseChangelog as $, STATUS_CLASSES as A, DEFAULT_CHANGELOGS as B, pageShell as C, utcDay as D, shortDate as E, plainText as F, globFiles as G, mergeReleases as H, readStatusBoard as I, checkStateOf as J, GITHUB_API as K, roadmapItems as L, linksOf as M, markdownTables as N, OPEN_CLASSES as O, parseRoadmap as P, headingAnchor as Q, splitRow as R, BASE_CSS as S, longDate as T, readChangelogs as U, ReleaseDataError as V, readReleases as W, githubReleases as X, githubOpenWork as Y, firstSentence as Z, renderReleasesPage as _, runCli as a, releaseSummary as b, STATUS_SCRIPT as c, renderStatusPage as d, releaseBodyEntries as et, sectionsOf as f, releasesLead as g, RELEASES_SCRIPT as h, parseBuildArgs as i, buildStatusBoard as j, RoadmapParseError as k, classCounts as l, statusLead as m, UsageError as n, TYPESCRIPT_PROBE as o, slugOf as p, GITHUB_GRAPHQL as q, build as r, probeScript as s, HELP as t, openGroups as u, laneCenter as v, dayRange as w, timelineLayout as x, oldestFirst as y, statusClassOf as z };
2374
+ export { firstSentence as $, STATUS_CLASSES as A, DEFAULT_CHANGELOGS as B, pageShell as C, utcDay as D, shortDate as E, plainText as F, releaseReading as G, mergeReleases as H, readStatusBoard as I, GITHUB_GRAPHQL as J, globFiles as K, roadmapItems as L, linksOf as M, markdownTables as N, OPEN_CLASSES as O, parseRoadmap as P, changelogVersions as Q, splitRow as R, BASE_CSS as S, longDate as T, readChangelogs as U, ReleaseDataError as V, readReleases as W, githubOpenWork as X, checkStateOf as Y, githubReleases as Z, renderReleasesPage as _, runCli as a, releaseSummary as b, STATUS_SCRIPT as c, renderStatusPage as d, headingAnchor as et, sectionsOf as f, releasesLead as g, RELEASES_SCRIPT as h, parseBuildArgs as i, buildStatusBoard as j, RoadmapParseError as k, classCounts as l, statusLead as m, UsageError as n, releaseBodyEntries as nt, TYPESCRIPT_PROBE as o, slugOf as p, GITHUB_API as q, build as r, probeScript as s, HELP as t, parseChangelog as tt, openGroups as u, laneCenter as v, dayRange as w, timelineLayout as x, oldestFirst as y, statusClassOf as z };
2306
2375
 
2307
2376
  //# sourceMappingURL=build.js.map