@f5-sales-demo/xcsh 23.1.0 → 23.2.2
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/package.json +8 -8
- package/src/cli.ts +11 -0
- package/src/corpus-measurement.ts +65 -0
- package/src/internal-urls/api-catalog-index.generated.ts +25301 -25301
- package/src/internal-urls/api-catalog-qmd-index.generated.ts +4 -4
- package/src/internal-urls/api-spec-index.generated.ts +1 -1
- package/src/internal-urls/build-info.generated.ts +8 -8
- package/src/internal-urls/documentation-repository.ts +21 -1
- package/src/internal-urls/documentation-snapshot.ts +86 -2
- package/src/internal-urls/public-citation-destinations.generated.ts +3 -3
- package/src/internal-urls/terraform-documentation-assets.generated.ts +27 -27
- package/src/internal-urls/terraform-index.generated.ts +1 -1
- package/src/internal-urls/terraform-provider-pin.generated.ts +1 -1
- package/src/npm-binary-bootstrap.ts +1 -0
- package/src/qmd-smoke.ts +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/src/internal-urls/api-spec-index.generated.ts
|
|
3
3
|
size: 41998054 bytes
|
|
4
|
-
sha256:
|
|
4
|
+
sha256: 5f7ecc36f0680afc707380a988aefc9339bf005c08406d615ffa1860de1f3c6d
|
|
@@ -17,17 +17,17 @@ export interface BuildInfo {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const BUILD_INFO: BuildInfo = {
|
|
20
|
-
"version": "23.
|
|
21
|
-
"commit": "
|
|
22
|
-
"shortCommit": "
|
|
20
|
+
"version": "23.2.2",
|
|
21
|
+
"commit": "985e73f7cb97d485eabd38967868af3acc5ec7ae",
|
|
22
|
+
"shortCommit": "985e73f",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v23.
|
|
25
|
-
"commitDate": "2026-10-
|
|
26
|
-
"buildDate": "2026-10-
|
|
24
|
+
"tag": "v23.2.2",
|
|
25
|
+
"commitDate": "2026-10-09T18:01:54Z",
|
|
26
|
+
"buildDate": "2026-10-09T18:48:44.757Z",
|
|
27
27
|
"dirty": true,
|
|
28
28
|
"prNumber": "",
|
|
29
29
|
"repoUrl": "https://github.com/f5-sales-demo/xcsh",
|
|
30
30
|
"repoSlug": "f5-sales-demo/xcsh",
|
|
31
|
-
"commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/
|
|
32
|
-
"releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v23.
|
|
31
|
+
"commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/985e73f7cb97d485eabd38967868af3acc5ec7ae",
|
|
32
|
+
"releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v23.2.2"
|
|
33
33
|
};
|
|
@@ -243,7 +243,7 @@ function verifyDatabase(database: Database, assets: EmbeddedDocumentationAssets)
|
|
|
243
243
|
asset_count: String(assets.assetCount),
|
|
244
244
|
document_count: String(assets.documentCount),
|
|
245
245
|
fingerprint: assets.fingerprint,
|
|
246
|
-
index_schema: "
|
|
246
|
+
index_schema: "4",
|
|
247
247
|
release_tag: assets.releaseTag,
|
|
248
248
|
source_commit: assets.sourceCommit,
|
|
249
249
|
};
|
|
@@ -486,6 +486,16 @@ export function createEmbeddedDocumentationRepository(
|
|
|
486
486
|
},
|
|
487
487
|
readDocument: async (source, stablePath, anchor): Promise<DocumentationDocument | null> => {
|
|
488
488
|
const current = await state();
|
|
489
|
+
const route = current.database
|
|
490
|
+
.query(
|
|
491
|
+
"SELECT target_source, target_stable_path FROM documentation_routes WHERE source = ? AND stable_path = ?",
|
|
492
|
+
)
|
|
493
|
+
.get(source, stablePath) as { target_source: DocumentationSource; target_stable_path: string } | null;
|
|
494
|
+
if (route) {
|
|
495
|
+
source = route.target_source;
|
|
496
|
+
stablePath = route.target_stable_path;
|
|
497
|
+
}
|
|
498
|
+
|
|
489
499
|
const row = current.database
|
|
490
500
|
.query(
|
|
491
501
|
"SELECT title, original_url, markdown, lifecycle, replacement_url FROM documentation_documents WHERE source = ? AND stable_path = ?",
|
|
@@ -516,6 +526,16 @@ export function createEmbeddedDocumentationRepository(
|
|
|
516
526
|
},
|
|
517
527
|
readAsset: async (source, stablePath, filename): Promise<DocumentationAsset | null> => {
|
|
518
528
|
const current = await state();
|
|
529
|
+
const route = current.database
|
|
530
|
+
.query(
|
|
531
|
+
"SELECT target_source, target_stable_path FROM documentation_routes WHERE source = ? AND stable_path = ?",
|
|
532
|
+
)
|
|
533
|
+
.get(source, stablePath) as { target_source: DocumentationSource; target_stable_path: string } | null;
|
|
534
|
+
if (route) {
|
|
535
|
+
source = route.target_source;
|
|
536
|
+
stablePath = route.target_stable_path;
|
|
537
|
+
}
|
|
538
|
+
|
|
519
539
|
const row = current.database
|
|
520
540
|
.query(
|
|
521
541
|
"SELECT source, stable_path, filename, archive_path, mime_type, sha256, size_bytes FROM documentation_assets WHERE source = ? AND stable_path = ? AND filename = ?",
|
|
@@ -41,7 +41,7 @@ const COMMIT = /^[a-f0-9]{40}$/;
|
|
|
41
41
|
const RELEASE_TAG = /^content-[0-9]{8}T[0-9]{6}Z$/;
|
|
42
42
|
const TIMESTAMP = /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$/;
|
|
43
43
|
const FIXED_TIME = "2000-01-01T00:00:00.000Z";
|
|
44
|
-
const DOCUMENTATION_INDEX_SCHEMA_VERSION =
|
|
44
|
+
const DOCUMENTATION_INDEX_SCHEMA_VERSION = 4;
|
|
45
45
|
const MANIFEST_KEYS = [
|
|
46
46
|
"asset_count",
|
|
47
47
|
"assets",
|
|
@@ -142,7 +142,15 @@ export interface VerifiedDocumentationAsset {
|
|
|
142
142
|
readonly sizeBytes: number;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
export interface DocumentationRouteAlias {
|
|
146
|
+
readonly path: string;
|
|
147
|
+
readonly target: string;
|
|
148
|
+
readonly url: string;
|
|
149
|
+
}
|
|
150
|
+
|
|
145
151
|
export interface VerifiedDocumentationSnapshot {
|
|
152
|
+
readonly aliases?: readonly DocumentationRouteAlias[];
|
|
153
|
+
readonly enrichmentArtifactSha256?: string;
|
|
146
154
|
readonly archivePath: string;
|
|
147
155
|
readonly releaseTag: string;
|
|
148
156
|
readonly sourceCommit: string;
|
|
@@ -623,7 +631,11 @@ export async function verifyDocumentationRelease(
|
|
|
623
631
|
}
|
|
624
632
|
|
|
625
633
|
const manifest = parseJson(manifestEntry.data, "documentation manifest");
|
|
626
|
-
exactKeys(
|
|
634
|
+
exactKeys(
|
|
635
|
+
manifest,
|
|
636
|
+
[...MANIFEST_KEYS, ...(Object.hasOwn(manifest, "enrichment") ? ["enrichment"] : [])],
|
|
637
|
+
"documentation manifest",
|
|
638
|
+
);
|
|
627
639
|
if (manifest.schema_version !== 2) throw new Error("documentation manifest schema version is invalid");
|
|
628
640
|
string(manifest.tool_version, "documentation manifest tool version");
|
|
629
641
|
validateTimestamp(manifest.started_at, "documentation manifest started_at");
|
|
@@ -775,8 +787,60 @@ export async function verifyDocumentationRelease(
|
|
|
775
787
|
if (JSON.stringify([...seen].sort()) !== JSON.stringify(contentNames))
|
|
776
788
|
throw new Error("documentation manifest content member set mismatch");
|
|
777
789
|
|
|
790
|
+
const aliases: DocumentationRouteAlias[] = [];
|
|
791
|
+
let enrichmentArtifactSha256: string | undefined;
|
|
792
|
+
if (Object.hasOwn(manifest, "enrichment")) {
|
|
793
|
+
const enrichment = object(manifest.enrichment, "enrichment");
|
|
794
|
+
exactKeys(enrichment, ["artifact_sha256", "aliases"], "enrichment");
|
|
795
|
+
enrichmentArtifactSha256 = string(enrichment.artifact_sha256, "enrichment artifact digest");
|
|
796
|
+
if (!SHA256.test(enrichmentArtifactSha256) || !Array.isArray(enrichment.aliases))
|
|
797
|
+
throw new Error("invalid enrichment digest or aliases");
|
|
798
|
+
const canonicalPaths = new Set(documents.map(d => d.archivePath));
|
|
799
|
+
const aliasPaths = new Set<string>();
|
|
800
|
+
for (const value of enrichment.aliases) {
|
|
801
|
+
const alias = object(value, "enrichment alias");
|
|
802
|
+
exactKeys(alias, ["path", "target", "url"], "enrichment alias");
|
|
803
|
+
const route = {
|
|
804
|
+
path: string(alias.path, "enrichment alias path"),
|
|
805
|
+
target: string(alias.target, "enrichment alias target"),
|
|
806
|
+
url: string(alias.url, "enrichment alias URL"),
|
|
807
|
+
};
|
|
808
|
+
try {
|
|
809
|
+
validateMemberName(route.path);
|
|
810
|
+
validateMemberName(route.target);
|
|
811
|
+
} catch (error) {
|
|
812
|
+
throw new Error("unsafe enrichment alias path", { cause: error });
|
|
813
|
+
}
|
|
814
|
+
if (
|
|
815
|
+
!route.path.endsWith("/index.md") ||
|
|
816
|
+
!route.target.endsWith("/index.md") ||
|
|
817
|
+
canonicalPaths.has(route.path) ||
|
|
818
|
+
aliasPaths.has(route.path) ||
|
|
819
|
+
!canonicalPaths.has(route.target)
|
|
820
|
+
)
|
|
821
|
+
throw new Error("conflicting, dangling, or chained enrichment alias");
|
|
822
|
+
const source = route.path.split("/")[1] as DocumentationSource;
|
|
823
|
+
if (
|
|
824
|
+
!/^content\/[a-z0-9-]+\/(?:[A-Za-z0-9_~.-]+\/)*index\.md$/.test(route.path) ||
|
|
825
|
+
!/^content\/[a-z0-9-]+\/(?:[A-Za-z0-9_~.-]+\/)*index\.md$/.test(route.target)
|
|
826
|
+
)
|
|
827
|
+
throw new Error("unsafe enrichment alias route");
|
|
828
|
+
if (
|
|
829
|
+
source === "docs-cloud-f5-com" &&
|
|
830
|
+
route.url !== `${SOURCE_ROOT_URLS[source]}/${stableDocumentPath(route.path, source)}`
|
|
831
|
+
)
|
|
832
|
+
throw new Error("enrichment alias URL does not match its route");
|
|
833
|
+
validateCorpusUrl(route.url, source, "enrichment alias URL");
|
|
834
|
+
aliasPaths.add(route.path);
|
|
835
|
+
aliases.push(route);
|
|
836
|
+
}
|
|
837
|
+
aliases.sort((a, b) => a.path.localeCompare(b.path));
|
|
838
|
+
}
|
|
839
|
+
|
|
778
840
|
return {
|
|
779
841
|
archivePath,
|
|
842
|
+
aliases,
|
|
843
|
+
enrichmentArtifactSha256,
|
|
780
844
|
releaseTag: pin.release_tag,
|
|
781
845
|
sourceCommit: pin.source_commit,
|
|
782
846
|
archiveSha256: pin.assets["html-to-markdown-content.tar.gz"].sha256,
|
|
@@ -790,6 +854,8 @@ function fingerprint(snapshot: VerifiedDocumentationSnapshot): string {
|
|
|
790
854
|
JSON.stringify({
|
|
791
855
|
archiveSha256: snapshot.archiveSha256,
|
|
792
856
|
indexSchema: DOCUMENTATION_INDEX_SCHEMA_VERSION,
|
|
857
|
+
aliases: snapshot.aliases ?? [],
|
|
858
|
+
enrichmentArtifactSha256: snapshot.enrichmentArtifactSha256 ?? null,
|
|
793
859
|
releaseTag: snapshot.releaseTag,
|
|
794
860
|
sourceCommit: snapshot.sourceCommit,
|
|
795
861
|
qmdVersion: "2.8.3",
|
|
@@ -829,6 +895,24 @@ function canonicalizeDatabase(
|
|
|
829
895
|
key TEXT PRIMARY KEY NOT NULL,
|
|
830
896
|
value TEXT NOT NULL
|
|
831
897
|
)`);
|
|
898
|
+
db.exec(`CREATE TABLE documentation_routes (
|
|
899
|
+
source TEXT NOT NULL, stable_path TEXT NOT NULL,
|
|
900
|
+
target_source TEXT NOT NULL, target_stable_path TEXT NOT NULL,
|
|
901
|
+
original_url TEXT NOT NULL, PRIMARY KEY (source, stable_path)
|
|
902
|
+
)`);
|
|
903
|
+
const insertRoute = db.query("INSERT INTO documentation_routes VALUES (?, ?, ?, ?, ?)");
|
|
904
|
+
for (const alias of snapshot.aliases ?? []) {
|
|
905
|
+
const source = alias.path.split("/")[1] as DocumentationSource;
|
|
906
|
+
const targetSource = alias.target.split("/")[1] as DocumentationSource;
|
|
907
|
+
insertRoute.run(
|
|
908
|
+
source,
|
|
909
|
+
stableDocumentPath(alias.path, source),
|
|
910
|
+
targetSource,
|
|
911
|
+
stableDocumentPath(alias.target, targetSource),
|
|
912
|
+
alias.url,
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
|
|
832
916
|
db.exec(`CREATE TABLE documentation_documents (
|
|
833
917
|
source TEXT NOT NULL,
|
|
834
918
|
stable_path TEXT NOT NULL,
|