Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions examples/devtools-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@
console.log("Devtools test started", { jobId: _STD_.job.getId(), device: _STD_.device.getAddress() })
console.info("Processor info", { timestamp: Date.now() })

// Probe runtime for HTTP/upload primitives
console.log("Runtime probe", {
fetch: typeof fetch,
FormData: typeof FormData,
Blob: typeof Blob,
XMLHttpRequest: typeof XMLHttpRequest,
Request: typeof Request,
Response: typeof Response,
Headers: typeof Headers,
Buffer: typeof Buffer,
btoa: typeof btoa,
atob: typeof atob,
})

let tick = 0
const interval = setInterval(() => {
tick++
Expand All @@ -20,6 +34,36 @@ const interval = setInterval(() => {
}
}

if (tick === 2) {
const filename = "test-upload.json"
const content = JSON.stringify({
message: "hello from acurast processor",
jobId: _STD_.job.getId().id,
device: _STD_.device.getAddress(),
timestamp: Date.now(),
})

console.log("Uploading file: " + filename + " (" + content.length + " bytes)")

_DEVTOOLS_.uploadFile(
filename,
content,
"application/json",
(fileInfo) => {
console.log("Upload succeeded", {
id: fileInfo.id,
filename: fileInfo.filename,
mimeType: fileInfo.mimeType,
fileSize: fileInfo.fileSize,
createdAt: fileInfo.createdAt,
})
},
(error) => {
console.error("Upload failed:", error)
}
)
}

if (tick >= 12) {
clearInterval(interval)
console.log("Devtools test complete after " + tick + " ticks")
Expand Down
16 changes: 16 additions & 0 deletions src/devtools/acurast-processor.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@ declare function httpPOST(
onError: (error: string) => void
): void

declare const _DEVTOOLS_: {
uploadFile(
filename: string,
content: string,
mimeType: string,
onSuccess: (fileInfo: {
id: number
filename: string
mimeType: string
fileSize: number
createdAt: string
}) => void,
onError: (error: string) => void
): void
}

declare const _STD_: {
job: {
getId(): { origin: { kind: string; source: string }; id: string }
Expand Down
46 changes: 46 additions & 0 deletions src/devtools/devtools-snippet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,52 @@
}
}

// --- File upload via /v1/files ---
const uploadFile = (
filename: string,
content: string,
mimeType: string,
onSuccess: (fileInfo: { id: number; filename: string; mimeType: string; fileSize: number; createdAt: string }) => void,
onError: (error: string) => void
) => {
if (!apiKey) {
onError('[devtools] file upload failed: not authenticated yet')
return
}

// The processor's httpPOST JSON-parses the body regardless of Content-Type,
// so we cannot send multipart/form-data through it. Use fetch + FormData
// instead — fetch sets the Content-Type header (with boundary) automatically.
const formData = new FormData()
formData.append('file', new Blob([content], { type: mimeType }), filename)

fetch(`${DEVTOOLS_API_URL}/v1/files`, {
method: 'POST',
headers: { Authorization: 'Bearer ' + apiKey },
body: formData,
})
.then((res: Response) =>
res.text().then((text: string) => ({ ok: res.ok, status: res.status, text }))
)
.then(({ ok, status, text }: { ok: boolean; status: number; text: string }) => {
if (!ok) {
onError('[devtools] file upload failed: HTTP ' + status + ' ' + text)
return
}
try {
onSuccess(JSON.parse(text))
} catch (_e) {
onError('[devtools] failed to parse upload response: ' + text)
}
})
.catch((err: any) => {
onError('[devtools] file upload failed: ' + (err?.message ?? String(err)))
})
}

// Expose _DEVTOOLS_ global
;(globalThis as any)._DEVTOOLS_ = { uploadFile }

for (const level of Object.keys(originalConsole) as Array<
keyof typeof originalConsole
>) {
Expand Down
15 changes: 0 additions & 15 deletions test/devtools.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,6 @@ describe('devtools snippet injection', () => {
expect(content).not.toContain('__DEVTOOLS_API_URL__')
})

it('should not contain any unreplaced placeholders', async () => {
const zipPath = createTestZip('index.js', '// user code')
await injectDevtoolsSnippet(
zipPath,
'index.js',
'https://api.devtools.acurast.com',
SNIPPET_DIR
)

const zip = new AdmZip(zipPath)
const content = zip.getEntry('index.js')!.getData().toString('utf-8')

expect(content).not.toContain('__DEVTOOLS_API_URL__')
})

it('should strip TSC artifacts (export {}, sourcemap comment)', async () => {
const zipPath = createTestZip('index.js', '// user code')

Expand Down
Loading