@adea-ai/plugins 4.0.0 → 4.0.6
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/dist/agent-plugins-catalog.d.ts +2 -4
- package/dist/agent-plugins-catalog.js +42 -50
- package/dist/agent-plugins-catalog.js.map +1 -1
- package/dist/agent-plugins-schema.d.ts +8 -0
- package/dist/agent-plugins-schema.js +10 -1
- package/dist/agent-plugins-schema.js.map +1 -1
- package/dist/artifacts.d.ts +57 -0
- package/dist/artifacts.js +159 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/build.d.ts +20 -0
- package/dist/build.js +103 -0
- package/dist/build.js.map +1 -0
- package/dist/capabilities.d.ts +7 -0
- package/dist/capabilities.js +116 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/catalog-store.d.ts +76 -0
- package/dist/catalog-store.js +463 -0
- package/dist/catalog-store.js.map +1 -0
- package/dist/concurrency.d.ts +1 -0
- package/dist/concurrency.js +15 -0
- package/dist/concurrency.js.map +1 -0
- package/dist/consumer-index.d.ts +7 -29
- package/dist/consumer-index.js +24 -15
- package/dist/consumer-index.js.map +1 -1
- package/dist/digest.d.ts +13 -0
- package/dist/digest.js +47 -0
- package/dist/digest.js.map +1 -0
- package/dist/fs-atomic.d.ts +7 -0
- package/dist/fs-atomic.js +30 -0
- package/dist/fs-atomic.js.map +1 -0
- package/dist/harness.js +2 -1
- package/dist/harness.js.map +1 -1
- package/dist/icon-mirror.d.ts +5 -4
- package/dist/icon-mirror.js +73 -72
- package/dist/icon-mirror.js.map +1 -1
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +4 -12
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +16 -309
- package/dist/index.js +12 -1900
- package/dist/index.js.map +1 -1
- package/dist/integrity-manifest.d.ts +43 -13
- package/dist/integrity-manifest.js +28 -17
- package/dist/integrity-manifest.js.map +1 -1
- package/dist/json-values.d.ts +3 -0
- package/dist/json-values.js +10 -0
- package/dist/json-values.js.map +1 -0
- package/dist/plugin-release.d.ts +38 -0
- package/dist/plugin-release.js +321 -0
- package/dist/plugin-release.js.map +1 -0
- package/dist/plugin-skips.d.ts +19 -0
- package/dist/plugin-skips.js +65 -0
- package/dist/plugin-skips.js.map +1 -0
- package/dist/policy.d.ts +13 -0
- package/dist/policy.js +26 -0
- package/dist/policy.js.map +1 -0
- package/dist/portable-catalog.d.ts +4 -4
- package/dist/portable-catalog.js +14 -126
- package/dist/portable-catalog.js.map +1 -1
- package/dist/portable-verify.d.ts +2 -0
- package/dist/portable-verify.js +68 -0
- package/dist/portable-verify.js.map +1 -0
- package/dist/publication.d.ts +12 -12
- package/dist/publication.js +31 -21
- package/dist/publication.js.map +1 -1
- package/dist/published-output.d.ts +17 -0
- package/dist/published-output.js +49 -0
- package/dist/published-output.js.map +1 -0
- package/dist/site-icons.d.ts +4 -3
- package/dist/site-icons.js +38 -11
- package/dist/site-icons.js.map +1 -1
- package/dist/snapshots.d.ts +39 -0
- package/dist/snapshots.js +238 -0
- package/dist/snapshots.js.map +1 -0
- package/dist/source-resolution.d.ts +28 -0
- package/dist/source-resolution.js +158 -0
- package/dist/source-resolution.js.map +1 -0
- package/dist/sources.d.ts +5 -1
- package/dist/sources.js +21 -27
- package/dist/sources.js.map +1 -1
- package/dist/synchronize.d.ts +44 -0
- package/dist/synchronize.js +118 -0
- package/dist/synchronize.js.map +1 -0
- package/dist/taxonomy.d.ts +23 -0
- package/dist/taxonomy.js +62 -0
- package/dist/taxonomy.js.map +1 -0
- package/dist/upstream.d.ts +42 -0
- package/dist/upstream.js +179 -0
- package/dist/upstream.js.map +1 -0
- package/dist/verify-artifacts.d.ts +36 -0
- package/dist/verify-artifacts.js +286 -0
- package/dist/verify-artifacts.js.map +1 -0
- package/native/build-provenance.txt +5 -5
- package/native/staged-reader-win32-arm64.node +0 -0
- package/native/staged-reader-win32-x64.node +0 -0
- package/package.json +3 -3
- package/src/agent-plugins-catalog.test.ts +2 -2
- package/src/agent-plugins-catalog.ts +46 -49
- package/src/agent-plugins-schema.ts +11 -1
- package/src/artifacts.test.ts +80 -0
- package/src/artifacts.ts +234 -0
- package/src/build.ts +131 -0
- package/src/capabilities.ts +153 -0
- package/src/catalog-store.ts +519 -0
- package/src/concurrency.ts +19 -0
- package/src/consumer-index.test.ts +147 -16
- package/src/consumer-index.ts +35 -43
- package/src/default-head.test.ts +143 -0
- package/src/digest.ts +55 -0
- package/src/fs-atomic.ts +32 -0
- package/src/harness.test.ts +4 -32
- package/src/harness.ts +2 -1
- package/src/icon-mirror.ts +78 -72
- package/src/icons.test.ts +0 -4
- package/src/icons.ts +4 -4
- package/src/index.test.ts +172 -46
- package/src/index.ts +58 -2562
- package/src/integrity-manifest.ts +41 -21
- package/src/json-values.ts +11 -0
- package/src/manifest-retry.test.ts +49 -0
- package/src/plugin-release.ts +457 -0
- package/src/plugin-skips.ts +110 -0
- package/src/policy.ts +39 -0
- package/src/portable-catalog.test.ts +0 -5
- package/src/portable-catalog.ts +16 -143
- package/src/portable-verify.ts +71 -0
- package/src/publication.test.ts +29 -1
- package/src/publication.ts +38 -22
- package/src/published-output.ts +60 -0
- package/src/site-icons.test.ts +73 -1
- package/src/site-icons.ts +31 -14
- package/src/snapshots.ts +287 -0
- package/src/source-config-sync.test.ts +84 -0
- package/src/source-digest.test.ts +61 -8
- package/src/source-resolution.ts +233 -0
- package/src/sources-json.test.ts +18 -2
- package/src/sources.ts +27 -33
- package/src/synchronize.ts +213 -0
- package/src/taxonomy.ts +87 -0
- package/src/upstream.ts +194 -0
- package/src/verify-artifacts.ts +365 -0
- package/src/write-artifacts.test.ts +374 -0
- package/dist/source-digest.d.ts +0 -2
- package/dist/source-digest.js +0 -12
- package/dist/source-digest.js.map +0 -1
- package/native/README.md +0 -24
- package/src/source-digest.ts +0 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portable-catalog.js","sourceRoot":"","sources":["../src/portable-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"portable-catalog.js","sourceRoot":"","sources":["../src/portable-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AACpF,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAEpF,OAAO,EAAE,wBAAwB,EAAyB,MAAM,qBAAqB,CAAA;AACrF,OAAO,EAAE,aAAa,EAA6B,MAAM,aAAa,CAAA;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAmC,MAAM,kBAAkB,CAAA;AAE/E,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,CAAA;AAEtD,SAAS,eAAe,CAAC,OAA4B;IACnD,OAAO,CACL,CAAC,CAAC,OAAO;QACT,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAC/B,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE;YACzC,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,CAAC,oBAAoB,CAAC,CAAA;YAC3D,OAAO,CACL,OAAO,CAAC,iBAAiB,KAAK,UAAU;gBACxC,uEAAuE;gBACvE,uEAAuE;gBACvE,OAAO,CAAC,eAAe,CAAC,eAAe,KAAK,wBAAwB;gBACpE,KAAK,KAAK,IAAI;gBACd,OAAO,KAAK,KAAK,QAAQ;gBACzB,mBAAmB,IAAI,KAAK;gBAC5B,KAAK,CAAC,iBAAiB,KAAK,kBAAkB,CAC/C,CAAA;QACH,CAAC,CAAC,CACH,CACF,CAAA;AACH,CAAC;AACD,SAAS,aAAa,CACpB,GAA2C;IAE3C,mGAAmG;IACnG,OAAO,MAAM,CAAC,WAAW,CACvB,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QACrC,OAAO;QACP;YACE,MAAM,EACJ,GAAG,CAAC,MAAM,KAAK,aAAa;gBAC1B,CAAC,CAAC,aAAa;gBACf,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS;oBACxB,CAAC,CAAC,qBAAqB;oBACvB,CAAC,CAAC,SAAS;YACjB,OAAO,EAAE;gBACP,GAAG,CAAC,MAAM,KAAK,aAAa;oBAC1B,CAAC,CAAC,0CAA0C;oBAC5C,CAAC,CAAC,uIAAuI;aAC5I;YACD,uBAAuB,EAAE;gBACvB,GAAG,IAAI,GAAG,CAAC;oBACT,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAChD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAqB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;iBACvE,CAAC;aACH;SACF;KACF,CAAC,CAC+B,CAAA;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAkB;IAC1D,IAAI,OAAO,CAAC,eAAe;QAAE,qBAAqB,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IAC3E,MAAM,gBAAgB,GAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;QACtE,MAAM,OAAO,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,QAAQ,CAAA;QAChF,IACE,OAAO,CAAC,SAAS,KAAK,QAAQ,CAAC,SAAS;YACxC,OAAO,CAAC,sBAAsB,KAAK,QAAQ,CAAC,sBAAsB;YAClE,OAAO,CAAC,qBAAqB,KAAK,QAAQ,CAAC,qBAAqB;YAChE,OAAO,CAAC,iBAAiB,KAAK,QAAQ,CAAC,iBAAiB;YACxD,OAAO,CAAC,kBAAkB,KAAK,QAAQ,CAAC,kBAAkB;YAC1D,OAAO,CAAC,iBAAiB,KAAK,QAAQ,CAAC,iBAAiB;YAExD,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAA;QACzD,MAAM,GAAG,GAAG,mBAAmB,CAAC;YAC9B,GAAG,QAAQ;YACX,IAAI;YACJ,YAAY,EAAE,QAAQ,CAAC,sBAAsB;SAC9C,CAAC,CAAA;QACF,OAAO;YACL,GAAG,OAAO;YACV,eAAe,EAAE,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,oBAAoB,CAAC,EAAE,GAAG,EAAE;SAC7E,CAAA;IACH,CAAC,CAAA;IACD,8EAA8E;IAC9E,gFAAgF;IAChF,MAAM,KAAK,GAAc;QACvB,GAAG,OAAO;QACV,YAAY,EAAE,OAAO,CAAC,YAAY,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI;QACtE,gBAAgB;QAChB,oBAAoB,EAAE,CAAC,OAAO,EAAE,EAAE;YAChC,MAAM,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,oBAAoB,CAAC,CAAA;YACzD,OAAO,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACjE,CAAC;KACF,CAAA;IACD,IAAI,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,CAAA;IACrC,IACE,CAAC,MAAM,CAAC,OAAO;QACf,CAAC,KAAK,CAAC,YAAY;QACnB,CAAC,eAAe,CAAC,KAAK,CAAC,eAAe,CAAC;QACvC,KAAK,CAAC,YAAY,EAClB,CAAC;QACD,oFAAoF;QACpF,4EAA4E;QAC5E,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAA;IACxE,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY;QAAE,qBAAqB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAChF,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { verifyAgentPackage } from './agent-plugins-catalog.js';
|
|
2
|
+
import { PACKAGE_METADATA_KEY } from './agent-plugins-schema.js';
|
|
3
|
+
import { contentId } from './digest.js';
|
|
4
|
+
import { CatalogSchema } from './schema.js';
|
|
5
|
+
/**
|
|
6
|
+
* A single-line summary of why a release's package descriptor was refused.
|
|
7
|
+
*
|
|
8
|
+
* The schema's own failure is a structured issue list; the catalog's refusal
|
|
9
|
+
* contract is one typed line. The first issue is kept as the detail, because
|
|
10
|
+
* it names the field that was wrong.
|
|
11
|
+
*/
|
|
12
|
+
function describeProvenanceFailure(error) {
|
|
13
|
+
const issues = error.issues;
|
|
14
|
+
if (Array.isArray(issues) && issues.length > 0) {
|
|
15
|
+
const first = issues[0];
|
|
16
|
+
const path = Array.isArray(first.path) ? first.path.join('.') : '';
|
|
17
|
+
const message = typeof first.message === 'string' ? first.message : '';
|
|
18
|
+
return [path, message].filter(Boolean).join(': ').replace(/\s+/g, ' ').slice(0, 200);
|
|
19
|
+
}
|
|
20
|
+
return error instanceof Error
|
|
21
|
+
? error.message.replace(/\s+/g, ' ').slice(0, 200)
|
|
22
|
+
: 'the descriptor is not a package recipe';
|
|
23
|
+
}
|
|
24
|
+
export function verifyPortableCatalog(catalog, requirePortable = false) {
|
|
25
|
+
const { catalogId, ...body } = CatalogSchema.parse(catalog);
|
|
26
|
+
if (catalogId !== contentId('catalog', body))
|
|
27
|
+
throw new Error('CATALOG_ID_MISMATCH');
|
|
28
|
+
const ids = new Set();
|
|
29
|
+
for (const plugin of catalog.plugins) {
|
|
30
|
+
if (ids.has(plugin.pluginId))
|
|
31
|
+
throw new Error('DUPLICATE_PLUGIN_ID');
|
|
32
|
+
ids.add(plugin.pluginId);
|
|
33
|
+
const releases = new Set(plugin.availableReleases.map((release) => release.releaseId));
|
|
34
|
+
if (releases.size !== plugin.availableReleases.length || !releases.has(plugin.currentReleaseId))
|
|
35
|
+
throw new Error('RELEASE_SELECTION_INVALID');
|
|
36
|
+
}
|
|
37
|
+
for (const plugin of catalog.plugins)
|
|
38
|
+
for (const release of plugin.availableReleases) {
|
|
39
|
+
if (requirePortable && release.contentResolution !== 'complete')
|
|
40
|
+
throw new Error('COMPLETE_SOURCE_REQUIRED');
|
|
41
|
+
const descriptor = release.releaseMetadata[PACKAGE_METADATA_KEY];
|
|
42
|
+
if (descriptor === undefined) {
|
|
43
|
+
if (requirePortable && release.contentResolution === 'complete')
|
|
44
|
+
throw new Error(`PORTABLE_RESYNC_REQUIRED: ${plugin.pluginId}`);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
let pkg;
|
|
48
|
+
try {
|
|
49
|
+
pkg = verifyAgentPackage(descriptor);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
// A consumer imports a catalog it did not compile, so a malformed
|
|
53
|
+
// provenance descriptor is an IMPORT failure, and it must be refused
|
|
54
|
+
// the way every other failure here is refused: one typed, single-line
|
|
55
|
+
// reason that names the plugin. The schema's own multi-line issue
|
|
56
|
+
// dump is not a refusal a consumer can match on.
|
|
57
|
+
throw new Error(`PACKAGE_PROVENANCE_INVALID: ${plugin.pluginId} (${describeProvenanceFailure(error)})`, { cause: error });
|
|
58
|
+
}
|
|
59
|
+
if (release.contentResolution !== 'complete' ||
|
|
60
|
+
pkg.sourceDigest !== release.canonicalContentDigest)
|
|
61
|
+
throw new Error(`PACKAGE_PROVENANCE_MISMATCH: ${plugin.pluginId}`);
|
|
62
|
+
const sourcePaths = new Set(release.fileIndex);
|
|
63
|
+
for (const file of pkg.files)
|
|
64
|
+
if (file.action === 'copy' && !sourcePaths.has(file.sourcePath))
|
|
65
|
+
throw new Error(`PACKAGE_SOURCE_FILE_MISSING: ${plugin.pluginId}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=portable-verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portable-verify.js","sourceRoot":"","sources":["../src/portable-verify.ts"],"names":[],"mappings":"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"}
|
package/dist/publication.d.ts
CHANGED
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
* that slot, so no version is ever the one a visitor sees first.
|
|
10
10
|
*
|
|
11
11
|
* The branch gives each catalog an immutable path — `catalogs/<catalogId>/…`,
|
|
12
|
-
* where `catalogId` is the canonical digest of the catalog itself
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* CORS so a browser
|
|
12
|
+
* where `catalogId` is the canonical digest of the catalog itself. The
|
|
13
|
+
* publisher must reject replacement of existing snapshot bytes. GitLab raw URLs
|
|
14
|
+
* serve the branch to servers and image tags; unlike
|
|
15
|
+
* `raw.githubusercontent.com` they send no CORS header, so a browser `fetch`
|
|
16
|
+
* needs a same-origin proxy.
|
|
16
17
|
*/
|
|
17
18
|
export declare const publishedArtifactNames: readonly ['catalog.v1.json', 'catalog-summary.v1.json', 'categories.v1.json', 'compatibility.v1.json', 'integrity.json', 'sources.lock.json'];
|
|
18
19
|
export type PublishedArtifactName = (typeof publishedArtifactNames)[number];
|
|
@@ -48,11 +49,9 @@ export interface StagedAssetAudit {
|
|
|
48
49
|
/**
|
|
49
50
|
* Audits the bytes this build staged against what it declared.
|
|
50
51
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* therefore a different path. What survives is the check that cannot be
|
|
55
|
-
* delegated to the path — that the bytes exist here at all.
|
|
52
|
+
* This checks that the declared bytes exist here at all. Publication must
|
|
53
|
+
* separately compare the complete staged snapshot with any existing snapshot:
|
|
54
|
+
* companion artifacts can differ without changing the catalog identity.
|
|
56
55
|
*/
|
|
57
56
|
export declare function auditStagedAssets(input: {
|
|
58
57
|
readonly declared: readonly DeclaredAsset[];
|
|
@@ -69,9 +68,8 @@ export interface PublicationPlan {
|
|
|
69
68
|
/**
|
|
70
69
|
* The 64-hex digest a `catalog:<hex>` identity is addressed by.
|
|
71
70
|
*
|
|
72
|
-
* A catalog identity names
|
|
73
|
-
* snapshot path
|
|
74
|
-
* different identity and cannot write over this one.
|
|
71
|
+
* A catalog identity names the catalog content. The publisher must also guard
|
|
72
|
+
* the snapshot path against changes to companion artifacts under the same ID.
|
|
75
73
|
*/
|
|
76
74
|
export declare function catalogIdSuffix(catalogId: string): string;
|
|
77
75
|
/**
|
|
@@ -87,6 +85,8 @@ export declare function createPublicationPlan(input: {
|
|
|
87
85
|
readonly repositoryUrl: string;
|
|
88
86
|
readonly catalogId: string;
|
|
89
87
|
}): PublicationPlan;
|
|
88
|
+
/** A flat file name that is safe as both a local file and a URL path segment. */
|
|
89
|
+
export declare function isPublishedName(name: string): boolean;
|
|
90
90
|
/**
|
|
91
91
|
* Immutable URL for one artifact of one catalog.
|
|
92
92
|
*
|
package/dist/publication.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CatalogSchema } from './schema.js';
|
|
1
2
|
/**
|
|
2
3
|
* Where a published catalog lives, and the URLs that address it.
|
|
3
4
|
*
|
|
@@ -9,10 +10,11 @@
|
|
|
9
10
|
* that slot, so no version is ever the one a visitor sees first.
|
|
10
11
|
*
|
|
11
12
|
* The branch gives each catalog an immutable path — `catalogs/<catalogId>/…`,
|
|
12
|
-
* where `catalogId` is the canonical digest of the catalog itself
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* CORS so a browser
|
|
13
|
+
* where `catalogId` is the canonical digest of the catalog itself. The
|
|
14
|
+
* publisher must reject replacement of existing snapshot bytes. GitLab raw URLs
|
|
15
|
+
* serve the branch to servers and image tags; unlike
|
|
16
|
+
* `raw.githubusercontent.com` they send no CORS header, so a browser `fetch`
|
|
17
|
+
* needs a same-origin proxy.
|
|
16
18
|
*/
|
|
17
19
|
export const publishedArtifactNames = [
|
|
18
20
|
'catalog.v1.json',
|
|
@@ -36,11 +38,9 @@ export const latestPointerName = 'catalog-latest.v1.json';
|
|
|
36
38
|
/**
|
|
37
39
|
* Audits the bytes this build staged against what it declared.
|
|
38
40
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* therefore a different path. What survives is the check that cannot be
|
|
43
|
-
* delegated to the path — that the bytes exist here at all.
|
|
41
|
+
* This checks that the declared bytes exist here at all. Publication must
|
|
42
|
+
* separately compare the complete staged snapshot with any existing snapshot:
|
|
43
|
+
* companion artifacts can differ without changing the catalog identity.
|
|
44
44
|
*/
|
|
45
45
|
export function auditStagedAssets(input) {
|
|
46
46
|
const unstaged = [...new Set(input.unstaged ?? [])].toSorted();
|
|
@@ -55,22 +55,23 @@ export function auditStagedAssets(input) {
|
|
|
55
55
|
/**
|
|
56
56
|
* The 64-hex digest a `catalog:<hex>` identity is addressed by.
|
|
57
57
|
*
|
|
58
|
-
* A catalog identity names
|
|
59
|
-
* snapshot path
|
|
60
|
-
* different identity and cannot write over this one.
|
|
58
|
+
* A catalog identity names the catalog content. The publisher must also guard
|
|
59
|
+
* the snapshot path against changes to companion artifacts under the same ID.
|
|
61
60
|
*/
|
|
62
61
|
export function catalogIdSuffix(catalogId) {
|
|
63
|
-
|
|
64
|
-
if (!match)
|
|
62
|
+
if (!CatalogSchema.shape.catalogId.safeParse(catalogId).success)
|
|
65
63
|
throw new Error(`CATALOG_ID_INVALID: ${catalogId}`);
|
|
66
|
-
return
|
|
64
|
+
return catalogId.slice('catalog:'.length);
|
|
67
65
|
}
|
|
68
66
|
/**
|
|
69
67
|
* Root of the branch that carries mirrored brand marks and the mutable
|
|
70
68
|
* catalog pointer.
|
|
71
69
|
*/
|
|
72
70
|
export function catalogAssetsBaseUrl(repositoryUrl) {
|
|
73
|
-
|
|
71
|
+
const { host, path } = repositoryLocation(repositoryUrl);
|
|
72
|
+
return host === 'gitlab.com'
|
|
73
|
+
? `https://gitlab.com/${path}/-/raw/${catalogAssetsBranch}`
|
|
74
|
+
: `https://raw.githubusercontent.com/${path}/${catalogAssetsBranch}`;
|
|
74
75
|
}
|
|
75
76
|
/** Root of one catalog's immutable artifacts, content-addressed by identity. */
|
|
76
77
|
export function catalogSnapshotBaseUrl(repositoryUrl, catalogId) {
|
|
@@ -90,6 +91,10 @@ export function createPublicationPlan(input) {
|
|
|
90
91
|
artifactNames: publishedArtifactNames,
|
|
91
92
|
};
|
|
92
93
|
}
|
|
94
|
+
/** A flat file name that is safe as both a local file and a URL path segment. */
|
|
95
|
+
export function isPublishedName(name) {
|
|
96
|
+
return /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(name);
|
|
97
|
+
}
|
|
93
98
|
/**
|
|
94
99
|
* Immutable URL for one artifact of one catalog.
|
|
95
100
|
*
|
|
@@ -99,11 +104,11 @@ export function createPublicationPlan(input) {
|
|
|
99
104
|
* and substitute it for `catalogAssetsBaseUrl`.
|
|
100
105
|
*/
|
|
101
106
|
export function immutableAssetUrl(repositoryUrl, catalogId, assetName) {
|
|
102
|
-
if (
|
|
107
|
+
if (!isPublishedName(assetName))
|
|
103
108
|
throw new Error(`ASSET_NAME_INVALID: ${assetName}`);
|
|
104
109
|
return `${catalogSnapshotBaseUrl(repositoryUrl, catalogId)}/${assetName}`;
|
|
105
110
|
}
|
|
106
|
-
function
|
|
111
|
+
function repositoryLocation(repositoryUrl) {
|
|
107
112
|
let parsed;
|
|
108
113
|
try {
|
|
109
114
|
parsed = new URL(repositoryUrl);
|
|
@@ -111,11 +116,16 @@ function repositorySlug(repositoryUrl) {
|
|
|
111
116
|
catch {
|
|
112
117
|
throw new Error(`REPOSITORY_URL_INVALID: ${repositoryUrl}`);
|
|
113
118
|
}
|
|
114
|
-
|
|
119
|
+
const host = parsed.hostname;
|
|
120
|
+
if (parsed.protocol !== 'https:' || (host !== 'github.com' && host !== 'gitlab.com'))
|
|
115
121
|
throw new Error(`REPOSITORY_URL_UNSUPPORTED: ${repositoryUrl}`);
|
|
116
122
|
const path = parsed.pathname.replace(/^\/+|\/+$/g, '').replace(/\.git$/, '');
|
|
117
|
-
|
|
123
|
+
// GitLab projects can sit in nested groups; GitHub is always owner/repo.
|
|
124
|
+
const shape = host === 'gitlab.com'
|
|
125
|
+
? /^[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)+$/
|
|
126
|
+
: /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
127
|
+
if (!shape.test(path) || path.split('/').some((part) => part === '.' || part === '..'))
|
|
118
128
|
throw new Error(`REPOSITORY_URL_INVALID: ${repositoryUrl}`);
|
|
119
|
-
return path;
|
|
129
|
+
return { host, path };
|
|
120
130
|
}
|
|
121
131
|
//# sourceMappingURL=publication.js.map
|
package/dist/publication.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publication.js","sourceRoot":"","sources":["../src/publication.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"publication.js","sourceRoot":"","sources":["../src/publication.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { GeneratedArtifacts } from './artifacts.js';
|
|
2
|
+
import { type PublishedAsset } from './integrity-manifest.js';
|
|
3
|
+
import { type Catalog } from './schema.js';
|
|
4
|
+
/**
|
|
5
|
+
* Reads a published artifact set. `integrity.json` is the file list, so the
|
|
6
|
+
* consumer shards can grow with the category configuration.
|
|
7
|
+
*/
|
|
8
|
+
export declare function readArtifacts(directory: string): Promise<GeneratedArtifacts>;
|
|
9
|
+
/** Verifies an artifact set and returns its catalog, checked as a portable catalog. */
|
|
10
|
+
export declare function verifiedCatalog(artifacts: GeneratedArtifacts, requirePortable?: boolean): Catalog;
|
|
11
|
+
/** The mirrored marks `integrity.json` declares, or undefined for a snapshot without any. */
|
|
12
|
+
export declare function declaredAssets(artifacts: GeneratedArtifacts): readonly PublishedAsset[] | undefined;
|
|
13
|
+
/** Compares staged mark bytes in `directory` with the digests they were declared with. */
|
|
14
|
+
export declare function checkStagedAssets(directory: string, declared: readonly PublishedAsset[]): Promise<{
|
|
15
|
+
readonly missing: readonly string[];
|
|
16
|
+
readonly mismatched: readonly string[];
|
|
17
|
+
}>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { byteDigest } from './digest.js';
|
|
2
|
+
import { parseIntegrityManifest } from './integrity-manifest.js';
|
|
3
|
+
import { verifyPortableCatalog } from './portable-verify.js';
|
|
4
|
+
import { parseCatalog } from './schema.js';
|
|
5
|
+
import { readStagedFile } from './staged-file.js';
|
|
6
|
+
import { verifyArtifacts } from './verify-artifacts.js';
|
|
7
|
+
/**
|
|
8
|
+
* Reads a published artifact set. `integrity.json` is the file list, so the
|
|
9
|
+
* consumer shards can grow with the category configuration.
|
|
10
|
+
*/
|
|
11
|
+
export async function readArtifacts(directory) {
|
|
12
|
+
const integrity = (await readStagedFile(directory, 'integrity.json')).toString('utf8');
|
|
13
|
+
const { files } = parseIntegrityManifest(JSON.parse(integrity));
|
|
14
|
+
const names = Object.keys(files).toSorted();
|
|
15
|
+
const values = await Promise.all(names.map(async (name) => [name, (await readStagedFile(directory, name)).toString('utf8')]));
|
|
16
|
+
return Object.fromEntries([
|
|
17
|
+
...values,
|
|
18
|
+
['integrity.json', integrity],
|
|
19
|
+
]);
|
|
20
|
+
}
|
|
21
|
+
/** Verifies an artifact set and returns its catalog, checked as a portable catalog. */
|
|
22
|
+
export function verifiedCatalog(artifacts, requirePortable = false) {
|
|
23
|
+
verifyArtifacts(artifacts);
|
|
24
|
+
const catalog = parseCatalog(JSON.parse(artifacts['catalog.v1.json']));
|
|
25
|
+
verifyPortableCatalog(catalog, requirePortable);
|
|
26
|
+
return catalog;
|
|
27
|
+
}
|
|
28
|
+
/** The mirrored marks `integrity.json` declares, or undefined for a snapshot without any. */
|
|
29
|
+
export function declaredAssets(artifacts) {
|
|
30
|
+
return parseIntegrityManifest(JSON.parse(artifacts['integrity.json'])).assets;
|
|
31
|
+
}
|
|
32
|
+
/** Compares staged mark bytes in `directory` with the digests they were declared with. */
|
|
33
|
+
export async function checkStagedAssets(directory, declared) {
|
|
34
|
+
const missing = [];
|
|
35
|
+
const mismatched = [];
|
|
36
|
+
for (const asset of declared) {
|
|
37
|
+
const bytes = await readStagedFile(directory, asset.name).catch((error) => {
|
|
38
|
+
if (error.code === 'ENOENT')
|
|
39
|
+
return undefined;
|
|
40
|
+
throw error;
|
|
41
|
+
});
|
|
42
|
+
if (!bytes)
|
|
43
|
+
missing.push(asset.name);
|
|
44
|
+
else if (byteDigest(bytes) !== asset.digest || bytes.byteLength !== asset.bytes)
|
|
45
|
+
mismatched.push(asset.name);
|
|
46
|
+
}
|
|
47
|
+
return { missing, mismatched };
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=published-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"published-output.js","sourceRoot":"","sources":["../src/published-output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,sBAAsB,EAAuB,MAAM,yBAAyB,CAAA;AACrF,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAgB,MAAM,aAAa,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACnD,MAAM,SAAS,GAAG,CAAC,MAAM,cAAc,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IACtF,MAAM,EAAE,KAAK,EAAE,GAAG,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAA;IAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAA;IAC3C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B,KAAK,CAAC,GAAG,CACP,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU,CAC1F,CACF,CAAA;IACD,OAAO,MAAM,CAAC,WAAW,CAAC;QACxB,GAAG,MAAM;QACT,CAAC,gBAAgB,EAAE,SAAS,CAAC;KAC9B,CAAkC,CAAA;AACrC,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,eAAe,CAAC,SAA6B,EAAE,eAAe,GAAG,KAAK;IACpF,eAAe,CAAC,SAAS,CAAC,CAAA;IAC1B,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAA;IACtE,qBAAqB,CAAC,OAAO,EAAE,eAAe,CAAC,CAAA;IAC/C,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,cAAc,CAC5B,SAA6B;IAE7B,OAAO,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;AAC/E,CAAC;AAED,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAiB,EACjB,QAAmC;IAEnC,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,MAAM,UAAU,GAAa,EAAE,CAAA;IAC/B,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACjF,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAA;YACxE,MAAM,KAAK,CAAA;QACb,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;aAC/B,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,UAAU,KAAK,KAAK,CAAC,KAAK;YAC7E,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAA;AAChC,CAAC"}
|
package/dist/site-icons.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { type IconContentType } from './icons.js';
|
|
|
4
4
|
*
|
|
5
5
|
* Many plugins are a thin wrapper over a vendor's API: the content carries no
|
|
6
6
|
* logo, and the declared homepage is the only pointer to the vendor. Fetching
|
|
7
|
-
* that site's icon once at publish time, verifying it and mirroring it
|
|
8
|
-
*
|
|
7
|
+
* that site's icon once at publish time, verifying it and mirroring it beside
|
|
8
|
+
* the catalog replaces a per-render favicon lookup in the client.
|
|
9
9
|
*/
|
|
10
10
|
export declare const SITE_ICON_MAX_HTML_BYTES: number;
|
|
11
11
|
/**
|
|
@@ -36,12 +36,13 @@ export declare function isPublicHostname(hostname: string): boolean;
|
|
|
36
36
|
* `apple-touch-icon` is preferred because it is a square PNG sized for a home
|
|
37
37
|
* screen; declared `icon` links follow in declared order; `/favicon.ico` is the
|
|
38
38
|
* conventional last resort when nothing is declared.
|
|
39
|
+
* Relative links use the document's first base href when present; the fallback
|
|
40
|
+
* stays on the homepage origin.
|
|
39
41
|
*/
|
|
40
42
|
export declare function discoverSiteIcons(html: string, baseUrl: string): readonly string[];
|
|
41
43
|
export interface SiteIconFetcher {
|
|
42
44
|
readonly fetchText: (url: string) => Promise<string>;
|
|
43
45
|
readonly fetchBytes: (url: string) => Promise<Uint8Array>;
|
|
44
|
-
readonly digest: (bytes: Uint8Array) => string;
|
|
45
46
|
}
|
|
46
47
|
/**
|
|
47
48
|
* Resolves the best usable icon for a vendor homepage.
|
package/dist/site-icons.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { parseFragment } from 'parse5';
|
|
2
|
+
import { byteDigest } from './digest.js';
|
|
1
3
|
import { inspectIconBytes, MAX_ICON_BYTES } from './icons.js';
|
|
2
4
|
/**
|
|
3
5
|
* Site icon discovery, for products that ship no brand mark of their own.
|
|
4
6
|
*
|
|
5
7
|
* Many plugins are a thin wrapper over a vendor's API: the content carries no
|
|
6
8
|
* logo, and the declared homepage is the only pointer to the vendor. Fetching
|
|
7
|
-
* that site's icon once at publish time, verifying it and mirroring it
|
|
8
|
-
*
|
|
9
|
+
* that site's icon once at publish time, verifying it and mirroring it beside
|
|
10
|
+
* the catalog replaces a per-render favicon lookup in the client.
|
|
9
11
|
*/
|
|
10
12
|
export const SITE_ICON_MAX_HTML_BYTES = 4 * 1024 * 1024;
|
|
11
13
|
/**
|
|
@@ -67,17 +69,42 @@ export function isPublicHostname(hostname) {
|
|
|
67
69
|
* `apple-touch-icon` is preferred because it is a square PNG sized for a home
|
|
68
70
|
* screen; declared `icon` links follow in declared order; `/favicon.ico` is the
|
|
69
71
|
* conventional last resort when nothing is declared.
|
|
72
|
+
* Relative links use the document's first base href when present; the fallback
|
|
73
|
+
* stays on the homepage origin.
|
|
70
74
|
*/
|
|
71
75
|
export function discoverSiteIcons(html, baseUrl) {
|
|
72
76
|
const candidates = [];
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
const elements = [];
|
|
78
|
+
const nodes = parseFragment(html).childNodes.toReversed();
|
|
79
|
+
while (nodes.length > 0) {
|
|
80
|
+
const node = nodes.pop();
|
|
81
|
+
if (!('tagName' in node))
|
|
82
|
+
continue;
|
|
83
|
+
if (node.namespaceURI === 'http://www.w3.org/1999/xhtml')
|
|
84
|
+
elements.push(node);
|
|
85
|
+
// Template contents are a separate, inert document fragment.
|
|
86
|
+
if (node.tagName !== 'template')
|
|
87
|
+
nodes.push(...node.childNodes.toReversed());
|
|
88
|
+
}
|
|
89
|
+
let resolutionBase = baseUrl;
|
|
90
|
+
for (const element of elements) {
|
|
91
|
+
if (element.tagName !== 'base')
|
|
92
|
+
continue;
|
|
93
|
+
const attributes = new Map(element.attrs.map(({ name, value }) => [name, value]));
|
|
94
|
+
if (!attributes.has('href'))
|
|
95
|
+
continue;
|
|
96
|
+
try {
|
|
97
|
+
resolutionBase = new URL(attributes.get('href'), baseUrl).toString();
|
|
80
98
|
}
|
|
99
|
+
catch {
|
|
100
|
+
// An invalid first base falls back to the document URL.
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
for (const element of elements) {
|
|
105
|
+
if (element.tagName !== 'link')
|
|
106
|
+
continue;
|
|
107
|
+
const attributes = new Map(element.attrs.map(({ name, value }) => [name, value]));
|
|
81
108
|
const rel = new Set((attributes.get('rel') ?? '').toLowerCase().split(/\s+/));
|
|
82
109
|
if (!['apple-touch-icon', 'apple-touch-icon-precomposed', 'icon', 'mask-icon'].some((name) => rel.has(name)))
|
|
83
110
|
continue;
|
|
@@ -97,7 +124,7 @@ export function discoverSiteIcons(html, baseUrl) {
|
|
|
97
124
|
const resolved = [];
|
|
98
125
|
for (const candidate of candidates.toSorted((left, right) => left.rank - right.rank)) {
|
|
99
126
|
try {
|
|
100
|
-
const url = new URL(candidate.href,
|
|
127
|
+
const url = new URL(candidate.href, resolutionBase);
|
|
101
128
|
if (url.protocol !== 'https:' || !isPublicHostname(url.hostname))
|
|
102
129
|
continue;
|
|
103
130
|
resolved.push({ url: url.toString(), rank: candidate.rank });
|
|
@@ -155,7 +182,7 @@ export async function resolveSiteIcon(homepage, fetcher) {
|
|
|
155
182
|
homepage,
|
|
156
183
|
bytes,
|
|
157
184
|
contentType: inspected.contentType,
|
|
158
|
-
digest:
|
|
185
|
+
digest: byteDigest(bytes),
|
|
159
186
|
};
|
|
160
187
|
}
|
|
161
188
|
return { failed: 'NO_USABLE_ICON' };
|
package/dist/site-icons.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-icons.js","sourceRoot":"","sources":["../src/site-icons.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAwB,MAAM,YAAY,CAAA;AAEnF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA;AAEvD;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,GAAG,IAAI,CAAA;AAE9C,sEAAsE;AACtE,MAAM,gBAAgB,GACpB,kHAAkH,CAAA;AAWpH;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAA4B;IAC3D,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3B,IAAI,MAAW,CAAA;IACf,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC9C,OAAO,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;AACrF,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IAC3D,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAA;IAChG,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,KAAK,CAAA;IAC3E,IACE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAClB,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAE9F,OAAO,KAAK,CAAA;IACd,MAAM,IAAI,GAAG,8CAA8C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACtE,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAqB,CAAA;QAC5D,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,GAAG;YAAE,OAAO,KAAK,CAAA;QAC9D,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,KAAK,CAAA;QACxC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO,KAAK,CAAA;QACjD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,KAAK,CAAA;QACxC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,sDAAsD;IACtD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;AAC3B,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"site-icons.js","sourceRoot":"","sources":["../src/site-icons.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { CatalogPolicy } from './policy.js';
|
|
2
|
+
import { type SourceConfig } from './sources.js';
|
|
3
|
+
export interface Snapshot {
|
|
4
|
+
readonly files: ReadonlyMap<string, Uint8Array>;
|
|
5
|
+
readonly symlinks: readonly string[];
|
|
6
|
+
}
|
|
7
|
+
export interface SnapshotLoader {
|
|
8
|
+
load(repositoryUrl: string, commitSha: string, pluginSubdirectory: string): Promise<Snapshot>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Read one GitHub repository tarball into path -> bytes.
|
|
12
|
+
*
|
|
13
|
+
* GitHub wraps every entry in a single top-level `<repo>-<sha>/` directory,
|
|
14
|
+
* which is stripped so the keys match the tree API's repository-relative
|
|
15
|
+
* paths. Only regular files are taken: directories, symlinks, hardlinks and
|
|
16
|
+
* the `pax_global_header` record are skipped, so a link can never be
|
|
17
|
+
* materialized as content. Every remaining path goes through
|
|
18
|
+
* `safeRelativePath`, so an archive that tries to escape the repository is
|
|
19
|
+
* rejected rather than partially trusted. This is a whole-repository archive
|
|
20
|
+
* shared across plugins, so an oversized unrelated file is drained and
|
|
21
|
+
* counted against the archive budget but not retained. The selected plugin's
|
|
22
|
+
* files are checked against the tree before the archive is fetched and again
|
|
23
|
+
* when its snapshot is validated.
|
|
24
|
+
*/
|
|
25
|
+
export declare function readArchiveFiles(archive: Uint8Array, policy: CatalogPolicy): Promise<Map<string, Uint8Array>>;
|
|
26
|
+
export declare class NetworkSnapshotLoader implements SnapshotLoader {
|
|
27
|
+
#private;
|
|
28
|
+
constructor(policy: CatalogPolicy);
|
|
29
|
+
load(repositoryUrl: string, commitSha: string, pluginSubdirectory: string): Promise<Snapshot>;
|
|
30
|
+
}
|
|
31
|
+
export declare class FixtureSnapshotLoader implements SnapshotLoader {
|
|
32
|
+
#private;
|
|
33
|
+
constructor(root: string, sources: readonly SourceConfig[]);
|
|
34
|
+
load(repositoryUrl: string, _commitSha: string, pluginSubdirectory: string): Promise<Snapshot>;
|
|
35
|
+
}
|
|
36
|
+
export declare class DirectorySnapshotLoader implements SnapshotLoader {
|
|
37
|
+
load(_repositoryUrl: string, _commitSha: string, pluginSubdirectory: string): Promise<Snapshot>;
|
|
38
|
+
}
|
|
39
|
+
export declare function snapshotFromDirectory(root: string, pluginSubdirectory: string): Promise<Snapshot>;
|