chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
+90
View File
@@ -0,0 +1,90 @@
import { workspaceFileBroker } from '@/lib/execution/sandbox/brokers/workspace-file'
import { defineSandboxTask } from '@/lib/execution/sandbox/define-task'
import type { SandboxTaskInput } from '@/lib/execution/sandbox/types'
export const pdfGenerateTask = defineSandboxTask<SandboxTaskInput>({
id: 'pdf-generate',
timeoutMs: 60_000,
bundles: ['pdf-lib'],
brokers: [workspaceFileBroker],
bootstrap: `
const PDFLib = globalThis.__bundles['pdf-lib'];
if (!PDFLib) throw new Error('pdf-lib bundle not loaded');
globalThis.PDFLib = PDFLib;
globalThis.pdf = await PDFLib.PDFDocument.create();
// Convenience shortcuts — avoids verbose PDFLib.rgb() / PDFLib.StandardFonts.Helvetica
globalThis.rgb = PDFLib.rgb;
globalThis.StandardFonts = PDFLib.StandardFonts;
// Page-size constants in points (1pt = 1/72 inch)
globalThis.LETTER = [612, 792]; // 8.5" × 11"
globalThis.A4 = [595.28, 841.89]; // 210mm × 297mm
// 6 MB raw ≈ 8 MB base64; reject above this to avoid sandbox OOM.
const _MAX_IMG_B64 = 8 * 1024 * 1024;
/**
* embedImage(dataUri) — embed a data-URI image into the active PDF document.
* Dispatches to embedPng or embedJpg based on MIME type.
*/
globalThis.embedImage = async function embedImage(dataUri) {
if (!dataUri || typeof dataUri !== 'string') {
throw new Error('embedImage: dataUri must be a non-empty string');
}
const comma = dataUri.indexOf(',');
if (comma === -1) throw new Error('embedImage: invalid data URI (no comma separator)');
const header = dataUri.slice(0, comma);
const base64 = dataUri.slice(comma + 1);
if (!globalThis.Buffer) throw new Error('embedImage: Buffer polyfill missing');
const binary = globalThis.Buffer.from(base64, 'base64');
const mime = header.split(';')[0].split(':')[1] || '';
// image/jpg is non-standard but tolerated; the canonical MIME is image/jpeg
if (mime === 'image/png') return globalThis.pdf.embedPng(binary);
if (mime === 'image/jpeg' || mime === 'image/jpg') return globalThis.pdf.embedJpg(binary);
throw new Error('embedImage: only PNG and JPEG are supported (got ' + (mime || 'unknown — check data URI header') + ')');
};
/**
* getFileBase64(fileId) — load a workspace file as a data URI string.
*/
globalThis.getFileBase64 = async function getFileBase64(fileId) {
if (!fileId || typeof fileId !== 'string') {
throw new Error('getFileBase64: fileId must be a non-empty string');
}
const res = await globalThis.__brokers.workspaceFile({ fileId });
if (!res || !res.dataUri) {
throw new Error('getFileBase64: broker returned no data for file ' + fileId);
}
if (res.dataUri.length > _MAX_IMG_B64) {
throw new Error(
'getFileBase64: image exceeds the 6 MB embed limit (~8 MB base64). Use a smaller/compressed image.'
);
}
return res.dataUri;
};
/**
* drawImage(page, fileId, opts) — fetch a workspace file and draw it on the given page.
* Required opts: x, y, width, height (points).
* Example: await drawImage(page, 'abc123', { x: 50, y: 700, width: 200, height: 100 });
*/
globalThis.drawImage = async function drawImage(page, fileId, opts) {
if (!opts || opts.x == null || opts.y == null || opts.width == null || opts.height == null) {
throw new Error('drawImage: opts must include x, y, width, and height (in points)');
}
const dataUri = await globalThis.getFileBase64(fileId);
const img = await globalThis.embedImage(dataUri);
page.drawImage(img, opts);
};
`,
finalize: `
const pdf = globalThis.pdf;
if (!pdf) {
throw new Error('No PDF document. Use the injected pdf object or load one with PDFLib.PDFDocument.load().');
}
const bytes = await pdf.save();
return bytes;
`,
toResult: (bytes) => Buffer.from(bytes),
})