@elastic/isomer-image-takumi 0.0.0 → 0.2.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/LICENSE.txt +93 -0
- package/NOTICE.txt +1861 -0
- package/README.md +32 -0
- package/THIRD_PARTY_LICENSES.md +957 -0
- package/dist/backend.d.ts +168 -0
- package/dist/backend.d.ts.map +1 -0
- package/dist/backend.js +170 -0
- package/dist/backend.js.map +1 -0
- package/dist/cjs/backend.js +207 -0
- package/dist/cjs/backend.js.map +1 -0
- package/dist/cjs/index.js +17 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/render_pdf.js +38 -0
- package/dist/cjs/render_pdf.js.map +1 -0
- package/dist/cjs/render_png.js +50 -0
- package/dist/cjs/render_png.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/render_pdf.d.ts +42 -0
- package/dist/render_pdf.d.ts.map +1 -0
- package/dist/render_pdf.js +34 -0
- package/dist/render_pdf.js.map +1 -0
- package/dist/render_png.d.ts +75 -0
- package/dist/render_png.d.ts.map +1 -0
- package/dist/render_png.js +45 -0
- package/dist/render_png.js.map +1 -0
- package/package.json +44 -5
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
4
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
5
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
6
|
+
* 2.0.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.renderPng = exports.renderPdf = exports.createTakumiImageBackend = exports.TAKUMI_FORMATS = void 0;
|
|
10
|
+
var backend_1 = require("./backend");
|
|
11
|
+
Object.defineProperty(exports, "TAKUMI_FORMATS", { enumerable: true, get: function () { return backend_1.TAKUMI_FORMATS; } });
|
|
12
|
+
Object.defineProperty(exports, "createTakumiImageBackend", { enumerable: true, get: function () { return backend_1.createTakumiImageBackend; } });
|
|
13
|
+
var render_pdf_1 = require("./render_pdf");
|
|
14
|
+
Object.defineProperty(exports, "renderPdf", { enumerable: true, get: function () { return render_pdf_1.renderPdf; } });
|
|
15
|
+
var render_png_1 = require("./render_png");
|
|
16
|
+
Object.defineProperty(exports, "renderPng", { enumerable: true, get: function () { return render_png_1.renderPng; } });
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,qCAcmB;AAFjB,yGAAA,cAAc,OAAA;AACd,mHAAA,wBAAwB,OAAA;AAE1B,2CAKsB;AADpB,uGAAA,SAAS,OAAA;AAEX,2CAQsB;AADpB,uGAAA,SAAS,OAAA","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nexport {\n type ImageInput,\n type LayoutBox,\n type PdfInput,\n type TakumiBackend,\n type TakumiImageBackend,\n type TakumiImageBackendOptions,\n type TakumiMeasuringBackend,\n type TakumiPdfBackend,\n type TakumiPdfMetadata,\n type TakumiPdfOptions,\n type TakumiRenderOptions,\n TAKUMI_FORMATS,\n createTakumiImageBackend,\n} from './backend';\nexport {\n type PdfRuntime,\n type RenderPdfOptions,\n type RenderPdfResult,\n renderPdf,\n} from './render_pdf';\nexport {\n type PngCheckedValidationResult,\n type PngRuntime,\n type PngValidationResult,\n type RenderPngOptions,\n type RenderPngResult,\n type SnapshotOptions,\n renderPng,\n} from './render_png';\nexport type { Font, FontDetails, FontLoader } from '@takumi-rs/core';\nexport type { ImagesInput } from 'takumi-pdf';\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
4
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
5
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
6
|
+
* 2.0.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.renderPdf = void 0;
|
|
10
|
+
const render_png_1 = require("./render_png");
|
|
11
|
+
/**
|
|
12
|
+
* Validates, renders, and writes a deck as one PDF in one call, a page per
|
|
13
|
+
* composition.
|
|
14
|
+
*
|
|
15
|
+
* Every composition is rendered, even an invalid one: `validations` is how a
|
|
16
|
+
* caller finds out, rather than a thrown error. What is drawn is the copy
|
|
17
|
+
* validation checked. Validation runs twice, once here and once inside
|
|
18
|
+
* `renderPages`, which discards its own result. An empty deck throws the
|
|
19
|
+
* runtime's `EMPTY_PAGES`.
|
|
20
|
+
*/
|
|
21
|
+
const renderPdf = async (runtime, deck, backend, { snapshot, ...options } = {}) => {
|
|
22
|
+
const pages = deck.map((composition) => (0, render_png_1.checkedForDrawing)('renderPdf', runtime.validate(composition)));
|
|
23
|
+
const validations = pages.map(({ validation }) => validation);
|
|
24
|
+
const rendered = runtime.surfaces.snapshot.renderPages(pages.map(({ checked }) => checked), {
|
|
25
|
+
...snapshot,
|
|
26
|
+
onValidationError: 'collect',
|
|
27
|
+
});
|
|
28
|
+
const pdf = await backend.pdf(rendered, options);
|
|
29
|
+
return {
|
|
30
|
+
pdf,
|
|
31
|
+
pageCount: rendered.pages.length,
|
|
32
|
+
width: rendered.width,
|
|
33
|
+
height: rendered.height,
|
|
34
|
+
validations,
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
exports.renderPdf = renderPdf;
|
|
38
|
+
//# sourceMappingURL=render_pdf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render_pdf.js","sourceRoot":"","sources":["../../src/render_pdf.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAGH,6CAKsB;AAkCtB;;;;;;;;;GASG;AACI,MAAM,SAAS,GAAG,KAAK,EAC5B,OAAmB,EACnB,IAAwB,EACxB,OAAyB,EACzB,EAAE,QAAQ,EAAE,GAAG,OAAO,KAAuB,EAAE,EACrB,EAAE;IAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CACrC,IAAA,8BAAiB,EAAC,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAC9D,CAAC;IACF,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CACpD,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,EACnC;QACE,GAAG,QAAQ;QACX,iBAAiB,EAAE,SAAS;KAC7B,CACF,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjD,OAAO;QACL,GAAG;QACH,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;QAChC,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,WAAW;KACZ,CAAC;AACJ,CAAC,CAAC;AAzBW,QAAA,SAAS,aAyBpB","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport type { PdfInput, TakumiPdfBackend, TakumiPdfOptions } from './backend';\nimport {\n checkedForDrawing,\n type PngCheckedValidationResult,\n type PngValidationResult,\n type SnapshotOptions,\n} from './render_png';\n\n/**\n * The slice of `IsomerRuntime` this helper needs, declared structurally like\n * {@link PdfInput}. A runtime built with `frames` satisfies it.\n */\nexport interface PdfRuntime {\n validate(composition: unknown): PngCheckedValidationResult;\n surfaces: {\n snapshot: {\n renderPages(\n compositions: readonly unknown[],\n options?: SnapshotOptions & { onValidationError?: 'collect' | 'throw' }\n ): PdfInput;\n };\n };\n}\n\n/** Options for {@link renderPdf}. */\nexport interface RenderPdfOptions extends TakumiPdfOptions {\n /** Forwarded to `runtime.surfaces.snapshot.renderPages`, so every page shares one frame. */\n snapshot?: SnapshotOptions;\n}\n\n/** What {@link renderPdf} resolves to: the bytes, the page count and size, and one finding set per composition. */\nexport interface RenderPdfResult {\n pdf: Buffer;\n pageCount: number;\n width: number;\n height: number;\n /** One per composition, in order. */\n validations: PngValidationResult[];\n}\n\n/**\n * Validates, renders, and writes a deck as one PDF in one call, a page per\n * composition.\n *\n * Every composition is rendered, even an invalid one: `validations` is how a\n * caller finds out, rather than a thrown error. What is drawn is the copy\n * validation checked. Validation runs twice, once here and once inside\n * `renderPages`, which discards its own result. An empty deck throws the\n * runtime's `EMPTY_PAGES`.\n */\nexport const renderPdf = async (\n runtime: PdfRuntime,\n deck: readonly unknown[],\n backend: TakumiPdfBackend,\n { snapshot, ...options }: RenderPdfOptions = {}\n): Promise<RenderPdfResult> => {\n const pages = deck.map((composition) =>\n checkedForDrawing('renderPdf', runtime.validate(composition))\n );\n const validations = pages.map(({ validation }) => validation);\n const rendered = runtime.surfaces.snapshot.renderPages(\n pages.map(({ checked }) => checked),\n {\n ...snapshot,\n onValidationError: 'collect',\n }\n );\n const pdf = await backend.pdf(rendered, options);\n return {\n pdf,\n pageCount: rendered.pages.length,\n width: rendered.width,\n height: rendered.height,\n validations,\n };\n};\n"]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
4
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
5
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
6
|
+
* 2.0.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.renderPng = exports.checkedForDrawing = void 0;
|
|
10
|
+
/**
|
|
11
|
+
* Splits a {@link PngCheckedValidationResult} into the copy to draw and the findings to report.
|
|
12
|
+
*
|
|
13
|
+
* Throws rather than draw the caller's value: shaped as the SDK's
|
|
14
|
+
* `CompositionValidationError` when the runtime refused the input, and a plain
|
|
15
|
+
* `Error` when the runtime returned no copy at all.
|
|
16
|
+
*/
|
|
17
|
+
const checkedForDrawing = (caller, { composition, ...validation }) => {
|
|
18
|
+
if (composition !== undefined) {
|
|
19
|
+
return { checked: composition, validation };
|
|
20
|
+
}
|
|
21
|
+
if (validation.valid) {
|
|
22
|
+
throw new Error(`${caller}: runtime.validate returned no checked composition to draw`);
|
|
23
|
+
}
|
|
24
|
+
throw Object.assign(new Error(`${caller}: the runtime refused the composition before parsing`), {
|
|
25
|
+
name: 'CompositionValidationError',
|
|
26
|
+
code: 'COMPOSITION_INVALID',
|
|
27
|
+
errors: validation.errors,
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
exports.checkedForDrawing = checkedForDrawing;
|
|
31
|
+
/**
|
|
32
|
+
* Validates, renders, and rasterizes a composition in one call.
|
|
33
|
+
*
|
|
34
|
+
* The composition is rendered even when invalid: `validation` is how a caller
|
|
35
|
+
* finds out, rather than a thrown error. What is drawn is the copy validation
|
|
36
|
+
* checked, and input refused before parsing, which has none, throws
|
|
37
|
+
* `CompositionValidationError`. Validation runs twice, once here and once inside `render`, which
|
|
38
|
+
* discards its own result.
|
|
39
|
+
*/
|
|
40
|
+
const renderPng = async (runtime, composition, backend, { snapshot, ...options } = {}) => {
|
|
41
|
+
const { checked, validation } = (0, exports.checkedForDrawing)('renderPng', runtime.validate(composition));
|
|
42
|
+
const rendered = runtime.surfaces.snapshot.render(checked, {
|
|
43
|
+
...snapshot,
|
|
44
|
+
onValidationError: 'collect',
|
|
45
|
+
});
|
|
46
|
+
const png = await backend.png(rendered, options);
|
|
47
|
+
return { png, width: rendered.width, height: rendered.height, validation };
|
|
48
|
+
};
|
|
49
|
+
exports.renderPng = renderPng;
|
|
50
|
+
//# sourceMappingURL=render_png.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render_png.js","sourceRoot":"","sources":["../../src/render_png.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAmBH;;;;;;GAMG;AACI,MAAM,iBAAiB,GAAG,CAC/B,MAAc,EACd,EAAE,WAAW,EAAE,GAAG,UAAU,EAA8B,EACH,EAAE;IACzD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;IAC9C,CAAC;IACD,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,4DAA4D,CACtE,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CAAC,GAAG,MAAM,sDAAsD,CAAC,EAC1E;QACE,IAAI,EAAE,4BAA4B;QAClC,IAAI,EAAE,qBAAqB;QAC3B,MAAM,EAAE,UAAU,CAAC,MAAM;KAC1B,CACF,CAAC;AACJ,CAAC,CAAC;AApBW,QAAA,iBAAiB,qBAoB5B;AAkDF;;;;;;;;GAQG;AACI,MAAM,SAAS,GAAG,KAAK,EAC5B,OAAmB,EACnB,WAAoB,EACpB,OAA2B,EAC3B,EAAE,QAAQ,EAAE,GAAG,OAAO,KAAuB,EAAE,EACrB,EAAE;IAC5B,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,IAAA,yBAAiB,EAC/C,WAAW,EACX,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAC9B,CAAC;IACF,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE;QACzD,GAAG,QAAQ;QACX,iBAAiB,EAAE,SAAS;KAC7B,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC;AAC7E,CAAC,CAAC;AAhBW,QAAA,SAAS,aAgBpB","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport type {\n ImageInput,\n TakumiImageBackend,\n TakumiRenderOptions,\n} from './backend';\n\n/** A validation result shaped like the SDK's `ValidationResult`, declared structurally. */\nexport interface PngValidationResult {\n valid: boolean;\n errors: readonly unknown[];\n}\n\n/** What `runtime.validate` returns: findings, and the copy they describe, `undefined` only for refused input. */\nexport type PngCheckedValidationResult = PngValidationResult & {\n composition: unknown;\n};\n\n/**\n * Splits a {@link PngCheckedValidationResult} into the copy to draw and the findings to report.\n *\n * Throws rather than draw the caller's value: shaped as the SDK's\n * `CompositionValidationError` when the runtime refused the input, and a plain\n * `Error` when the runtime returned no copy at all.\n */\nexport const checkedForDrawing = (\n caller: string,\n { composition, ...validation }: PngCheckedValidationResult\n): { checked: unknown; validation: PngValidationResult } => {\n if (composition !== undefined) {\n return { checked: composition, validation };\n }\n if (validation.valid) {\n throw new Error(\n `${caller}: runtime.validate returned no checked composition to draw`\n );\n }\n throw Object.assign(\n new Error(`${caller}: the runtime refused the composition before parsing`),\n {\n name: 'CompositionValidationError',\n code: 'COMPOSITION_INVALID',\n errors: validation.errors,\n }\n );\n};\n\n/**\n * The `snapshot` surface's per-render options, mirroring the runtime's\n * `SnapshotRenderOptions` so a caller gets completion without importing it.\n */\nexport interface SnapshotOptions {\n /** Which of the runtime's frames this render uses; defaults to its `defaultFrame`. */\n frame?: string;\n /** Overrides the frame's `defaultWidth`. */\n width?: number;\n /** Overrides the frame's estimated height. */\n height?: number;\n /** Theme mode; falls back to the composition's own `theme`. `auto` resolves light. */\n theme?: 'light' | 'dark' | 'auto';\n}\n\n/**\n * The slice of `IsomerRuntime` this helper needs, declared structurally like\n * {@link ImageInput} so this package depends on no isomer package. `surfaces.snapshot`\n * is required where the runtime's generic form has `SnapshotSurface | undefined`; a\n * runtime built with `frames` carries `SnapshotSurface` there and satisfies this.\n */\nexport interface PngRuntime {\n validate(composition: unknown): PngCheckedValidationResult;\n surfaces: {\n snapshot: {\n render(\n composition: unknown,\n options?: SnapshotOptions & { onValidationError?: 'collect' | 'throw' }\n ): ImageInput;\n };\n };\n}\n\n/** Options for {@link renderPng}. */\nexport interface RenderPngOptions extends TakumiRenderOptions {\n /** Forwarded to `runtime.surfaces.snapshot.render`. */\n snapshot?: SnapshotOptions;\n}\n\n/** What {@link renderPng} resolves to: the bytes, their size, and the findings on the composition drawn. */\nexport interface RenderPngResult {\n png: Buffer;\n /** The viewport, in CSS pixels; the raster is this times `scale`, rounded. */\n width: number;\n height: number;\n validation: PngValidationResult;\n}\n\n/**\n * Validates, renders, and rasterizes a composition in one call.\n *\n * The composition is rendered even when invalid: `validation` is how a caller\n * finds out, rather than a thrown error. What is drawn is the copy validation\n * checked, and input refused before parsing, which has none, throws\n * `CompositionValidationError`. Validation runs twice, once here and once inside `render`, which\n * discards its own result.\n */\nexport const renderPng = async (\n runtime: PngRuntime,\n composition: unknown,\n backend: TakumiImageBackend,\n { snapshot, ...options }: RenderPngOptions = {}\n): Promise<RenderPngResult> => {\n const { checked, validation } = checkedForDrawing(\n 'renderPng',\n runtime.validate(composition)\n );\n const rendered = runtime.surfaces.snapshot.render(checked, {\n ...snapshot,\n onValidationError: 'collect',\n });\n const png = await backend.png(rendered, options);\n return { png, width: rendered.width, height: rendered.height, validation };\n};\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { type ImageInput, type LayoutBox, type PdfInput, type TakumiBackend, type TakumiImageBackend, type TakumiImageBackendOptions, type TakumiMeasuringBackend, type TakumiPdfBackend, type TakumiPdfMetadata, type TakumiPdfOptions, type TakumiRenderOptions, TAKUMI_FORMATS, createTakumiImageBackend, } from './backend.js';
|
|
2
|
+
export { type PdfRuntime, type RenderPdfOptions, type RenderPdfResult, renderPdf, } from './render_pdf.js';
|
|
3
|
+
export { type PngCheckedValidationResult, type PngRuntime, type PngValidationResult, type RenderPngOptions, type RenderPngResult, type SnapshotOptions, renderPng, } from './render_png.js';
|
|
4
|
+
export type { Font, FontDetails, FontLoader } from '@takumi-rs/core';
|
|
5
|
+
export type { ImagesInput } from 'takumi-pdf';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,cAAc,EACd,wBAAwB,GACzB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,SAAS,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,SAAS,GACV,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
3
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
4
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
5
|
+
* 2.0.
|
|
6
|
+
*/
|
|
7
|
+
export { TAKUMI_FORMATS, createTakumiImageBackend, } from './backend.js';
|
|
8
|
+
export { renderPdf, } from './render_pdf.js';
|
|
9
|
+
export { renderPng, } from './render_png.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAYL,cAAc,EACd,wBAAwB,GACzB,MAAM,WAAW,CAAC;AACnB,OAAO,EAIL,SAAS,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAOL,SAAS,GACV,MAAM,cAAc,CAAC","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nexport {\n type ImageInput,\n type LayoutBox,\n type PdfInput,\n type TakumiBackend,\n type TakumiImageBackend,\n type TakumiImageBackendOptions,\n type TakumiMeasuringBackend,\n type TakumiPdfBackend,\n type TakumiPdfMetadata,\n type TakumiPdfOptions,\n type TakumiRenderOptions,\n TAKUMI_FORMATS,\n createTakumiImageBackend,\n} from './backend';\nexport {\n type PdfRuntime,\n type RenderPdfOptions,\n type RenderPdfResult,\n renderPdf,\n} from './render_pdf';\nexport {\n type PngCheckedValidationResult,\n type PngRuntime,\n type PngValidationResult,\n type RenderPngOptions,\n type RenderPngResult,\n type SnapshotOptions,\n renderPng,\n} from './render_png';\nexport type { Font, FontDetails, FontLoader } from '@takumi-rs/core';\nexport type { ImagesInput } from 'takumi-pdf';\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { PdfInput, TakumiPdfBackend, TakumiPdfOptions } from './backend.js';
|
|
2
|
+
import { type PngCheckedValidationResult, type PngValidationResult, type SnapshotOptions } from './render_png.js';
|
|
3
|
+
/**
|
|
4
|
+
* The slice of `IsomerRuntime` this helper needs, declared structurally like
|
|
5
|
+
* {@link PdfInput}. A runtime built with `frames` satisfies it.
|
|
6
|
+
*/
|
|
7
|
+
export interface PdfRuntime {
|
|
8
|
+
validate(composition: unknown): PngCheckedValidationResult;
|
|
9
|
+
surfaces: {
|
|
10
|
+
snapshot: {
|
|
11
|
+
renderPages(compositions: readonly unknown[], options?: SnapshotOptions & {
|
|
12
|
+
onValidationError?: 'collect' | 'throw';
|
|
13
|
+
}): PdfInput;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** Options for {@link renderPdf}. */
|
|
18
|
+
export interface RenderPdfOptions extends TakumiPdfOptions {
|
|
19
|
+
/** Forwarded to `runtime.surfaces.snapshot.renderPages`, so every page shares one frame. */
|
|
20
|
+
snapshot?: SnapshotOptions;
|
|
21
|
+
}
|
|
22
|
+
/** What {@link renderPdf} resolves to: the bytes, the page count and size, and one finding set per composition. */
|
|
23
|
+
export interface RenderPdfResult {
|
|
24
|
+
pdf: Buffer;
|
|
25
|
+
pageCount: number;
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
/** One per composition, in order. */
|
|
29
|
+
validations: PngValidationResult[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Validates, renders, and writes a deck as one PDF in one call, a page per
|
|
33
|
+
* composition.
|
|
34
|
+
*
|
|
35
|
+
* Every composition is rendered, even an invalid one: `validations` is how a
|
|
36
|
+
* caller finds out, rather than a thrown error. What is drawn is the copy
|
|
37
|
+
* validation checked. Validation runs twice, once here and once inside
|
|
38
|
+
* `renderPages`, which discards its own result. An empty deck throws the
|
|
39
|
+
* runtime's `EMPTY_PAGES`.
|
|
40
|
+
*/
|
|
41
|
+
export declare const renderPdf: (runtime: PdfRuntime, deck: readonly unknown[], backend: TakumiPdfBackend, { snapshot, ...options }?: RenderPdfOptions) => Promise<RenderPdfResult>;
|
|
42
|
+
//# sourceMappingURL=render_pdf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render_pdf.d.ts","sourceRoot":"","sources":["../src/render_pdf.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC9E,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACrB,MAAM,cAAc,CAAC;AAEtB;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,WAAW,EAAE,OAAO,GAAG,0BAA0B,CAAC;IAC3D,QAAQ,EAAE;QACR,QAAQ,EAAE;YACR,WAAW,CACT,YAAY,EAAE,SAAS,OAAO,EAAE,EAChC,OAAO,CAAC,EAAE,eAAe,GAAG;gBAAE,iBAAiB,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;aAAE,GACtE,QAAQ,CAAC;SACb,CAAC;KACH,CAAC;CACH;AAED,qCAAqC;AACrC,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,mHAAmH;AACnH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,WAAW,EAAE,mBAAmB,EAAE,CAAC;CACpC;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,GACpB,SAAS,UAAU,EACnB,MAAM,SAAS,OAAO,EAAE,EACxB,SAAS,gBAAgB,EACzB,2BAA0B,gBAAqB,KAC9C,OAAO,CAAC,eAAe,CAoBzB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
3
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
4
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
5
|
+
* 2.0.
|
|
6
|
+
*/
|
|
7
|
+
import { checkedForDrawing, } from './render_png.js';
|
|
8
|
+
/**
|
|
9
|
+
* Validates, renders, and writes a deck as one PDF in one call, a page per
|
|
10
|
+
* composition.
|
|
11
|
+
*
|
|
12
|
+
* Every composition is rendered, even an invalid one: `validations` is how a
|
|
13
|
+
* caller finds out, rather than a thrown error. What is drawn is the copy
|
|
14
|
+
* validation checked. Validation runs twice, once here and once inside
|
|
15
|
+
* `renderPages`, which discards its own result. An empty deck throws the
|
|
16
|
+
* runtime's `EMPTY_PAGES`.
|
|
17
|
+
*/
|
|
18
|
+
export const renderPdf = async (runtime, deck, backend, { snapshot, ...options } = {}) => {
|
|
19
|
+
const pages = deck.map((composition) => checkedForDrawing('renderPdf', runtime.validate(composition)));
|
|
20
|
+
const validations = pages.map(({ validation }) => validation);
|
|
21
|
+
const rendered = runtime.surfaces.snapshot.renderPages(pages.map(({ checked }) => checked), {
|
|
22
|
+
...snapshot,
|
|
23
|
+
onValidationError: 'collect',
|
|
24
|
+
});
|
|
25
|
+
const pdf = await backend.pdf(rendered, options);
|
|
26
|
+
return {
|
|
27
|
+
pdf,
|
|
28
|
+
pageCount: rendered.pages.length,
|
|
29
|
+
width: rendered.width,
|
|
30
|
+
height: rendered.height,
|
|
31
|
+
validations,
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=render_pdf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render_pdf.js","sourceRoot":"","sources":["../src/render_pdf.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,iBAAiB,GAIlB,MAAM,cAAc,CAAC;AAkCtB;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,OAAmB,EACnB,IAAwB,EACxB,OAAyB,EACzB,EAAE,QAAQ,EAAE,GAAG,OAAO,KAAuB,EAAE,EACrB,EAAE;IAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CACrC,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAC9D,CAAC;IACF,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CACpD,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,EACnC;QACE,GAAG,QAAQ;QACX,iBAAiB,EAAE,SAAS;KAC7B,CACF,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjD,OAAO;QACL,GAAG;QACH,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;QAChC,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,WAAW;KACZ,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport type { PdfInput, TakumiPdfBackend, TakumiPdfOptions } from './backend';\nimport {\n checkedForDrawing,\n type PngCheckedValidationResult,\n type PngValidationResult,\n type SnapshotOptions,\n} from './render_png';\n\n/**\n * The slice of `IsomerRuntime` this helper needs, declared structurally like\n * {@link PdfInput}. A runtime built with `frames` satisfies it.\n */\nexport interface PdfRuntime {\n validate(composition: unknown): PngCheckedValidationResult;\n surfaces: {\n snapshot: {\n renderPages(\n compositions: readonly unknown[],\n options?: SnapshotOptions & { onValidationError?: 'collect' | 'throw' }\n ): PdfInput;\n };\n };\n}\n\n/** Options for {@link renderPdf}. */\nexport interface RenderPdfOptions extends TakumiPdfOptions {\n /** Forwarded to `runtime.surfaces.snapshot.renderPages`, so every page shares one frame. */\n snapshot?: SnapshotOptions;\n}\n\n/** What {@link renderPdf} resolves to: the bytes, the page count and size, and one finding set per composition. */\nexport interface RenderPdfResult {\n pdf: Buffer;\n pageCount: number;\n width: number;\n height: number;\n /** One per composition, in order. */\n validations: PngValidationResult[];\n}\n\n/**\n * Validates, renders, and writes a deck as one PDF in one call, a page per\n * composition.\n *\n * Every composition is rendered, even an invalid one: `validations` is how a\n * caller finds out, rather than a thrown error. What is drawn is the copy\n * validation checked. Validation runs twice, once here and once inside\n * `renderPages`, which discards its own result. An empty deck throws the\n * runtime's `EMPTY_PAGES`.\n */\nexport const renderPdf = async (\n runtime: PdfRuntime,\n deck: readonly unknown[],\n backend: TakumiPdfBackend,\n { snapshot, ...options }: RenderPdfOptions = {}\n): Promise<RenderPdfResult> => {\n const pages = deck.map((composition) =>\n checkedForDrawing('renderPdf', runtime.validate(composition))\n );\n const validations = pages.map(({ validation }) => validation);\n const rendered = runtime.surfaces.snapshot.renderPages(\n pages.map(({ checked }) => checked),\n {\n ...snapshot,\n onValidationError: 'collect',\n }\n );\n const pdf = await backend.pdf(rendered, options);\n return {\n pdf,\n pageCount: rendered.pages.length,\n width: rendered.width,\n height: rendered.height,\n validations,\n };\n};\n"]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ImageInput, TakumiImageBackend, TakumiRenderOptions } from './backend.js';
|
|
2
|
+
/** A validation result shaped like the SDK's `ValidationResult`, declared structurally. */
|
|
3
|
+
export interface PngValidationResult {
|
|
4
|
+
valid: boolean;
|
|
5
|
+
errors: readonly unknown[];
|
|
6
|
+
}
|
|
7
|
+
/** What `runtime.validate` returns: findings, and the copy they describe, `undefined` only for refused input. */
|
|
8
|
+
export type PngCheckedValidationResult = PngValidationResult & {
|
|
9
|
+
composition: unknown;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Splits a {@link PngCheckedValidationResult} into the copy to draw and the findings to report.
|
|
13
|
+
*
|
|
14
|
+
* Throws rather than draw the caller's value: shaped as the SDK's
|
|
15
|
+
* `CompositionValidationError` when the runtime refused the input, and a plain
|
|
16
|
+
* `Error` when the runtime returned no copy at all.
|
|
17
|
+
*/
|
|
18
|
+
export declare const checkedForDrawing: (caller: string, { composition, ...validation }: PngCheckedValidationResult) => {
|
|
19
|
+
checked: unknown;
|
|
20
|
+
validation: PngValidationResult;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* The `snapshot` surface's per-render options, mirroring the runtime's
|
|
24
|
+
* `SnapshotRenderOptions` so a caller gets completion without importing it.
|
|
25
|
+
*/
|
|
26
|
+
export interface SnapshotOptions {
|
|
27
|
+
/** Which of the runtime's frames this render uses; defaults to its `defaultFrame`. */
|
|
28
|
+
frame?: string;
|
|
29
|
+
/** Overrides the frame's `defaultWidth`. */
|
|
30
|
+
width?: number;
|
|
31
|
+
/** Overrides the frame's estimated height. */
|
|
32
|
+
height?: number;
|
|
33
|
+
/** Theme mode; falls back to the composition's own `theme`. `auto` resolves light. */
|
|
34
|
+
theme?: 'light' | 'dark' | 'auto';
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The slice of `IsomerRuntime` this helper needs, declared structurally like
|
|
38
|
+
* {@link ImageInput} so this package depends on no isomer package. `surfaces.snapshot`
|
|
39
|
+
* is required where the runtime's generic form has `SnapshotSurface | undefined`; a
|
|
40
|
+
* runtime built with `frames` carries `SnapshotSurface` there and satisfies this.
|
|
41
|
+
*/
|
|
42
|
+
export interface PngRuntime {
|
|
43
|
+
validate(composition: unknown): PngCheckedValidationResult;
|
|
44
|
+
surfaces: {
|
|
45
|
+
snapshot: {
|
|
46
|
+
render(composition: unknown, options?: SnapshotOptions & {
|
|
47
|
+
onValidationError?: 'collect' | 'throw';
|
|
48
|
+
}): ImageInput;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** Options for {@link renderPng}. */
|
|
53
|
+
export interface RenderPngOptions extends TakumiRenderOptions {
|
|
54
|
+
/** Forwarded to `runtime.surfaces.snapshot.render`. */
|
|
55
|
+
snapshot?: SnapshotOptions;
|
|
56
|
+
}
|
|
57
|
+
/** What {@link renderPng} resolves to: the bytes, their size, and the findings on the composition drawn. */
|
|
58
|
+
export interface RenderPngResult {
|
|
59
|
+
png: Buffer;
|
|
60
|
+
/** The viewport, in CSS pixels; the raster is this times `scale`, rounded. */
|
|
61
|
+
width: number;
|
|
62
|
+
height: number;
|
|
63
|
+
validation: PngValidationResult;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Validates, renders, and rasterizes a composition in one call.
|
|
67
|
+
*
|
|
68
|
+
* The composition is rendered even when invalid: `validation` is how a caller
|
|
69
|
+
* finds out, rather than a thrown error. What is drawn is the copy validation
|
|
70
|
+
* checked, and input refused before parsing, which has none, throws
|
|
71
|
+
* `CompositionValidationError`. Validation runs twice, once here and once inside `render`, which
|
|
72
|
+
* discards its own result.
|
|
73
|
+
*/
|
|
74
|
+
export declare const renderPng: (runtime: PngRuntime, composition: unknown, backend: TakumiImageBackend, { snapshot, ...options }?: RenderPngOptions) => Promise<RenderPngResult>;
|
|
75
|
+
//# sourceMappingURL=render_png.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render_png.d.ts","sourceRoot":"","sources":["../src/render_png.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,WAAW,CAAC;AAEnB,2FAA2F;AAC3F,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;CAC5B;AAED,iHAAiH;AACjH,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAAG;IAC7D,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,EACd,gCAAgC,0BAA0B,KACzD;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,mBAAmB,CAAA;CAiBrD,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,WAAW,EAAE,OAAO,GAAG,0BAA0B,CAAC;IAC3D,QAAQ,EAAE;QACR,QAAQ,EAAE;YACR,MAAM,CACJ,WAAW,EAAE,OAAO,EACpB,OAAO,CAAC,EAAE,eAAe,GAAG;gBAAE,iBAAiB,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;aAAE,GACtE,UAAU,CAAC;SACf,CAAC;KACH,CAAC;CACH;AAED,qCAAqC;AACrC,MAAM,WAAW,gBAAiB,SAAQ,mBAAmB;IAC3D,uDAAuD;IACvD,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,4GAA4G;AAC5G,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,mBAAmB,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,GACpB,SAAS,UAAU,EACnB,aAAa,OAAO,EACpB,SAAS,kBAAkB,EAC3B,2BAA0B,gBAAqB,KAC9C,OAAO,CAAC,eAAe,CAWzB,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
3
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
4
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
5
|
+
* 2.0.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Splits a {@link PngCheckedValidationResult} into the copy to draw and the findings to report.
|
|
9
|
+
*
|
|
10
|
+
* Throws rather than draw the caller's value: shaped as the SDK's
|
|
11
|
+
* `CompositionValidationError` when the runtime refused the input, and a plain
|
|
12
|
+
* `Error` when the runtime returned no copy at all.
|
|
13
|
+
*/
|
|
14
|
+
export const checkedForDrawing = (caller, { composition, ...validation }) => {
|
|
15
|
+
if (composition !== undefined) {
|
|
16
|
+
return { checked: composition, validation };
|
|
17
|
+
}
|
|
18
|
+
if (validation.valid) {
|
|
19
|
+
throw new Error(`${caller}: runtime.validate returned no checked composition to draw`);
|
|
20
|
+
}
|
|
21
|
+
throw Object.assign(new Error(`${caller}: the runtime refused the composition before parsing`), {
|
|
22
|
+
name: 'CompositionValidationError',
|
|
23
|
+
code: 'COMPOSITION_INVALID',
|
|
24
|
+
errors: validation.errors,
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Validates, renders, and rasterizes a composition in one call.
|
|
29
|
+
*
|
|
30
|
+
* The composition is rendered even when invalid: `validation` is how a caller
|
|
31
|
+
* finds out, rather than a thrown error. What is drawn is the copy validation
|
|
32
|
+
* checked, and input refused before parsing, which has none, throws
|
|
33
|
+
* `CompositionValidationError`. Validation runs twice, once here and once inside `render`, which
|
|
34
|
+
* discards its own result.
|
|
35
|
+
*/
|
|
36
|
+
export const renderPng = async (runtime, composition, backend, { snapshot, ...options } = {}) => {
|
|
37
|
+
const { checked, validation } = checkedForDrawing('renderPng', runtime.validate(composition));
|
|
38
|
+
const rendered = runtime.surfaces.snapshot.render(checked, {
|
|
39
|
+
...snapshot,
|
|
40
|
+
onValidationError: 'collect',
|
|
41
|
+
});
|
|
42
|
+
const png = await backend.png(rendered, options);
|
|
43
|
+
return { png, width: rendered.width, height: rendered.height, validation };
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=render_png.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render_png.js","sourceRoot":"","sources":["../src/render_png.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAmBH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,MAAc,EACd,EAAE,WAAW,EAAE,GAAG,UAAU,EAA8B,EACH,EAAE;IACzD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;IAC9C,CAAC;IACD,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,4DAA4D,CACtE,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CAAC,GAAG,MAAM,sDAAsD,CAAC,EAC1E;QACE,IAAI,EAAE,4BAA4B;QAClC,IAAI,EAAE,qBAAqB;QAC3B,MAAM,EAAE,UAAU,CAAC,MAAM;KAC1B,CACF,CAAC;AACJ,CAAC,CAAC;AAkDF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,OAAmB,EACnB,WAAoB,EACpB,OAA2B,EAC3B,EAAE,QAAQ,EAAE,GAAG,OAAO,KAAuB,EAAE,EACrB,EAAE;IAC5B,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAC/C,WAAW,EACX,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAC9B,CAAC;IACF,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE;QACzD,GAAG,QAAQ;QACX,iBAAiB,EAAE,SAAS;KAC7B,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC;AAC7E,CAAC,CAAC","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport type {\n ImageInput,\n TakumiImageBackend,\n TakumiRenderOptions,\n} from './backend';\n\n/** A validation result shaped like the SDK's `ValidationResult`, declared structurally. */\nexport interface PngValidationResult {\n valid: boolean;\n errors: readonly unknown[];\n}\n\n/** What `runtime.validate` returns: findings, and the copy they describe, `undefined` only for refused input. */\nexport type PngCheckedValidationResult = PngValidationResult & {\n composition: unknown;\n};\n\n/**\n * Splits a {@link PngCheckedValidationResult} into the copy to draw and the findings to report.\n *\n * Throws rather than draw the caller's value: shaped as the SDK's\n * `CompositionValidationError` when the runtime refused the input, and a plain\n * `Error` when the runtime returned no copy at all.\n */\nexport const checkedForDrawing = (\n caller: string,\n { composition, ...validation }: PngCheckedValidationResult\n): { checked: unknown; validation: PngValidationResult } => {\n if (composition !== undefined) {\n return { checked: composition, validation };\n }\n if (validation.valid) {\n throw new Error(\n `${caller}: runtime.validate returned no checked composition to draw`\n );\n }\n throw Object.assign(\n new Error(`${caller}: the runtime refused the composition before parsing`),\n {\n name: 'CompositionValidationError',\n code: 'COMPOSITION_INVALID',\n errors: validation.errors,\n }\n );\n};\n\n/**\n * The `snapshot` surface's per-render options, mirroring the runtime's\n * `SnapshotRenderOptions` so a caller gets completion without importing it.\n */\nexport interface SnapshotOptions {\n /** Which of the runtime's frames this render uses; defaults to its `defaultFrame`. */\n frame?: string;\n /** Overrides the frame's `defaultWidth`. */\n width?: number;\n /** Overrides the frame's estimated height. */\n height?: number;\n /** Theme mode; falls back to the composition's own `theme`. `auto` resolves light. */\n theme?: 'light' | 'dark' | 'auto';\n}\n\n/**\n * The slice of `IsomerRuntime` this helper needs, declared structurally like\n * {@link ImageInput} so this package depends on no isomer package. `surfaces.snapshot`\n * is required where the runtime's generic form has `SnapshotSurface | undefined`; a\n * runtime built with `frames` carries `SnapshotSurface` there and satisfies this.\n */\nexport interface PngRuntime {\n validate(composition: unknown): PngCheckedValidationResult;\n surfaces: {\n snapshot: {\n render(\n composition: unknown,\n options?: SnapshotOptions & { onValidationError?: 'collect' | 'throw' }\n ): ImageInput;\n };\n };\n}\n\n/** Options for {@link renderPng}. */\nexport interface RenderPngOptions extends TakumiRenderOptions {\n /** Forwarded to `runtime.surfaces.snapshot.render`. */\n snapshot?: SnapshotOptions;\n}\n\n/** What {@link renderPng} resolves to: the bytes, their size, and the findings on the composition drawn. */\nexport interface RenderPngResult {\n png: Buffer;\n /** The viewport, in CSS pixels; the raster is this times `scale`, rounded. */\n width: number;\n height: number;\n validation: PngValidationResult;\n}\n\n/**\n * Validates, renders, and rasterizes a composition in one call.\n *\n * The composition is rendered even when invalid: `validation` is how a caller\n * finds out, rather than a thrown error. What is drawn is the copy validation\n * checked, and input refused before parsing, which has none, throws\n * `CompositionValidationError`. Validation runs twice, once here and once inside `render`, which\n * discards its own result.\n */\nexport const renderPng = async (\n runtime: PngRuntime,\n composition: unknown,\n backend: TakumiImageBackend,\n { snapshot, ...options }: RenderPngOptions = {}\n): Promise<RenderPngResult> => {\n const { checked, validation } = checkedForDrawing(\n 'renderPng',\n runtime.validate(composition)\n );\n const rendered = runtime.surfaces.snapshot.render(checked, {\n ...snapshot,\n onValidationError: 'collect',\n });\n const png = await backend.png(rendered, options);\n return { png, width: rendered.width, height: rendered.height, validation };\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,45 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@elastic/isomer-image-takumi",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Takumi image backend for Isomer: rasterizes the snapshot surface's output to PNG, SVG, or PDF.",
|
|
5
|
+
"license": "Elastic-2.0",
|
|
6
|
+
"author": "Elastic",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/elastic/isomer.git",
|
|
10
|
+
"directory": "packages/isomer-image-takumi"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"main": "./dist/cjs/index.js",
|
|
15
|
+
"module": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"require": "./dist/cjs/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"NOTICE.txt",
|
|
27
|
+
"THIRD_PARTY_LICENSES.md",
|
|
28
|
+
"LICENSE.txt"
|
|
29
|
+
],
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@takumi-rs/core": "2.14.0",
|
|
32
|
+
"@takumi-rs/helpers": "2.14.0",
|
|
33
|
+
"takumi-pdf": "0.15.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@fontsource/inter": "^5.3.0",
|
|
37
|
+
"@types/react": "^18.2.14",
|
|
38
|
+
"@types/react-dom": "^18.2.6",
|
|
39
|
+
"react": "^18.3.1",
|
|
40
|
+
"react-dom": "^18.3.1"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
44
|
+
}
|
|
45
|
+
}
|