@sme.up/doc-alchemist 1.6.0-SNAPSHOT-20251212145333 → 1.6.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/dist/converters/pdf/pdfmake/adapter-processor.js +4 -2
- package/dist/converters/pdf/pdfmake/adapter-processor.js.map +1 -1
- package/dist/converters/pdf/pdfmake/adapters/page-element-adapter.d.ts +3 -2
- package/dist/converters/pdf/pdfmake/adapters/page-element-adapter.js +14 -7
- package/dist/converters/pdf/pdfmake/adapters/page-element-adapter.js.map +1 -1
- package/dist/converters/pdf/pdfmake/pdfmake.types.d.ts +6 -0
- package/dist/converters/pdf/pdfmake/pdfmake.types.js.map +1 -1
- package/package.json +1 -1
|
@@ -38,6 +38,8 @@ const EXCLUDED_PROPERTIES = new Set([
|
|
|
38
38
|
* @returns The transformed element
|
|
39
39
|
*/
|
|
40
40
|
const processDocument = async (element, adapters, context) => {
|
|
41
|
+
// Add adapters to context for use by adapters that need recursive processing
|
|
42
|
+
const contextWithAdapters = { ...context, _adapters: adapters };
|
|
41
43
|
// Handle null/undefined
|
|
42
44
|
if (element == null) {
|
|
43
45
|
return element;
|
|
@@ -53,7 +55,7 @@ const processDocument = async (element, adapters, context) => {
|
|
|
53
55
|
const elementType = element.type;
|
|
54
56
|
if (elementType && adapters.has(elementType)) {
|
|
55
57
|
const adapter = adapters.get(elementType);
|
|
56
|
-
element = await adapter(element,
|
|
58
|
+
element = await adapter(element, contextWithAdapters);
|
|
57
59
|
// After transformation, element might not be a plain object anymore
|
|
58
60
|
if (!isPlainObject(element)) {
|
|
59
61
|
return element;
|
|
@@ -66,7 +68,7 @@ const processDocument = async (element, adapters, context) => {
|
|
|
66
68
|
continue;
|
|
67
69
|
// Apply adapter if it matches a property name
|
|
68
70
|
if (key in element) {
|
|
69
|
-
const transformed = await adapter(element,
|
|
71
|
+
const transformed = await adapter(element, contextWithAdapters);
|
|
70
72
|
// Only accept transformation if adapter actually changed something
|
|
71
73
|
if (transformed !== element) {
|
|
72
74
|
element = transformed;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-processor.js","sourceRoot":"","sources":["../../../../src/converters/pdf/pdfmake/adapter-processor.ts"],"names":[],"mappings":";;;AAAA,mDAKyB;AAGzB;;GAEG;AACH,MAAM,aAAa,GAAG,CAAC,KAAc,EAAoC,EAAE;IACzE,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,iBAAiB,CAC5D,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,QAAQ;IACR,cAAc;IACd,UAAU;IACV,aAAa;IACb,iBAAiB;IACjB,iBAAiB;IACjB,MAAM;IACN,aAAa;IACb,UAAU;IACV,cAAc;IACd,eAAe;IACf,SAAS;CACV,CAAC,CAAC;AAEH;;;;;;;GAOG;AACI,MAAM,eAAe,GAAG,KAAK,EAClC,OAAgB,EAChB,QAAqC,EACrC,OAAgC,EACd,EAAE;IACpB,wBAAwB;IACxB,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,CAAC;QACH,oCAAoC;QACpC,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,OAAO,MAAM,OAAO,CAAC,GAAG,CACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAA,uBAAe,EAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAC9D,CAAC;QACJ,CAAC;QAED,uBAAuB;QACvB,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,8CAA8C;YAC9C,MAAM,WAAW,GAAG,OAAO,CAAC,IAA0B,CAAC;YACvD,IAAI,WAAW,IAAI,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC7C,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAE,CAAC;gBAC3C,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"adapter-processor.js","sourceRoot":"","sources":["../../../../src/converters/pdf/pdfmake/adapter-processor.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n PdfMakeConverterContext,\n AdapterError,\n PdfmakeAdapter,\n AdapterRegistry,\n} from \"./pdfmake.types\";\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\n/**\n * Helper to check if a value is a plain object\n */\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n Object.prototype.toString.call(value) === \"[object Object]\"\n );\n};\n\n/**\n * Properties of pdfmake document that should not be processed by adapters.\n * These are configuration properties, not content.\n */\nconst EXCLUDED_PROPERTIES = new Set([\n \"styles\",\n \"defaultStyle\",\n \"pageSize\",\n \"pageMargins\",\n \"pageOrientation\",\n \"pageBreakBefore\",\n \"info\",\n \"permissions\",\n \"compress\",\n \"userPassword\",\n \"ownerPassword\",\n \"version\",\n]);\n\n/**\n * Processes a document recursively, applying adapters to matching elements.\n *\n * @param element - The current element to process\n * @param adapters - Map of element types to their adapter functions\n * @param context - Current processing context\n * @returns The transformed element\n */\nexport const processDocument = async (\n element: unknown,\n adapters: Map<string, PdfmakeAdapter>,\n context: PdfMakeConverterContext,\n): Promise<unknown> => {\n // Add adapters to context for use by adapters that need recursive processing\n const contextWithAdapters = { ...context, _adapters: adapters };\n \n // Handle null/undefined\n if (element == null) {\n return element;\n }\n try {\n // Handle arrays - process each item\n if (Array.isArray(element)) {\n return await Promise.all(\n element.map(item => processDocument(item, adapters, context)),\n );\n }\n\n // Handle plain objects\n if (isPlainObject(element)) {\n // Try to apply adapters based on element type\n const elementType = element.type as string | undefined;\n if (elementType && adapters.has(elementType)) {\n const adapter = adapters.get(elementType)!;\n element = await adapter(element, contextWithAdapters);\n\n // After transformation, element might not be a plain object anymore\n if (!isPlainObject(element)) {\n return element;\n }\n }\n\n // Also try adapters based on properties (e.g., \"table\" property)\n for (const [key, adapter] of adapters.entries()) {\n // Skip type-based adapters already processed\n if (key === elementType) continue;\n\n // Apply adapter if it matches a property name\n if (key in element) {\n const transformed = await adapter(element, contextWithAdapters);\n // Only accept transformation if adapter actually changed something\n if (transformed !== element) {\n element = transformed;\n // After transformation, element might not be a plain object anymore\n if (!isPlainObject(element)) {\n return element;\n }\n // Continue to apply other adapters (e.g., both header and footer)\n }\n }\n }\n\n // Recursively process all properties\n const processed: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(\n element as Record<string, unknown>,\n )) {\n // Skip excluded properties (don't process them recursively)\n if (EXCLUDED_PROPERTIES.has(key)) {\n processed[key] = value;\n } else {\n processed[key] = await processDocument(value, adapters, context);\n }\n }\n return processed;\n }\n\n // Primitive values - return as-is\n return element;\n } catch (err) {\n throw new AdapterError(err as string, element);\n }\n};\n\nexport const preProcessPdfMakeDocument = async (\n documentDefinition: TDocumentDefinitions,\n context: Partial<PdfMakeConverterContext>,\n registry?: AdapterRegistry,\n): Promise<TDocumentDefinitions> => {\n if (!registry) {\n return Promise.resolve(documentDefinition);\n } else {\n documentDefinition.images = documentDefinition.images || {};\n\n const processedDoc = (await registry?.process(\n documentDefinition,\n context,\n )) as TDocumentDefinitions;\n\n return processedDoc;\n }\n};\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { PdfMakeConverterContext } from "../pdfmake.types";
|
|
1
2
|
/**
|
|
2
3
|
* Adapter for header elements with page number placeholder support.
|
|
3
4
|
*/
|
|
4
|
-
export declare const headerAdapter: () => (element: unknown) => unknown
|
|
5
|
+
export declare const headerAdapter: () => (element: unknown, context: PdfMakeConverterContext) => Promise<unknown>;
|
|
5
6
|
/**
|
|
6
7
|
* Adapter for footer elements with page number placeholder support.
|
|
7
8
|
*/
|
|
8
|
-
export declare const footerAdapter: () => (element: unknown) => unknown
|
|
9
|
+
export declare const footerAdapter: () => (element: unknown, context: PdfMakeConverterContext) => Promise<unknown>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.footerAdapter = exports.headerAdapter = void 0;
|
|
4
|
+
const adapter_processor_1 = require("../adapter-processor");
|
|
4
5
|
/**
|
|
5
6
|
* Type guard to check if an element has a specific property
|
|
6
7
|
*/
|
|
@@ -42,16 +43,16 @@ const replacePlaceholders = (obj, currentPage, pageCount) => {
|
|
|
42
43
|
*
|
|
43
44
|
* This adapter function checks if the provided element contains the specified property (header or footer).
|
|
44
45
|
* - If the property is already a function, it leaves it unchanged.
|
|
45
|
-
* - If the property is an object, it
|
|
46
|
-
* [CurrentPage] with the current page number and
|
|
47
|
-
* page count at rendering time.
|
|
46
|
+
* - If the property is an object, it first recursively processes it with all registered adapters,
|
|
47
|
+
* then wraps it in a function that replaces [CurrentPage] with the current page number and
|
|
48
|
+
* [PageCount] with the total page count at rendering time.
|
|
48
49
|
*
|
|
49
50
|
* @param propertyName - The name of the property to adapt ('header' or 'footer')
|
|
50
51
|
* @returns A function that takes an element and returns the adapted element for PDFMake,
|
|
51
52
|
* or the original element if it does not contain the specified property.
|
|
52
53
|
*/
|
|
53
54
|
const createPageElementAdapter = (propertyName) => {
|
|
54
|
-
return (element) => {
|
|
55
|
+
return async (element, context) => {
|
|
55
56
|
if (!hasProperty(element, propertyName)) {
|
|
56
57
|
return element;
|
|
57
58
|
}
|
|
@@ -60,9 +61,15 @@ const createPageElementAdapter = (propertyName) => {
|
|
|
60
61
|
if (typeof propertyValue === "function") {
|
|
61
62
|
return element;
|
|
62
63
|
}
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
// First, recursively process the header/footer content with all adapters
|
|
65
|
+
// This ensures nested elements (like tables with layouts) are properly transformed
|
|
66
|
+
let processedValue = propertyValue;
|
|
67
|
+
if (context._adapters) {
|
|
68
|
+
processedValue = await (0, adapter_processor_1.processDocument)(propertyValue, context._adapters, context);
|
|
69
|
+
}
|
|
70
|
+
// Then wrap the processed content in a function that replaces placeholders at render time
|
|
71
|
+
const dynamicContent = (currentPage, pageCount, _pageSize) => {
|
|
72
|
+
return replacePlaceholders(processedValue, currentPage, pageCount);
|
|
66
73
|
};
|
|
67
74
|
return {
|
|
68
75
|
...element,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-element-adapter.js","sourceRoot":"","sources":["../../../../../src/converters/pdf/pdfmake/adapters/page-element-adapter.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"page-element-adapter.js","sourceRoot":"","sources":["../../../../../src/converters/pdf/pdfmake/adapters/page-element-adapter.ts"],"names":[],"mappings":";;;AACA,4DAAuD;AAGvD;;GAEG;AACH,MAAM,WAAW,GAAG,CAClB,OAAgB,EAChB,YAAe,EACiC,EAAE;IAClD,OAAO,CACL,OAAO,KAAK,IAAI;QAChB,OAAO,OAAO,KAAK,QAAQ;QAC3B,YAAY,IAAI,OAAO;QACtB,OAAmC,CAAC,YAAY,CAAC,KAAK,SAAS,CACjE,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,mBAAmB,GAAG,CAC1B,GAAY,EACZ,WAAmB,EACnB,SAAiB,EACR,EAAE;IACX,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,GAAG;aACP,OAAO,CAAC,kBAAkB,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;aAChD,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5C,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,wBAAwB,GAAG,CAAC,YAAiC,EAAE,EAAE;IACrE,OAAO,KAAK,EACV,OAAgB,EAChB,OAAgC,EACd,EAAE;QACpB,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;YACxC,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,MAAM,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;QAE5C,oDAAoD;QACpD,IAAI,OAAO,aAAa,KAAK,UAAU,EAAE,CAAC;YACxC,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,yEAAyE;QACzE,mFAAmF;QACnF,IAAI,cAAc,GAAY,aAAa,CAAC;QAC5C,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,cAAc,GAAG,MAAM,IAAA,mCAAe,EACpC,aAAa,EACb,OAAO,CAAC,SAAS,EACjB,OAAO,CACR,CAAC;QACJ,CAAC;QAED,0FAA0F;QAC1F,MAAM,cAAc,GAAmB,CACrC,WAAW,EACX,SAAS,EACT,SAAS,EACT,EAAE;YACF,OAAO,mBAAmB,CACxB,cAAc,EACd,WAAW,EACX,SAAS,CACC,CAAC;QACf,CAAC,CAAC;QAEF,OAAO;YACL,GAAG,OAAO;YACV,CAAC,YAAY,CAAC,EAAE,cAAc;SAC/B,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACI,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAAC;AAAzD,QAAA,aAAa,iBAA4C;AAEtE;;GAEG;AACI,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAAC;AAAzD,QAAA,aAAa,iBAA4C","sourcesContent":["import { Content, DynamicContent } from \"pdfmake/interfaces\";\nimport { processDocument } from \"../adapter-processor\";\nimport { PdfMakeConverterContext } from \"../pdfmake.types\";\n\n/**\n * Type guard to check if an element has a specific property\n */\nconst hasProperty = <T extends string>(\n element: unknown,\n propertyName: T,\n): element is Record<T, Content | DynamicContent> => {\n return (\n element !== null &&\n typeof element === \"object\" &&\n propertyName in element &&\n (element as Record<string, unknown>)[propertyName] !== undefined\n );\n};\n\n/**\n * Recursively searches for [CurrentPage] and [PageCount] placeholders in an object\n * and replaces them with the actual values.\n *\n * @param obj - The object to process\n * @param currentPage - The current page number\n * @param pageCount - The total page count\n * @returns The processed object with replaced placeholders\n */\nconst replacePlaceholders = (\n obj: unknown,\n currentPage: number,\n pageCount: number,\n): unknown => {\n if (typeof obj === \"string\") {\n return obj\n .replace(/\\[CurrentPage\\]/g, String(currentPage))\n .replace(/\\[PageCount\\]/g, String(pageCount));\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => replacePlaceholders(item, currentPage, pageCount));\n }\n\n if (obj !== null && typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = replacePlaceholders(value, currentPage, pageCount);\n }\n return result;\n }\n\n return obj;\n};\n\n/**\n * Adapts a header or footer to support dynamic page number placeholders.\n *\n * This adapter function checks if the provided element contains the specified property (header or footer).\n * - If the property is already a function, it leaves it unchanged.\n * - If the property is an object, it first recursively processes it with all registered adapters,\n * then wraps it in a function that replaces [CurrentPage] with the current page number and\n * [PageCount] with the total page count at rendering time.\n *\n * @param propertyName - The name of the property to adapt ('header' or 'footer')\n * @returns A function that takes an element and returns the adapted element for PDFMake,\n * or the original element if it does not contain the specified property.\n */\nconst createPageElementAdapter = (propertyName: \"header\" | \"footer\") => {\n return async (\n element: unknown,\n context: PdfMakeConverterContext,\n ): Promise<unknown> => {\n if (!hasProperty(element, propertyName)) {\n return element;\n }\n\n const propertyValue = element[propertyName];\n\n // If property is already a function, leave it as is\n if (typeof propertyValue === \"function\") {\n return element;\n }\n\n // First, recursively process the header/footer content with all adapters\n // This ensures nested elements (like tables with layouts) are properly transformed\n let processedValue: unknown = propertyValue;\n if (context._adapters) {\n processedValue = await processDocument(\n propertyValue,\n context._adapters,\n context,\n );\n }\n\n // Then wrap the processed content in a function that replaces placeholders at render time\n const dynamicContent: DynamicContent = (\n currentPage,\n pageCount,\n _pageSize,\n ) => {\n return replacePlaceholders(\n processedValue,\n currentPage,\n pageCount,\n ) as Content;\n };\n\n return {\n ...element,\n [propertyName]: dynamicContent,\n };\n };\n};\n\n/**\n * Adapter for header elements with page number placeholder support.\n */\nexport const headerAdapter = () => createPageElementAdapter(\"header\");\n\n/**\n * Adapter for footer elements with page number placeholder support.\n */\nexport const footerAdapter = () => createPageElementAdapter(\"footer\");\n"]}
|
|
@@ -12,6 +12,12 @@ export interface PdfMakeConverterContext<T extends SmeupDataStructure = SmeupDat
|
|
|
12
12
|
damSvcEndpoint?: string;
|
|
13
13
|
getSmeupDataStructure?: (fun: string) => Promise<T>;
|
|
14
14
|
fetchData?: (url: string) => Promise<Response>;
|
|
15
|
+
/**
|
|
16
|
+
* Internal property used by adapters that need to recursively process content.
|
|
17
|
+
* This is populated by the adapter processor and should not be set by external code.
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
_adapters?: Map<string, PdfmakeAdapter>;
|
|
15
21
|
}
|
|
16
22
|
/**
|
|
17
23
|
* Function that transforms an element from custom format to pdfmake standard format.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdfmake.types.js","sourceRoot":"","sources":["../../../../src/converters/pdf/pdfmake/pdfmake.types.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"pdfmake.types.js","sourceRoot":"","sources":["../../../../src/converters/pdf/pdfmake/pdfmake.types.ts"],"names":[],"mappings":";;;AAuDA,MAAa,YAAa,SAAQ,KAAK;IACrC,OAAO,CAAU;IACjB,YAAY,OAAe,EAAE,OAAgB;QAC3C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;CACF;AAPD,oCAOC","sourcesContent":["import {\n ContentImage,\n Table,\n TDocumentDefinitions,\n ContentSvg,\n} from \"pdfmake/interfaces\";\nimport { SmeupDataObj, WebupManagerData } from \"../../../types\";\nimport { SmeupDataStructure } from \"../../../types/data-structures/smeupDataStructure\";\nimport { SmeupDataTable } from \"../../../types/data-structures/smeupDataTable\";\nimport { ComponentOptions } from \"../../../types/component\";\n\n/**\n * Context passed to adapter functions during document processing.\n */\nexport interface PdfMakeConverterContext<\n T extends SmeupDataStructure = SmeupDataStructure,\n> {\n webupManagerData: WebupManagerData;\n pdfDocument?: TDocumentDefinitions;\n damSvcEndpoint?: string;\n getSmeupDataStructure?: (fun: string) => Promise<T>;\n fetchData?: (url: string) => Promise<Response>;\n /**\n * Internal property used by adapters that need to recursively process content.\n * This is populated by the adapter processor and should not be set by external code.\n * @internal\n */\n _adapters?: Map<string, PdfmakeAdapter>;\n}\n\n/**\n * Function that transforms an element from custom format to pdfmake standard format.\n * Adapters are pure functions that receive an element and context, and return the transformed element.\n * Can be synchronous or asynchronous.\n */\nexport type PdfmakeAdapter = (\n element: unknown,\n context: PdfMakeConverterContext,\n) => unknown | Promise<unknown>;\n\n/**\n * Registry interface for managing pdfmake adapters at runtime.\n */\nexport interface AdapterRegistry {\n /** Register an adapter for a specific element type */\n register: (elementType: string, adapter: PdfmakeAdapter) => void;\n /** Unregister an adapter for a specific element type */\n unregister: (elementType: string) => void;\n /** Process a document by applying registered adapters */\n process: (\n document: unknown,\n context: Partial<PdfMakeConverterContext>,\n ) => Promise<unknown>;\n}\n\nexport class AdapterError extends Error {\n element: unknown;\n constructor(message: string, element: unknown) {\n super(message);\n this.element = element;\n Object.setPrototypeOf(this, AdapterError.prototype);\n }\n}\n\ninterface SmeupExtensionImageMetadata {\n url?: string;\n obj?: SmeupDataObj;\n}\n\ninterface SmeupExtensionTableMetadata<T = ComponentOptions> {\n fun?: string;\n data?: SmeupDataTable;\n options?: T;\n}\n\nexport interface ContentImageExtension extends ContentImage {\n smeup?: SmeupExtensionImageMetadata;\n}\n\nexport interface TableExtension extends Table {\n smeup?: SmeupExtensionTableMetadata;\n}\n\nexport interface ElementWithImageExtension {\n image: ContentImage & { smeup?: SmeupExtensionImageMetadata };\n}\n\nexport interface ElementWithTableExtension {\n table: Table & { smeup?: SmeupExtensionTableMetadata };\n}\n\nexport type LayoutLineFunction = (i: number, node?: unknown) => number;\nexport type LayoutColorFunction = (i: number, node?: unknown) => string;\n\nexport interface Layout {\n hLineWidth?: number | LayoutLineFunction;\n vLineWidth?: number | LayoutLineFunction;\n hLineColor?: string | LayoutColorFunction;\n vLineColor?: string | LayoutColorFunction;\n}\n\nexport interface ElementWithLayout {\n layout?: Layout;\n [key: string]: unknown;\n}\n\nexport interface ContentChartExtension extends ContentSvg {\n smeup?: SmeupExtensionTableMetadata;\n}\n\nexport interface ElementWithChartExtension {\n chart: ContentChartExtension;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sme.up/doc-alchemist",
|
|
3
|
-
"version": "1.6.0
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Library for generating documents in various formats, including Excel and PDF.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Smeup LAB <info@smeup.com> (https://www.smeup.com/)",
|