@clipbus/plugin-sdk 0.9.8 → 0.10.0
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/API.md +94 -27
- package/CHANGELOG.md +84 -0
- package/README.md +11 -3
- package/SPECIFICATION.md +3 -2
- package/dist/dom/index.cjs +29 -34
- package/dist/dom/index.js +29 -34
- package/dist/dom/topicAdapter.d.ts +1 -1
- package/dist/generated/capabilities.generated.d.ts +355 -0
- package/dist/generated/data.generated.d.ts +33 -0
- package/dist/generated/hostClients.generated.d.ts +8 -5
- package/dist/generated/hostEvents.generated.d.ts +68 -0
- package/dist/generated/nodeIPC.generated.d.ts +106 -0
- package/dist/generated/{runtime.definePlugin.generated.d.ts → runtime.registry.generated.d.ts} +2 -2
- package/dist/generated/ui.clipbus.generated.d.ts +19 -20
- package/dist/generated/wireConstants.generated.d.ts +21 -0
- package/dist/internal/capabilities.d.ts +1 -1
- package/dist/internal/hostEvents.d.ts +15 -0
- package/dist/internal/pluginCall.d.ts +11 -0
- package/dist/internal/pluginContext.d.ts +6 -0
- package/dist/preview/index.cjs +41 -48
- package/dist/preview/index.js +41 -48
- package/dist/preview/wire.d.ts +2 -2
- package/dist/runtime/defineMessage.d.ts +1 -1
- package/dist/runtime/definePlugin.d.ts +2 -0
- package/dist/runtime/index.cjs +10 -82
- package/dist/runtime/index.d.cts +7 -1
- package/dist/runtime/index.d.ts +7 -1
- package/dist/runtime/index.js +9 -80
- package/dist/ui/index.cjs +107 -169
- package/dist/ui/index.d.cts +5 -1
- package/dist/ui/index.d.ts +5 -1
- package/dist/ui/index.js +107 -169
- package/dist/validate/index.d.cts +5 -4
- package/dist/validate/index.d.ts +5 -4
- package/docs/authoring.md +1 -1
- package/docs/capability-detection.md +2 -2
- package/docs/entry.md +4 -3
- package/docs/item-context.md +5 -3
- package/docs/permissions.md +1 -1
- package/package.json +7 -5
- package/dist/generated/INDEX.runtime.generated.d.ts +0 -6
- package/dist/generated/INDEX.ui.generated.d.ts +0 -4
- package/dist/generated/capabilityClients.generated.d.ts +0 -231
- package/dist/generated/hostBootstrap.generated.d.ts +0 -23
- package/dist/generated/runtime.host.generated.d.ts +0 -39
- package/dist/generated/topicSubscribers.generated.d.ts +0 -39
- package/dist/generated/ui.bootstrap.generated.d.ts +0 -17
- package/dist/internal/ipcBus.d.ts +0 -48
- package/dist/internal/runtimeInvokeClient.d.ts +0 -3
package/dist/ui/index.js
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
var STRUCTURED_ERROR_PREFIX = "__clipbus_structured_error__:";
|
|
3
3
|
var CAPABILITIES_GLOBAL = "__CLIPBUS_PLUGIN_CAPABILITIES__";
|
|
4
4
|
var CAPABILITY_UNSUPPORTED_ERROR_NAME = "PluginCapabilityUnsupported";
|
|
5
|
+
var PLUGIN_CALL_HANDLER_NAME = "clipbusPluginCall";
|
|
6
|
+
var WIRE_ERROR_NAMES = {
|
|
7
|
+
methodNotFound: "PluginRuntimeMethodNotFound",
|
|
8
|
+
handlerNotFound: "PluginRuntimeHandlerNotFound",
|
|
9
|
+
invocationExpired: "PluginRuntimeInvocationExpired",
|
|
10
|
+
hostCallLimitExceeded: "PluginRuntimeHostCallLimitExceeded",
|
|
11
|
+
hostBridgeUnavailable: "PluginHostBridgeUnavailable"
|
|
12
|
+
};
|
|
5
13
|
|
|
6
14
|
// src/internal/capabilities.ts
|
|
7
15
|
var CapabilityUnsupportedError = class extends Error {
|
|
@@ -36,35 +44,36 @@ function mapToCapabilityError(err, unsupportedName) {
|
|
|
36
44
|
return err;
|
|
37
45
|
}
|
|
38
46
|
|
|
39
|
-
// src/internal/
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const handler = globalThis.webkit?.messageHandlers?.[HANDLER_NAME];
|
|
47
|
+
// src/internal/pluginCall.ts
|
|
48
|
+
async function callPluginMethod(method, payload) {
|
|
49
|
+
const handler = globalThis.webkit?.messageHandlers?.[PLUGIN_CALL_HANDLER_NAME];
|
|
43
50
|
if (!handler) {
|
|
44
|
-
|
|
51
|
+
const err = new Error("clipbus." + method + " is only available inside a Clipbus plugin WebView");
|
|
52
|
+
err.name = WIRE_ERROR_NAMES.hostBridgeUnavailable;
|
|
53
|
+
throw err;
|
|
45
54
|
}
|
|
46
55
|
const normalized = JSON.parse(JSON.stringify(payload));
|
|
47
|
-
let reply;
|
|
48
56
|
try {
|
|
49
|
-
|
|
57
|
+
return await handler.postMessage({ method, payload: normalized });
|
|
50
58
|
} catch (err) {
|
|
51
59
|
throw parseReplyError(err);
|
|
52
60
|
}
|
|
61
|
+
}
|
|
62
|
+
async function callRuntimeInvoke(payload) {
|
|
63
|
+
if (!globalThis.webkit?.messageHandlers?.[PLUGIN_CALL_HANDLER_NAME]) {
|
|
64
|
+
throw new Error("runtime.invoke is only available inside a Clipbus plugin WebView");
|
|
65
|
+
}
|
|
66
|
+
const reply = await callPluginMethod("runtime.invoke", payload);
|
|
53
67
|
return reply?.response;
|
|
54
68
|
}
|
|
55
69
|
function parseReplyError(raw) {
|
|
56
70
|
const message = extractMessage(raw);
|
|
57
71
|
if (message.startsWith(STRUCTURED_ERROR_PREFIX)) {
|
|
58
|
-
const json = message.slice(STRUCTURED_ERROR_PREFIX.length);
|
|
59
72
|
try {
|
|
60
|
-
const parsed = JSON.parse(
|
|
73
|
+
const parsed = JSON.parse(message.slice(STRUCTURED_ERROR_PREFIX.length));
|
|
61
74
|
const err = new Error(typeof parsed.message === "string" ? parsed.message : "");
|
|
62
|
-
if (typeof parsed.name === "string" && parsed.name.length > 0)
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
if (parsed.data !== void 0) {
|
|
66
|
-
err.data = parsed.data;
|
|
67
|
-
}
|
|
75
|
+
if (typeof parsed.name === "string" && parsed.name.length > 0) err.name = parsed.name;
|
|
76
|
+
if (parsed.data !== void 0) err.data = parsed.data;
|
|
68
77
|
return mapToCapabilityError(err, CAPABILITY_UNSUPPORTED_ERROR_NAME);
|
|
69
78
|
} catch {
|
|
70
79
|
return new Error(message);
|
|
@@ -82,44 +91,20 @@ function extractMessage(raw) {
|
|
|
82
91
|
return String(raw);
|
|
83
92
|
}
|
|
84
93
|
|
|
85
|
-
// src/generated/
|
|
86
|
-
var
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
throw parseReplyError(err);
|
|
100
|
-
}
|
|
101
|
-
return reply;
|
|
102
|
-
}
|
|
103
|
-
var callItemReadAttachment = (payload) => callPluginMethod("item.readAttachment", payload);
|
|
104
|
-
var callAssetCurrentItemImageUrl = () => callPluginMethod("asset.currentItemImageUrl", {});
|
|
105
|
-
var callAssetPathReferenceImageUrl = (payload) => callPluginMethod("asset.pathReferenceImageUrl", payload);
|
|
106
|
-
var callAssetCurrentActionInputImageUrl = () => callPluginMethod("asset.currentActionInputImageUrl", {});
|
|
107
|
-
var callAssetCurrentActionInputPathReferenceImageUrl = (payload) => callPluginMethod("asset.currentActionInputPathReferenceImageUrl", payload);
|
|
108
|
-
var callClipboardCopyText = (payload) => callPluginMethod("clipboard.copyText", payload);
|
|
109
|
-
var callNavigationOpenUrl = (payload) => callPluginMethod("navigation.openUrl", payload);
|
|
110
|
-
var callNavigationRevealInFinder = (payload) => callPluginMethod("navigation.revealInFinder", payload);
|
|
111
|
-
var callNavigationOpenFilePath = (payload) => callPluginMethod("navigation.openFilePath", payload);
|
|
112
|
-
var callActionSetButtons = (payload) => callPluginMethod("action.setButtons", payload);
|
|
113
|
-
var callActionComplete = (payload) => callPluginMethod("action.complete", payload);
|
|
114
|
-
var callAttachmentRendererSetButtons = (payload) => callPluginMethod("attachmentRenderer.setButtons", payload);
|
|
115
|
-
var callWindowSetHeight = (payload) => callPluginMethod("window.setHeight", payload);
|
|
116
|
-
var callWindowAutoFit = () => callPluginMethod("window.autoFit", {});
|
|
117
|
-
var callInfoPanelOpen = (payload) => callPluginMethod("infoPanel.open", payload);
|
|
118
|
-
var callInfoPanelClose = (payload) => callPluginMethod("infoPanel.close", payload);
|
|
119
|
-
var callSettingsGet = (payload) => callPluginMethod("settings.get", payload);
|
|
120
|
-
var callSettingsGetAll = () => callPluginMethod("settings.getAll", {});
|
|
121
|
-
var callConsoleLog = (payload) => callPluginMethod("console.log", payload);
|
|
122
|
-
var callTextInputStateChanged = (payload) => callPluginMethod("textInput.stateChanged", payload);
|
|
94
|
+
// src/generated/hostEvents.generated.ts
|
|
95
|
+
var HOST_EVENT_WINDOW_GLOBALS = {
|
|
96
|
+
"clipbus-plugin-context": "__CLIPBUS_PLUGIN_CONTEXT__",
|
|
97
|
+
"clipbus-plugin-item": "__CLIPBUS_PLUGIN_ITEM__",
|
|
98
|
+
"clipbus-plugin-attachment": "__CLIPBUS_PLUGIN_ATTACHMENT__",
|
|
99
|
+
"clipbus-plugin-draft": "__CLIPBUS_PLUGIN_DRAFT__",
|
|
100
|
+
"clipbus-plugin-action-input": "__CLIPBUS_PLUGIN_ACTION_INPUT__",
|
|
101
|
+
"clipbus-plugin-theme": "__CLIPBUS_PLUGIN_THEME__",
|
|
102
|
+
"clipbus-plugin-attachment-host-invoke": null,
|
|
103
|
+
"clipbus-plugin-action-host-invoke": null,
|
|
104
|
+
"clipbus-plugin-info-panel-on-action": null,
|
|
105
|
+
"clipbus-plugin-info-panel-on-close": null,
|
|
106
|
+
"clipbus-plugin-locale": "__CLIPBUS_PLUGIN_LOCALE__"
|
|
107
|
+
};
|
|
123
108
|
|
|
124
109
|
// src/internal/topic.ts
|
|
125
110
|
function createTopic(initial) {
|
|
@@ -164,95 +149,36 @@ function readWindowGlobal(key) {
|
|
|
164
149
|
return window[key];
|
|
165
150
|
}
|
|
166
151
|
|
|
167
|
-
// src/
|
|
168
|
-
function
|
|
169
|
-
const handler = (e) => listener(e.detail);
|
|
170
|
-
globalThis.addEventListener("clipbus-plugin-context", handler);
|
|
171
|
-
return () => globalThis.removeEventListener("clipbus-plugin-context", handler);
|
|
172
|
-
}
|
|
173
|
-
function onItem(listener) {
|
|
174
|
-
const handler = (e) => listener(e.detail);
|
|
175
|
-
globalThis.addEventListener("clipbus-plugin-item", handler);
|
|
176
|
-
return () => globalThis.removeEventListener("clipbus-plugin-item", handler);
|
|
177
|
-
}
|
|
178
|
-
function onAttachment(listener) {
|
|
179
|
-
const handler = (e) => listener(e.detail);
|
|
180
|
-
globalThis.addEventListener("clipbus-plugin-attachment", handler);
|
|
181
|
-
return () => globalThis.removeEventListener("clipbus-plugin-attachment", handler);
|
|
182
|
-
}
|
|
183
|
-
function onDraft(listener) {
|
|
184
|
-
const handler = (e) => listener(e.detail);
|
|
185
|
-
globalThis.addEventListener("clipbus-plugin-draft", handler);
|
|
186
|
-
return () => globalThis.removeEventListener("clipbus-plugin-draft", handler);
|
|
187
|
-
}
|
|
188
|
-
function onActionInput(listener) {
|
|
152
|
+
// src/internal/hostEvents.ts
|
|
153
|
+
function onHostEvent(name, listener) {
|
|
189
154
|
const handler = (e) => listener(e.detail);
|
|
190
|
-
globalThis.addEventListener(
|
|
191
|
-
return () => globalThis.removeEventListener(
|
|
155
|
+
globalThis.addEventListener(name, handler);
|
|
156
|
+
return () => globalThis.removeEventListener(name, handler);
|
|
192
157
|
}
|
|
193
|
-
function
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
globalThis.addEventListener("clipbus-plugin-attachment-host-invoke", handler);
|
|
201
|
-
return () => globalThis.removeEventListener("clipbus-plugin-attachment-host-invoke", handler);
|
|
202
|
-
}
|
|
203
|
-
function onActionHostInvoke(listener) {
|
|
204
|
-
const handler = (e) => listener(e.detail);
|
|
205
|
-
globalThis.addEventListener("clipbus-plugin-action-host-invoke", handler);
|
|
206
|
-
return () => globalThis.removeEventListener("clipbus-plugin-action-host-invoke", handler);
|
|
158
|
+
function createHostTopic(name) {
|
|
159
|
+
const windowGlobal = HOST_EVENT_WINDOW_GLOBALS[name];
|
|
160
|
+
const topic = createTopic(
|
|
161
|
+
windowGlobal === null ? void 0 : readWindowGlobal(windowGlobal)
|
|
162
|
+
);
|
|
163
|
+
onHostEvent(name, (payload) => topic.set(payload));
|
|
164
|
+
return topic;
|
|
207
165
|
}
|
|
208
|
-
function
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
return
|
|
212
|
-
}
|
|
213
|
-
function onInfoPanelOnClose(listener) {
|
|
214
|
-
const handler = (e) => listener(e.detail);
|
|
215
|
-
globalThis.addEventListener("clipbus-plugin-info-panel-on-close", handler);
|
|
216
|
-
return () => globalThis.removeEventListener("clipbus-plugin-info-panel-on-close", handler);
|
|
217
|
-
}
|
|
218
|
-
function onLocale(listener) {
|
|
219
|
-
const handler = (e) => listener(e.detail);
|
|
220
|
-
globalThis.addEventListener("clipbus-plugin-locale", handler);
|
|
221
|
-
return () => globalThis.removeEventListener("clipbus-plugin-locale", handler);
|
|
166
|
+
function createHostStream(name) {
|
|
167
|
+
const stream = createStream();
|
|
168
|
+
onHostEvent(name, (payload) => stream.emit(payload));
|
|
169
|
+
return stream;
|
|
222
170
|
}
|
|
223
171
|
|
|
224
|
-
// src/
|
|
225
|
-
var _pluginContextTopic = createTopic(readWindowGlobal("__CLIPBUS_PLUGIN_CONTEXT__"));
|
|
226
|
-
onContext((p) => _pluginContextTopic.set(p));
|
|
227
|
-
var _itemTopic = createTopic(readWindowGlobal("__CLIPBUS_PLUGIN_ITEM__"));
|
|
228
|
-
onItem((p) => _itemTopic.set(p));
|
|
229
|
-
var _itemAttachmentTopic = createTopic(readWindowGlobal("__CLIPBUS_PLUGIN_ATTACHMENT__"));
|
|
230
|
-
onAttachment((p) => _itemAttachmentTopic.set(p));
|
|
231
|
-
var _actionDraftTopic = createTopic(readWindowGlobal("__CLIPBUS_PLUGIN_DRAFT__"));
|
|
232
|
-
onDraft((p) => _actionDraftTopic.set(p));
|
|
233
|
-
var _actionInputTopic = createTopic(readWindowGlobal("__CLIPBUS_PLUGIN_ACTION_INPUT__"));
|
|
234
|
-
onActionInput((p) => _actionInputTopic.set(p));
|
|
235
|
-
var _themeTopic = createTopic(readWindowGlobal("__CLIPBUS_PLUGIN_THEME__"));
|
|
236
|
-
onTheme((p) => _themeTopic.set(p));
|
|
237
|
-
var _attachmentRendererOnHostInvokeStream = createStream();
|
|
238
|
-
onAttachmentHostInvoke((p) => _attachmentRendererOnHostInvokeStream.emit(p));
|
|
239
|
-
var _actionOnHostInvokeStream = createStream();
|
|
240
|
-
onActionHostInvoke((p) => _actionOnHostInvokeStream.emit(p));
|
|
241
|
-
var _infoPanelOnActionStream = createStream();
|
|
242
|
-
onInfoPanelOnAction((p) => _infoPanelOnActionStream.emit(p));
|
|
243
|
-
var _infoPanelOnCloseStream = createStream();
|
|
244
|
-
onInfoPanelOnClose((p) => _infoPanelOnCloseStream.emit(p));
|
|
245
|
-
var _localeTopic = createTopic(readWindowGlobal("__CLIPBUS_PLUGIN_LOCALE__"));
|
|
246
|
-
onLocale((p) => _localeTopic.set(p));
|
|
172
|
+
// src/internal/pluginContext.ts
|
|
247
173
|
var PluginContextError = class extends Error {
|
|
248
174
|
constructor(message) {
|
|
249
175
|
super(message);
|
|
250
176
|
this.name = "PluginContextError";
|
|
251
177
|
}
|
|
252
178
|
};
|
|
253
|
-
function guardContext(expected, run) {
|
|
179
|
+
function guardContext(contextTopic, expected, run) {
|
|
254
180
|
return (...args) => {
|
|
255
|
-
const current =
|
|
181
|
+
const current = contextTopic.current()?.mode;
|
|
256
182
|
if (current !== expected) {
|
|
257
183
|
throw new PluginContextError(
|
|
258
184
|
`This verb is not available in the current plugin context (expected: ${expected}, got: ${current || "unknown"})`
|
|
@@ -263,90 +189,102 @@ function guardContext(expected, run) {
|
|
|
263
189
|
}
|
|
264
190
|
|
|
265
191
|
// src/generated/ui.clipbus.generated.ts
|
|
192
|
+
var pluginContextTopic = createHostTopic("clipbus-plugin-context");
|
|
193
|
+
var itemTopic = createHostTopic("clipbus-plugin-item");
|
|
194
|
+
var itemAttachmentTopic = createHostTopic("clipbus-plugin-attachment");
|
|
195
|
+
var actionDraftTopic = createHostTopic("clipbus-plugin-draft");
|
|
196
|
+
var actionInputTopic = createHostTopic("clipbus-plugin-action-input");
|
|
197
|
+
var themeTopic = createHostTopic("clipbus-plugin-theme");
|
|
198
|
+
var attachmentRendererOnHostInvokeStream = createHostStream("clipbus-plugin-attachment-host-invoke");
|
|
199
|
+
var actionOnHostInvokeStream = createHostStream("clipbus-plugin-action-host-invoke");
|
|
200
|
+
var infoPanelOnActionStream = createHostStream("clipbus-plugin-info-panel-on-action");
|
|
201
|
+
var infoPanelOnCloseStream = createHostStream("clipbus-plugin-info-panel-on-close");
|
|
202
|
+
var localeTopic = createHostTopic("clipbus-plugin-locale");
|
|
266
203
|
var clipbus = {
|
|
267
204
|
capabilities: createCapabilitiesApi(() => readInjectedCapabilities(globalThis, CAPABILITIES_GLOBAL)),
|
|
268
205
|
runtime: {
|
|
269
|
-
invoke: (payload) =>
|
|
206
|
+
invoke: (payload) => callRuntimeInvoke(payload)
|
|
270
207
|
},
|
|
271
208
|
item: {
|
|
272
|
-
current:
|
|
273
|
-
on:
|
|
274
|
-
readAttachment: (payload) =>
|
|
209
|
+
current: itemTopic.current,
|
|
210
|
+
on: itemTopic.on,
|
|
211
|
+
readAttachment: (payload) => callPluginMethod("item.readAttachment", payload),
|
|
275
212
|
attachment: {
|
|
276
|
-
current:
|
|
277
|
-
on:
|
|
213
|
+
current: itemAttachmentTopic.current,
|
|
214
|
+
on: itemAttachmentTopic.on
|
|
278
215
|
}
|
|
279
216
|
},
|
|
280
217
|
asset: {
|
|
281
|
-
currentItemImageUrl: () =>
|
|
282
|
-
pathReferenceImageUrl: (payload) =>
|
|
283
|
-
currentActionInputImageUrl: guardContext("action", () =>
|
|
284
|
-
currentActionInputPathReferenceImageUrl: guardContext("action", (payload) =>
|
|
218
|
+
currentItemImageUrl: () => callPluginMethod("asset.currentItemImageUrl", {}),
|
|
219
|
+
pathReferenceImageUrl: (payload) => callPluginMethod("asset.pathReferenceImageUrl", payload),
|
|
220
|
+
currentActionInputImageUrl: guardContext(pluginContextTopic, "action", () => callPluginMethod("asset.currentActionInputImageUrl", {})),
|
|
221
|
+
currentActionInputPathReferenceImageUrl: guardContext(pluginContextTopic, "action", (payload) => callPluginMethod("asset.currentActionInputPathReferenceImageUrl", payload))
|
|
285
222
|
},
|
|
286
223
|
clipboard: {
|
|
287
|
-
copyText: (payload) =>
|
|
224
|
+
copyText: (payload) => callPluginMethod("clipboard.copyText", payload)
|
|
288
225
|
},
|
|
289
226
|
navigation: {
|
|
290
|
-
openUrl: (payload) =>
|
|
291
|
-
revealInFinder: (payload) =>
|
|
292
|
-
openFilePath: (payload) =>
|
|
227
|
+
openUrl: (payload) => callPluginMethod("navigation.openUrl", payload),
|
|
228
|
+
revealInFinder: (payload) => callPluginMethod("navigation.revealInFinder", payload),
|
|
229
|
+
openFilePath: (payload) => callPluginMethod("navigation.openFilePath", payload)
|
|
293
230
|
},
|
|
294
231
|
action: {
|
|
295
|
-
setButtons: guardContext("action", (payload) =>
|
|
296
|
-
complete: guardContext("action", (payload) =>
|
|
232
|
+
setButtons: guardContext(pluginContextTopic, "action", (payload) => callPluginMethod("action.setButtons", payload)),
|
|
233
|
+
complete: guardContext(pluginContextTopic, "action", (payload) => callPluginMethod("action.complete", payload)),
|
|
297
234
|
draft: {
|
|
298
|
-
current:
|
|
299
|
-
on:
|
|
235
|
+
current: actionDraftTopic.current,
|
|
236
|
+
on: actionDraftTopic.on
|
|
300
237
|
},
|
|
301
238
|
input: {
|
|
302
|
-
current:
|
|
303
|
-
on:
|
|
239
|
+
current: actionInputTopic.current,
|
|
240
|
+
on: actionInputTopic.on
|
|
304
241
|
},
|
|
305
242
|
onHostInvoke: {
|
|
306
|
-
on:
|
|
243
|
+
on: actionOnHostInvokeStream.on
|
|
307
244
|
}
|
|
308
245
|
},
|
|
309
246
|
attachmentRenderer: {
|
|
310
|
-
setButtons: guardContext("attachmentRenderer", (payload) =>
|
|
247
|
+
setButtons: guardContext(pluginContextTopic, "attachmentRenderer", (payload) => callPluginMethod("attachmentRenderer.setButtons", payload)),
|
|
311
248
|
onHostInvoke: {
|
|
312
|
-
on:
|
|
249
|
+
on: attachmentRendererOnHostInvokeStream.on
|
|
313
250
|
}
|
|
314
251
|
},
|
|
315
252
|
window: {
|
|
316
|
-
setHeight: (payload) =>
|
|
317
|
-
autoFit: () =>
|
|
253
|
+
setHeight: (payload) => callPluginMethod("window.setHeight", payload),
|
|
254
|
+
autoFit: () => callPluginMethod("window.autoFit", {})
|
|
318
255
|
},
|
|
319
256
|
infoPanel: {
|
|
320
|
-
open: (payload) =>
|
|
321
|
-
close: (payload) =>
|
|
257
|
+
open: (payload) => callPluginMethod("infoPanel.open", payload),
|
|
258
|
+
close: (payload) => callPluginMethod("infoPanel.close", payload),
|
|
322
259
|
onAction: {
|
|
323
|
-
on:
|
|
260
|
+
on: infoPanelOnActionStream.on
|
|
324
261
|
},
|
|
325
262
|
onClose: {
|
|
326
|
-
on:
|
|
263
|
+
on: infoPanelOnCloseStream.on
|
|
327
264
|
}
|
|
328
265
|
},
|
|
329
266
|
settings: {
|
|
330
|
-
get: (payload) =>
|
|
331
|
-
getAll: () =>
|
|
267
|
+
get: (payload) => callPluginMethod("settings.get", payload),
|
|
268
|
+
getAll: () => callPluginMethod("settings.getAll", {})
|
|
332
269
|
},
|
|
333
270
|
console: {
|
|
334
|
-
log: (payload) =>
|
|
271
|
+
log: (payload) => callPluginMethod("console.log", payload),
|
|
272
|
+
diagnostic: (payload) => callPluginMethod("console.diagnostic", payload)
|
|
335
273
|
},
|
|
336
274
|
textInput: {
|
|
337
|
-
stateChanged: (payload) =>
|
|
275
|
+
stateChanged: (payload) => callPluginMethod("textInput.stateChanged", payload)
|
|
338
276
|
},
|
|
339
277
|
pluginContext: {
|
|
340
|
-
current:
|
|
341
|
-
on:
|
|
278
|
+
current: pluginContextTopic.current,
|
|
279
|
+
on: pluginContextTopic.on
|
|
342
280
|
},
|
|
343
281
|
theme: {
|
|
344
|
-
current:
|
|
345
|
-
on:
|
|
282
|
+
current: themeTopic.current,
|
|
283
|
+
on: themeTopic.on
|
|
346
284
|
},
|
|
347
285
|
locale: {
|
|
348
|
-
current:
|
|
349
|
-
on:
|
|
286
|
+
current: localeTopic.current,
|
|
287
|
+
on: localeTopic.on
|
|
350
288
|
}
|
|
351
289
|
};
|
|
352
290
|
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* JavaScript mirror of the native PluginManifestValidator (Swift).
|
|
5
5
|
* Authority: platform/macos/Sources/Services/Impl/Plugins/PluginManifestValidator.swift
|
|
6
6
|
*
|
|
7
|
-
* Parity:
|
|
8
|
-
* MANIFEST_VALIDATION_CODES
|
|
9
|
-
*
|
|
7
|
+
* Parity: Swift, JavaScript and C# validator tests all consume
|
|
8
|
+
* protocol/plugin/fixtures/manifest-validator-parity.v4.json; MANIFEST_VALIDATION_CODES
|
|
9
|
+
* mirrors the Swift ValidationError case set and CANONICAL_ITEM_TYPES mirrors
|
|
10
|
+
* ClipboardItemType.swift enum case raw values.
|
|
10
11
|
*
|
|
11
12
|
* Design difference from native: native throws on the first error (fail-fast); this
|
|
12
13
|
* function collects ALL issues and returns them — better DX for development so that
|
|
@@ -32,7 +33,7 @@ export interface ValidateManifestOptions {
|
|
|
32
33
|
}
|
|
33
34
|
/**
|
|
34
35
|
* All validation error codes, verbatim camelCase mirror of Swift ValidationError cases.
|
|
35
|
-
* Parity with native is
|
|
36
|
+
* Parity with native is proven by the shared manifest-validator-parity corpus.
|
|
36
37
|
*/
|
|
37
38
|
export declare const MANIFEST_VALIDATION_CODES: readonly ["unsupportedSchemaVersion", "missingManifest", "missingRuntimeEntry", "missingUIRoot", "legacyFieldNotSupported", "duplicateAttachmentRendererID", "duplicateDetectorID", "duplicateActionID", "emptyPluginID", "invalidPluginID", "emptyPluginTitle", "installEntryMissing", "installEntryOutsideRoot", "rendererTitleEmpty", "detectorTitleEmpty", "actionTitleEmpty", "detectorMissingSupportedInputKinds", "detectorAttachmentTypesEmpty", "detectorAttachmentTypeNotRenderable", "detectorAttachmentTypeOutsideNamespace", "rendererUIEntryMissing", "rendererUIEntryOutsideRoot", "actionMissingSupportedInputKinds", "actionUIEntryMissing", "actionUIEntryOutsideRoot", "detectorInvalidSupportedInputKind", "actionInvalidSupportedInputKind"];
|
|
38
39
|
/**
|
package/dist/validate/index.d.ts
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* JavaScript mirror of the native PluginManifestValidator (Swift).
|
|
5
5
|
* Authority: platform/macos/Sources/Services/Impl/Plugins/PluginManifestValidator.swift
|
|
6
6
|
*
|
|
7
|
-
* Parity:
|
|
8
|
-
* MANIFEST_VALIDATION_CODES
|
|
9
|
-
*
|
|
7
|
+
* Parity: Swift, JavaScript and C# validator tests all consume
|
|
8
|
+
* protocol/plugin/fixtures/manifest-validator-parity.v4.json; MANIFEST_VALIDATION_CODES
|
|
9
|
+
* mirrors the Swift ValidationError case set and CANONICAL_ITEM_TYPES mirrors
|
|
10
|
+
* ClipboardItemType.swift enum case raw values.
|
|
10
11
|
*
|
|
11
12
|
* Design difference from native: native throws on the first error (fail-fast); this
|
|
12
13
|
* function collects ALL issues and returns them — better DX for development so that
|
|
@@ -32,7 +33,7 @@ export interface ValidateManifestOptions {
|
|
|
32
33
|
}
|
|
33
34
|
/**
|
|
34
35
|
* All validation error codes, verbatim camelCase mirror of Swift ValidationError cases.
|
|
35
|
-
* Parity with native is
|
|
36
|
+
* Parity with native is proven by the shared manifest-validator-parity corpus.
|
|
36
37
|
*/
|
|
37
38
|
export declare const MANIFEST_VALIDATION_CODES: readonly ["unsupportedSchemaVersion", "missingManifest", "missingRuntimeEntry", "missingUIRoot", "legacyFieldNotSupported", "duplicateAttachmentRendererID", "duplicateDetectorID", "duplicateActionID", "emptyPluginID", "invalidPluginID", "emptyPluginTitle", "installEntryMissing", "installEntryOutsideRoot", "rendererTitleEmpty", "detectorTitleEmpty", "actionTitleEmpty", "detectorMissingSupportedInputKinds", "detectorAttachmentTypesEmpty", "detectorAttachmentTypeNotRenderable", "detectorAttachmentTypeOutsideNamespace", "rendererUIEntryMissing", "rendererUIEntryOutsideRoot", "actionMissingSupportedInputKinds", "actionUIEntryMissing", "actionUIEntryOutsideRoot", "detectorInvalidSupportedInputKind", "actionInvalidSupportedInputKind"];
|
|
38
39
|
/**
|
package/docs/authoring.md
CHANGED
|
@@ -278,7 +278,7 @@ import { defineMessage } from '@clipbus/plugin-sdk/runtime'; // 或 /ui,类
|
|
|
278
278
|
export const GenerateImage = defineMessage<{ prompt: string }, { imageTempPath: string }>('generate-image');
|
|
279
279
|
|
|
280
280
|
// runtime/index.ts
|
|
281
|
-
const { definePlugin
|
|
281
|
+
const { definePlugin } = require('@clipbus/plugin-sdk/runtime');
|
|
282
282
|
const fs = require('node:fs/promises');
|
|
283
283
|
const { GenerateImage } = require('../shared/contracts');
|
|
284
284
|
|
|
@@ -55,9 +55,9 @@ try {
|
|
|
55
55
|
### 调用前门控
|
|
56
56
|
|
|
57
57
|
```ts
|
|
58
|
-
import type {
|
|
58
|
+
import type { PluginAutoRunActionHandler } from '@clipbus/plugin-sdk/runtime';
|
|
59
59
|
|
|
60
|
-
const action:
|
|
60
|
+
const action: PluginAutoRunActionHandler = {
|
|
61
61
|
async runAutoAction(input, ctx) {
|
|
62
62
|
if (ctx.host.capabilities.has('item.setTags')) {
|
|
63
63
|
await ctx.host.item.setTags({ tags: ['processed'] });
|
package/docs/entry.md
CHANGED
|
@@ -8,7 +8,7 @@ SDK 暴露两个 subpath。每个入口导出的符号**完全由 codegen 生成
|
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
// CommonJS(推荐与现行 bundler 配合)
|
|
11
|
-
const { definePlugin,
|
|
11
|
+
const { definePlugin, actionResult, defineMessage } = require('@clipbus/plugin-sdk/runtime');
|
|
12
12
|
|
|
13
13
|
// ESM(types)
|
|
14
14
|
import type { PluginAttachmentRendererHandler, PluginAutoRunActionHandler, PluginDetectorHandler } from '@clipbus/plugin-sdk/runtime';
|
|
@@ -16,11 +16,12 @@ import type { PluginAttachmentRendererHandler, PluginAutoRunActionHandler, Plugi
|
|
|
16
16
|
|
|
17
17
|
入口导出:
|
|
18
18
|
|
|
19
|
-
- `definePlugin` —— 注册 handler;本地校验 registry
|
|
20
|
-
- `host` —— 直接调宿主能力的单例(`host.<domain>.<verb>(payload)`)。**推荐写法**是从 handler 收到的 `ctx.host` 调用(同一个对象,但写在 handler 内更显式)。
|
|
19
|
+
- `definePlugin` —— 注册 handler;本地校验 registry 形状。传入 `{ setup(context) { … } }` 时,`context` 是宿主提供的 `PluginRuntimeLaunchContext`(`plugin`、`host`、`supportedCapabilities`)
|
|
21
20
|
- `actionResult` —— `runAutoAction` 的返回值构造器
|
|
22
21
|
- `defineMessage` —— UI ↔ Runtime RPC 的类型契约
|
|
23
22
|
|
|
23
|
+
宿主能力只能通过 handler 收到的 `ctx.host.<domain>.<verb>(payload)` 调用:`ctx` 与本次调用绑定,调用结束后失效。0.10.0 起不再导出 `host` 单例(它从未能在宿主中工作);迁移方式是把 `host.x.y(...)` 改为 handler 内的 `ctx.host.x.y(...)`。
|
|
24
|
+
|
|
24
25
|
## UI 入口
|
|
25
26
|
|
|
26
27
|
```ts
|
package/docs/item-context.md
CHANGED
|
@@ -153,6 +153,7 @@ WebView 沙箱禁止 `file://`,且 SDK **从不**把真实文件路径暴露
|
|
|
153
153
|
| `clipbus.asset.pathReferenceImageUrl({ index })` | UI | `{ index }` | `{ url?: string }` | 当前 item 第 `index` 个 `path_reference` 条目的图(越界 / 非图片文件 → `url` 缺失) |
|
|
154
154
|
| `clipbus.asset.currentActionInputImageUrl()` | UI/action | `{}` | `{ url?: string }` | 当前 Action image 值,与原始 item type 无关 |
|
|
155
155
|
| `clipbus.asset.currentActionInputPathReferenceImageUrl({ index })` | UI/action | `{ index }` | `{ url?: string }` | 当前 Action path_reference 中第 `index` 张图 |
|
|
156
|
+
| `host.asset.allocateImageTempPath({ formatHint })` | runtime | `{ formatHint }` | `{ path: string }` | 为当前 session 分配生成图片的路径;随 owner 释放 |
|
|
156
157
|
| `host.asset.registerImage({ path })` | runtime | `{ path }` | `{ url: string }` | 把 **Node 产出 / 已有**的本地图注册进当前 session,签发 URL |
|
|
157
158
|
|
|
158
159
|
capability 完整签名见 [API.md](../API.md)。
|
|
@@ -196,8 +197,9 @@ const { GenerateImage } = require('../shared/contracts');
|
|
|
196
197
|
module.exports = definePlugin({
|
|
197
198
|
messageHandlers: Object.fromEntries([
|
|
198
199
|
GenerateImage.handle(async (_req, ctx) => {
|
|
199
|
-
const
|
|
200
|
-
|
|
200
|
+
const { path } = await ctx.host.asset.allocateImageTempPath({ formatHint: 'png' });
|
|
201
|
+
await writeSomePng(path); // Node 写入宿主分配的会话路径
|
|
202
|
+
const { url } = await ctx.host.asset.registerImage({ path });
|
|
201
203
|
return { url }; // 只回传 URL,不回传字节
|
|
202
204
|
}),
|
|
203
205
|
]),
|
|
@@ -209,7 +211,7 @@ const { url } = await GenerateImage.invoke({});
|
|
|
209
211
|
imageUrl.value = url; // <img :src="imageUrl">
|
|
210
212
|
```
|
|
211
213
|
|
|
212
|
-
>
|
|
214
|
+
> **路径与 token 生命周期:** 分配的文件及 URL 绑定当前 session owner,invocation / WebView 释放时一并失效,且跨 owner 隔离——不要持久化或跨会话复用。Windows 只接受该 owner 已分配的注册路径。
|
|
213
215
|
> **何时用哪个:** renderer 显示原始 item 用 `currentItemImageUrl` /
|
|
214
216
|
> `pathReferenceImageUrl`;Draft Action 显示当前级联值用
|
|
215
217
|
> `currentActionInputImageUrl` / `currentActionInputPathReferenceImageUrl`;
|
package/docs/permissions.md
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
| `setAttachment` | `host.item.setAttachments` |
|
|
24
24
|
| `setSearchExtension` | `host.item.setSearchExtension` |
|
|
25
25
|
|
|
26
|
-
**不受门控:** `host.clipboard.*`、`host.navigation.*`、`host.settings.*`(只读)、`host.console.log`、`host.action.allocateImageTempPath`、`host.action.materializeInputImagePath`、`host.action.allocateOutputFilePath`、`host.item.materializeImagePath`、`host.item.readAttachment`、所有 `clipbus.*` 中的 UI 专属 verb(`window.*`、`action.setButtons`、`action.complete`、`attachmentRenderer.setButtons` 等)。
|
|
26
|
+
**不受门控:** `host.clipboard.*`、`host.navigation.*`、`host.settings.*`(只读)、`host.console.log`、`host.console.diagnostic`、`host.asset.allocateImageTempPath`、`host.asset.registerImage`、`host.action.allocateImageTempPath`、`host.action.materializeInputImagePath`、`host.action.allocateOutputFilePath`、`host.item.materializeImagePath`、`host.item.readAttachment`、所有 `clipbus.*` 中的 UI 专属 verb(`window.*`、`action.setButtons`、`action.complete`、`attachmentRenderer.setButtons` 等)。
|
|
27
27
|
|
|
28
28
|
各 verb 的完整签名见 [API.md](../API.md)。
|
|
29
29
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clipbus/plugin-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Typed SDK for authoring Clipbus plugins — runtime (Node.js) and UI (WebView) helpers generated from the Clipbus plugin wire contract.",
|
|
6
6
|
"keywords": [
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
"sdk"
|
|
10
10
|
],
|
|
11
11
|
"license": "MIT",
|
|
12
|
+
"homepage": "https://github.com/scubers/clipbus-release/releases?q=%22Clipbus+Plugin+SDK%22&expanded=true",
|
|
12
13
|
"repository": {
|
|
13
14
|
"type": "git",
|
|
14
|
-
"url": "git+https://github.com/scubers/clipbus.git"
|
|
15
|
-
"directory": "packages/plugin-sdk"
|
|
15
|
+
"url": "git+https://github.com/scubers/clipbus-release.git"
|
|
16
16
|
},
|
|
17
17
|
"engines": {
|
|
18
18
|
"node": ">=18.0.0"
|
|
@@ -77,8 +77,9 @@
|
|
|
77
77
|
"prepare": "node ./scripts/build.mjs",
|
|
78
78
|
"build": "node ./scripts/build.mjs",
|
|
79
79
|
"pretest": "node ./scripts/build.mjs",
|
|
80
|
-
"test": "node --require ./tests/setup.cjs --test
|
|
81
|
-
"
|
|
80
|
+
"test": "node --require ./tests/setup.cjs --test",
|
|
81
|
+
"prepack": "node ./scripts/release-notes.mjs changelog",
|
|
82
|
+
"prepublishOnly": "npm run build && npm test && node ./scripts/release-notes.mjs check"
|
|
82
83
|
},
|
|
83
84
|
"files": [
|
|
84
85
|
"dist",
|
|
@@ -86,6 +87,7 @@
|
|
|
86
87
|
"SPECIFICATION.md",
|
|
87
88
|
"README.md",
|
|
88
89
|
"API.md",
|
|
90
|
+
"CHANGELOG.md",
|
|
89
91
|
"docs"
|
|
90
92
|
],
|
|
91
93
|
"publishConfig": {
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { host } from './runtime.host.generated.js';
|
|
2
|
-
export { definePlugin } from './runtime.definePlugin.generated.js';
|
|
3
|
-
export { actionResult } from './runtime.actionResult.generated.js';
|
|
4
|
-
export type * from './data.generated.js';
|
|
5
|
-
export type * from './capabilityClients.generated.js';
|
|
6
|
-
export type * from './runtime.handlers.generated.js';
|