@plasius/images 1.0.0 → 1.0.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.
- package/CHANGELOG.md +16 -1
- package/dist/index.cjs +225 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +27 -0
- package/dist/index.d.ts +27 -2
- package/dist/index.js +186 -1
- package/dist/index.js.map +1 -0
- package/docs/adrs/index.md +4 -0
- package/package.json +6 -7
- package/dist/detectFormat.d.ts +0 -2
- package/dist/detectFormat.d.ts.map +0 -1
- package/dist/detectFormat.js +0 -20
- package/dist/index.d.ts.map +0 -1
- package/dist/parse/index.d.ts +0 -5
- package/dist/parse/index.d.ts.map +0 -1
- package/dist/parse/index.js +0 -4
- package/dist/parse/parseJpeg.d.ts +0 -5
- package/dist/parse/parseJpeg.d.ts.map +0 -1
- package/dist/parse/parseJpeg.js +0 -18
- package/dist/parse/parsePng.d.ts +0 -5
- package/dist/parse/parsePng.d.ts.map +0 -1
- package/dist/parse/parsePng.js +0 -6
- package/dist/parse/parseSVG.d.ts +0 -5
- package/dist/parse/parseSVG.d.ts.map +0 -1
- package/dist/parse/parseSVG.js +0 -23
- package/dist/parse/parseWebp.d.ts +0 -5
- package/dist/parse/parseWebp.d.ts.map +0 -1
- package/dist/parse/parseWebp.js +0 -17
- package/dist/validators/avatarValidator.d.ts +0 -9
- package/dist/validators/avatarValidator.d.ts.map +0 -1
- package/dist/validators/avatarValidator.js +0 -51
- package/dist/validators/index.d.ts +0 -3
- package/dist/validators/index.d.ts.map +0 -1
- package/dist/validators/index.js +0 -2
- package/dist/validators/svgValidator.d.ts +0 -18
- package/dist/validators/svgValidator.d.ts.map +0 -1
- package/dist/validators/svgValidator.js +0 -139
- package/dist-cjs/detectFormat.d.ts +0 -2
- package/dist-cjs/detectFormat.d.ts.map +0 -1
- package/dist-cjs/detectFormat.js +0 -23
- package/dist-cjs/index.d.ts +0 -2
- package/dist-cjs/index.d.ts.map +0 -1
- package/dist-cjs/index.js +0 -17
- package/dist-cjs/parse/index.d.ts +0 -5
- package/dist-cjs/parse/index.d.ts.map +0 -1
- package/dist-cjs/parse/index.js +0 -20
- package/dist-cjs/parse/parseJpeg.d.ts +0 -5
- package/dist-cjs/parse/parseJpeg.d.ts.map +0 -1
- package/dist-cjs/parse/parseJpeg.js +0 -21
- package/dist-cjs/parse/parsePng.d.ts +0 -5
- package/dist-cjs/parse/parsePng.d.ts.map +0 -1
- package/dist-cjs/parse/parsePng.js +0 -9
- package/dist-cjs/parse/parseSVG.d.ts +0 -5
- package/dist-cjs/parse/parseSVG.d.ts.map +0 -1
- package/dist-cjs/parse/parseSVG.js +0 -26
- package/dist-cjs/parse/parseWebp.d.ts +0 -5
- package/dist-cjs/parse/parseWebp.d.ts.map +0 -1
- package/dist-cjs/parse/parseWebp.js +0 -20
- package/dist-cjs/validators/avatarValidator.d.ts +0 -9
- package/dist-cjs/validators/avatarValidator.d.ts.map +0 -1
- package/dist-cjs/validators/avatarValidator.js +0 -57
- package/dist-cjs/validators/index.d.ts +0 -3
- package/dist-cjs/validators/index.d.ts.map +0 -1
- package/dist-cjs/validators/index.js +0 -18
- package/dist-cjs/validators/svgValidator.d.ts +0 -18
- package/dist-cjs/validators/svgValidator.d.ts.map +0 -1
- package/dist-cjs/validators/svgValidator.js +0 -143
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./svgValidator.js"), exports);
|
|
18
|
-
__exportStar(require("./avatarValidator.js"), exports);
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { ImageValidationResult } from "./avatarValidator.js";
|
|
2
|
-
export declare function sanitiseSVG(svgText: string, options: {
|
|
3
|
-
allowedTags: string[];
|
|
4
|
-
allowedAttributes: {
|
|
5
|
-
"*": string[];
|
|
6
|
-
};
|
|
7
|
-
allowComments: boolean;
|
|
8
|
-
allowUnknownElements: boolean;
|
|
9
|
-
allowUnknownAttributes: boolean;
|
|
10
|
-
}): {
|
|
11
|
-
svg: string;
|
|
12
|
-
audit: {
|
|
13
|
-
strippedTags: string[];
|
|
14
|
-
strippedAttributes: string[];
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
export declare function validateSvgAvatar(buffer: Buffer): Promise<ImageValidationResult>;
|
|
18
|
-
//# sourceMappingURL=svgValidator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"svgValidator.d.ts","sourceRoot":"","sources":["../../src/validators/svgValidator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAIlE,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iBAAiB,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACrC,aAAa,EAAE,OAAO,CAAC;IACvB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,sBAAsB,EAAE,OAAO,CAAC;CACjC,GACA;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE;QAAE,YAAY,EAAE,MAAM,EAAE,CAAC;QAAC,kBAAkB,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACjE,CA+FA;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,qBAAqB,CAAC,CAkEhC"}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sanitiseSVG = sanitiseSVG;
|
|
4
|
-
exports.validateSvgAvatar = validateSvgAvatar;
|
|
5
|
-
const xmldom_1 = require("@xmldom/xmldom");
|
|
6
|
-
function sanitiseSVG(svgText, options) {
|
|
7
|
-
const strippedTags = [];
|
|
8
|
-
const strippedAttributes = [];
|
|
9
|
-
const parser = new xmldom_1.DOMParser({
|
|
10
|
-
onError: (level, msg) => {
|
|
11
|
-
switch (level) {
|
|
12
|
-
case "warning":
|
|
13
|
-
break;
|
|
14
|
-
default:
|
|
15
|
-
throw new Error(msg);
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
});
|
|
19
|
-
const serializer = new xmldom_1.XMLSerializer();
|
|
20
|
-
const doc = parser.parseFromString(svgText, "image/svg+xml");
|
|
21
|
-
function cleanNode(node) {
|
|
22
|
-
// TODO: optionally sanitize <style> elements and inline style attributes
|
|
23
|
-
if (node === null)
|
|
24
|
-
return;
|
|
25
|
-
if (node.nodeType === 8 /* Comment */ && !options.allowComments) {
|
|
26
|
-
node.parentNode?.removeChild(node);
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
if (node.nodeType === 1 /* Element */) {
|
|
30
|
-
const el = node;
|
|
31
|
-
const tagName = el.tagName.toLowerCase();
|
|
32
|
-
// Strip <style> elements entirely
|
|
33
|
-
if (tagName === "style") {
|
|
34
|
-
strippedTags.push(tagName);
|
|
35
|
-
node.parentNode?.removeChild(node);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
if (!options.allowedTags.includes(tagName) &&
|
|
39
|
-
!options.allowUnknownElements) {
|
|
40
|
-
strippedTags.push(tagName);
|
|
41
|
-
node.parentNode?.removeChild(node);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
// Clean attributes
|
|
45
|
-
const allowedAttrs = options.allowedAttributes["*"] || [];
|
|
46
|
-
const toRemove = [];
|
|
47
|
-
for (const attr of Array.from(el.attributes)) {
|
|
48
|
-
const attrName = attr.name.toLowerCase();
|
|
49
|
-
if (attrName.startsWith("on")) {
|
|
50
|
-
toRemove.push(attr.name);
|
|
51
|
-
strippedAttributes.push(`${tagName}.${attr.name}`);
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
if (attrName === "xlink:href" || attrName === "xmlns:xlink") {
|
|
55
|
-
toRemove.push(attr.name);
|
|
56
|
-
strippedAttributes.push(`${tagName}.${attr.name}`);
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
if (attrName === "style") {
|
|
60
|
-
toRemove.push(attr.name);
|
|
61
|
-
strippedAttributes.push(`${tagName}.${attr.name}`);
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
if (!allowedAttrs.includes(attr.name) &&
|
|
65
|
-
!options.allowUnknownAttributes) {
|
|
66
|
-
toRemove.push(attr.name);
|
|
67
|
-
strippedAttributes.push(`${tagName}.${attr.name}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
toRemove.forEach((attrName) => el.removeAttribute(attrName));
|
|
71
|
-
}
|
|
72
|
-
// Recursively clean children
|
|
73
|
-
const children = Array.from(node.childNodes);
|
|
74
|
-
children.forEach((child) => cleanNode(child));
|
|
75
|
-
}
|
|
76
|
-
cleanNode(doc.documentElement);
|
|
77
|
-
return {
|
|
78
|
-
svg: serializer.serializeToString(doc),
|
|
79
|
-
audit: { strippedTags, strippedAttributes },
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
function validateSvgAvatar(buffer) {
|
|
83
|
-
const svgText = buffer.toString("utf8");
|
|
84
|
-
const { svg: cleanSvg } = sanitiseSVG(svgText, {
|
|
85
|
-
allowedTags: [
|
|
86
|
-
"svg",
|
|
87
|
-
"g",
|
|
88
|
-
"rect",
|
|
89
|
-
"circle",
|
|
90
|
-
"ellipse",
|
|
91
|
-
"line",
|
|
92
|
-
"polygon",
|
|
93
|
-
"polyline",
|
|
94
|
-
"path",
|
|
95
|
-
"text",
|
|
96
|
-
"title",
|
|
97
|
-
"desc",
|
|
98
|
-
],
|
|
99
|
-
allowedAttributes: {
|
|
100
|
-
"*": [
|
|
101
|
-
"width",
|
|
102
|
-
"height",
|
|
103
|
-
"viewBox",
|
|
104
|
-
"xmlns",
|
|
105
|
-
"transform",
|
|
106
|
-
"x",
|
|
107
|
-
"y",
|
|
108
|
-
"cx",
|
|
109
|
-
"cy",
|
|
110
|
-
"r",
|
|
111
|
-
"rx",
|
|
112
|
-
"ry",
|
|
113
|
-
"x1",
|
|
114
|
-
"y1",
|
|
115
|
-
"x2",
|
|
116
|
-
"y2",
|
|
117
|
-
"points",
|
|
118
|
-
"d",
|
|
119
|
-
"fill",
|
|
120
|
-
"stroke",
|
|
121
|
-
"stroke-width",
|
|
122
|
-
"font-family",
|
|
123
|
-
"font-size",
|
|
124
|
-
"text-anchor",
|
|
125
|
-
],
|
|
126
|
-
},
|
|
127
|
-
allowComments: false,
|
|
128
|
-
allowUnknownElements: false,
|
|
129
|
-
allowUnknownAttributes: false,
|
|
130
|
-
});
|
|
131
|
-
const cleanBuffer = Buffer.from(cleanSvg, "utf8");
|
|
132
|
-
// Basic sanity checks
|
|
133
|
-
if (cleanBuffer.length > 256 * 1024) {
|
|
134
|
-
throw new Error("SVG too large (max 256 KB)");
|
|
135
|
-
}
|
|
136
|
-
return Promise.resolve({
|
|
137
|
-
width: 0, // SVG is scalable, can’t guarantee pixel dimensions
|
|
138
|
-
height: 0,
|
|
139
|
-
format: "svg",
|
|
140
|
-
size: cleanBuffer.length,
|
|
141
|
-
safeBuffer: cleanBuffer,
|
|
142
|
-
});
|
|
143
|
-
}
|