
Security News
arXiv Is Rate Limiting Authors Following a Flood of AI Slop Submissions
arXiv now limits authors to two submissions a month as AI slop overwhelms moderators, delays good papers, and sparks debate over applying the limit to everyone.
@deckops/sdk
Advanced tools
Languages: English | 简体中文 | 繁體中文 | Français | Español | Русский | 日本語
Node.js and browser-compatible SDK for Deckops/Deckflow task APIs.
pnpm add @deckops/sdk
In this monorepo:
pnpm --filter @deckops/sdk build
import { createDeck } from '@deckops/sdk';
const deck = createDeck({
root: 'https://app.deckflow.com/v1',
token: 'user-token',
apiKey: 'api-key',
spaceId: 'space-id',
});
Options:
root?: string - API root address. Defaults to https://app.deckflow.com/v1.token?: string - sent as X-Auth-Token.apiKey?: string - sent as Authorization: Bearer {apiKey}.spaceId?: string - default space id for task and file calls.authUuid?: string - explicit client UUID (UUID v4) sent as X-Auth-UUID. Skips automatic persistence.authUuidStorage?: { get(), set(value) } - custom storage for client UUID (SSR, tests, embedded apps).onUnauthorized?: () => Promise<{ token: string; spaceId?: string } | string> - called once after a 401, then the request is retried.onPaymentRequired?: () => Promise<void> - called once after a 402, then the request is retried.Every Deckops API request automatically includes X-Auth-UUID, a stable UUID v4 used to track the client across sessions.
localStorage under df_uuid.~/.deckops/auth-uuid (override the directory with DECKOPS_CONFIG_DIR).authUuid or set DECKOPS_AUTH_UUID (Node only) for fixed IDs in CI, containers, or multi-tenant servers.const uuid = await deck.getAuthUuid();
console.log('Client UUID:', uuid);
Pass user-selected files directly to task methods. The SDK uploads them internally and sends the resulting file ids to the task API:
const task = await deck.convertPptToPdf({
files: ['./slides.pptx'],
upload: {
onProgress: (p) => console.log(`${Math.round(p * 100)}%`),
},
});
files supports:
'./a.pptx'Uint8Array or ArrayBufferBlob/FileFor browser file pickers, pass the selected File object:
await deck.convertPptToPdf({
files: [file],
});
For binary data without a file name, include per-file upload options:
await deck.imageOcr({
files: [{ input: bytes, name: 'image.png' }],
params: { language: 'en' },
});
For compatibility with existing integrations, fileIds is still accepted and can be combined with files.
const task = await deck.tasks.create({
type: 'convertor.ppt2pdf',
files: ['./slides.pptx'],
name: 'slides',
params: {},
});
await deck.tasks.list({ type: 'convertor.ppt2pdf', startIndex: 0, maxResults: 50 });
await deck.tasks.get(task.id);
await deck.tasks.wait(task.id, { timeout: 300, useEventStream: true });
await deck.tasks.down<'convertor.ppt2pdf'>(task.id);
await deck.tasks.delete(task.id);
const cancel = await deck.tasks.subscribe(task.id, {
onUpdate: (next) => console.log(next.status),
onError: console.error,
});
cancel();
Task detail responses are for status/progress metadata. Task results should be read through deck.tasks.down(...) or the backend-name alias deck.ttask.down(...).
const result = await deck.ttask.down<'convertor.ppt2pdf'>(task.id);
const generationDownload = await deck.ttask.down<'generation'>(task.id, { type: 'pptx' });
console.log(generationDownload.downloadUrl);
The SDK exports concrete result types for every task type through DeckTaskTypeResult.
Most file-producing tasks return tuple-shaped file results because that is the backend contract:
type FileResult = [
path: string,
bytes: number,
hash: string,
];
type ConvertFileResult = [
path: string,
bytes: number,
hash: string,
bounds?: { w?: number; h?: number; total?: number } | null,
];
path is the storage key or relative path in raw backend data. When the task detail API expands downloadable results, it may already be a signed/access URL.
Examples:
deck.convertPptToPdf(...) returns ConvertFileResult[].deck.convertHtmlToPptx(...) returns { target: FileResult; usedFonts: string[] }.deck.pptxSplit(...) returns { ppt, sections, slides } with typed slide file metadata.deck.pptxGetFontInfo(...) returns { fonts, embeddedFont, subsetFont }.deck.pptxGetTextShapes(...) returns typed page/shape/text/image metadata.Every helper accepts { spaceId?, files?, fileIds?, name?, params?, upload? }, sets the backend task type, uploads files when needed, and returns a typed DeckTask.
await deck.fileCompress({ files: ['./document.pdf'] });
await deck.imageOcr({ files: [file], params: { language: 'en' } });
await deck.imageConvertWebp({ files: [file] });
await deck.imageResize({ files: [file], params: { maxWidth: 1024 } });
await deck.pptxSplit({ files: ['./slides.pptx'], params: { indexes: [0, 1] } });
await deck.pptxJoin({ files: ['./part1.pptx', './part2.pptx'], name: 'merged' });
await deck.pptxGetFontInfo({ files: ['./slides.pptx'] });
await deck.pptxGetTextShapes({
files: ['./slides.pptx'],
params: { includeNotes: true, ignoreEmptyText: true },
});
await deck.pptxEmbedFonts({
files: ['./slides.pptx'],
params: { usedFonts: ['Arial'] },
});
await deck.convertPptToImage({
files: ['./slides.pptx'],
params: { resolution: 1920, format: 'jpg' },
});
await deck.convertPptToPptx({ files: ['./slides.ppt'] });
await deck.convertPptToPdf({ files: ['./slides.pptx'] });
await deck.convertDocToPdf({ files: ['./handbook.docx'] });
await deck.convertPptToVideo({ files: ['./slides.pptx'] });
await deck.convertPdfToImage({ files: ['./document.pdf'] });
await deck.convertKeynoteToImage({ files: ['./deck.key'] });
await deck.convertKeynoteToHtml({ files: ['./deck.key'] });
await deck.convertKeynoteToPdf({ files: ['./deck.key'] });
await deck.convertHtmlToPng({
files: [{ input: htmlBytes, name: 'page.html' }],
params: { width: 1280, height: 720, fullPage: true },
});
await deck.convertMarkdownToPng({
files: [{ input: markdownBytes, name: 'page.md' }],
params: { theme: 'dark', pageWidth: 960 },
});
await deck.convertHtmlToPptx({
files: [{ input: htmlBytes, name: 'deck.html' }],
params: { width: 1280, height: 720, needEmbedFonts: false },
});
await deck.convertHtmlToPptx({
files: ['./page1.html', './page2.html'],
params: { width: 1280, height: 720 },
});
Ordered multi-source files are meaningful for task types that map the whole file
array into backend parameters, including pptx.join, convertor.html2pptx,
html.buildPlayer, and generation. Most other task types read one source file;
pass one file per task for those.
await deck.htmlBuildPlayer({
params: {
contents: [{ key: 'pages/1.html' }],
pageWidth: 1280,
pageHeight: 720,
title: 'Deck',
description: 'Deck player',
brandMarkPosition: 'none',
},
});
await deck.generation({
files: [referenceFile],
params: {
inputText: 'Write a product launch plan',
enableSearch: true,
pageCount: 8,
},
});
await deck.translation({
files: [file],
params: {
from: 'zh',
to: 'en',
model: 'Standard',
useGlossary: false,
imageTranslate: false,
},
});
await deck.revamp({
files: [file],
params: { lang: 'zh' },
});
Blob/File; the SDK reads the file name and calculates MD5.deck.tasks.wait(taskId, { useEventStream: false }) is the most portable option.FAQs
Deckops TypeScript SDK for Node.js and browsers
The npm package @deckops/sdk receives a total of 24 weekly downloads. As such, @deckops/sdk popularity was classified as not popular.
We found that @deckops/sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
arXiv now limits authors to two submissions a month as AI slop overwhelms moderators, delays good papers, and sparks debate over applying the limit to everyone.

Research
/Security News
A new GhostAction wave hits hundreds of GitHub repos, expanding CI/CD secret theft to cloud and AI credentials in source code and git history.

Research
/Security News
Tensorlake npm SDK version 0.5.144 was compromised in a ChainDrop / Shai-Hulud attack, delivering credential-stealing malware.