headless-svg-to-excalidraw 0.0.9 → 0.0.11

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/index.d.mts CHANGED
@@ -1,8 +1,153 @@
1
+ //#region src/types.d.ts
2
+ declare const FONT_FAMILY: {
3
+ readonly 1: "Virgil";
4
+ readonly 2: "Helvetica";
5
+ readonly 3: "Cascadia";
6
+ };
7
+ declare type RoughPoint = [number, number];
8
+ type Point$1 = Readonly<RoughPoint>;
9
+ type FillStyle = "hachure" | "cross-hatch" | "solid";
10
+ type FontFamily = keyof typeof FONT_FAMILY;
11
+ type GroupId = string;
12
+ type StrokeSharpness = "round" | "sharp";
13
+ type StrokeStyle = "solid" | "dashed" | "dotted";
14
+ type TextAlign = "left" | "center" | "right";
15
+ type VerticalAlign = "top" | "middle";
16
+ type _ExcalidrawElementBase = Readonly<{
17
+ id: string;
18
+ x: number;
19
+ y: number;
20
+ strokeColor: string;
21
+ backgroundColor: string;
22
+ fillStyle: FillStyle;
23
+ strokeWidth: number;
24
+ strokeStyle: StrokeStyle;
25
+ strokeSharpness: StrokeSharpness;
26
+ roughness: number;
27
+ opacity: number;
28
+ width: number;
29
+ height: number;
30
+ angle: number;
31
+ /** Random integer used to seed shape generation so that the roughjs shape
32
+ doesn't differ across renders. */
33
+ seed: number;
34
+ /** Integer that is sequentially incremented on each change. Used to reconcile
35
+ elements during collaboration or when saving to server. */
36
+ version: number;
37
+ /** Random integer that is regenerated on each change.
38
+ Used for deterministic reconciliation of updates during collaboration,
39
+ in case the versions (see above) are identical. */
40
+ versionNonce: number;
41
+ isDeleted: boolean;
42
+ /** List of groups the element belongs to.
43
+ Ordered from deepest to shallowest. */
44
+ groupIds: readonly GroupId[]; /** Ids of (linear) elements that are bound to this element. */
45
+ boundElementIds: readonly ExcalidrawLinearElement["id"][] | null;
46
+ }>;
47
+ type ExcalidrawRectangleElement = _ExcalidrawElementBase & {
48
+ type: "rectangle";
49
+ };
50
+ type ExcalidrawDiamondElement = _ExcalidrawElementBase & {
51
+ type: "diamond";
52
+ };
53
+ type ExcalidrawEllipseElement = _ExcalidrawElementBase & {
54
+ type: "ellipse";
55
+ };
56
+ type ExcalidrawTextElement = _ExcalidrawElementBase & Readonly<{
57
+ type: "text";
58
+ fontSize: number;
59
+ fontFamily: FontFamily;
60
+ text: string;
61
+ baseline: number;
62
+ textAlign: TextAlign;
63
+ verticalAlign: VerticalAlign;
64
+ }>;
65
+ type ExcalidrawBindableElement = ExcalidrawRectangleElement | ExcalidrawDiamondElement | ExcalidrawEllipseElement | ExcalidrawTextElement;
66
+ type PointBinding = {
67
+ elementId: ExcalidrawBindableElement["id"];
68
+ focus: number;
69
+ gap: number;
70
+ };
71
+ type Arrowhead = "arrow" | "bar" | "dot";
72
+ type ExcalidrawLinearElement = _ExcalidrawElementBase & Readonly<{
73
+ type: "line" | "draw" | "arrow";
74
+ points: readonly Point$1[];
75
+ lastCommittedPoint: Point$1 | null;
76
+ startBinding: PointBinding | null;
77
+ endBinding: PointBinding | null;
78
+ startArrowhead: Arrowhead | null;
79
+ endArrowhead: Arrowhead | null;
80
+ }>;
81
+ //#endregion
82
+ //#region src/elements/ExcalidrawElement.d.ts
83
+ type Point = [number, number];
84
+ type ExcalidrawElementBase = {
85
+ id: string;
86
+ x: number;
87
+ y: number;
88
+ strokeColor: string;
89
+ backgroundColor: string;
90
+ fillStyle: FillStyle;
91
+ strokeWidth: number;
92
+ strokeStyle: StrokeStyle;
93
+ strokeSharpness: StrokeSharpness;
94
+ roughness: number;
95
+ opacity: number;
96
+ width: number;
97
+ height: number;
98
+ angle: number;
99
+ /** Random integer used to seed shape generation so that the roughjs shape
100
+ doesn't differ across renders. */
101
+ seed: number;
102
+ /** Integer that is sequentially incremented on each change. Used to reconcile
103
+ elements during collaboration or when saving to server. */
104
+ version: number;
105
+ /** Random integer that is regenerated on each change.
106
+ Used for deterministic reconciliation of updates during collaboration,
107
+ in case the versions (see above) are identical. */
108
+ versionNonce: number;
109
+ isDeleted: boolean;
110
+ /** List of groups the element belongs to.
111
+ Ordered from deepest to shallowest. */
112
+ groupIds: GroupId[]; /** Ids of (linear) elements that are bound to this element. */
113
+ boundElementIds: ExcalidrawLinearElement["id"][] | null;
114
+ };
115
+ type ExcalidrawRectangle = ExcalidrawElementBase & {
116
+ type: "rectangle";
117
+ };
118
+ type ExcalidrawLine = ExcalidrawElementBase & {
119
+ type: "line";
120
+ points: readonly Point[];
121
+ };
122
+ type ExcalidrawEllipse = ExcalidrawElementBase & {
123
+ type: "ellipse";
124
+ };
125
+ type ExcalidrawGenericElement = ExcalidrawRectangle | ExcalidrawEllipse | ExcalidrawLine | ExcalidrawDraw;
126
+ type ExcalidrawDraw = ExcalidrawElementBase & {
127
+ type: "draw";
128
+ points: readonly Point[];
129
+ };
130
+ //#endregion
131
+ //#region src/elements/ExcalidrawScene.d.ts
132
+ declare class ExcalidrawScene {
133
+ type: string;
134
+ version: number;
135
+ source: string;
136
+ elements: ExcalidrawGenericElement[];
137
+ constructor(elements?: ExcalidrawGenericElement[]);
138
+ toExJSON(): {
139
+ type: string;
140
+ version: number;
141
+ source: string;
142
+ elements: ExcalidrawGenericElement[];
143
+ };
144
+ }
145
+ //#endregion
1
146
  //#region src/parser.d.ts
2
147
  type ConversionResult = {
3
148
  hasErrors: boolean;
4
- errors: any;
5
- content: any;
149
+ errors: NodeList | null;
150
+ content: ReturnType<ExcalidrawScene["toExJSON"]> | null;
6
151
  warnings: string[];
7
152
  };
8
153
  declare const convert: (svgString: string) => ConversionResult;
package/dist/index.mjs CHANGED
@@ -1,10 +1,38 @@
1
- import { Random } from "roughjs/bin/math";
2
- import { nanoid } from "nanoid";
3
- import chroma from "chroma-js";
4
- import { mat4, vec3 } from "gl-matrix";
5
1
  import { DOMParser, parseHTML } from "linkedom";
2
+ import { mat4, vec3 } from "gl-matrix";
6
3
  import { pointsOnPath } from "points-on-path";
4
+ import chroma from "chroma-js";
5
+ import { nanoid } from "nanoid";
6
+ import { Random } from "roughjs/bin/math";
7
+
8
+ //#region src/dom.ts
9
+ /**
10
+ * DOM API provider using linkedom
11
+ * Works in browser, Node.js, and serverless/edge environments
12
+ */
13
+ const dom = parseHTML("<!DOCTYPE html>");
14
+ const DOMParser$1 = new DOMParser();
15
+ const document = dom.document;
16
+ const NodeFilter = {
17
+ SHOW_ALL: 4294967295,
18
+ SHOW_ELEMENT: 1,
19
+ SHOW_ATTRIBUTE: 2,
20
+ SHOW_TEXT: 4,
21
+ SHOW_CDATA_SECTION: 8,
22
+ SHOW_ENTITY_REFERENCE: 16,
23
+ SHOW_ENTITY: 32,
24
+ SHOW_PROCESSING_INSTRUCTION: 64,
25
+ SHOW_COMMENT: 128,
26
+ SHOW_DOCUMENT: 256,
27
+ SHOW_DOCUMENT_TYPE: 512,
28
+ SHOW_DOCUMENT_FRAGMENT: 1024,
29
+ SHOW_NOTATION: 2048,
30
+ FILTER_ACCEPT: 1,
31
+ FILTER_REJECT: 2,
32
+ FILTER_SKIP: 3
33
+ };
7
34
 
35
+ //#endregion
8
36
  //#region src/elements/ExcalidrawScene.ts
9
37
  var ExcalidrawScene = class {
10
38
  type = "excalidraw";
@@ -16,36 +44,15 @@ var ExcalidrawScene = class {
16
44
  }
17
45
  toExJSON() {
18
46
  return {
19
- ...this,
47
+ type: this.type,
48
+ version: this.version,
49
+ source: this.source,
20
50
  elements: this.elements.map((el) => ({ ...el }))
21
51
  };
22
52
  }
23
53
  };
24
54
  var ExcalidrawScene_default = ExcalidrawScene;
25
55
 
26
- //#endregion
27
- //#region src/utils.ts
28
- const random = new Random(Date.now());
29
- const randomInteger = () => Math.floor(random.next() * 2 ** 31);
30
- const randomId = () => nanoid();
31
- function dimensionsFromPoints(points) {
32
- const xCoords = points.map(([x]) => x);
33
- const yCoords = points.map(([, y]) => y);
34
- const minX = Math.min(...xCoords);
35
- const minY = Math.min(...yCoords);
36
- const maxX = Math.max(...xCoords);
37
- const maxY = Math.max(...yCoords);
38
- return [maxX - minX, maxY - minY];
39
- }
40
- function getWindingOrder(points) {
41
- return points.reduce((acc, [x1, y1], idx, arr) => {
42
- const p2 = arr[idx + 1];
43
- const x2 = p2 ? p2[0] : 0;
44
- const y2 = p2 ? p2[1] : 0;
45
- return (x2 - x1) * (y2 + y1) + acc;
46
- }, 0) > 0 ? "clockwise" : "counterclockwise";
47
- }
48
-
49
56
  //#endregion
50
57
  //#region src/attributes.ts
51
58
  function hexWithAlpha(color, alpha) {
@@ -108,52 +115,27 @@ function pointsAttrToPoints(el) {
108
115
  }
109
116
 
110
117
  //#endregion
111
- //#region src/elements/Group.ts
112
- function getGroupAttrs(groups) {
113
- return groups.reduce((acc, { element }) => {
114
- const elVals = presAttrsToElementValues(element);
115
- return {
116
- ...acc,
117
- ...elVals
118
- };
119
- }, {});
118
+ //#region src/utils.ts
119
+ const random = new Random(Date.now());
120
+ const randomInteger = () => Math.floor(random.next() * 2 ** 31);
121
+ const randomId = () => nanoid();
122
+ function dimensionsFromPoints(points) {
123
+ const xCoords = points.map(([x]) => x);
124
+ const yCoords = points.map(([, y]) => y);
125
+ const minX = Math.min(...xCoords);
126
+ const minY = Math.min(...yCoords);
127
+ const maxX = Math.max(...xCoords);
128
+ const maxY = Math.max(...yCoords);
129
+ return [maxX - minX, maxY - minY];
130
+ }
131
+ function getWindingOrder(points) {
132
+ return points.reduce((acc, [x1, y1], idx, arr) => {
133
+ const p2 = arr[idx + 1];
134
+ const x2 = p2 ? p2[0] : 0;
135
+ const y2 = p2 ? p2[1] : 0;
136
+ return (x2 - x1) * (y2 + y1) + acc;
137
+ }, 0) > 0 ? "clockwise" : "counterclockwise";
120
138
  }
121
- var Group = class {
122
- id = randomId();
123
- element;
124
- constructor(element) {
125
- this.element = element;
126
- }
127
- };
128
- var Group_default = Group;
129
-
130
- //#endregion
131
- //#region src/dom.ts
132
- /**
133
- * DOM API provider using linkedom
134
- * Works in browser, Node.js, and serverless/edge environments
135
- */
136
- const dom = parseHTML("<!DOCTYPE html>");
137
- const DOMParser$1 = new DOMParser();
138
- const document = dom.document;
139
- const NodeFilter = {
140
- SHOW_ALL: 4294967295,
141
- SHOW_ELEMENT: 1,
142
- SHOW_ATTRIBUTE: 2,
143
- SHOW_TEXT: 4,
144
- SHOW_CDATA_SECTION: 8,
145
- SHOW_ENTITY_REFERENCE: 16,
146
- SHOW_ENTITY: 32,
147
- SHOW_PROCESSING_INSTRUCTION: 64,
148
- SHOW_COMMENT: 128,
149
- SHOW_DOCUMENT: 256,
150
- SHOW_DOCUMENT_TYPE: 512,
151
- SHOW_DOCUMENT_FRAGMENT: 1024,
152
- SHOW_NOTATION: 2048,
153
- FILTER_ACCEPT: 1,
154
- FILTER_REJECT: 2,
155
- FILTER_SKIP: 3
156
- };
157
139
 
158
140
  //#endregion
159
141
  //#region src/elements/ExcalidrawElement.ts
@@ -208,6 +190,23 @@ function createExDraw() {
208
190
  };
209
191
  }
210
192
 
193
+ //#endregion
194
+ //#region src/elements/Group.ts
195
+ function getGroupAttrs(groups) {
196
+ return groups.reduce((acc, { element }) => {
197
+ const elVals = presAttrsToElementValues(element);
198
+ return Object.assign(acc, elVals);
199
+ }, {});
200
+ }
201
+ var Group = class {
202
+ id = randomId();
203
+ element;
204
+ constructor(element) {
205
+ this.element = element;
206
+ }
207
+ };
208
+ var Group_default = Group;
209
+
211
210
  //#endregion
212
211
  //#region src/transform.ts
213
212
  const transformFunctionsArr = Object.keys({
@@ -531,7 +530,7 @@ const walkers = {
531
530
  let elements = [];
532
531
  let localGroup = randomId();
533
532
  switch (fillRule) {
534
- case "nonzero":
533
+ case "nonzero": {
535
534
  let initialWindingOrder = "clockwise";
536
535
  elements = points.map((pointArr, idx) => {
537
536
  const tPoints = transformPoints(pointArr, mat4.clone(mat));
@@ -561,6 +560,7 @@ const walkers = {
561
560
  };
562
561
  });
563
562
  break;
563
+ }
564
564
  case "evenodd":
565
565
  elements = points.map((pointArr, idx) => {
566
566
  const tPoints = transformPoints(pointArr, mat4.clone(mat));
@@ -608,9 +608,9 @@ const convert = (svgString) => {
608
608
  console.error(error);
609
609
  return {
610
610
  hasErrors: true,
611
- errors: [error],
611
+ errors: null,
612
612
  content: null,
613
- warnings
613
+ warnings: [error]
614
614
  };
615
615
  }
616
616
  const svgDOM = DOMParser$1.parseFromString(svgString, "image/svg+xml");
package/package.json CHANGED
@@ -1,56 +1,55 @@
1
1
  {
2
- "name": "headless-svg-to-excalidraw",
3
- "version": "0.0.9",
4
- "description": "Convert SVG to Excalidraw's file format, no browser required.",
5
- "type": "module",
6
- "publishConfig": {
7
- "access": "public"
8
- },
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/awhiteside1/headless-svg-to-excalidraw.git"
12
- },
13
- "bugs": {
14
- "url": "https://github.com/awhiteside1/headless-svg-to-excalidraw/issues"
15
- },
16
- "homepage": "https://github.com/awhiteside1/headless-svg-to-excalidraw#readme",
17
- "exports": {
18
- ".": {
19
- "import": {
20
- "types": "./dist/index.d.mts",
21
- "default": "./dist/index.mjs"
22
- }
23
- }
24
- },
25
- "files": [
26
- "dist",
27
- "package.json"
28
- ],
29
- "scripts": {
30
- "build": "tsdown",
31
- "clean": "rm -rf dist",
32
- "typecheck": "tsc --noEmit",
33
- "test": "bun test"
34
- },
35
- "license": "MIT",
36
- "devDependencies": {
37
- "@tsconfig/bun": "^1.0.10",
38
- "@types/bun": "^1.3.7",
39
- "@types/chroma-js": "^2.1.3",
40
- "tsdown": "^0.20.1",
41
- "typescript": "^5.9.3"
42
- },
43
- "peerDependencies": {
44
- "typescript": "^4.5.5"
45
- },
46
- "dependencies": {
47
- "chroma-js": "^2.1.2",
48
- "gl-matrix": "^3.3.0",
49
- "linkedom": "^0.18.12",
50
- "nanoid": "5.0.9",
51
- "path-data-parser": "^0.1.0",
52
- "points-on-curve": "^0.2.0",
53
- "points-on-path": "^0.2.1",
54
- "roughjs": "^4.4.1"
55
- }
2
+ "name": "headless-svg-to-excalidraw",
3
+ "version": "0.0.11",
4
+ "description": "Convert SVG to Excalidraw's file format, no browser required.",
5
+ "type": "module",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "repository": "github:awhiteside1/headless-svg-to-excalidraw",
10
+ "bugs": {
11
+ "url": "https://github.com/awhiteside1/headless-svg-to-excalidraw/issues"
12
+ },
13
+ "homepage": "https://github.com/awhiteside1/headless-svg-to-excalidraw#readme",
14
+ "exports": {
15
+ ".": {
16
+ "import": {
17
+ "types": "./dist/index.d.mts",
18
+ "default": "./dist/index.mjs"
19
+ }
20
+ }
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "package.json"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsdown",
28
+ "clean": "rm -rf dist",
29
+ "typecheck": "tsc --noEmit",
30
+ "test": "bun test",
31
+ "lint": "biome check --write"
32
+ },
33
+ "license": "MIT",
34
+ "devDependencies": {
35
+ "@biomejs/biome": "^2.3.13",
36
+ "@tsconfig/bun": "^1.0.10",
37
+ "@types/bun": "^1.3.7",
38
+ "@types/chroma-js": "^2.1.3",
39
+ "tsdown": "^0.20.1",
40
+ "typescript": "^5.9.3"
41
+ },
42
+ "peerDependencies": {
43
+ "typescript": "^4.5.5"
44
+ },
45
+ "dependencies": {
46
+ "chroma-js": "^2.1.2",
47
+ "gl-matrix": "^3.3.0",
48
+ "linkedom": "^0.18.12",
49
+ "nanoid": "5.0.9",
50
+ "path-data-parser": "^0.1.0",
51
+ "points-on-curve": "^0.2.0",
52
+ "points-on-path": "^0.2.1",
53
+ "roughjs": "^4.4.1"
54
+ }
56
55
  }