@lapis-notes/api 0.1.0 → 0.1.3
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/CHANGELOG.md +39 -0
- package/README.md +5 -0
- package/dist/app-database-host.d.ts +1 -0
- package/dist/app-database-host.js +1 -0
- package/dist/browser-sync-security.d.ts +45 -0
- package/dist/browser-sync-security.js +189 -0
- package/dist/build-tools/vite.d.ts +15 -0
- package/dist/build-tools/vite.js +36 -0
- package/dist/cache.svelte.d.ts +1 -1
- package/dist/cache.svelte.js +4 -1
- package/dist/components/editor/editor.css +54 -2
- package/dist/components/editor/extensions/lint/lapis-lint-tooltip.svelte +18 -5
- package/dist/components/editor/extensions/lint/lint-tooltip-actions.d.ts +0 -2
- package/dist/components/editor/extensions/lint/lint-tooltip-actions.js +0 -14
- package/dist/components/editor/language-service/index.js +23 -2
- package/dist/components/icon/icon-list.svelte.d.ts +1 -1
- package/dist/components/select/select.svelte.d.ts +1 -1
- package/dist/context.svelte.d.ts +11 -1
- package/dist/context.svelte.js +38 -1
- package/dist/docs-api.d.ts +2 -0
- package/dist/docs-api.js +1 -0
- package/dist/generated/plugin-host-modules.schema.generated.d.ts +443 -13
- package/dist/generated/plugin-host-modules.schema.generated.js +970 -306
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/language-service/manager.d.ts +5 -0
- package/dist/language-service/manager.js +58 -14
- package/dist/lapis-extension.d.ts +1 -1
- package/dist/lapis-extension.js +12 -0
- package/dist/nostr-signer.d.ts +68 -0
- package/dist/nostr-signer.js +49 -0
- package/dist/plugin-asset-server.d.ts +1 -0
- package/dist/plugin-asset-server.js +3 -0
- package/dist/plugin-capability-facade.d.ts +1 -1
- package/dist/plugin-capability-facade.js +6 -0
- package/dist/plugin-distribution/catalog-media.d.ts +4 -0
- package/dist/plugin-distribution/catalog-media.js +40 -0
- package/dist/plugin-distribution/download-stats.d.ts +4 -0
- package/dist/plugin-distribution/download-stats.js +19 -0
- package/dist/plugin-distribution/index.d.ts +4 -0
- package/dist/plugin-distribution/index.js +4 -0
- package/dist/plugin-distribution/installer.d.ts +3 -0
- package/dist/plugin-distribution/installer.js +26 -3
- package/dist/plugin-distribution/manager.d.ts +71 -5
- package/dist/plugin-distribution/manager.js +376 -37
- package/dist/plugin-distribution/nostr-registry-adapter.d.ts +29 -0
- package/dist/plugin-distribution/nostr-registry-adapter.js +152 -0
- package/dist/plugin-distribution/plugin-bundle-verifier.d.ts +43 -0
- package/dist/plugin-distribution/plugin-bundle-verifier.js +64 -1
- package/dist/plugin-distribution/plugin-bundle.d.ts +14 -0
- package/dist/plugin-distribution/plugin-bundle.js +46 -7
- package/dist/plugin-distribution/plugin-markdown.d.ts +6 -0
- package/dist/plugin-distribution/plugin-markdown.js +94 -0
- package/dist/plugin-distribution/registry-client.d.ts +6 -1
- package/dist/plugin-distribution/registry-client.js +32 -10
- package/dist/plugin-distribution/registry-source-state.d.ts +15 -0
- package/dist/plugin-distribution/registry-source-state.js +42 -0
- package/dist/plugin-distribution/schemas.d.ts +2511 -2824
- package/dist/plugin-distribution/schemas.js +111 -42
- package/dist/plugin-distribution/types.d.ts +116 -5
- package/dist/plugin-distribution-host.d.ts +4 -0
- package/dist/plugin-distribution-host.js +2 -0
- package/dist/plugin-install-progress.js +1 -1
- package/dist/plugin-manager.d.ts +3 -0
- package/dist/plugin-manager.js +21 -13
- package/dist/plugin-settings.d.ts +21 -0
- package/dist/plugin-settings.js +41 -0
- package/dist/plugin.d.ts +13 -0
- package/dist/plugin.js +56 -0
- package/dist/registry-schema/catalog-v1.d.ts +4143 -0
- package/dist/registry-schema/catalog-v1.js +172 -0
- package/dist/registry-schema/catalog-v2.d.ts +5275 -0
- package/dist/registry-schema/catalog-v2.js +137 -0
- package/dist/registry-schema/index.d.ts +1 -0
- package/dist/registry-schema/index.js +1 -0
- package/dist/registry-schema/release-notes.d.ts +5 -0
- package/dist/registry-schema/release-notes.js +21 -0
- package/dist/server-host.d.ts +28 -0
- package/dist/server-host.js +17 -0
- package/dist/storage/app-database.d.ts +37 -2
- package/dist/storage/app-database.js +41 -1
- package/dist/storage/browser-coordinated-app-database.d.ts +3 -1
- package/dist/storage/browser-coordinated-app-database.js +8 -0
- package/dist/storage/browser.d.ts +4 -1
- package/dist/storage/browser.js +84 -0
- package/dist/storage/desktop-native.d.ts +4 -2
- package/dist/storage/desktop-native.js +90 -1
- package/dist/storage/fs.d.ts +17 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +1 -0
- package/dist/storage/memory-vault-adapter.d.ts +3 -1
- package/dist/storage/memory-vault-adapter.js +60 -0
- package/dist/storage/remote-app-database.d.ts +19 -0
- package/dist/storage/remote-app-database.js +130 -0
- package/dist/storage/task-projection.d.ts +2 -1
- package/dist/storage/task-projection.js +7 -2
- package/dist/storage/turso-app-database.d.ts +3 -1
- package/dist/storage/turso-app-database.js +45 -0
- package/dist/storage/vault-session.js +11 -0
- package/dist/storage/vault-state.d.ts +1 -1
- package/dist/storage/vault.svelte.d.ts +3 -1
- package/dist/storage/vault.svelte.js +76 -3
- package/dist/sync-host-security.d.ts +285 -0
- package/dist/sync-host-security.js +2237 -0
- package/dist/sync-host.d.ts +179 -0
- package/dist/sync-host.js +769 -0
- package/dist/workspace.svelte.d.ts +1 -1
- package/dist/workspace.svelte.js +1 -1
- package/package.json +48 -10
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
import { normalizeRegistryCatalogEntry, normalizeRegistryCatalogIndex, normalizeRegistryCatalogDetail, } from "../registry-schema/index.js";
|
|
1
2
|
import { z } from "zod";
|
|
2
3
|
import { PluginDistributionError } from "./errors";
|
|
3
4
|
const isoDate = z.string().datetime({ offset: true });
|
|
5
|
+
const utcDate = z
|
|
6
|
+
.string()
|
|
7
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
8
|
+
.refine((value) => {
|
|
9
|
+
const parsed = new Date(`${value}T00:00:00.000Z`);
|
|
10
|
+
return (!Number.isNaN(parsed.valueOf()) &&
|
|
11
|
+
parsed.toISOString().slice(0, 10) === value);
|
|
12
|
+
});
|
|
4
13
|
const sha256 = z.string().regex(/^[a-fA-F0-9]{64}$/);
|
|
5
14
|
const nonEmpty = z.string().min(1);
|
|
6
15
|
const urlOrRelative = z.string().min(1);
|
|
@@ -18,6 +27,11 @@ export const pluginProvenanceSchema = z.enum([
|
|
|
18
27
|
"development",
|
|
19
28
|
]);
|
|
20
29
|
export const pluginRegistryChannelSchema = z.enum(["official", "community"]);
|
|
30
|
+
export const pluginCatalogStatusSchema = z.enum([
|
|
31
|
+
"active",
|
|
32
|
+
"pending",
|
|
33
|
+
"revoked",
|
|
34
|
+
]);
|
|
21
35
|
export const pluginPlatformSchema = z.enum(["web", "electron", "desktop"]);
|
|
22
36
|
export const pluginBadgeSchema = z.enum([
|
|
23
37
|
"official",
|
|
@@ -43,10 +57,38 @@ export const trustedSigningKeySchema = z.object({
|
|
|
43
57
|
export const remoteFileReferenceSchema = z
|
|
44
58
|
.object({
|
|
45
59
|
url: urlOrRelative,
|
|
60
|
+
downloadUrl: urlOrRelative.optional(),
|
|
46
61
|
sha256,
|
|
47
62
|
size: z.number().int().nonnegative().optional(),
|
|
48
63
|
})
|
|
49
64
|
.passthrough();
|
|
65
|
+
export const pluginMarkdownReferenceSchema = z
|
|
66
|
+
.object({
|
|
67
|
+
url: httpsUrl,
|
|
68
|
+
sourceUrl: httpsUrl,
|
|
69
|
+
sha256,
|
|
70
|
+
size: z
|
|
71
|
+
.number()
|
|
72
|
+
.int()
|
|
73
|
+
.nonnegative()
|
|
74
|
+
.max(256 * 1024),
|
|
75
|
+
mediaType: z.literal("text/markdown"),
|
|
76
|
+
})
|
|
77
|
+
.passthrough();
|
|
78
|
+
export const pluginCatalogContentSchema = z
|
|
79
|
+
.object({
|
|
80
|
+
overview: pluginMarkdownReferenceSchema.optional(),
|
|
81
|
+
changelog: pluginMarkdownReferenceSchema.optional(),
|
|
82
|
+
})
|
|
83
|
+
.passthrough();
|
|
84
|
+
export const pluginCatalogLinksSchema = z
|
|
85
|
+
.object({
|
|
86
|
+
homepage: httpsUrl.optional(),
|
|
87
|
+
repository: httpsUrl.optional(),
|
|
88
|
+
documentation: httpsUrl.optional(),
|
|
89
|
+
issues: httpsUrl.optional(),
|
|
90
|
+
})
|
|
91
|
+
.passthrough();
|
|
50
92
|
export const pluginReleaseFileSchema = z
|
|
51
93
|
.object({
|
|
52
94
|
path: nonEmpty,
|
|
@@ -149,35 +191,43 @@ export const pluginContributionSummarySchema = z
|
|
|
149
191
|
.optional(),
|
|
150
192
|
})
|
|
151
193
|
.passthrough();
|
|
152
|
-
export const pluginCatalogEntrySchema =
|
|
194
|
+
export const pluginCatalogEntrySchema = sharedCatalogSchema(normalizeRegistryCatalogEntry);
|
|
195
|
+
export const pluginCatalogIndexSchema = sharedCatalogSchema(normalizeRegistryCatalogIndex);
|
|
196
|
+
const nonnegativeSafeInteger = z.number().int().nonnegative().safe();
|
|
197
|
+
const pluginDownloadCountsSchema = z.record(nonnegativeSafeInteger);
|
|
198
|
+
const pluginDownloadStatsPluginSchema = z
|
|
153
199
|
.object({
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
description: z.string(),
|
|
157
|
-
readmeUrl: httpsUrl.optional(),
|
|
158
|
-
author: nonEmpty,
|
|
159
|
-
channel: pluginRegistryChannelSchema,
|
|
160
|
-
latestVersion: nonEmpty,
|
|
161
|
-
minAppVersion: nonEmpty,
|
|
162
|
-
platforms: z.array(pluginPlatformSchema).min(1),
|
|
163
|
-
categories: z.array(nonEmpty),
|
|
164
|
-
badges: z.array(pluginBadgeSchema).optional(),
|
|
165
|
-
detail: urlOrRelative,
|
|
166
|
-
contributes: pluginContributionSummarySchema.optional(),
|
|
200
|
+
total: nonnegativeSafeInteger,
|
|
201
|
+
versions: pluginDownloadCountsSchema,
|
|
167
202
|
})
|
|
168
203
|
.passthrough();
|
|
169
|
-
|
|
204
|
+
const pluginDownloadStatsPeriodSchema = z
|
|
205
|
+
.object({
|
|
206
|
+
from: utcDate.nullable(),
|
|
207
|
+
through: utcDate.nullable(),
|
|
208
|
+
total: nonnegativeSafeInteger,
|
|
209
|
+
plugins: z.record(pluginDownloadStatsPluginSchema),
|
|
210
|
+
versions: pluginDownloadCountsSchema,
|
|
211
|
+
actions: pluginDownloadCountsSchema,
|
|
212
|
+
platforms: pluginDownloadCountsSchema,
|
|
213
|
+
os: pluginDownloadCountsSchema,
|
|
214
|
+
})
|
|
215
|
+
.passthrough();
|
|
216
|
+
export const pluginDownloadStatsSummarySchema = z
|
|
170
217
|
.object({
|
|
171
218
|
schemaVersion: z.literal(1),
|
|
172
219
|
generatedAt: isoDate,
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
.
|
|
179
|
-
|
|
180
|
-
|
|
220
|
+
dataset: z.literal("lapis_plugin_downloads_v1"),
|
|
221
|
+
metric: z.literal("approximate_redirect_requests"),
|
|
222
|
+
trackedSince: utcDate,
|
|
223
|
+
through: utcDate.nullable(),
|
|
224
|
+
periods: z
|
|
225
|
+
.object({
|
|
226
|
+
lifetime: pluginDownloadStatsPeriodSchema,
|
|
227
|
+
"7d": pluginDownloadStatsPeriodSchema,
|
|
228
|
+
"30d": pluginDownloadStatsPeriodSchema,
|
|
229
|
+
})
|
|
230
|
+
.passthrough(),
|
|
181
231
|
})
|
|
182
232
|
.passthrough();
|
|
183
233
|
export const pluginRevocationRecordSchema = z.object({
|
|
@@ -206,25 +256,7 @@ export const pluginCatalogReleaseSchema = z
|
|
|
206
256
|
revoked: pluginRevocationRecordSchema.optional(),
|
|
207
257
|
})
|
|
208
258
|
.passthrough();
|
|
209
|
-
export const pluginCatalogDetailSchema =
|
|
210
|
-
.object({
|
|
211
|
-
schemaVersion: z.literal(1),
|
|
212
|
-
id: nonEmpty,
|
|
213
|
-
name: nonEmpty,
|
|
214
|
-
description: z.string(),
|
|
215
|
-
readmeUrl: httpsUrl.optional(),
|
|
216
|
-
channel: pluginRegistryChannelSchema,
|
|
217
|
-
owner: z.object({
|
|
218
|
-
name: nonEmpty,
|
|
219
|
-
verified: z.boolean().optional(),
|
|
220
|
-
url: z.string().url().optional(),
|
|
221
|
-
}),
|
|
222
|
-
latestVersion: nonEmpty,
|
|
223
|
-
readme: remoteFileReferenceSchema.optional(),
|
|
224
|
-
versions: z.record(pluginCatalogReleaseSchema),
|
|
225
|
-
signatures: z.array(signatureRecordSchema).optional(),
|
|
226
|
-
})
|
|
227
|
-
.passthrough();
|
|
259
|
+
export const pluginCatalogDetailSchema = sharedCatalogSchema(normalizeRegistryCatalogDetail);
|
|
228
260
|
export const pluginReleaseManifestSchema = z.object({
|
|
229
261
|
schemaVersion: z.literal(1),
|
|
230
262
|
type: z.literal("lapis.plugin.release"),
|
|
@@ -269,6 +301,17 @@ export const installedPluginRecordSchema = z
|
|
|
269
301
|
})),
|
|
270
302
|
runtimeWarnings: z.array(pluginReleaseRuntimeDiagnosticSchema).optional(),
|
|
271
303
|
signature: signatureRecordSchema.optional(),
|
|
304
|
+
nostrProof: z
|
|
305
|
+
.object({
|
|
306
|
+
authorizationEventId: nonEmpty,
|
|
307
|
+
releaseEventId: nonEmpty,
|
|
308
|
+
decisionEventId: nonEmpty,
|
|
309
|
+
manifestSha256: sha256,
|
|
310
|
+
artifactSha256: sha256,
|
|
311
|
+
artifactSize: z.number().int().nonnegative(),
|
|
312
|
+
requiresRelayRefresh: z.boolean(),
|
|
313
|
+
})
|
|
314
|
+
.optional(),
|
|
272
315
|
revoked: pluginRevocationRecordSchema.optional(),
|
|
273
316
|
restartRequired: z.boolean().optional(),
|
|
274
317
|
})
|
|
@@ -288,6 +331,18 @@ export const installedPluginsStateSchema = z
|
|
|
288
331
|
.optional(),
|
|
289
332
|
})
|
|
290
333
|
.passthrough();
|
|
334
|
+
export const pluginRegistrySourcePreferenceSchema = z
|
|
335
|
+
.object({
|
|
336
|
+
enabled: z.boolean(),
|
|
337
|
+
})
|
|
338
|
+
.passthrough();
|
|
339
|
+
export const pluginRegistrySourcePreferencesStateSchema = z
|
|
340
|
+
.object({
|
|
341
|
+
schemaVersion: z.literal(1),
|
|
342
|
+
updatedAt: isoDate,
|
|
343
|
+
sources: z.record(pluginRegistrySourcePreferenceSchema),
|
|
344
|
+
})
|
|
345
|
+
.passthrough();
|
|
291
346
|
export const parsePluginDistributionMetadata = (schema, value) => {
|
|
292
347
|
const result = schema.safeParse(value);
|
|
293
348
|
if (!result.success) {
|
|
@@ -297,3 +352,17 @@ export const parsePluginDistributionMetadata = (schema, value) => {
|
|
|
297
352
|
}
|
|
298
353
|
return result.data;
|
|
299
354
|
};
|
|
355
|
+
function sharedCatalogSchema(normalize) {
|
|
356
|
+
return z.unknown().transform((value, context) => {
|
|
357
|
+
try {
|
|
358
|
+
return normalize(value);
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
context.addIssue({
|
|
362
|
+
code: z.ZodIssueCode.custom,
|
|
363
|
+
message: error instanceof Error ? error.message : String(error),
|
|
364
|
+
});
|
|
365
|
+
return z.NEVER;
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
}
|
|
@@ -1,14 +1,38 @@
|
|
|
1
|
+
import type { RegistryCatalogV2Entry, RegistryCatalogV2Detail, RegistryReleaseChangelog } from "../registry-schema/index.js";
|
|
1
2
|
export type PluginProvenance = "bundled" | "official" | "community" | "manual" | "development";
|
|
2
3
|
export type RegistryTrustTier = "official" | "community" | "local";
|
|
4
|
+
export type PluginRegistrySourceKind = "http" | "nostr";
|
|
3
5
|
export interface PluginRegistrySource {
|
|
4
6
|
id: string;
|
|
5
7
|
name: string;
|
|
8
|
+
/** Omitted by legacy sources and treated as `http`. */
|
|
9
|
+
kind?: PluginRegistrySourceKind;
|
|
6
10
|
url: string;
|
|
11
|
+
downloadStatsUrl?: string;
|
|
12
|
+
relays?: string[];
|
|
13
|
+
curatorPubkeys?: string[];
|
|
14
|
+
installQuorum?: number;
|
|
7
15
|
trustTier: RegistryTrustTier;
|
|
8
16
|
enabled: boolean;
|
|
9
17
|
builtin?: boolean;
|
|
10
18
|
}
|
|
19
|
+
export type PluginRegistrySourcePhase = "idle" | "ready" | "degraded" | "error";
|
|
20
|
+
export interface PluginRegistrySourceState {
|
|
21
|
+
source: PluginRegistrySource;
|
|
22
|
+
phase: PluginRegistrySourcePhase;
|
|
23
|
+
installReady: boolean;
|
|
24
|
+
message?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface PluginRegistrySourcePreference {
|
|
27
|
+
enabled: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface PluginRegistrySourcePreferencesState {
|
|
30
|
+
schemaVersion: 1;
|
|
31
|
+
updatedAt: string;
|
|
32
|
+
sources: Record<string, PluginRegistrySourcePreference>;
|
|
33
|
+
}
|
|
11
34
|
export type PluginRegistryChannel = "official" | "community";
|
|
35
|
+
export type PluginCatalogStatus = RegistryCatalogV2Entry["status"];
|
|
12
36
|
export type PluginPlatform = "web" | "electron" | "desktop";
|
|
13
37
|
export type PluginBadge = "official" | "verified" | "community" | "desktop-only" | "requires-trust" | "update-available" | "revoked";
|
|
14
38
|
export interface PluginContributionSummary {
|
|
@@ -36,7 +60,7 @@ export interface PluginContributionSummary {
|
|
|
36
60
|
}>;
|
|
37
61
|
}
|
|
38
62
|
export interface PluginCatalogIndex {
|
|
39
|
-
schemaVersion: 1;
|
|
63
|
+
schemaVersion: 1 | 2;
|
|
40
64
|
generatedAt: string;
|
|
41
65
|
registries?: Record<string, {
|
|
42
66
|
name: string;
|
|
@@ -46,47 +70,120 @@ export interface PluginCatalogIndex {
|
|
|
46
70
|
signatures?: SignatureRecord[];
|
|
47
71
|
}
|
|
48
72
|
export interface PluginCatalogEntry {
|
|
73
|
+
owner?: RegistryCatalogV2Entry["owner"];
|
|
74
|
+
appearance?: RegistryCatalogV2Entry["appearance"];
|
|
75
|
+
authorAvatarUrl?: string;
|
|
49
76
|
id: string;
|
|
50
77
|
name: string;
|
|
51
78
|
description: string;
|
|
52
79
|
readmeUrl?: string;
|
|
53
80
|
author: string;
|
|
81
|
+
authorUrl?: string;
|
|
54
82
|
channel: PluginRegistryChannel;
|
|
83
|
+
status?: PluginCatalogStatus;
|
|
55
84
|
latestVersion: string;
|
|
56
85
|
minAppVersion: string;
|
|
57
|
-
platforms:
|
|
86
|
+
platforms: string[];
|
|
58
87
|
categories: string[];
|
|
59
|
-
badges?:
|
|
88
|
+
badges?: string[];
|
|
89
|
+
latestRelease?: PluginCatalogLatestRelease;
|
|
60
90
|
detail: string;
|
|
61
91
|
contributes?: PluginContributionSummary;
|
|
62
92
|
}
|
|
63
|
-
export interface
|
|
93
|
+
export interface PluginCatalogLatestRelease {
|
|
94
|
+
releasedAt: string;
|
|
95
|
+
bundleSize: number;
|
|
96
|
+
}
|
|
97
|
+
export interface PluginDownloadStatsPlugin {
|
|
98
|
+
total: number;
|
|
99
|
+
versions: Record<string, number>;
|
|
100
|
+
}
|
|
101
|
+
export interface PluginDownloadStatsPeriod {
|
|
102
|
+
from: string | null;
|
|
103
|
+
through: string | null;
|
|
104
|
+
total: number;
|
|
105
|
+
plugins: Record<string, PluginDownloadStatsPlugin>;
|
|
106
|
+
versions: Record<string, number>;
|
|
107
|
+
actions: Record<string, number>;
|
|
108
|
+
platforms: Record<string, number>;
|
|
109
|
+
os: Record<string, number>;
|
|
110
|
+
}
|
|
111
|
+
export interface PluginDownloadStatsSummary {
|
|
64
112
|
schemaVersion: 1;
|
|
113
|
+
generatedAt: string;
|
|
114
|
+
dataset: "lapis_plugin_downloads_v1";
|
|
115
|
+
metric: "approximate_redirect_requests";
|
|
116
|
+
trackedSince: string;
|
|
117
|
+
through: string | null;
|
|
118
|
+
periods: {
|
|
119
|
+
lifetime: PluginDownloadStatsPeriod;
|
|
120
|
+
"7d": PluginDownloadStatsPeriod;
|
|
121
|
+
"30d": PluginDownloadStatsPeriod;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export interface PluginDownloadCounts {
|
|
125
|
+
lifetime: number;
|
|
126
|
+
recent: number;
|
|
127
|
+
}
|
|
128
|
+
export interface PluginCatalogDetail {
|
|
129
|
+
schemaVersion: 1 | 2;
|
|
130
|
+
author?: string;
|
|
131
|
+
authorUrl?: string;
|
|
132
|
+
authorAvatarUrl?: string;
|
|
133
|
+
appearance?: RegistryCatalogV2Detail["appearance"];
|
|
134
|
+
media?: RegistryCatalogV2Detail["media"];
|
|
135
|
+
gallery?: RegistryCatalogV2Detail["gallery"];
|
|
65
136
|
id: string;
|
|
66
137
|
name: string;
|
|
67
138
|
description: string;
|
|
68
139
|
readmeUrl?: string;
|
|
69
140
|
channel: PluginRegistryChannel;
|
|
141
|
+
status?: PluginCatalogStatus;
|
|
70
142
|
owner: {
|
|
71
143
|
name: string;
|
|
72
144
|
verified?: boolean;
|
|
73
145
|
url?: string;
|
|
74
146
|
};
|
|
75
147
|
latestVersion: string;
|
|
148
|
+
license?: string;
|
|
149
|
+
links?: PluginCatalogLinks;
|
|
150
|
+
highlights?: string[];
|
|
151
|
+
content?: PluginCatalogContent;
|
|
76
152
|
readme?: RemoteFileReference;
|
|
153
|
+
contributes?: PluginContributionSummary;
|
|
77
154
|
versions: Record<string, PluginCatalogRelease>;
|
|
78
155
|
signatures?: SignatureRecord[];
|
|
79
156
|
}
|
|
157
|
+
export interface PluginCatalogLinks {
|
|
158
|
+
homepage?: string;
|
|
159
|
+
repository?: string;
|
|
160
|
+
documentation?: string;
|
|
161
|
+
issues?: string;
|
|
162
|
+
}
|
|
163
|
+
export interface PluginMarkdownReference {
|
|
164
|
+
url: string;
|
|
165
|
+
sourceUrl: string;
|
|
166
|
+
sha256: string;
|
|
167
|
+
size: number;
|
|
168
|
+
mediaType: "text/markdown";
|
|
169
|
+
}
|
|
170
|
+
export interface PluginCatalogContent {
|
|
171
|
+
overview?: PluginMarkdownReference;
|
|
172
|
+
changelog?: PluginMarkdownReference;
|
|
173
|
+
}
|
|
80
174
|
export interface PluginCatalogRelease {
|
|
175
|
+
changelog?: RegistryReleaseChangelog;
|
|
176
|
+
releasePost?: string;
|
|
81
177
|
version: string;
|
|
82
178
|
minAppVersion: string;
|
|
83
179
|
releasedAt: string;
|
|
84
|
-
platforms:
|
|
180
|
+
platforms: string[];
|
|
85
181
|
bundle: RemoteFileReference;
|
|
86
182
|
revoked?: PluginRevocationRecord;
|
|
87
183
|
}
|
|
88
184
|
export interface RemoteFileReference {
|
|
89
185
|
url: string;
|
|
186
|
+
downloadUrl?: string;
|
|
90
187
|
sha256: string;
|
|
91
188
|
size?: number;
|
|
92
189
|
}
|
|
@@ -196,6 +293,20 @@ export interface InstalledPluginRecord {
|
|
|
196
293
|
}>;
|
|
197
294
|
runtimeWarnings?: PluginReleaseRuntimeDiagnostic[];
|
|
198
295
|
signature?: SignatureRecord;
|
|
296
|
+
nostrProof?: {
|
|
297
|
+
authorizationEventId: string;
|
|
298
|
+
releaseEventId: string;
|
|
299
|
+
decisionEventId: string;
|
|
300
|
+
manifestSha256: string;
|
|
301
|
+
/** Digest and size of the exact inner payload authenticated at installation. */
|
|
302
|
+
artifactSha256: string;
|
|
303
|
+
artifactSize: number;
|
|
304
|
+
/**
|
|
305
|
+
* Portable proof is valid, but a relay quorum has not checked later
|
|
306
|
+
* revocations.
|
|
307
|
+
*/
|
|
308
|
+
requiresRelayRefresh: boolean;
|
|
309
|
+
};
|
|
199
310
|
revoked?: PluginRevocationRecord;
|
|
200
311
|
restartRequired?: boolean;
|
|
201
312
|
[key: string]: unknown;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { createNostrPluginRegistryAdapter } from "./plugin-distribution/nostr-registry-adapter";
|
|
2
|
+
export { DEFAULT_OFFICIAL_PLUGIN_REGISTRY_SOURCE } from "./plugin-distribution/manager";
|
|
3
|
+
export type { PluginRegistrySource } from "./plugin-distribution/types";
|
|
4
|
+
export type { PluginDistributionManager } from "./plugin-distribution/manager";
|
|
@@ -67,7 +67,7 @@ export async function withPluginInstallProgress(app, options, action) {
|
|
|
67
67
|
source: options.source ?? "Plugin registry",
|
|
68
68
|
location: options.location ?? "status",
|
|
69
69
|
cancellable: true,
|
|
70
|
-
persistOnError: options.persistOnError ??
|
|
70
|
+
persistOnError: options.persistOnError ?? true,
|
|
71
71
|
}, async (progressHandle, token) => {
|
|
72
72
|
const removeProgressListener = app.pluginDistribution.addProgressListener((event) => {
|
|
73
73
|
if (event.pluginId !== options.pluginId) {
|
package/dist/plugin-manager.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { type PluginDependencyResolver, type PluginDependencyResolverFactory } f
|
|
|
9
9
|
import { type PluginAssetServer } from "./plugin-asset-server";
|
|
10
10
|
import type { PluginProvenance } from "./plugin-distribution/types";
|
|
11
11
|
import { EventDispatcher } from "./events";
|
|
12
|
+
import type { SyncHostCapabilities } from "./sync-host";
|
|
12
13
|
export interface PluginLoader {
|
|
13
14
|
pluginsPath: string;
|
|
14
15
|
}
|
|
@@ -41,6 +42,8 @@ export interface PluginManagerOptions {
|
|
|
41
42
|
communityPluginHost?: CommunityPluginExecutionHost;
|
|
42
43
|
createCommunityPluginDependencyResolver?: PluginDependencyResolverFactory;
|
|
43
44
|
pluginAssetServer?: PluginAssetServer;
|
|
45
|
+
createSyncHostCapabilities?: (pluginId: string, grants: readonly HostedPluginCapability[]) => SyncHostCapabilities;
|
|
46
|
+
revokeSyncHostCapabilities?: (pluginId: string) => void;
|
|
44
47
|
}
|
|
45
48
|
export interface PluginDataAliasMigration {
|
|
46
49
|
fromPluginId: string;
|
package/dist/plugin-manager.js
CHANGED
|
@@ -17,14 +17,11 @@ function formatPluginError(error) {
|
|
|
17
17
|
}
|
|
18
18
|
function resolvePluginModuleExport(moduleExports) {
|
|
19
19
|
const exportRecord = isRecord(moduleExports) ? moduleExports : {};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return value;
|
|
23
|
-
}
|
|
20
|
+
if (exportRecord.default !== undefined) {
|
|
21
|
+
return exportRecord.default;
|
|
24
22
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
moduleExports);
|
|
23
|
+
const namedPluginClass = Object.values(exportRecord).find((value) => typeof value === "function" && value.prototype instanceof Plugin);
|
|
24
|
+
return namedPluginClass ?? Object.values(exportRecord)[0] ?? moduleExports;
|
|
28
25
|
}
|
|
29
26
|
function isRecord(value) {
|
|
30
27
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -415,6 +412,8 @@ export class PluginManager extends EventDispatcher {
|
|
|
415
412
|
#deferredIndexedExtensions = new Map();
|
|
416
413
|
#communityPluginHost;
|
|
417
414
|
#pluginAssetServer;
|
|
415
|
+
#createSyncHostCapabilities;
|
|
416
|
+
#revokeSyncHostCapabilities;
|
|
418
417
|
constructor(app, pluginsPath, adapter, options = {}) {
|
|
419
418
|
super();
|
|
420
419
|
this.app = app;
|
|
@@ -424,6 +423,8 @@ export class PluginManager extends EventDispatcher {
|
|
|
424
423
|
const dependencyResolver = options.createCommunityPluginDependencyResolver?.(this.dependencies) ??
|
|
425
424
|
this.dependencies;
|
|
426
425
|
this.#pluginAssetServer = options.pluginAssetServer;
|
|
426
|
+
this.#createSyncHostCapabilities = options.createSyncHostCapabilities;
|
|
427
|
+
this.#revokeSyncHostCapabilities = options.revokeSyncHostCapabilities;
|
|
427
428
|
const commonJsHost = options.communityPluginHost ??
|
|
428
429
|
new RendererCommunityPluginExecutionHost(adapter, dependencyResolver);
|
|
429
430
|
this.#communityPluginHost = options.pluginAssetServer
|
|
@@ -1144,6 +1145,12 @@ export class PluginManager extends EventDispatcher {
|
|
|
1144
1145
|
if (this.plugins.has(plugin.manifest.id)) {
|
|
1145
1146
|
throw new Error(`Plugin id ${plugin.manifest.id} is already registered`);
|
|
1146
1147
|
}
|
|
1148
|
+
const grantedCapabilities = isExternalPluginSource(options.source)
|
|
1149
|
+
? this.getGrantedCapabilities(plugin.manifest)
|
|
1150
|
+
: options.source === "system"
|
|
1151
|
+
? (this.#lapisExtensionIndex.get(plugin.manifest.id)
|
|
1152
|
+
?.grantedCapabilities ?? [])
|
|
1153
|
+
: (plugin.manifest.requiredCapabilities ?? []).filter((capability) => typeof capability === "string");
|
|
1147
1154
|
plugin.configureRuntime({
|
|
1148
1155
|
source: options.source,
|
|
1149
1156
|
provenance: options.provenance,
|
|
@@ -1176,12 +1183,13 @@ export class PluginManager extends EventDispatcher {
|
|
|
1176
1183
|
? (this.#lapisExtensionIndex.get(plugin.manifest.id)
|
|
1177
1184
|
?.requestedCapabilities ?? [])
|
|
1178
1185
|
: [],
|
|
1179
|
-
grantedCapabilities
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1186
|
+
grantedCapabilities,
|
|
1187
|
+
createSyncHostCapabilities: this.#createSyncHostCapabilities
|
|
1188
|
+
? () => this.#createSyncHostCapabilities(plugin.manifest.id, grantedCapabilities)
|
|
1189
|
+
: undefined,
|
|
1190
|
+
revokeSyncHostCapabilities: this.#revokeSyncHostCapabilities
|
|
1191
|
+
? () => this.#revokeSyncHostCapabilities(plugin.manifest.id)
|
|
1192
|
+
: undefined,
|
|
1185
1193
|
});
|
|
1186
1194
|
this.plugins.set(plugin.manifest.id, plugin);
|
|
1187
1195
|
if (isExternalPluginSource(options.source) ||
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type WorkspaceActionResult, type WorkspaceActionSetting, type WorkspaceCustomFieldAdapter, type WorkspaceCustomSetting, type WorkspaceCustomSettingProps, type WorkspaceObjectCollectionSetting, type WorkspaceObjectProperty, type WorkspaceObjectRowAction, type WorkspaceOutputSetting, type WorkspaceSettingField, type WorkspaceSettingsDefinition, type WorkspaceSettingsSection, type WorkspaceSettingsSource } from "@lapismd/design-core/workspace/settings";
|
|
2
|
+
import type { App } from "./context.svelte";
|
|
3
|
+
import type { Plugin } from "./plugin";
|
|
4
|
+
import { PluginSettingTab } from "./settings.svelte";
|
|
5
|
+
export type PluginSettingsDefinition = WorkspaceSettingsDefinition;
|
|
6
|
+
export interface PluginSettingsRegistration {
|
|
7
|
+
readonly definition: PluginSettingsDefinition;
|
|
8
|
+
open(fieldId?: string): boolean;
|
|
9
|
+
dispose(): void;
|
|
10
|
+
}
|
|
11
|
+
export type { WorkspaceActionResult, WorkspaceActionSetting, WorkspaceCustomFieldAdapter, WorkspaceCustomSetting, WorkspaceCustomSettingProps, WorkspaceObjectCollectionSetting, WorkspaceObjectProperty, WorkspaceObjectRowAction, WorkspaceOutputSetting, WorkspaceSettingField, WorkspaceSettingsSection, WorkspaceSettingsSource, };
|
|
12
|
+
/**
|
|
13
|
+
* Compatibility settings tab backed by the same controlled definition as the
|
|
14
|
+
* Workspace Settings surface.
|
|
15
|
+
*/
|
|
16
|
+
export declare class DeclarativePluginSettingTab extends PluginSettingTab {
|
|
17
|
+
#private;
|
|
18
|
+
constructor(app: App, plugin: Plugin, definition: PluginSettingsDefinition);
|
|
19
|
+
display(): void;
|
|
20
|
+
hide(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { DeclarativeSettingsSection, WorkspaceSettingsController, } from "@lapismd/design-core/workspace/settings";
|
|
2
|
+
import { mount, unmount } from "svelte";
|
|
3
|
+
import { PluginSettingTab } from "./settings.svelte";
|
|
4
|
+
/**
|
|
5
|
+
* Compatibility settings tab backed by the same controlled definition as the
|
|
6
|
+
* Workspace Settings surface.
|
|
7
|
+
*/
|
|
8
|
+
export class DeclarativePluginSettingTab extends PluginSettingTab {
|
|
9
|
+
#definition;
|
|
10
|
+
#component = null;
|
|
11
|
+
#controller = null;
|
|
12
|
+
constructor(app, plugin, definition) {
|
|
13
|
+
super(app, plugin);
|
|
14
|
+
this.#definition = definition;
|
|
15
|
+
}
|
|
16
|
+
display() {
|
|
17
|
+
this.#disposeRenderer();
|
|
18
|
+
this.containerEl.empty();
|
|
19
|
+
const controller = new WorkspaceSettingsController();
|
|
20
|
+
controller.registerDefinition(this.#definition);
|
|
21
|
+
this.#controller = controller;
|
|
22
|
+
this.#component = mount(DeclarativeSettingsSection, {
|
|
23
|
+
target: this.containerEl,
|
|
24
|
+
props: {
|
|
25
|
+
controller,
|
|
26
|
+
section: this.#definition.section,
|
|
27
|
+
class: "ui-workspace-settings--legacy-tab",
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
hide() {
|
|
32
|
+
this.#disposeRenderer();
|
|
33
|
+
}
|
|
34
|
+
#disposeRenderer() {
|
|
35
|
+
if (this.#component)
|
|
36
|
+
void unmount(this.#component);
|
|
37
|
+
this.#component = null;
|
|
38
|
+
this.#controller?.destroy();
|
|
39
|
+
this.#controller = null;
|
|
40
|
+
}
|
|
41
|
+
}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -8,11 +8,13 @@ import type { LapisExtensionContributions, LapisExtensionKind, LapisExtensionMan
|
|
|
8
8
|
import type { EditorViewContribution } from "./editor-view-registry";
|
|
9
9
|
import type { ConfigurationOptionSourceProvider, ConfigurationOptionSourceRegistration } from "./configuration-option-source-registry";
|
|
10
10
|
import type { HostedPluginCapability } from "./plugin-capability-facade";
|
|
11
|
+
import type { SyncHostCapabilities } from "./sync-host";
|
|
11
12
|
import type { MarkdownDirectiveRenderer, MarkdownPostProcessor, MarkdownPostProcessorContext, MarkdownViewMenuItemProvider } from "./markdown";
|
|
12
13
|
import type { MarkdownExtensionContribution } from "./markdown-extension-registry";
|
|
13
14
|
import type { MarkdownFileSurfaceProvider } from "./markdown-file-surface-registry";
|
|
14
15
|
import type { TypeWidget } from "./metadata.svelte";
|
|
15
16
|
import type { PluginSettingTab } from "./settings.svelte";
|
|
17
|
+
import type { PluginSettingsDefinition, PluginSettingsRegistration } from "./plugin-settings";
|
|
16
18
|
import type { EditorSuggest } from "./suggest";
|
|
17
19
|
import type { TelemetryAttributes, TelemetryMeasurementOptions, TelemetrySpan, TelemetrySpanOptions } from "./telemetry";
|
|
18
20
|
import type { PluginProvenance } from "./plugin-distribution/types";
|
|
@@ -168,6 +170,8 @@ export interface PluginRuntimeOptions {
|
|
|
168
170
|
hostMode?: string;
|
|
169
171
|
requestedCapabilities?: HostedPluginCapability[];
|
|
170
172
|
grantedCapabilities?: HostedPluginCapability[];
|
|
173
|
+
createSyncHostCapabilities?: () => SyncHostCapabilities;
|
|
174
|
+
revokeSyncHostCapabilities?: () => void;
|
|
171
175
|
}
|
|
172
176
|
/**
|
|
173
177
|
* Base class for Lapis plugins.
|
|
@@ -224,6 +228,8 @@ export declare abstract class Plugin extends Component {
|
|
|
224
228
|
get requestedCapabilities(): HostedPluginCapability[];
|
|
225
229
|
get grantedCapabilities(): HostedPluginCapability[];
|
|
226
230
|
get id(): string;
|
|
231
|
+
/** Host-authenticated durable capabilities for sync and similar plugins. */
|
|
232
|
+
get syncHost(): SyncHostCapabilities;
|
|
227
233
|
private getDataPath;
|
|
228
234
|
private readLegacyData;
|
|
229
235
|
private writeLegacyData;
|
|
@@ -347,4 +353,11 @@ export declare abstract class Plugin extends Component {
|
|
|
347
353
|
* @see {@link https://docs.obsidian.md/Plugins/User+interface/Settings#Register+a+settings+tab}
|
|
348
354
|
*/
|
|
349
355
|
addSettingTab(settingTab: PluginSettingTab): void;
|
|
356
|
+
/**
|
|
357
|
+
* Register one controlled declarative settings definition with Workspace
|
|
358
|
+
* Settings. Source-backed values remain owned by the plugin.
|
|
359
|
+
*
|
|
360
|
+
* @public
|
|
361
|
+
*/
|
|
362
|
+
registerSettingsSection(definition: PluginSettingsDefinition): PluginSettingsRegistration;
|
|
350
363
|
}
|