latex-renderer-sdk 1.0.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/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # latex-renderer-sdk
2
+
3
+ TypeScript SDK for the LaTeX Renderer API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install latex-renderer-sdk
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { LatexRenderer } from "latex-renderer-sdk";
15
+
16
+ const client = new LatexRenderer({
17
+ apiKey: "your-api-key",
18
+ baseUrl: "https://your-api-url.com", // optional, defaults to http://localhost:8080
19
+ });
20
+ ```
21
+
22
+ ### Render LaTeX to HTML
23
+
24
+ ```typescript
25
+ const html = await client.renderHTML(
26
+ "\\documentclass{article}\\begin{document}Hello $E=mc^2$\\end{document}",
27
+ );
28
+ ```
29
+
30
+ ### Render LaTeX to PDF
31
+
32
+ ```typescript
33
+ import { writeFile } from "fs/promises";
34
+
35
+ const pdf = await client.renderPDF(
36
+ "\\documentclass{article}\\begin{document}Hello World\\end{document}",
37
+ );
38
+
39
+ await writeFile("output.pdf", pdf);
40
+ ```
41
+
42
+ ### Error handling
43
+
44
+ ```typescript
45
+ import {
46
+ LatexRenderer,
47
+ RenderError,
48
+ AuthenticationError,
49
+ ConnectionError,
50
+ } from "latex-renderer-sdk";
51
+
52
+ try {
53
+ const html = await client.renderHTML(latex);
54
+ } catch (error) {
55
+ if (error instanceof RenderError) {
56
+ console.error("LaTeX compilation failed:", error.detail);
57
+ } else if (error instanceof AuthenticationError) {
58
+ console.error("Invalid API key:", error.message);
59
+ } else if (error instanceof ConnectionError) {
60
+ console.error("Network error:", error.message);
61
+ }
62
+ }
63
+ ```
64
+
65
+ ### Request cancellation
66
+
67
+ ```typescript
68
+ const controller = new AbortController();
69
+ setTimeout(() => controller.abort(), 5000);
70
+
71
+ const html = await client.renderHTML(latex, { signal: controller.signal });
72
+ ```
73
+
74
+ ## Configuration
75
+
76
+ | Option | Type | Default | Description |
77
+ | --------- | -------- | ------------------------ | ----------------------- |
78
+ | `apiKey` | `string` | _(required)_ | API authentication key |
79
+ | `baseUrl` | `string` | `http://localhost:8080` | API base URL |
80
+ | `timeout` | `number` | `30000` | Request timeout (ms) |
81
+
82
+ ## Requirements
83
+
84
+ Node.js >= 18.0.0
@@ -0,0 +1,18 @@
1
+ export declare class LatexRendererError extends Error {
2
+ readonly statusCode?: number;
3
+ constructor(message: string, statusCode?: number);
4
+ }
5
+ export declare class AuthenticationError extends LatexRendererError {
6
+ constructor(message: string);
7
+ }
8
+ export declare class RenderError extends LatexRendererError {
9
+ readonly detail?: string;
10
+ constructor(message: string, detail?: string);
11
+ }
12
+ export declare class APIError extends LatexRendererError {
13
+ constructor(message: string, statusCode: number);
14
+ }
15
+ export declare class ConnectionError extends LatexRendererError {
16
+ readonly cause?: Error;
17
+ constructor(message: string, cause?: Error);
18
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,36 @@
1
+ export class LatexRendererError extends Error {
2
+ statusCode;
3
+ constructor(message, statusCode) {
4
+ super(message);
5
+ this.name = "LatexRendererError";
6
+ this.statusCode = statusCode;
7
+ }
8
+ }
9
+ export class AuthenticationError extends LatexRendererError {
10
+ constructor(message) {
11
+ super(message, 401);
12
+ this.name = "AuthenticationError";
13
+ }
14
+ }
15
+ export class RenderError extends LatexRendererError {
16
+ detail;
17
+ constructor(message, detail) {
18
+ super(message, 400);
19
+ this.name = "RenderError";
20
+ this.detail = detail;
21
+ }
22
+ }
23
+ export class APIError extends LatexRendererError {
24
+ constructor(message, statusCode) {
25
+ super(message, statusCode);
26
+ this.name = "APIError";
27
+ }
28
+ }
29
+ export class ConnectionError extends LatexRendererError {
30
+ cause;
31
+ constructor(message, cause) {
32
+ super(message);
33
+ this.name = "ConnectionError";
34
+ this.cause = cause;
35
+ }
36
+ }
@@ -0,0 +1,13 @@
1
+ import type { LatexRendererConfig, RenderOptions } from "./types.js";
2
+ export { LatexRendererError, AuthenticationError, RenderError, APIError, ConnectionError, } from "./errors.js";
3
+ export type { LatexRendererConfig, RenderOptions } from "./types.js";
4
+ export declare class LatexRenderer {
5
+ private readonly apiKey;
6
+ private readonly baseUrl;
7
+ private readonly timeout;
8
+ constructor(config: LatexRendererConfig);
9
+ renderHTML(latex: string, options?: RenderOptions): Promise<string>;
10
+ renderPDF(latex: string, options?: RenderOptions): Promise<Uint8Array>;
11
+ private request;
12
+ private handleError;
13
+ }
package/dist/index.js ADDED
@@ -0,0 +1,72 @@
1
+ import { LatexRendererError, AuthenticationError, RenderError, APIError, ConnectionError, } from "./errors.js";
2
+ export { LatexRendererError, AuthenticationError, RenderError, APIError, ConnectionError, } from "./errors.js";
3
+ export class LatexRenderer {
4
+ apiKey;
5
+ baseUrl;
6
+ timeout;
7
+ constructor(config) {
8
+ if (!config.apiKey) {
9
+ throw new LatexRendererError("apiKey is required");
10
+ }
11
+ this.apiKey = config.apiKey;
12
+ this.baseUrl = (config.baseUrl ?? "http://localhost:8080").replace(/\/$/, "");
13
+ this.timeout = config.timeout ?? 30_000;
14
+ }
15
+ async renderHTML(latex, options) {
16
+ const response = await this.request("/render", latex, options);
17
+ return response.text();
18
+ }
19
+ async renderPDF(latex, options) {
20
+ const response = await this.request("/render/pdf", latex, options);
21
+ const buffer = await response.arrayBuffer();
22
+ return new Uint8Array(buffer);
23
+ }
24
+ async request(endpoint, body, options) {
25
+ const controller = new AbortController();
26
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
27
+ try {
28
+ const response = await fetch(`${this.baseUrl}${endpoint}`, {
29
+ method: "POST",
30
+ headers: {
31
+ Authorization: `Bearer ${this.apiKey}`,
32
+ "Content-Type": "text/plain",
33
+ },
34
+ body,
35
+ signal: options?.signal ?? controller.signal,
36
+ });
37
+ if (!response.ok) {
38
+ await this.handleError(response);
39
+ }
40
+ return response;
41
+ }
42
+ catch (error) {
43
+ if (error instanceof LatexRendererError)
44
+ throw error;
45
+ if (error instanceof Error && error.name === "AbortError") {
46
+ throw new ConnectionError("Request timed out or was cancelled", error);
47
+ }
48
+ throw new ConnectionError(error instanceof Error ? error.message : "Unknown network error", error instanceof Error ? error : undefined);
49
+ }
50
+ finally {
51
+ clearTimeout(timeoutId);
52
+ }
53
+ }
54
+ async handleError(response) {
55
+ let json;
56
+ try {
57
+ json = await response.json();
58
+ }
59
+ catch {
60
+ throw new APIError(`HTTP ${response.status}: ${response.statusText}`, response.status);
61
+ }
62
+ const message = json?.error ?? "Unknown error";
63
+ if (response.status === 401) {
64
+ throw new AuthenticationError(message);
65
+ }
66
+ if (response.status === 400 &&
67
+ (message === "latex render failed" || message === "pdf render failed")) {
68
+ throw new RenderError(message, json?.detail);
69
+ }
70
+ throw new APIError(message, response.status);
71
+ }
72
+ }
@@ -0,0 +1,8 @@
1
+ export interface LatexRendererConfig {
2
+ apiKey: string;
3
+ baseUrl?: string;
4
+ timeout?: number;
5
+ }
6
+ export interface RenderOptions {
7
+ signal?: AbortSignal;
8
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "latex-renderer-sdk",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript SDK for LaTeX Renderer API",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "clean": "rm -rf dist",
21
+ "prepublishOnly": "npm run clean && npm run build",
22
+ "publish:first": "npm publish --access public",
23
+ "publish:patch": "npm version patch && npm publish --access public",
24
+ "publish:minor": "npm version minor && npm publish --access public",
25
+ "publish:major": "npm version major && npm publish --access public"
26
+ },
27
+ "keywords": [
28
+ "latex",
29
+ "renderer",
30
+ "pdf",
31
+ "html",
32
+ "mathml",
33
+ "sdk"
34
+ ],
35
+ "license": "MIT",
36
+ "engines": {
37
+ "node": ">=18.0.0"
38
+ },
39
+ "devDependencies": {
40
+ "typescript": "^5.3.0"
41
+ }
42
+ }