@mdwrk/extension-runtime 1.0.1
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 +34 -0
- package/dist/catalog.d.ts +29 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +244 -0
- package/dist/catalog.js.map +1 -0
- package/dist/compatibility.d.ts +12 -0
- package/dist/compatibility.d.ts.map +1 -0
- package/dist/compatibility.js +108 -0
- package/dist/compatibility.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/loader.d.ts +7 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +34 -0
- package/dist/loader.js.map +1 -0
- package/dist/registry.d.ts +12 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +52 -0
- package/dist/registry.js.map +1 -0
- package/dist/runtime.d.ts +3 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +765 -0
- package/dist/runtime.js.map +1 -0
- package/dist/storage.d.ts +13 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +63 -0
- package/dist/storage.js.map +1 -0
- package/dist/types.d.ts +172 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +4 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +54 -0
- package/dist/validation.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +85 -0
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# mdwrk/extension-runtime
|
|
2
|
+
|
|
3
|
+
Portable extension runtime for Markdown Workspace hosts.
|
|
4
|
+
|
|
5
|
+
This package provides:
|
|
6
|
+
- bundled extension registration
|
|
7
|
+
- external catalog registration and loading
|
|
8
|
+
- manifest validation
|
|
9
|
+
- compatibility checks
|
|
10
|
+
- persisted enabled/config/install state with deterministic namespaced keys
|
|
11
|
+
- activation and deactivation lifecycle management
|
|
12
|
+
- capability-scoped host wrappers
|
|
13
|
+
- runtime diagnostics and state snapshots
|
|
14
|
+
- signed-manifest verification
|
|
15
|
+
- module integrity verification
|
|
16
|
+
- install/update/remove flows for external extensions
|
|
17
|
+
- installed extension cache rehydration
|
|
18
|
+
|
|
19
|
+
## Public runtime surface
|
|
20
|
+
|
|
21
|
+
The runtime exposes methods for:
|
|
22
|
+
- registering bundled entries
|
|
23
|
+
- registering or loading catalogs
|
|
24
|
+
- listing available catalog entries
|
|
25
|
+
- installing, updating, and removing external extensions
|
|
26
|
+
- enabling/disabling and activating/deactivating extensions
|
|
27
|
+
- reading configuration stores and runtime services
|
|
28
|
+
|
|
29
|
+
## Current status
|
|
30
|
+
|
|
31
|
+
Implemented through Phase 13.
|
|
32
|
+
|
|
33
|
+
The package is publishable and includes the formal third-party catalog installer/runtime path described in the repository architecture docs.
|
|
34
|
+
Production deployments should still use managed signing keys and hosted catalog infrastructure rather than the development sample signer generated in checkpoint tooling.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ExtensionCatalogDocument, ExtensionCatalogEntry, ExtensionIntegrity, ExtensionManifest, SignedExtensionManifest, TrustedExtensionSigner } from "@mdwrk/extension-manifest";
|
|
2
|
+
import type { ExtensionArtifactTransport, ExtensionRuntimeTrustPolicy, RegisteredExternalCatalogEntry } from "./types.js";
|
|
3
|
+
export declare const EXTENSION_CATALOG_SIGNED_MANIFEST_SCHEMA_VERSION: 1;
|
|
4
|
+
export declare const createExtensionCatalogEntryId: (extensionId: string, version: string) => string;
|
|
5
|
+
export declare function resolveCatalogUrl(baseUrl: string | undefined, value: string): string;
|
|
6
|
+
export declare function canonicalizeJson(value: unknown): string;
|
|
7
|
+
export declare function bytesToBase64Url(bytes: Uint8Array): string;
|
|
8
|
+
export declare function digestText(value: string, algorithm?: ExtensionIntegrity["algorithm"]): Promise<string>;
|
|
9
|
+
export declare function verifyTextIntegrity(value: string, integrity: ExtensionIntegrity): Promise<boolean>;
|
|
10
|
+
export interface VerifiedSignedManifest {
|
|
11
|
+
readonly manifest: ExtensionManifest;
|
|
12
|
+
readonly signer: TrustedExtensionSigner | null;
|
|
13
|
+
readonly signatureVerified: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function verifySignedManifest(signedManifest: SignedExtensionManifest, signers: readonly TrustedExtensionSigner[]): Promise<VerifiedSignedManifest>;
|
|
16
|
+
export declare function createFetchExtensionArtifactTransport(fetchImpl?: typeof fetch): ExtensionArtifactTransport;
|
|
17
|
+
export declare function createInMemoryExtensionArtifactTransport(seed: Readonly<Record<string, string | unknown>>): ExtensionArtifactTransport;
|
|
18
|
+
export declare function evaluateCatalogEntryPolicy(entry: ExtensionCatalogEntry, trustPolicy: ExtensionRuntimeTrustPolicy | undefined): readonly string[];
|
|
19
|
+
export declare function validateCatalogDocument(document: ExtensionCatalogDocument): readonly string[];
|
|
20
|
+
export interface InstallableCatalogPayload {
|
|
21
|
+
readonly catalogEntry: RegisteredExternalCatalogEntry;
|
|
22
|
+
readonly manifest: ExtensionManifest;
|
|
23
|
+
readonly signedManifest: SignedExtensionManifest | null;
|
|
24
|
+
readonly moduleCode: string;
|
|
25
|
+
readonly signatureVerified: boolean;
|
|
26
|
+
readonly signer: TrustedExtensionSigner | null;
|
|
27
|
+
}
|
|
28
|
+
export declare function fetchInstallableCatalogPayload(catalogEntry: RegisteredExternalCatalogEntry, transport: ExtensionArtifactTransport, trustPolicy: ExtensionRuntimeTrustPolicy): Promise<InstallableCatalogPayload>;
|
|
29
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EACV,0BAA0B,EAC1B,2BAA2B,EAC3B,8BAA8B,EAC/B,MAAM,YAAY,CAAC;AAIpB,eAAO,MAAM,gDAAgD,EAAG,CAAU,CAAC;AAE3E,eAAO,MAAM,6BAA6B,GAAI,aAAa,MAAM,EAAE,SAAS,MAAM,KAAG,MAAqC,CAAC;AAE3H,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQpF;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEvD;AA+CD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAU1D;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,kBAAkB,CAAC,WAAW,CAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAOtH;AAED,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAGxG;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC/C,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;CACrC;AAMD,wBAAsB,oBAAoB,CACxC,cAAc,EAAE,uBAAuB,EACvC,OAAO,EAAE,SAAS,sBAAsB,EAAE,GACzC,OAAO,CAAC,sBAAsB,CAAC,CA6BjC;AAED,wBAAgB,qCAAqC,CAAC,SAAS,GAAE,OAAO,KAAyC,GAAG,0BAA0B,CAa7I;AAED,wBAAgB,wCAAwC,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,0BAA0B,CAarI;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,2BAA2B,GAAG,SAAS,GAAG,SAAS,MAAM,EAAE,CAkBhJ;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,SAAS,MAAM,EAAE,CAoC7F;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,YAAY,EAAE,8BAA8B,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,cAAc,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACxD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;CAChD;AAED,wBAAsB,8BAA8B,CAClD,YAAY,EAAE,8BAA8B,EAC5C,SAAS,EAAE,0BAA0B,EACrC,WAAW,EAAE,2BAA2B,GACvC,OAAO,CAAC,yBAAyB,CAAC,CAgEpC"}
|
package/dist/catalog.js
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
const textEncoder = new TextEncoder();
|
|
2
|
+
export const EXTENSION_CATALOG_SIGNED_MANIFEST_SCHEMA_VERSION = 1;
|
|
3
|
+
export const createExtensionCatalogEntryId = (extensionId, version) => `${extensionId}@${version}`;
|
|
4
|
+
export function resolveCatalogUrl(baseUrl, value) {
|
|
5
|
+
if (/^[a-zA-Z][a-zA-Z\d+.-]*:/.test(value)) {
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
if (!baseUrl) {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
return new URL(value, baseUrl).toString();
|
|
12
|
+
}
|
|
13
|
+
export function canonicalizeJson(value) {
|
|
14
|
+
return JSON.stringify(sortJson(value));
|
|
15
|
+
}
|
|
16
|
+
function sortJson(value) {
|
|
17
|
+
if (Array.isArray(value)) {
|
|
18
|
+
return value.map((entry) => sortJson(entry));
|
|
19
|
+
}
|
|
20
|
+
if (!value || typeof value !== "object") {
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
return Object.keys(value)
|
|
24
|
+
.sort((left, right) => left.localeCompare(right))
|
|
25
|
+
.reduce((output, key) => {
|
|
26
|
+
output[key] = sortJson(value[key]);
|
|
27
|
+
return output;
|
|
28
|
+
}, {});
|
|
29
|
+
}
|
|
30
|
+
function hexToBytes(value) {
|
|
31
|
+
const clean = value.trim().toLowerCase();
|
|
32
|
+
if (clean.length % 2 !== 0) {
|
|
33
|
+
throw new Error(`Expected an even-length hexadecimal digest, received '${value}'.`);
|
|
34
|
+
}
|
|
35
|
+
const bytes = new Uint8Array(clean.length / 2);
|
|
36
|
+
for (let index = 0; index < clean.length; index += 2) {
|
|
37
|
+
bytes[index / 2] = Number.parseInt(clean.slice(index, index + 2), 16);
|
|
38
|
+
}
|
|
39
|
+
return bytes;
|
|
40
|
+
}
|
|
41
|
+
function bytesToHex(bytes) {
|
|
42
|
+
return Array.from(bytes).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
43
|
+
}
|
|
44
|
+
function base64UrlToBytes(value) {
|
|
45
|
+
const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
46
|
+
const padded = normalized + "=".repeat((4 - (normalized.length % 4 || 4)) % 4);
|
|
47
|
+
if (typeof atob === "function") {
|
|
48
|
+
const text = atob(padded);
|
|
49
|
+
return Uint8Array.from(text, (character) => character.charCodeAt(0));
|
|
50
|
+
}
|
|
51
|
+
const nodeBuffer = globalThis.Buffer;
|
|
52
|
+
if (nodeBuffer) {
|
|
53
|
+
return Uint8Array.from(nodeBuffer.from(padded, "base64"));
|
|
54
|
+
}
|
|
55
|
+
throw new Error("Base64url decoding is unavailable in this runtime.");
|
|
56
|
+
}
|
|
57
|
+
export function bytesToBase64Url(bytes) {
|
|
58
|
+
const nodeBuffer = globalThis.Buffer;
|
|
59
|
+
if (nodeBuffer) {
|
|
60
|
+
return nodeBuffer.from(bytes).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
61
|
+
}
|
|
62
|
+
if (typeof btoa === "function") {
|
|
63
|
+
const text = Array.from(bytes).map((byte) => String.fromCharCode(byte)).join("");
|
|
64
|
+
return btoa(text).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
65
|
+
}
|
|
66
|
+
throw new Error("Base64url encoding is unavailable in this runtime.");
|
|
67
|
+
}
|
|
68
|
+
export async function digestText(value, algorithm = "sha256") {
|
|
69
|
+
if (!globalThis.crypto?.subtle) {
|
|
70
|
+
throw new Error("Web Crypto SubtleCrypto is required for extension integrity verification.");
|
|
71
|
+
}
|
|
72
|
+
const algo = algorithm.toUpperCase().replace("SHA", "SHA-");
|
|
73
|
+
const digest = await globalThis.crypto.subtle.digest(algo, textEncoder.encode(value));
|
|
74
|
+
return bytesToHex(new Uint8Array(digest));
|
|
75
|
+
}
|
|
76
|
+
export async function verifyTextIntegrity(value, integrity) {
|
|
77
|
+
const digest = await digestText(value, integrity.algorithm);
|
|
78
|
+
return digest.toLowerCase() === integrity.digest.toLowerCase();
|
|
79
|
+
}
|
|
80
|
+
function toArrayBuffer(bytes) {
|
|
81
|
+
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
82
|
+
}
|
|
83
|
+
export async function verifySignedManifest(signedManifest, signers) {
|
|
84
|
+
const signer = signers.find((candidate) => candidate.keyId === signedManifest.signature.keyId && candidate.algorithm === signedManifest.signature.algorithm) ?? null;
|
|
85
|
+
if (!signer) {
|
|
86
|
+
throw new Error(`No trusted signer with key id '${signedManifest.signature.keyId}' is configured.`);
|
|
87
|
+
}
|
|
88
|
+
if (!globalThis.crypto?.subtle) {
|
|
89
|
+
throw new Error("Web Crypto SubtleCrypto is required for extension manifest signature verification.");
|
|
90
|
+
}
|
|
91
|
+
const key = await globalThis.crypto.subtle.importKey("jwk", signer.publicKeyJwk, { name: "ECDSA", namedCurve: "P-256" }, false, ["verify"]);
|
|
92
|
+
const verified = await globalThis.crypto.subtle.verify({ name: "ECDSA", hash: "SHA-256" }, key, toArrayBuffer(base64UrlToBytes(signedManifest.signature.signature)), toArrayBuffer(textEncoder.encode(canonicalizeJson(signedManifest.manifest))));
|
|
93
|
+
if (!verified) {
|
|
94
|
+
throw new Error(`Signature verification failed for '${signedManifest.manifest.id}'.`);
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
manifest: signedManifest.manifest,
|
|
98
|
+
signer,
|
|
99
|
+
signatureVerified: true,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export function createFetchExtensionArtifactTransport(fetchImpl = globalThis.fetch.bind(globalThis)) {
|
|
103
|
+
return {
|
|
104
|
+
async fetchText(url) {
|
|
105
|
+
const response = await fetchImpl(url);
|
|
106
|
+
if (!response.ok) {
|
|
107
|
+
throw new Error(`Failed to fetch '${url}': ${response.status} ${response.statusText}`);
|
|
108
|
+
}
|
|
109
|
+
return await response.text();
|
|
110
|
+
},
|
|
111
|
+
async fetchJson(url) {
|
|
112
|
+
return JSON.parse(await this.fetchText(url));
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export function createInMemoryExtensionArtifactTransport(seed) {
|
|
117
|
+
const table = new Map(Object.entries(seed).map(([key, value]) => [key, typeof value === "string" ? value : JSON.stringify(value)]));
|
|
118
|
+
return {
|
|
119
|
+
async fetchText(url) {
|
|
120
|
+
if (!table.has(url)) {
|
|
121
|
+
throw new Error(`Missing in-memory extension artifact '${url}'.`);
|
|
122
|
+
}
|
|
123
|
+
return table.get(url) ?? "";
|
|
124
|
+
},
|
|
125
|
+
async fetchJson(url) {
|
|
126
|
+
return JSON.parse(await this.fetchText(url));
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
export function evaluateCatalogEntryPolicy(entry, trustPolicy) {
|
|
131
|
+
const issues = [];
|
|
132
|
+
if (!trustPolicy) {
|
|
133
|
+
issues.push("External extension installation is disabled because no trust policy is configured.");
|
|
134
|
+
return issues;
|
|
135
|
+
}
|
|
136
|
+
if (trustPolicy.allowedExtensionIds && trustPolicy.allowedExtensionIds.length > 0 && !trustPolicy.allowedExtensionIds.includes(entry.extensionId)) {
|
|
137
|
+
issues.push(`Extension id '${entry.extensionId}' is not allowlisted.`);
|
|
138
|
+
}
|
|
139
|
+
if (trustPolicy.allowedPackageNames && trustPolicy.allowedPackageNames.length > 0 && !trustPolicy.allowedPackageNames.includes(entry.packageName)) {
|
|
140
|
+
issues.push(`Package '${entry.packageName}' is not allowlisted.`);
|
|
141
|
+
}
|
|
142
|
+
if (trustPolicy.allowedPublishers && trustPolicy.allowedPublishers.length > 0) {
|
|
143
|
+
if (!entry.publisher || !trustPolicy.allowedPublishers.includes(entry.publisher)) {
|
|
144
|
+
issues.push(`Publisher '${entry.publisher ?? "unknown"}' is not allowlisted.`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return issues;
|
|
148
|
+
}
|
|
149
|
+
export function validateCatalogDocument(document) {
|
|
150
|
+
const issues = [];
|
|
151
|
+
if (document.schemaVersion !== 1) {
|
|
152
|
+
issues.push(`Unsupported extension catalog schemaVersion '${String(document.schemaVersion)}'.`);
|
|
153
|
+
}
|
|
154
|
+
if (!Array.isArray(document.extensions)) {
|
|
155
|
+
issues.push("Extension catalog 'extensions' must be an array.");
|
|
156
|
+
return issues;
|
|
157
|
+
}
|
|
158
|
+
const entryIds = new Set();
|
|
159
|
+
for (const entry of document.extensions) {
|
|
160
|
+
if (!entry.entryId) {
|
|
161
|
+
issues.push("Extension catalog entryId is required.");
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (entryIds.has(entry.entryId)) {
|
|
165
|
+
issues.push(`Duplicate catalog entry id '${entry.entryId}'.`);
|
|
166
|
+
}
|
|
167
|
+
entryIds.add(entry.entryId);
|
|
168
|
+
if (!entry.extensionId) {
|
|
169
|
+
issues.push(`Catalog entry '${entry.entryId}' is missing extensionId.`);
|
|
170
|
+
}
|
|
171
|
+
if (!entry.packageName) {
|
|
172
|
+
issues.push(`Catalog entry '${entry.entryId}' is missing packageName.`);
|
|
173
|
+
}
|
|
174
|
+
if (!entry.version) {
|
|
175
|
+
issues.push(`Catalog entry '${entry.entryId}' is missing version.`);
|
|
176
|
+
}
|
|
177
|
+
if (!entry.urls?.manifest || !entry.urls?.signedManifest || !entry.urls?.module) {
|
|
178
|
+
issues.push(`Catalog entry '${entry.entryId}' must include urls.manifest, urls.signedManifest, and urls.module.`);
|
|
179
|
+
}
|
|
180
|
+
if (!entry.integrity?.module?.digest) {
|
|
181
|
+
issues.push(`Catalog entry '${entry.entryId}' must include module integrity metadata.`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return issues;
|
|
185
|
+
}
|
|
186
|
+
export async function fetchInstallableCatalogPayload(catalogEntry, transport, trustPolicy) {
|
|
187
|
+
const entryPolicyIssues = evaluateCatalogEntryPolicy(catalogEntry.entry, trustPolicy);
|
|
188
|
+
if (entryPolicyIssues.length > 0) {
|
|
189
|
+
throw new Error(entryPolicyIssues.join(" "));
|
|
190
|
+
}
|
|
191
|
+
const manifestUrl = resolveCatalogUrl(catalogEntry.baseUrl, catalogEntry.entry.urls.manifest);
|
|
192
|
+
const signedManifestUrl = resolveCatalogUrl(catalogEntry.baseUrl, catalogEntry.entry.urls.signedManifest);
|
|
193
|
+
const moduleUrl = resolveCatalogUrl(catalogEntry.baseUrl, catalogEntry.entry.urls.module);
|
|
194
|
+
const signedManifest = await transport.fetchJson(signedManifestUrl);
|
|
195
|
+
const manifestText = canonicalizeJson(signedManifest.manifest);
|
|
196
|
+
if (catalogEntry.entry.integrity.manifest) {
|
|
197
|
+
const manifestIntegrityOk = await verifyTextIntegrity(manifestText, catalogEntry.entry.integrity.manifest);
|
|
198
|
+
if (!manifestIntegrityOk) {
|
|
199
|
+
throw new Error(`Manifest integrity verification failed for '${catalogEntry.entry.extensionId}'.`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
let signer = null;
|
|
203
|
+
let signatureVerified = false;
|
|
204
|
+
if (signedManifest) {
|
|
205
|
+
if (!trustPolicy.allowUnsigned) {
|
|
206
|
+
const result = await verifySignedManifest(signedManifest, trustPolicy.trustedSigners ?? []);
|
|
207
|
+
signer = result.signer;
|
|
208
|
+
signatureVerified = result.signatureVerified;
|
|
209
|
+
}
|
|
210
|
+
else if ((trustPolicy.trustedSigners?.length ?? 0) > 0) {
|
|
211
|
+
const result = await verifySignedManifest(signedManifest, trustPolicy.trustedSigners ?? []);
|
|
212
|
+
signer = result.signer;
|
|
213
|
+
signatureVerified = result.signatureVerified;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const manifest = signedManifest.manifest;
|
|
217
|
+
if (manifest.id !== catalogEntry.entry.extensionId) {
|
|
218
|
+
throw new Error(`Catalog entry '${catalogEntry.entry.entryId}' expected extension id '${catalogEntry.entry.extensionId}' but manifest declared '${manifest.id}'.`);
|
|
219
|
+
}
|
|
220
|
+
if (manifest.version !== catalogEntry.entry.version) {
|
|
221
|
+
throw new Error(`Catalog entry '${catalogEntry.entry.entryId}' expected version '${catalogEntry.entry.version}' but manifest declared '${manifest.version}'.`);
|
|
222
|
+
}
|
|
223
|
+
const manifestDocument = await transport.fetchJson(manifestUrl).catch(async () => JSON.parse(await transport.fetchText(manifestUrl)));
|
|
224
|
+
if (canonicalizeJson(manifestDocument) !== manifestText) {
|
|
225
|
+
throw new Error(`Manifest fetched from '${manifestUrl}' did not match the signed manifest payload for '${manifest.id}'.`);
|
|
226
|
+
}
|
|
227
|
+
const moduleCode = await transport.fetchText(moduleUrl);
|
|
228
|
+
const moduleIntegrityOk = await verifyTextIntegrity(moduleCode, catalogEntry.entry.integrity.module);
|
|
229
|
+
if (!moduleIntegrityOk) {
|
|
230
|
+
throw new Error(`Module integrity verification failed for '${catalogEntry.entry.extensionId}'.`);
|
|
231
|
+
}
|
|
232
|
+
if (!signatureVerified && !trustPolicy.allowIntegrityOnly) {
|
|
233
|
+
throw new Error(`Signed manifest verification is required for '${catalogEntry.entry.extensionId}'.`);
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
catalogEntry,
|
|
237
|
+
manifest,
|
|
238
|
+
signedManifest,
|
|
239
|
+
moduleCode,
|
|
240
|
+
signatureVerified,
|
|
241
|
+
signer,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ExtensionManifest } from "@mdwrk/extension-manifest";
|
|
2
|
+
import type { ExtensionRuntimeCompatibilityResult } from "./types.js";
|
|
3
|
+
interface CompatibilityContext {
|
|
4
|
+
readonly hostApiVersion: string;
|
|
5
|
+
readonly hostVersion: string;
|
|
6
|
+
readonly runtimeVersion: string;
|
|
7
|
+
readonly themeContractVersion: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function satisfiesVersionRange(actual: string, range: string | number | undefined): boolean;
|
|
10
|
+
export declare function evaluateExtensionCompatibility(manifest: ExtensionManifest, context?: CompatibilityContext): ExtensionRuntimeCompatibilityResult;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=compatibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compatibility.d.ts","sourceRoot":"","sources":["../src/compatibility.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,EAAsC,mCAAmC,EAAE,MAAM,YAAY,CAAC;AAE1G,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACvC;AA8DD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAKjG;AAED,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,GAAE,oBAKR,GACA,mCAAmC,CAqCrC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { EXTENSION_HOST_API_VERSION } from "@mdwrk/extension-host";
|
|
2
|
+
import { EXTENSION_MANIFEST_VERSION, EXTENSION_RUNTIME_API_BASELINE, } from "@mdwrk/extension-manifest";
|
|
3
|
+
import { THEME_CONTRACT_VERSION } from "@mdwrk/theme-contract";
|
|
4
|
+
const parseVersion = (value) => {
|
|
5
|
+
const match = value.trim().match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
6
|
+
if (!match)
|
|
7
|
+
return null;
|
|
8
|
+
return {
|
|
9
|
+
major: Number(match[1]),
|
|
10
|
+
minor: Number(match[2]),
|
|
11
|
+
patch: Number(match[3]),
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
const compareVersions = (left, right) => {
|
|
15
|
+
const a = parseVersion(left);
|
|
16
|
+
const b = parseVersion(right);
|
|
17
|
+
if (!a || !b) {
|
|
18
|
+
return left === right ? 0 : left.localeCompare(right);
|
|
19
|
+
}
|
|
20
|
+
if (a.major !== b.major)
|
|
21
|
+
return a.major - b.major;
|
|
22
|
+
if (a.minor !== b.minor)
|
|
23
|
+
return a.minor - b.minor;
|
|
24
|
+
return a.patch - b.patch;
|
|
25
|
+
};
|
|
26
|
+
const matchesComparator = (actual, comparator) => {
|
|
27
|
+
const trimmed = comparator.trim();
|
|
28
|
+
if (!trimmed || trimmed === "*")
|
|
29
|
+
return true;
|
|
30
|
+
if (trimmed.startsWith("^")) {
|
|
31
|
+
const expected = parseVersion(trimmed.slice(1));
|
|
32
|
+
const current = parseVersion(actual);
|
|
33
|
+
if (!expected || !current)
|
|
34
|
+
return actual === trimmed.slice(1);
|
|
35
|
+
return current.major == expected.major && compareVersions(actual, `${expected.major}.${expected.minor}.${expected.patch}`) >= 0;
|
|
36
|
+
}
|
|
37
|
+
if (trimmed.startsWith("~")) {
|
|
38
|
+
const expected = parseVersion(trimmed.slice(1));
|
|
39
|
+
const current = parseVersion(actual);
|
|
40
|
+
if (!expected || !current)
|
|
41
|
+
return actual === trimmed.slice(1);
|
|
42
|
+
return current.major == expected.major && current.minor == expected.minor && compareVersions(actual, `${expected.major}.${expected.minor}.${expected.patch}`) >= 0;
|
|
43
|
+
}
|
|
44
|
+
const operators = [">=", "<=", ">", "<"];
|
|
45
|
+
for (const operator of operators) {
|
|
46
|
+
if (trimmed.startsWith(operator)) {
|
|
47
|
+
const expected = trimmed.slice(operator.length).trim();
|
|
48
|
+
const delta = compareVersions(actual, expected);
|
|
49
|
+
if (operator === ">=")
|
|
50
|
+
return delta >= 0;
|
|
51
|
+
if (operator === "<=")
|
|
52
|
+
return delta <= 0;
|
|
53
|
+
if (operator === ">")
|
|
54
|
+
return delta > 0;
|
|
55
|
+
return delta < 0;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return compareVersions(actual, trimmed) === 0;
|
|
59
|
+
};
|
|
60
|
+
export function satisfiesVersionRange(actual, range) {
|
|
61
|
+
if (range == null)
|
|
62
|
+
return true;
|
|
63
|
+
const normalized = String(range).trim();
|
|
64
|
+
if (!normalized || normalized === "*")
|
|
65
|
+
return true;
|
|
66
|
+
return normalized.split(/\s+/).every((part) => matchesComparator(actual, part));
|
|
67
|
+
}
|
|
68
|
+
export function evaluateExtensionCompatibility(manifest, context = {
|
|
69
|
+
hostApiVersion: EXTENSION_HOST_API_VERSION,
|
|
70
|
+
hostVersion: "0.0.0",
|
|
71
|
+
runtimeVersion: EXTENSION_RUNTIME_API_BASELINE,
|
|
72
|
+
themeContractVersion: THEME_CONTRACT_VERSION,
|
|
73
|
+
}) {
|
|
74
|
+
const issues = [];
|
|
75
|
+
if (manifest.manifestVersion !== EXTENSION_MANIFEST_VERSION) {
|
|
76
|
+
issues.push({
|
|
77
|
+
target: "manifestVersion",
|
|
78
|
+
expected: EXTENSION_MANIFEST_VERSION,
|
|
79
|
+
actual: manifest.manifestVersion,
|
|
80
|
+
message: `Manifest version ${String(manifest.manifestVersion)} is incompatible with runtime manifest baseline ${EXTENSION_MANIFEST_VERSION}.`,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const checks = [
|
|
84
|
+
["hostApi", manifest.compatibility.hostApi, context.hostApiVersion],
|
|
85
|
+
["runtime", manifest.compatibility.runtime, context.runtimeVersion],
|
|
86
|
+
["app", manifest.compatibility.app, context.hostVersion],
|
|
87
|
+
["themeContract", manifest.compatibility.themeContract, context.themeContractVersion],
|
|
88
|
+
["renderer", manifest.compatibility.renderer, "0.0.0"],
|
|
89
|
+
["editor", manifest.compatibility.editor, "0.0.0"],
|
|
90
|
+
];
|
|
91
|
+
for (const [target, expected, actual] of checks) {
|
|
92
|
+
if (expected == null)
|
|
93
|
+
continue;
|
|
94
|
+
if (!satisfiesVersionRange(actual, expected)) {
|
|
95
|
+
issues.push({
|
|
96
|
+
target,
|
|
97
|
+
expected,
|
|
98
|
+
actual,
|
|
99
|
+
message: `Expected ${target} to satisfy ${String(expected)}, received ${actual}.`,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
compatible: issues.length === 0,
|
|
105
|
+
issues,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=compatibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compatibility.js","sourceRoot":"","sources":["../src/compatibility.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./version.js";
|
|
2
|
+
export * from "./types.js";
|
|
3
|
+
export * from "./catalog.js";
|
|
4
|
+
export * from "./storage.js";
|
|
5
|
+
export * from "./validation.js";
|
|
6
|
+
export * from "./compatibility.js";
|
|
7
|
+
export * from "./loader.js";
|
|
8
|
+
export * from "./registry.js";
|
|
9
|
+
export * from "./runtime.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./version.js";
|
|
2
|
+
export * from "./types.js";
|
|
3
|
+
export * from "./catalog.js";
|
|
4
|
+
export * from "./storage.js";
|
|
5
|
+
export * from "./validation.js";
|
|
6
|
+
export * from "./compatibility.js";
|
|
7
|
+
export * from "./loader.js";
|
|
8
|
+
export * from "./registry.js";
|
|
9
|
+
export * from "./runtime.js";
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
|
package/dist/loader.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MarkdownWorkspaceExtension } from "@mdwrk/extension-host";
|
|
2
|
+
import type { RegisteredRuntimeExtensionCatalogEntry } from "./types.js";
|
|
3
|
+
export interface ExtensionLoader {
|
|
4
|
+
load(entry: RegisteredRuntimeExtensionCatalogEntry): Promise<MarkdownWorkspaceExtension>;
|
|
5
|
+
}
|
|
6
|
+
export declare function createExtensionLoader(): ExtensionLoader;
|
|
7
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAExE,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,KAAK,EAAE,sCAAsC,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;CAC1F;AAiBD,wBAAgB,qBAAqB,IAAI,eAAe,CAiBvD"}
|
package/dist/loader.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { validateExtensionManifest } from "./validation.js";
|
|
2
|
+
function normalizeLoadedExtension(value) {
|
|
3
|
+
if (value && typeof value === "object") {
|
|
4
|
+
if ("manifest" in value && "activate" in value) {
|
|
5
|
+
return value;
|
|
6
|
+
}
|
|
7
|
+
if ("default" in value && value.default && typeof value.default === "object") {
|
|
8
|
+
const nested = value.default;
|
|
9
|
+
if (nested && typeof nested === "object" && "manifest" in nested && "activate" in nested) {
|
|
10
|
+
return nested;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
throw new Error("Extension loader did not return a MarkdownWorkspaceExtension object.");
|
|
15
|
+
}
|
|
16
|
+
export function createExtensionLoader() {
|
|
17
|
+
return {
|
|
18
|
+
async load(entry) {
|
|
19
|
+
const loaded = normalizeLoadedExtension(await entry.load());
|
|
20
|
+
const issues = validateExtensionManifest(loaded.manifest);
|
|
21
|
+
if (issues.length > 0) {
|
|
22
|
+
throw new Error(`Loaded extension manifest is invalid: ${issues.map((issue) => `${issue.path}: ${issue.message}`).join("; ")}`);
|
|
23
|
+
}
|
|
24
|
+
if (loaded.manifest.id !== entry.manifest.id) {
|
|
25
|
+
throw new Error(`Loaded extension manifest id '${loaded.manifest.id}' does not match registered id '${entry.manifest.id}'.`);
|
|
26
|
+
}
|
|
27
|
+
if (loaded.manifest.version !== entry.manifest.version) {
|
|
28
|
+
throw new Error(`Loaded extension version '${loaded.manifest.version}' does not match registered version '${entry.manifest.version}'.`);
|
|
29
|
+
}
|
|
30
|
+
return loaded;
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAO5D,SAAS,wBAAwB,CAAC,KAAc;IAC9C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,IAAI,UAAU,IAAI,KAAK,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YAC/C,OAAO,KAAmC,CAAC;QAC7C,CAAC;QACD,IAAI,SAAS,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC7E,MAAM,MAAM,GAAG,KAAK,CAAC,OAAkB,CAAC;YACxC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,UAAU,IAAI,MAAM,IAAI,UAAU,IAAI,MAAM,EAAE,CAAC;gBACzF,OAAO,MAAoC,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,KAA6C;YACtD,MAAM,MAAM,GAAG,wBAAwB,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5D,MAAM,MAAM,GAAG,yBAAyB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC1D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,yCAAyC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClI,CAAC;YACD,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAC7C,MAAM,IAAI,KAAK,CAAC,iCAAiC,MAAM,CAAC,QAAQ,CAAC,EAAE,mCAAmC,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;YAC/H,CAAC;YACD,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,KAAK,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACvD,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,CAAC,QAAQ,CAAC,OAAO,wCAAwC,KAAK,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;YAC1I,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Disposable } from "@mdwrk/extension-host";
|
|
2
|
+
import type { BundledExtensionCatalogEntry, InstalledExtensionCatalogEntry, RegisteredRuntimeExtensionCatalogEntry, RuntimeExtensionCatalogEntry } from "./types.js";
|
|
3
|
+
export interface ExtensionRegistry {
|
|
4
|
+
register(entry: RuntimeExtensionCatalogEntry): Disposable;
|
|
5
|
+
registerBundled(entry: BundledExtensionCatalogEntry): Disposable;
|
|
6
|
+
registerInstalled(entry: InstalledExtensionCatalogEntry): Disposable;
|
|
7
|
+
unregister(id: string): void;
|
|
8
|
+
list(): readonly RegisteredRuntimeExtensionCatalogEntry[];
|
|
9
|
+
get(id: string): RegisteredRuntimeExtensionCatalogEntry | undefined;
|
|
10
|
+
}
|
|
11
|
+
export declare function createExtensionRegistry(): ExtensionRegistry;
|
|
12
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EACV,4BAA4B,EAC5B,8BAA8B,EAC9B,sCAAsC,EACtC,4BAA4B,EAC7B,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,4BAA4B,GAAG,UAAU,CAAC;IAC1D,eAAe,CAAC,KAAK,EAAE,4BAA4B,GAAG,UAAU,CAAC;IACjE,iBAAiB,CAAC,KAAK,EAAE,8BAA8B,GAAG,UAAU,CAAC;IACrE,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,IAAI,SAAS,sCAAsC,EAAE,CAAC;IAC1D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,sCAAsC,GAAG,SAAS,CAAC;CACrE;AAED,wBAAgB,uBAAuB,IAAI,iBAAiB,CAkD3D"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { validateExtensionManifest } from "./validation.js";
|
|
2
|
+
export function createExtensionRegistry() {
|
|
3
|
+
const entries = new Map();
|
|
4
|
+
const register = (entry) => {
|
|
5
|
+
const issues = validateExtensionManifest(entry.manifest);
|
|
6
|
+
if (issues.length > 0) {
|
|
7
|
+
throw new Error(`Invalid extension manifest for '${entry.manifest.id ?? "unknown"}': ${issues.map((issue) => `${issue.path}: ${issue.message}`).join("; ")}`);
|
|
8
|
+
}
|
|
9
|
+
if (entries.has(entry.manifest.id)) {
|
|
10
|
+
throw new Error(`Extension '${entry.manifest.id}' is already registered.`);
|
|
11
|
+
}
|
|
12
|
+
const source = entry.source ?? "bundled";
|
|
13
|
+
const normalized = {
|
|
14
|
+
...entry,
|
|
15
|
+
id: entry.manifest.id,
|
|
16
|
+
source,
|
|
17
|
+
activation: entry.activation ?? (source === "installed" ? "lazy" : "lazy"),
|
|
18
|
+
};
|
|
19
|
+
entries.set(normalized.id, normalized);
|
|
20
|
+
return {
|
|
21
|
+
dispose() {
|
|
22
|
+
if (entries.get(normalized.id) === normalized) {
|
|
23
|
+
entries.delete(normalized.id);
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
register,
|
|
30
|
+
registerBundled(entry) {
|
|
31
|
+
return register({ ...entry, source: "bundled" });
|
|
32
|
+
},
|
|
33
|
+
registerInstalled(entry) {
|
|
34
|
+
return register({ ...entry, source: "installed" });
|
|
35
|
+
},
|
|
36
|
+
unregister(id) {
|
|
37
|
+
entries.delete(id);
|
|
38
|
+
},
|
|
39
|
+
list() {
|
|
40
|
+
return Array.from(entries.values()).sort((left, right) => {
|
|
41
|
+
const sourceOrder = left.source.localeCompare(right.source);
|
|
42
|
+
if (sourceOrder !== 0)
|
|
43
|
+
return sourceOrder;
|
|
44
|
+
return left.manifest.displayName.defaultMessage.localeCompare(right.manifest.displayName.defaultMessage);
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
get(id) {
|
|
48
|
+
return entries.get(id);
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAW5D,MAAM,UAAU,uBAAuB;IACrC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkD,CAAC;IAE1E,MAAM,QAAQ,GAAG,CAAC,KAAmC,EAAc,EAAE;QACnE,MAAM,MAAM,GAAG,yBAAyB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,mCAAmC,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,SAAS,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChK,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,CAAC,QAAQ,CAAC,EAAE,0BAA0B,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,SAAS,CAAC;QACzC,MAAM,UAAU,GAA2C;YACzD,GAAG,KAAK;YACR,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE;YACrB,MAAM;YACN,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;SACjC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QACvC,OAAO;YACL,OAAO;gBACL,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,UAAU,EAAE,CAAC;oBAC9C,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO;QACL,QAAQ;QACR,eAAe,CAAC,KAAmC;YACjD,OAAO,QAAQ,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,iBAAiB,CAAC,KAAqC;YACrD,OAAO,QAAQ,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,UAAU,CAAC,EAAU;YACnB,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;QACD,IAAI;YACF,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBACvD,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC5D,IAAI,WAAW,KAAK,CAAC;oBAAE,OAAO,WAAW,CAAC;gBAC1C,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,cAAc,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;YAC3G,CAAC,CAAC,CAAC;QACL,CAAC;QACD,GAAG,CAAC,EAAU;YACZ,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;KACF,CAAC;AACJ,CAAC"}
|