@jsonpdf/plugins 0.1.0-alpha.1

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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/barcode/barcode-generator.d.ts +18 -0
  4. package/dist/barcode/barcode-generator.d.ts.map +1 -0
  5. package/dist/barcode/barcode-generator.js +94 -0
  6. package/dist/barcode/barcode-generator.js.map +1 -0
  7. package/dist/barcode/barcode-plugin.d.ts +4 -0
  8. package/dist/barcode/barcode-plugin.d.ts.map +1 -0
  9. package/dist/barcode/barcode-plugin.js +70 -0
  10. package/dist/barcode/barcode-plugin.js.map +1 -0
  11. package/dist/barcode/barcode-types.d.ts +29 -0
  12. package/dist/barcode/barcode-types.d.ts.map +1 -0
  13. package/dist/barcode/barcode-types.js +60 -0
  14. package/dist/barcode/barcode-types.js.map +1 -0
  15. package/dist/chart/chart-generator.d.ts +17 -0
  16. package/dist/chart/chart-generator.d.ts.map +1 -0
  17. package/dist/chart/chart-generator.js +77 -0
  18. package/dist/chart/chart-generator.js.map +1 -0
  19. package/dist/chart/chart-plugin.d.ts +4 -0
  20. package/dist/chart/chart-plugin.d.ts.map +1 -0
  21. package/dist/chart/chart-plugin.js +65 -0
  22. package/dist/chart/chart-plugin.js.map +1 -0
  23. package/dist/chart/chart-types.d.ts +18 -0
  24. package/dist/chart/chart-types.d.ts.map +1 -0
  25. package/dist/chart/chart-types.js +18 -0
  26. package/dist/chart/chart-types.js.map +1 -0
  27. package/dist/container/container-plugin.d.ts +15 -0
  28. package/dist/container/container-plugin.d.ts.map +1 -0
  29. package/dist/container/container-plugin.js +190 -0
  30. package/dist/container/container-plugin.js.map +1 -0
  31. package/dist/frame/frame-plugin.d.ts +4 -0
  32. package/dist/frame/frame-plugin.d.ts.map +1 -0
  33. package/dist/frame/frame-plugin.js +52 -0
  34. package/dist/frame/frame-plugin.js.map +1 -0
  35. package/dist/frame/frame-types.d.ts +8 -0
  36. package/dist/frame/frame-types.d.ts.map +1 -0
  37. package/dist/frame/frame-types.js +17 -0
  38. package/dist/frame/frame-types.js.map +1 -0
  39. package/dist/image/image-loader.d.ts +13 -0
  40. package/dist/image/image-loader.d.ts.map +1 -0
  41. package/dist/image/image-loader.js +73 -0
  42. package/dist/image/image-loader.js.map +1 -0
  43. package/dist/image/image-plugin.d.ts +19 -0
  44. package/dist/image/image-plugin.d.ts.map +1 -0
  45. package/dist/image/image-plugin.js +112 -0
  46. package/dist/image/image-plugin.js.map +1 -0
  47. package/dist/image/svg-rasterizer.d.ts +30 -0
  48. package/dist/image/svg-rasterizer.d.ts.map +1 -0
  49. package/dist/image/svg-rasterizer.js +97 -0
  50. package/dist/image/svg-rasterizer.js.map +1 -0
  51. package/dist/index.d.ts +32 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +38 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/line/line-plugin.d.ts +11 -0
  56. package/dist/line/line-plugin.d.ts.map +1 -0
  57. package/dist/line/line-plugin.js +68 -0
  58. package/dist/line/line-plugin.js.map +1 -0
  59. package/dist/list/list-plugin.d.ts +13 -0
  60. package/dist/list/list-plugin.d.ts.map +1 -0
  61. package/dist/list/list-plugin.js +194 -0
  62. package/dist/list/list-plugin.js.map +1 -0
  63. package/dist/list/list-types.d.ts +9 -0
  64. package/dist/list/list-types.d.ts.map +1 -0
  65. package/dist/list/list-types.js +9 -0
  66. package/dist/list/list-types.js.map +1 -0
  67. package/dist/platform/base64.d.ts +7 -0
  68. package/dist/platform/base64.d.ts.map +1 -0
  69. package/dist/platform/base64.js +17 -0
  70. package/dist/platform/base64.js.map +1 -0
  71. package/dist/platform/font-store.d.ts +3 -0
  72. package/dist/platform/font-store.d.ts.map +1 -0
  73. package/dist/platform/font-store.js +8 -0
  74. package/dist/platform/font-store.js.map +1 -0
  75. package/dist/platform/fs.browser.d.ts +6 -0
  76. package/dist/platform/fs.browser.d.ts.map +1 -0
  77. package/dist/platform/fs.browser.js +10 -0
  78. package/dist/platform/fs.browser.js.map +1 -0
  79. package/dist/platform/fs.d.ts +5 -0
  80. package/dist/platform/fs.d.ts.map +1 -0
  81. package/dist/platform/fs.js +10 -0
  82. package/dist/platform/fs.js.map +1 -0
  83. package/dist/platform/init.browser.d.ts +10 -0
  84. package/dist/platform/init.browser.d.ts.map +1 -0
  85. package/dist/platform/init.browser.js +24 -0
  86. package/dist/platform/init.browser.js.map +1 -0
  87. package/dist/platform/init.d.ts +6 -0
  88. package/dist/platform/init.d.ts.map +1 -0
  89. package/dist/platform/init.js +12 -0
  90. package/dist/platform/init.js.map +1 -0
  91. package/dist/platform/svg-rasterizer.browser.d.ts +2 -0
  92. package/dist/platform/svg-rasterizer.browser.d.ts.map +1 -0
  93. package/dist/platform/svg-rasterizer.browser.js +2 -0
  94. package/dist/platform/svg-rasterizer.browser.js.map +1 -0
  95. package/dist/platform/svg-rasterizer.d.ts +2 -0
  96. package/dist/platform/svg-rasterizer.d.ts.map +1 -0
  97. package/dist/platform/svg-rasterizer.js +2 -0
  98. package/dist/platform/svg-rasterizer.js.map +1 -0
  99. package/dist/registry.d.ts +32 -0
  100. package/dist/registry.d.ts.map +1 -0
  101. package/dist/registry.js +67 -0
  102. package/dist/registry.js.map +1 -0
  103. package/dist/shape/shape-plugin.d.ts +21 -0
  104. package/dist/shape/shape-plugin.d.ts.map +1 -0
  105. package/dist/shape/shape-plugin.js +148 -0
  106. package/dist/shape/shape-plugin.js.map +1 -0
  107. package/dist/table/table-plugin.d.ts +4 -0
  108. package/dist/table/table-plugin.d.ts.map +1 -0
  109. package/dist/table/table-plugin.js +232 -0
  110. package/dist/table/table-plugin.js.map +1 -0
  111. package/dist/table/table-types.d.ts +50 -0
  112. package/dist/table/table-types.d.ts.map +1 -0
  113. package/dist/table/table-types.js +129 -0
  114. package/dist/table/table-types.js.map +1 -0
  115. package/dist/text/text-decoration.d.ts +22 -0
  116. package/dist/text/text-decoration.d.ts.map +1 -0
  117. package/dist/text/text-decoration.js +43 -0
  118. package/dist/text/text-decoration.js.map +1 -0
  119. package/dist/text/text-plugin.d.ts +9 -0
  120. package/dist/text/text-plugin.d.ts.map +1 -0
  121. package/dist/text/text-plugin.js +496 -0
  122. package/dist/text/text-plugin.js.map +1 -0
  123. package/dist/text/word-wrap.d.ts +41 -0
  124. package/dist/text/word-wrap.d.ts.map +1 -0
  125. package/dist/text/word-wrap.js +149 -0
  126. package/dist/text/word-wrap.js.map +1 -0
  127. package/dist/types.d.ts +96 -0
  128. package/dist/types.d.ts.map +1 -0
  129. package/dist/types.js +5 -0
  130. package/dist/types.js.map +1 -0
  131. package/dist/utils.d.ts +8 -0
  132. package/dist/utils.d.ts.map +1 -0
  133. package/dist/utils.js +27 -0
  134. package/dist/utils.js.map +1 -0
  135. package/package.json +62 -0
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Wrap text to fit within a given width.
3
+ *
4
+ * Splits on explicit newlines first, then wraps each paragraph.
5
+ * Words longer than maxWidth are broken at character level.
6
+ */
7
+ export function wrapText(text, font, fontSize, maxWidth, lineHeight, _options, letterSpacing) {
8
+ if (text === '') {
9
+ return {
10
+ lines: [''],
11
+ height: lineHeight,
12
+ wordsPerLine: [0],
13
+ isLastInParagraph: [true],
14
+ };
15
+ }
16
+ if (maxWidth <= 0) {
17
+ const paragraphs = text.split('\n');
18
+ return {
19
+ lines: paragraphs,
20
+ height: paragraphs.length * lineHeight,
21
+ wordsPerLine: paragraphs.map((p) => p.split(/\s+/).filter((w) => w.length > 0).length),
22
+ isLastInParagraph: paragraphs.map(() => true),
23
+ };
24
+ }
25
+ const paragraphs = text.split('\n');
26
+ const lines = [];
27
+ const wordsPerLine = [];
28
+ const isLastInParagraph = [];
29
+ for (let pIdx = 0; pIdx < paragraphs.length; pIdx++) {
30
+ const paragraph = paragraphs[pIdx];
31
+ if (paragraph === '') {
32
+ lines.push('');
33
+ wordsPerLine.push(0);
34
+ isLastInParagraph.push(true);
35
+ continue;
36
+ }
37
+ const words = paragraph.split(/\s+/).filter((w) => w.length > 0);
38
+ if (words.length === 0) {
39
+ lines.push('');
40
+ wordsPerLine.push(0);
41
+ isLastInParagraph.push(true);
42
+ continue;
43
+ }
44
+ let currentLine = '';
45
+ let currentWordCount = 0;
46
+ for (const word of words) {
47
+ const wordWidth = measureTextWidth(word, font, fontSize, letterSpacing);
48
+ if (wordWidth > maxWidth) {
49
+ // Word is longer than maxWidth — break at character level
50
+ if (currentLine) {
51
+ lines.push(currentLine);
52
+ wordsPerLine.push(currentWordCount);
53
+ isLastInParagraph.push(false);
54
+ currentLine = '';
55
+ currentWordCount = 0;
56
+ }
57
+ currentLine = breakLongWord(word, font, fontSize, maxWidth, lines, wordsPerLine, isLastInParagraph, letterSpacing);
58
+ currentWordCount = 1;
59
+ continue;
60
+ }
61
+ if (currentLine === '') {
62
+ currentLine = word;
63
+ currentWordCount = 1;
64
+ }
65
+ else {
66
+ const testLine = `${currentLine} ${word}`;
67
+ const testWidth = measureTextWidth(testLine, font, fontSize, letterSpacing);
68
+ if (testWidth <= maxWidth) {
69
+ currentLine = testLine;
70
+ currentWordCount++;
71
+ }
72
+ else {
73
+ lines.push(currentLine);
74
+ wordsPerLine.push(currentWordCount);
75
+ isLastInParagraph.push(false);
76
+ currentLine = word;
77
+ currentWordCount = 1;
78
+ }
79
+ }
80
+ }
81
+ if (currentLine !== '') {
82
+ lines.push(currentLine);
83
+ wordsPerLine.push(currentWordCount);
84
+ isLastInParagraph.push(true);
85
+ }
86
+ }
87
+ return { lines, height: lines.length * lineHeight, wordsPerLine, isLastInParagraph };
88
+ }
89
+ /**
90
+ * Break a word that exceeds maxWidth into lines at character boundaries.
91
+ * Pushes complete lines to the `lines` array and returns the remainder.
92
+ */
93
+ function breakLongWord(word, font, fontSize, maxWidth, lines, wordsPerLine, isLastInParagraph, letterSpacing) {
94
+ let current = '';
95
+ for (const char of word) {
96
+ const test = current + char;
97
+ const width = measureTextWidth(test, font, fontSize, letterSpacing);
98
+ if (width > maxWidth && current.length > 0) {
99
+ lines.push(current);
100
+ wordsPerLine.push(1);
101
+ isLastInParagraph.push(false);
102
+ current = char;
103
+ }
104
+ else {
105
+ current = test;
106
+ }
107
+ }
108
+ return current;
109
+ }
110
+ /**
111
+ * Split wrapped lines into two text strings at a given line index.
112
+ * Preserves paragraph boundaries (newlines) based on `isLastInParagraph` metadata.
113
+ *
114
+ * @param lines - Wrapped lines from `wrapText()`.
115
+ * @param isLastInParagraph - Parallel array indicating paragraph endings.
116
+ * @param splitIndex - Line index at which to split (lines 0..splitIndex-1 go to fit).
117
+ * @returns Two text strings: fit (before split) and overflow (after split).
118
+ */
119
+ export function splitWrappedText(lines, isLastInParagraph, splitIndex) {
120
+ return {
121
+ fitText: joinLines(lines, isLastInParagraph, 0, splitIndex),
122
+ overflowText: joinLines(lines, isLastInParagraph, splitIndex, lines.length),
123
+ };
124
+ }
125
+ /** Join a range of wrapped lines back into text, using spaces within paragraphs and newlines between. */
126
+ function joinLines(lines, isLastInParagraph, start, end) {
127
+ if (start >= end)
128
+ return '';
129
+ let result = lines[start];
130
+ for (let i = start + 1; i < end; i++) {
131
+ // If the previous line was the last in its paragraph, join with newline
132
+ if (isLastInParagraph[i - 1]) {
133
+ result += '\n' + lines[i];
134
+ }
135
+ else {
136
+ result += ' ' + lines[i];
137
+ }
138
+ }
139
+ return result;
140
+ }
141
+ /** Measure the width of a text string, accounting for optional letter spacing. */
142
+ export function measureTextWidth(text, font, fontSize, letterSpacing) {
143
+ const base = font.widthOfTextAtSize(text, fontSize);
144
+ if (letterSpacing && text.length > 1) {
145
+ return base + letterSpacing * (text.length - 1);
146
+ }
147
+ return base;
148
+ }
149
+ //# sourceMappingURL=word-wrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"word-wrap.js","sourceRoot":"","sources":["../../src/text/word-wrap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ import type { PDFDocument, PDFFont, PDFImage, PDFPage } from 'pdf-lib';
2
+ import type { Band, Element, Style, JSONSchema, ValidationError, RichContent } from '@jsonpdf/core';
3
+ /** An embedded image with its natural dimensions. */
4
+ export interface EmbeddedImage {
5
+ image: PDFImage;
6
+ width: number;
7
+ height: number;
8
+ }
9
+ /** Cache for embedded images. Deduplicates loads for the same src. */
10
+ export interface ImageCache {
11
+ getOrEmbed(src: string, doc: PDFDocument): Promise<EmbeddedImage>;
12
+ }
13
+ /** Map of font key to embedded PDFFont. */
14
+ export type FontMap = Map<string, PDFFont>;
15
+ /** Build a font key from style properties. */
16
+ export declare function fontKey(family: string, weight: 'normal' | 'bold', style: 'normal' | 'italic'): string;
17
+ /** Context available during the measure pass. */
18
+ export interface MeasureContext {
19
+ /** Embedded fonts keyed by fontKey(). */
20
+ fonts: FontMap;
21
+ /** Available width for the element content (element width minus padding). */
22
+ availableWidth: number;
23
+ /** Available height for the element content (element height minus padding). */
24
+ availableHeight: number;
25
+ /** Resolve a named style to its full Style object. */
26
+ resolveStyle: (name: string) => Style;
27
+ /** The element's computed style (defaults + named + overrides merged). */
28
+ elementStyle: Style;
29
+ /** The pdf-lib document (needed for embedding images). */
30
+ pdfDoc: PDFDocument;
31
+ /** Image cache for deduplicating image loads. */
32
+ imageCache: ImageCache;
33
+ /** Child elements for container plugins (from Element.elements). */
34
+ children?: Element[];
35
+ /** Measure a child element's content size. Only available for container plugins. */
36
+ measureChild?: (element: Element) => Promise<{
37
+ width: number;
38
+ height: number;
39
+ }>;
40
+ /** Expand and measure nested bands. Only available for frame plugins. */
41
+ measureBands?: (bands: Band[]) => Promise<{
42
+ totalHeight: number;
43
+ }>;
44
+ }
45
+ /** Context available during the render pass. */
46
+ export interface RenderContext extends MeasureContext {
47
+ /** The pdf-lib page to draw on. */
48
+ page: PDFPage;
49
+ /** X position of the content area in pdf-lib coordinates. */
50
+ x: number;
51
+ /** Y position of the top of the content area in pdf-lib coordinates. */
52
+ y: number;
53
+ /** Content width (element width minus padding). */
54
+ width: number;
55
+ /** Content height (element height minus padding, may be measured). */
56
+ height: number;
57
+ /** Render a child element at an offset from the container's content area. */
58
+ renderChild?: (element: Element, offsetX: number, offsetY: number) => Promise<void>;
59
+ /** Expand and render nested bands within the frame's content area. Only available for frame plugins. */
60
+ renderBands?: (bands: Band[]) => Promise<void>;
61
+ /** Map from anchor ID to the PDFPage it appears on. For internal "#anchor" links. */
62
+ anchorPageMap?: Map<string, PDFPage>;
63
+ /** Opacity for this element (0-1). Plugins should pass this to pdf-lib draw calls. */
64
+ opacity?: number;
65
+ /** Register a footnote and return the footnote number. Only available during the render pass. */
66
+ footnoteMarker?: (content: RichContent) => number;
67
+ }
68
+ /** An element plugin that can measure and render a specific element type. */
69
+ export interface Plugin<TProps = Record<string, unknown>> {
70
+ /** Unique plugin type identifier (e.g., 'text', 'line', 'list'). */
71
+ type: string;
72
+ /** JSON Schema that validates element.properties for this plugin. */
73
+ propsSchema: JSONSchema;
74
+ /** Default properties. */
75
+ defaultProps: TProps;
76
+ /** Merge raw element properties with defaults to produce typed props. */
77
+ resolveProps(raw: Record<string, unknown>): TProps;
78
+ /** Custom validation beyond JSON Schema. */
79
+ validate(props: TProps): ValidationError[];
80
+ /** Measure content size (for autoHeight). */
81
+ measure(props: TProps, ctx: MeasureContext): Promise<{
82
+ width: number;
83
+ height: number;
84
+ }>;
85
+ /** Render the element onto a PDF page. */
86
+ render(props: TProps, ctx: RenderContext): Promise<void>;
87
+ /** Whether this plugin supports splitting across page boundaries. */
88
+ canSplit?: boolean;
89
+ /** Split the element into two parts that fit within availableHeight.
90
+ * Returns null if the element cannot be meaningfully split. */
91
+ split?: (props: TProps, ctx: MeasureContext, availableHeight: number) => Promise<{
92
+ fit: TProps;
93
+ overflow: TProps;
94
+ } | null>;
95
+ }
96
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /** Build a font key from style properties. */
2
+ export function fontKey(family, weight, style) {
3
+ return `${family}:${weight}:${style}`;
4
+ }
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAkBA,8CAA8C;AAC9C,MAAM,UAAU,OAAO,CACrB,MAAc,EACd,MAAyB,EACzB,KAA0B;IAE1B,OAAO,GAAG,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;AACxC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { PDFFont } from 'pdf-lib';
2
+ import type { Style } from '@jsonpdf/core';
3
+ import type { FontMap } from './types.js';
4
+ /** Resolve a font from the FontMap based on style properties. Falls back to same family, then first available. */
5
+ export declare function getFont(fonts: FontMap, style: Style): PDFFont;
6
+ /** Compute line height from style properties. */
7
+ export declare function getLineHeight(style: Style): number;
8
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,kHAAkH;AAClH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAiB7D;AAED,iDAAiD;AACjD,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAElD"}
package/dist/utils.js ADDED
@@ -0,0 +1,27 @@
1
+ import { fontKey } from './types.js';
2
+ /** Resolve a font from the FontMap based on style properties. Falls back to same family, then first available. */
3
+ export function getFont(fonts, style) {
4
+ if (!style.fontFamily) {
5
+ throw new Error('fontFamily is missing — style was not resolved before calling getFont');
6
+ }
7
+ const key = fontKey(style.fontFamily, style.fontWeight ?? 'normal', style.fontStyle ?? 'normal');
8
+ const found = fonts.get(key);
9
+ if (found)
10
+ return found;
11
+ // Fallback: same family, any weight/style variant (case-insensitive)
12
+ const prefix = style.fontFamily.toLowerCase() + ':';
13
+ for (const [k, font] of fonts) {
14
+ if (k.toLowerCase().startsWith(prefix))
15
+ return font;
16
+ }
17
+ // Last resort: first available font in the map
18
+ for (const font of fonts.values()) {
19
+ return font;
20
+ }
21
+ throw new Error('No fonts available in FontMap');
22
+ }
23
+ /** Compute line height from style properties. */
24
+ export function getLineHeight(style) {
25
+ return (style.fontSize ?? 12) * (style.lineHeight ?? 1.2);
26
+ }
27
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,kHAAkH;AAClH,MAAM,UAAU,OAAO,CAAC,KAAc,EAAE,KAAY;IAClD,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;IAC3F,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,QAAQ,EAAE,KAAK,CAAC,SAAS,IAAI,QAAQ,CAAC,CAAC;IACjG,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,qEAAqE;IACrE,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC;IACpD,KAAK,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;QAC9B,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;IACtD,CAAC;IACD,+CAA+C;IAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;AACnD,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,aAAa,CAAC,KAAY;IACxC,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC;AAC5D,CAAC"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@jsonpdf/plugins",
3
+ "version": "0.1.0-alpha.1",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "import": "./dist/index.js"
9
+ }
10
+ },
11
+ "imports": {
12
+ "#platform/fs": {
13
+ "browser": {
14
+ "types": "./dist/platform/fs.browser.d.ts",
15
+ "default": "./dist/platform/fs.browser.js"
16
+ },
17
+ "default": {
18
+ "types": "./dist/platform/fs.d.ts",
19
+ "default": "./dist/platform/fs.js"
20
+ }
21
+ },
22
+ "#platform/svg-rasterizer": {
23
+ "browser": {
24
+ "types": "./dist/platform/svg-rasterizer.browser.d.ts",
25
+ "default": "./dist/platform/svg-rasterizer.browser.js"
26
+ },
27
+ "default": {
28
+ "types": "./dist/platform/svg-rasterizer.d.ts",
29
+ "default": "./dist/platform/svg-rasterizer.js"
30
+ }
31
+ },
32
+ "#platform/init": {
33
+ "browser": {
34
+ "types": "./dist/platform/init.browser.d.ts",
35
+ "default": "./dist/platform/init.browser.js"
36
+ },
37
+ "default": {
38
+ "types": "./dist/platform/init.d.ts",
39
+ "default": "./dist/platform/init.js"
40
+ }
41
+ }
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "files": [
47
+ "dist"
48
+ ],
49
+ "dependencies": {
50
+ "@resvg/resvg-js": "^2.6.2",
51
+ "@resvg/resvg-wasm": "^2.6.2",
52
+ "bwip-js": "^4.8.0",
53
+ "pdf-lib": "^1.17.1",
54
+ "vega": "^6.2.0",
55
+ "vega-lite": "^6.4.2",
56
+ "@jsonpdf/core": "0.1.0-alpha.1"
57
+ },
58
+ "scripts": {
59
+ "build": "tsc --build",
60
+ "typecheck": "tsc --build --noEmit"
61
+ }
62
+ }