@getpaseo/server 0.5.0-beta.1 → 0.5.0-beta.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/dist/server/server/plugins/compiler.js +3 -3
- package/dist/server/server/plugins/plugin-process.js +3 -2
- package/dist/server/server/plugins/plugin-sdk-specifiers.d.ts +3 -0
- package/dist/server/server/plugins/plugin-sdk-specifiers.js +17 -0
- package/dist/server/services/github-service.js +8 -2
- package/dist/server/skills/paseo-plugin/SKILL.md +14 -14
- package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-bridge-f239ab5605caa1976add6b0f69790041.js → desktop-attachment-bridge-4376f9e44ee3fcf3391f24a2a67d8863.js} +1 -1
- package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-bridge-f239ab5605caa1976add6b0f69790041.js.br → desktop-attachment-bridge-4376f9e44ee3fcf3391f24a2a67d8863.js.br} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-4376f9e44ee3fcf3391f24a2a67d8863.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-store-aa28d6b939ad73784f0e8da5768c9083.js → desktop-attachment-store-66859071c5bd14bebd1b80c619f1cd19.js} +1 -1
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-66859071c5bd14bebd1b80c619f1cd19.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-66859071c5bd14bebd1b80c619f1cd19.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-268f5af17c399a0556d5766816797d73.js → index-c849eac42efab4ece3dfb4572313762d.js} +250 -249
- package/dist/server/web-ui/_expo/static/js/web/index-c849eac42efab4ece3dfb4572313762d.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-c849eac42efab4ece3dfb4572313762d.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{indexeddb-attachment-store-d79d9aa427af19528055831153f099e6.js → indexeddb-attachment-store-bf20675e7273a75d5ad8a84abd8ae9e7.js} +1 -1
- package/dist/server/web-ui/_expo/static/js/web/{indexeddb-attachment-store-d79d9aa427af19528055831153f099e6.js.br → indexeddb-attachment-store-bf20675e7273a75d5ad8a84abd8ae9e7.js.br} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-bf20675e7273a75d5ad8a84abd8ae9e7.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{native-file-attachment-store-d07de2817dfa86583cd0a49a69a9655f.js → native-file-attachment-store-bfaeb0e6108d6f83a8247d675be58104.js} +3 -3
- package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-bfaeb0e6108d6f83a8247d675be58104.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-bfaeb0e6108d6f83a8247d675be58104.js.gz +0 -0
- package/dist/server/web-ui/index.html +1 -1
- package/dist/server/web-ui/index.html.br +0 -0
- package/dist/server/web-ui/index.html.gz +0 -0
- package/package.json +6 -6
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-f239ab5605caa1976add6b0f69790041.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-aa28d6b939ad73784f0e8da5768c9083.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-aa28d6b939ad73784f0e8da5768c9083.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-268f5af17c399a0556d5766816797d73.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-268f5af17c399a0556d5766816797d73.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-d79d9aa427af19528055831153f099e6.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-d07de2817dfa86583cd0a49a69a9655f.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-d07de2817dfa86583cd0a49a69a9655f.js.gz +0 -0
|
@@ -3,6 +3,7 @@ import { readFile } from "node:fs/promises";
|
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { parse } from "@babel/parser";
|
|
6
|
+
import { PLUGIN_SDK_SPECIFIERS } from "./plugin-sdk-specifiers.js";
|
|
6
7
|
const nodeRequire = createRequire(import.meta.url);
|
|
7
8
|
const ESBUILD_BINARY_PATH = "ESBUILD_BINARY_PATH";
|
|
8
9
|
// esbuild resolves its own platform binary via require.resolve() the first time its
|
|
@@ -246,15 +247,14 @@ async function compileTarget(entryPath, target) {
|
|
|
246
247
|
target: target === "server" ? "node20" : "es2020",
|
|
247
248
|
external: target === "client"
|
|
248
249
|
? [
|
|
249
|
-
|
|
250
|
-
"@paseo/plugin/server",
|
|
250
|
+
...PLUGIN_SDK_SPECIFIERS,
|
|
251
251
|
"@tanstack/react-query",
|
|
252
252
|
"react",
|
|
253
253
|
"react/jsx-runtime",
|
|
254
254
|
"react-native",
|
|
255
255
|
"zod",
|
|
256
256
|
]
|
|
257
|
-
: [
|
|
257
|
+
: [...PLUGIN_SDK_SPECIFIERS, "zod"],
|
|
258
258
|
plugins: [createRuntimeBoundaryPlugin(target), createUnusedPlatformModulePlugin(target)],
|
|
259
259
|
logLevel: "silent",
|
|
260
260
|
treeShaking: true,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import { defineAttachmentSource, defineRpc, } from "@
|
|
2
|
+
import { defineAttachmentSource, defineRpc, } from "@getpaseo/plugin/server";
|
|
3
3
|
import { createPaseoApi } from "@getpaseo/client";
|
|
4
4
|
import { DaemonClient } from "@getpaseo/client/internal/daemon-client";
|
|
5
5
|
import { createPluginDaemonTransportFactory } from "./daemon-transport.js";
|
|
6
|
+
import { isPluginSdkSpecifier } from "./plugin-sdk-specifiers.js";
|
|
6
7
|
const handlers = new Map();
|
|
7
8
|
let cleanup = null;
|
|
8
9
|
let daemonClient = null;
|
|
@@ -43,7 +44,7 @@ function register(contract, handler) {
|
|
|
43
44
|
}
|
|
44
45
|
const pluginAuthorRuntime = { defineAttachmentSource, defineRpc };
|
|
45
46
|
function runtimeRequire(name) {
|
|
46
|
-
if (name
|
|
47
|
+
if (isPluginSdkSpecifier(name))
|
|
47
48
|
return pluginAuthorRuntime;
|
|
48
49
|
return nodeRequire(name);
|
|
49
50
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Specifiers a plugin author can import to reach the SDK. The daemon never resolves these
|
|
2
|
+
// from disk: the compiler marks them external and the plugin subprocess hands back its own
|
|
3
|
+
// runtime, so a plugin typechecks against generated declarations without installing anything.
|
|
4
|
+
//
|
|
5
|
+
// COMPAT(plugin-sdk-scope): @paseo/plugin was the SDK name through 0.5.0-beta.1 and was never
|
|
6
|
+
// published — that scope is not ours. Plugins scaffolded against that name still import it, so
|
|
7
|
+
// both spellings resolve. Remove the @paseo/* entries after 2026-11-19.
|
|
8
|
+
export const PLUGIN_SDK_SPECIFIERS = [
|
|
9
|
+
"@getpaseo/plugin",
|
|
10
|
+
"@getpaseo/plugin/server",
|
|
11
|
+
"@paseo/plugin",
|
|
12
|
+
"@paseo/plugin/server",
|
|
13
|
+
];
|
|
14
|
+
export function isPluginSdkSpecifier(name) {
|
|
15
|
+
return PLUGIN_SDK_SPECIFIERS.includes(name);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=plugin-sdk-specifiers.js.map
|
|
@@ -754,7 +754,10 @@ export function createGitHubService(options = {}) {
|
|
|
754
754
|
return pullRequest.headRefName;
|
|
755
755
|
},
|
|
756
756
|
defaultCheckoutRefs({ changeRequestNumber }) {
|
|
757
|
-
return [
|
|
757
|
+
return [
|
|
758
|
+
{ remoteName: "origin", remoteRef: `refs/pull/${changeRequestNumber}/head` },
|
|
759
|
+
{ remoteName: "upstream", remoteRef: `refs/pull/${changeRequestNumber}/head` },
|
|
760
|
+
];
|
|
758
761
|
},
|
|
759
762
|
buildPrLocalBranchName({ headRef, checkoutTarget }) {
|
|
760
763
|
const owner = checkoutTarget.isCrossRepository
|
|
@@ -1808,7 +1811,10 @@ function toPullRequestCheckoutTarget(parsed) {
|
|
|
1808
1811
|
number: pullRequest.number,
|
|
1809
1812
|
baseRefName: pullRequest.baseRefName,
|
|
1810
1813
|
headRefName: pullRequest.headRefName,
|
|
1811
|
-
checkoutRefs: [
|
|
1814
|
+
checkoutRefs: [
|
|
1815
|
+
{ remoteName: "origin", remoteRef: `refs/pull/${pullRequest.number}/head` },
|
|
1816
|
+
{ remoteName: "upstream", remoteRef: `refs/pull/${pullRequest.number}/head` },
|
|
1817
|
+
],
|
|
1812
1818
|
headOwnerLogin: pullRequest.headRepositoryOwner?.login || null,
|
|
1813
1819
|
headRepositorySshUrl: pullRequest.headRepository?.sshUrl || null,
|
|
1814
1820
|
headRepositoryUrl: pullRequest.headRepository?.url || null,
|
|
@@ -50,7 +50,7 @@ The manifest supplies the default install ID:
|
|
|
50
50
|
Default-export one contribution function. It must return cleanup, even when there is nothing to clean:
|
|
51
51
|
|
|
52
52
|
```tsx
|
|
53
|
-
import type { PluginContext } from "@
|
|
53
|
+
import type { PluginContext } from "@getpaseo/plugin";
|
|
54
54
|
|
|
55
55
|
export default function contribute(plugin: PluginContext) {
|
|
56
56
|
// Register contributions here.
|
|
@@ -67,7 +67,7 @@ mobile, and Paseo has multiple themes. Every `Text` must take its color from `th
|
|
|
67
67
|
Use `layout.compact` for padding and stacking. Unstyled text is black and fails in dark themes.
|
|
68
68
|
|
|
69
69
|
```tsx
|
|
70
|
-
import { type PluginContext, type PluginWorkspacePanelProps, useWorkspace } from "@
|
|
70
|
+
import { type PluginContext, type PluginWorkspacePanelProps, useWorkspace } from "@getpaseo/plugin";
|
|
71
71
|
import { useMemo } from "react";
|
|
72
72
|
import { Text, View } from "react-native";
|
|
73
73
|
|
|
@@ -123,7 +123,7 @@ the active workspace or agent. Command callbacks receive the selected host's `pa
|
|
|
123
123
|
Plugin surfaces use React Native primitives and work across desktop, browser, iOS, and Android. Register the surface before its sidebar item. Color text from `theme.colors` and pad from `layout.compact`.
|
|
124
124
|
|
|
125
125
|
```tsx
|
|
126
|
-
import type { PluginContext, PluginSurfaceProps } from "@
|
|
126
|
+
import type { PluginContext, PluginSurfaceProps } from "@getpaseo/plugin";
|
|
127
127
|
import React, { useMemo, useState } from "react";
|
|
128
128
|
import { Pressable, Text, View } from "react-native";
|
|
129
129
|
|
|
@@ -172,12 +172,12 @@ export default function contribute(plugin: PluginContext) {
|
|
|
172
172
|
|
|
173
173
|
Icons are Lucide icon names. `theme` is a typed `PluginTheme` on every surface and panel. Primary text uses `theme.colors.foreground`; labels use `theme.colors.foregroundMuted`; the root view uses `theme.colors.surface0`. `layout.compact` is true on mobile and narrow windows. Paseo owns the route, header, host picker, close action, error boundary, and per-installation query client.
|
|
174
174
|
|
|
175
|
-
Client code may import `react`, `react-native`, `@tanstack/react-query`, `zod`, `@
|
|
175
|
+
Client code may import `react`, `react-native`, `@tanstack/react-query`, `zod`, `@getpaseo/plugin`, and `@getpaseo/plugin/server`. Install dependencies locally for typechecking; Paseo supplies these runtime modules.
|
|
176
176
|
|
|
177
|
-
| Module
|
|
178
|
-
|
|
|
179
|
-
| `@
|
|
180
|
-
| `@
|
|
177
|
+
| Module | Use it for |
|
|
178
|
+
| ------------------------- | ---------------------------------------------------- |
|
|
179
|
+
| `@getpaseo/plugin` | hooks and UI types |
|
|
180
|
+
| `@getpaseo/plugin/server` | `defineRpc`, `defineAttachmentSource`, handler types |
|
|
181
181
|
|
|
182
182
|
## Choose the correct API
|
|
183
183
|
|
|
@@ -188,7 +188,7 @@ Use the existing Paseo SDK for normal Paseo operations. Use plugin RPC only for
|
|
|
188
188
|
`usePaseo()` borrows the selected host's current connection. Never create another client inside a surface.
|
|
189
189
|
|
|
190
190
|
```tsx
|
|
191
|
-
import { usePaseo } from "@
|
|
191
|
+
import { usePaseo } from "@getpaseo/plugin";
|
|
192
192
|
|
|
193
193
|
function PullRequestAction() {
|
|
194
194
|
const paseo = usePaseo();
|
|
@@ -221,9 +221,9 @@ The API covers workspaces, agents, providers, and daemon config. It omits connec
|
|
|
221
221
|
Define one Zod contract, register its subprocess handler, and call it with `useRpc()`:
|
|
222
222
|
|
|
223
223
|
```tsx
|
|
224
|
-
import type { PluginContext } from "@
|
|
225
|
-
import { useRpc } from "@
|
|
226
|
-
import { defineRpc } from "@
|
|
224
|
+
import type { PluginContext } from "@getpaseo/plugin";
|
|
225
|
+
import { useRpc } from "@getpaseo/plugin";
|
|
226
|
+
import { defineRpc } from "@getpaseo/plugin/server";
|
|
227
227
|
import { z } from "zod";
|
|
228
228
|
|
|
229
229
|
const greeting = defineRpc({
|
|
@@ -275,8 +275,8 @@ daemon log. Never log credentials or other secrets.
|
|
|
275
275
|
Define a search RPC and register a declarative source:
|
|
276
276
|
|
|
277
277
|
```tsx
|
|
278
|
-
import type { PluginContext } from "@
|
|
279
|
-
import { defineAttachmentSource, defineRpc } from "@
|
|
278
|
+
import type { PluginContext } from "@getpaseo/plugin";
|
|
279
|
+
import { defineAttachmentSource, defineRpc } from "@getpaseo/plugin/server";
|
|
280
280
|
import { z } from "zod";
|
|
281
281
|
|
|
282
282
|
const searchIssues = defineRpc({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createDesktopAttachmentBridge=function(){const l=(0,s.createDesktopPreviewUrlResolver)({reader:(0,s.createDesktopFileReader)(),objectUrls:(0,s.createBrowserObjectUrlMinter)()});return{copyFile:t.copyDesktopAttachmentFile,writeBase64:t.writeDesktopAttachmentBase64,writeBytes:t.writeDesktopAttachmentBytes,deleteFile:t.deleteDesktopAttachmentFile,garbageCollect:t.garbageCollectDesktopAttachmentFiles,readFileBase64:s.readDesktopFileBase64,resolvePreviewUrl:t=>l.resolve(t),releasePreviewUrl:t=>l.release(t)}};var t=r(d[0]),s=r(d[1])},
|
|
1
|
+
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createDesktopAttachmentBridge=function(){const l=(0,s.createDesktopPreviewUrlResolver)({reader:(0,s.createDesktopFileReader)(),objectUrls:(0,s.createBrowserObjectUrlMinter)()});return{copyFile:t.copyDesktopAttachmentFile,writeBase64:t.writeDesktopAttachmentBase64,writeBytes:t.writeDesktopAttachmentBytes,deleteFile:t.deleteDesktopAttachmentFile,garbageCollect:t.garbageCollectDesktopAttachmentFiles,readFileBase64:s.readDesktopFileBase64,resolvePreviewUrl:t=>l.resolve(t),releasePreviewUrl:t=>l.release(t)}};var t=r(d[0]),s=r(d[1])},4915,[4273,4274]);
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createDesktopAttachmentStore=function(n){return{storageType:"desktop-file",async save(s){const o=s.id??(0,t.generateAttachmentId)(),l=s.fileName??null;if("file_uri"===s.source.kind)return await c(n,{id:o,uri:s.source.uri,mimeType:s.mimeType,fileName:l});if("data_url"===s.source.kind){const c=(0,t.parseDataUrl)(s.source.dataUrl),p=(0,t.normalizeMimeType)(s.mimeType??c.mimeType);return await y(n,{id:o,base64:c.base64,mimeType:p,fileName:l})}if("bytes"===s.source.kind){const c=(0,t.normalizeMimeType)(s.mimeType);return await p(n,{id:o,bytes:s.source.bytes,mimeType:c,fileName:l})}const f=(0,t.normalizeMimeType)(s.mimeType??s.source.blob.type),u=await(0,t.blobToBase64)(s.source.blob);return await y(n,{id:o,base64:u,mimeType:f,fileName:l})},encodeBase64:async({attachment:t})=>(f(t),await n.readFileBase64(t.storageKey)),resolvePreviewUrl:async({attachment:t})=>(f(t),await n.resolvePreviewUrl(t)),async releasePreviewUrl({attachment:t,url:s}){f(t),await n.releasePreviewUrl({url:s})},async delete({attachment:t}){f(t),await n.deleteFile({path:t.storageKey})},async garbageCollect({referencedIds:t}){await n.garbageCollect({referencedIds:Array.from(t)})}}};var t=r(d[0]);const n={"image/png":".png","image/jpeg":".jpg","image/jpg":".jpg","image/gif":".gif","image/webp":".webp","image/avif":".avif","image/heic":".heic","image/heif":".heif","image/tiff":".tiff","image/bmp":".bmp","image/svg+xml":".svg"};function s(t){const n=t.replace(/\\/g,"/").split("/"),s=n[n.length-1];return s&&s.length>0?s:null}function o(s){const o=(0,t.getFileExtensionFromName)(s.fileName);if(o)return o;const l=(0,t.getFileExtensionFromName)(s.sourcePath);return l||(n[s.mimeType]??".img")}function l(t){return{id:t.id,mimeType:t.mimeType,storageType:"desktop-file",storageKey:t.storagePath,fileName:t.fileName??null,byteSize:t.byteSize,createdAt:Date.now()}}async function c(n,c){const y=(0,t.fileUriToPath)(c.uri),p=c.fileName??s(y),f=(0,t.normalizeMimeType)(c.mimeType),u=o({fileName:p,sourcePath:y,mimeType:f}),T=await n.copyFile({attachmentId:c.id,sourcePath:y,extension:u});return l({id:c.id,mimeType:f,storagePath:T.path,byteSize:T.byteSize,fileName:p})}async function y(t,n){const s=o({fileName:n.fileName,mimeType:n.mimeType}),c=await t.writeBase64({attachmentId:n.id,base64:n.base64,extension:s});return l({id:n.id,mimeType:n.mimeType,storagePath:c.path,byteSize:c.byteSize,fileName:n.fileName})}async function p(t,n){const s=o({fileName:n.fileName,mimeType:n.mimeType}),c=await t.writeBytes({attachmentId:n.id,bytes:n.bytes,extension:s});return l({id:n.id,mimeType:n.mimeType,storagePath:c.path,byteSize:c.byteSize,fileName:n.fileName})}function f(t){if("desktop-file"!==t.storageType)throw new Error(`Unsupported desktop attachment storage type '${t.storageType}'.`)}},
|
|
1
|
+
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createDesktopAttachmentStore=function(n){return{storageType:"desktop-file",async save(s){const o=s.id??(0,t.generateAttachmentId)(),l=s.fileName??null;if("file_uri"===s.source.kind)return await c(n,{id:o,uri:s.source.uri,mimeType:s.mimeType,fileName:l});if("data_url"===s.source.kind){const c=(0,t.parseDataUrl)(s.source.dataUrl),p=(0,t.normalizeMimeType)(s.mimeType??c.mimeType);return await y(n,{id:o,base64:c.base64,mimeType:p,fileName:l})}if("bytes"===s.source.kind){const c=(0,t.normalizeMimeType)(s.mimeType);return await p(n,{id:o,bytes:s.source.bytes,mimeType:c,fileName:l})}const f=(0,t.normalizeMimeType)(s.mimeType??s.source.blob.type),u=await(0,t.blobToBase64)(s.source.blob);return await y(n,{id:o,base64:u,mimeType:f,fileName:l})},encodeBase64:async({attachment:t})=>(f(t),await n.readFileBase64(t.storageKey)),resolvePreviewUrl:async({attachment:t})=>(f(t),await n.resolvePreviewUrl(t)),async releasePreviewUrl({attachment:t,url:s}){f(t),await n.releasePreviewUrl({url:s})},async delete({attachment:t}){f(t),await n.deleteFile({path:t.storageKey})},async garbageCollect({referencedIds:t}){await n.garbageCollect({referencedIds:Array.from(t)})}}};var t=r(d[0]);const n={"image/png":".png","image/jpeg":".jpg","image/jpg":".jpg","image/gif":".gif","image/webp":".webp","image/avif":".avif","image/heic":".heic","image/heif":".heif","image/tiff":".tiff","image/bmp":".bmp","image/svg+xml":".svg"};function s(t){const n=t.replace(/\\/g,"/").split("/"),s=n[n.length-1];return s&&s.length>0?s:null}function o(s){const o=(0,t.getFileExtensionFromName)(s.fileName);if(o)return o;const l=(0,t.getFileExtensionFromName)(s.sourcePath);return l||(n[s.mimeType]??".img")}function l(t){return{id:t.id,mimeType:t.mimeType,storageType:"desktop-file",storageKey:t.storagePath,fileName:t.fileName??null,byteSize:t.byteSize,createdAt:Date.now()}}async function c(n,c){const y=(0,t.fileUriToPath)(c.uri),p=c.fileName??s(y),f=(0,t.normalizeMimeType)(c.mimeType),u=o({fileName:p,sourcePath:y,mimeType:f}),T=await n.copyFile({attachmentId:c.id,sourcePath:y,extension:u});return l({id:c.id,mimeType:f,storagePath:T.path,byteSize:T.byteSize,fileName:p})}async function y(t,n){const s=o({fileName:n.fileName,mimeType:n.mimeType}),c=await t.writeBase64({attachmentId:n.id,base64:n.base64,extension:s});return l({id:n.id,mimeType:n.mimeType,storagePath:c.path,byteSize:c.byteSize,fileName:n.fileName})}async function p(t,n){const s=o({fileName:n.fileName,mimeType:n.mimeType}),c=await t.writeBytes({attachmentId:n.id,bytes:n.bytes,extension:s});return l({id:n.id,mimeType:n.mimeType,storagePath:c.path,byteSize:c.byteSize,fileName:n.fileName})}function f(t){if("desktop-file"!==t.storageType)throw new Error(`Unsupported desktop attachment storage type '${t.storageType}'.`)}},4914,[4267]);
|
|
Binary file
|