skia-canvas 3.0.2 → 3.0.4
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/lib/classes/imagery.js +7 -41
- package/lib/prebuild.mjs +18 -12
- package/lib/urls.js +61 -0
- package/package.json +12 -12
- package/lib/fetch.js +0 -4
package/lib/classes/imagery.js
CHANGED
|
@@ -5,10 +5,9 @@
|
|
|
5
5
|
"use strict"
|
|
6
6
|
|
|
7
7
|
const {RustClass, core, readOnly, inspect, neon, argc, REPR} = require('./neon'),
|
|
8
|
-
{
|
|
8
|
+
{fetchURL, decodeDataURL, expandURL} = require('../urls'),
|
|
9
9
|
{EventEmitter} = require('events'),
|
|
10
|
-
{readFile} = require('fs/promises')
|
|
11
|
-
url = require('url')
|
|
10
|
+
{readFile} = require('fs/promises')
|
|
12
11
|
|
|
13
12
|
//
|
|
14
13
|
// Image
|
|
@@ -35,7 +34,7 @@ class Image extends RustClass {
|
|
|
35
34
|
constructor(data, src='') {
|
|
36
35
|
super(Image).alloc()
|
|
37
36
|
|
|
38
|
-
data =
|
|
37
|
+
data = expandURL(data)
|
|
39
38
|
this.prop("src", ''+src || '::Buffer::')
|
|
40
39
|
|
|
41
40
|
if (Buffer.isBuffer(data)) {
|
|
@@ -94,7 +93,7 @@ class Image extends RustClass {
|
|
|
94
93
|
}
|
|
95
94
|
}
|
|
96
95
|
|
|
97
|
-
src =
|
|
96
|
+
src = expandURL(src)
|
|
98
97
|
this.prop("src", typeof src=='string' ? src : '')
|
|
99
98
|
|
|
100
99
|
fetchData(src, undefined, loaded, failed)
|
|
@@ -221,41 +220,8 @@ function isSharpImage(obj){
|
|
|
221
220
|
}
|
|
222
221
|
}
|
|
223
222
|
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
let [header, mime, enc] = dataURL.slice(0, 40).match(/^\s*data:(?<mime>[^;]*);(?:charset=)?(?<enc>[^,]*),/) || []
|
|
227
|
-
if (!mime || !enc) return fail(TypeError(`Expected a valid data URL string (got: "${dataURL}")`))
|
|
228
|
-
|
|
229
|
-
// SVGs in particular may not be base64 encoded
|
|
230
|
-
let content = dataURL.slice(header.length)
|
|
231
|
-
if (enc.toLowerCase() != 'base64') content = decodeURIComponent(content)
|
|
232
|
-
|
|
233
|
-
try{ ok(Buffer.from(content, enc)) }
|
|
234
|
-
catch(e){ fail(e) }
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const fetchURL = (url, fetchOpts, ok, fail) => {
|
|
238
|
-
fetch(url, fetchOpts)
|
|
239
|
-
.then(resp => {
|
|
240
|
-
if (resp.ok) return resp.arrayBuffer()
|
|
241
|
-
else throw new Error(`Failed to load image from "${url}" (HTTP error ${resp.status})`)
|
|
242
|
-
})
|
|
243
|
-
.then(buf => ok(Buffer.from(buf)))
|
|
244
|
-
.catch(err => fail(err))
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const expandURLs = (src) => {
|
|
248
|
-
// convert URLs to strings, otherwise pass arg through unmodified
|
|
249
|
-
if (src instanceof URL){
|
|
250
|
-
if (src.protocol=='file:') src = url.fileURLToPath(src)
|
|
251
|
-
else if (src.protocol.match(/^(https?|data):/)) src = src.href
|
|
252
|
-
else throw Error(`Unsupported protocol: ${src.protocol.replace(':', '')}`)
|
|
253
|
-
}
|
|
254
|
-
return src
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const fetchData = (src, fetchOpts, loaded, failed) => {
|
|
258
|
-
src = expandURLs(src)
|
|
223
|
+
const fetchData = (src, reqOpts, loaded, failed) => {
|
|
224
|
+
src = expandURL(src)
|
|
259
225
|
if (Buffer.isBuffer(src)) {
|
|
260
226
|
loaded(src, '::Buffer::')
|
|
261
227
|
}else if (isSharpImage(src)){
|
|
@@ -272,7 +238,7 @@ const fetchData = (src, fetchOpts, loaded, failed) => {
|
|
|
272
238
|
err => failed(err),
|
|
273
239
|
)
|
|
274
240
|
}else if (/^\s*https?:\/\//.test(src)){
|
|
275
|
-
fetchURL(src,
|
|
241
|
+
fetchURL(src, reqOpts,
|
|
276
242
|
buffer => loaded(buffer, src),
|
|
277
243
|
err => failed(err)
|
|
278
244
|
)
|
package/lib/prebuild.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import {readFile, writeFile, rm} from 'fs/promises'
|
|
|
7
7
|
import {resolve} from 'path'
|
|
8
8
|
import {promisify} from 'util'
|
|
9
9
|
import {family} from 'detect-libc'
|
|
10
|
-
import
|
|
10
|
+
import https from 'follow-redirects/https.js'
|
|
11
11
|
import {HttpsProxyAgent} from 'https-proxy-agent'
|
|
12
12
|
|
|
13
13
|
const pipeline = promisify(stream.pipeline)
|
|
@@ -18,7 +18,10 @@ const REPO_URL = "https://github.com/samizdatco/skia-canvas"
|
|
|
18
18
|
const BINARY_HOST = `${REPO_URL}/releases/download`
|
|
19
19
|
const BINARY_PATH = `${ROOT}/lib/skia.node`
|
|
20
20
|
const PACKAGE_JSON = `${ROOT}/package.json`
|
|
21
|
-
const PROXY_URL =
|
|
21
|
+
const PROXY_URL =
|
|
22
|
+
process.env.https_proxy || process.env.HTTPS_PROXY ||
|
|
23
|
+
process.env.http_proxy || process.env.HTTP_PROXY ||
|
|
24
|
+
process.env.npm_config_https_proxy || process.env.npm_config_proxy
|
|
22
25
|
|
|
23
26
|
const CARGO_FEATURES = {
|
|
24
27
|
darwin: "metal,window",
|
|
@@ -80,16 +83,18 @@ async function download(...args){
|
|
|
80
83
|
|
|
81
84
|
let {version, triplet, prebuild} = await config(),
|
|
82
85
|
url = `${BINARY_HOST}/v${version}/${triplet}.gz`,
|
|
83
|
-
agent = PROXY_URL ? new HttpsProxyAgent(
|
|
86
|
+
agent = PROXY_URL ? new HttpsProxyAgent(PROXY_URL) : undefined
|
|
84
87
|
|
|
85
88
|
try{
|
|
86
|
-
let
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
let body = await new Promise((res, rej) => {
|
|
90
|
+
https.get(url, {agent}, resp => {
|
|
91
|
+
let {statusCode:status} = resp
|
|
92
|
+
if (status == 404) rej(`Prebuilt library not found at "${url}" (HTTP error ${status})`)
|
|
93
|
+
else if (status < 200 || status >= 300) rej(`Failed to load prebuilt binary from "${url}" (HTTP error ${status})`)
|
|
94
|
+
else res(resp)
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
console.log(`Fetched prebuilt libary from "${url}"`)
|
|
93
98
|
|
|
94
99
|
// write to /lib/skia.node while also hashing the .gz file
|
|
95
100
|
let sha = new Hasher()
|
|
@@ -113,8 +118,9 @@ async function download(...args){
|
|
|
113
118
|
}
|
|
114
119
|
|
|
115
120
|
function compile(...args){
|
|
116
|
-
let optimization = args.includes('
|
|
117
|
-
|
|
121
|
+
let optimization = args.includes('custom') || args.includes('dev') ? '' : "--release",
|
|
122
|
+
customFeatures = args.includes('custom') && (args[args.indexOf('custom')+1] || '').replace(/[^[a-z0-9\_\-\,]/g, ''),
|
|
123
|
+
features = `--features "${args.includes('custom') ? customFeatures || '' : CARGO_FEATURES}"`,
|
|
118
124
|
isFallback = args.includes('--fallback'),
|
|
119
125
|
isSrcRepo = existsSync(`${ROOT}/Cargo.toml`)
|
|
120
126
|
|
package/lib/urls.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const url = require('url'),
|
|
2
|
+
{http, https} = require('follow-redirects'),
|
|
3
|
+
{HttpsProxyAgent} = require('https-proxy-agent')
|
|
4
|
+
|
|
5
|
+
const UA = {"User-Agent": "Skia Canvas"}
|
|
6
|
+
const PROXY_URL =
|
|
7
|
+
process.env.https_proxy || process.env.HTTPS_PROXY ||
|
|
8
|
+
process.env.http_proxy || process.env.HTTP_PROXY
|
|
9
|
+
|
|
10
|
+
const fetchURL = (url, opts, ok, fail) => {
|
|
11
|
+
let proto = url.slice(0,5).split(':')[0],
|
|
12
|
+
client = {http, https}[proto.toLowerCase()]
|
|
13
|
+
|
|
14
|
+
if (!client){
|
|
15
|
+
fail(new Error(`Unsupported protocol: expected 'http' or 'https' (got: ${proto})`))
|
|
16
|
+
}else{
|
|
17
|
+
opts = opts || {}
|
|
18
|
+
opts.headers = {...UA, ...opts.headers}
|
|
19
|
+
opts.agent = opts.agent===undefined && PROXY_URL ? new HttpsProxyAgent(PROXY_URL) : opts.agent
|
|
20
|
+
|
|
21
|
+
let req = client.request(url, opts, resp => {
|
|
22
|
+
if (resp.statusCode < 200 || resp.statusCode >= 300){
|
|
23
|
+
fail(new Error(`Failed to load image from "${url}" (HTTP error ${resp.statusCode})`))
|
|
24
|
+
}else{
|
|
25
|
+
const chunks = []
|
|
26
|
+
resp.on("data", chunk => chunks.push(chunk))
|
|
27
|
+
resp.on("end", () => ok(Buffer.concat(chunks)))
|
|
28
|
+
resp.on('error', e => fail(e))
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
req.on('error', e => fail(e))
|
|
33
|
+
if (opts.body) req.write(opts.body)
|
|
34
|
+
req.end()
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const decodeDataURL = (dataURL, ok, fail) => {
|
|
39
|
+
if (typeof dataURL!='string') return fail(TypeError(`Expected a data URL string (got ${typeof dataURL})`))
|
|
40
|
+
let [header, mime, enc] = dataURL.slice(0, 40).match(/^\s*data:(?<mime>[^;]*);(?:charset=)?(?<enc>[^,]*),/) || []
|
|
41
|
+
if (!mime || !enc) return fail(TypeError(`Expected a valid data URL string (got: "${dataURL}")`))
|
|
42
|
+
|
|
43
|
+
// SVGs in particular may not be base64 encoded
|
|
44
|
+
let content = dataURL.slice(header.length)
|
|
45
|
+
if (enc.toLowerCase() != 'base64') content = decodeURIComponent(content)
|
|
46
|
+
|
|
47
|
+
try{ ok(Buffer.from(content, enc)) }
|
|
48
|
+
catch(e){ fail(e) }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const expandURL = (src) => {
|
|
52
|
+
// convert URLs to strings, otherwise pass arg through unmodified
|
|
53
|
+
if (src instanceof URL){
|
|
54
|
+
if (src.protocol=='file:') src = url.fileURLToPath(src)
|
|
55
|
+
else if (src.protocol.match(/^(https?|data):/)) src = src.href
|
|
56
|
+
else throw Error(`Unsupported protocol: ${src.protocol.replace(':', '')}`)
|
|
57
|
+
}
|
|
58
|
+
return src
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = {fetchURL, decodeDataURL, expandURL}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skia-canvas",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.4",
|
|
4
4
|
"description": "A multi-threaded, GPU-accelerated, Canvas API for Node",
|
|
5
5
|
"author": "Christian Swinehart <drafting@samizdat.co>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"detect-libc": "^2.0.4",
|
|
32
|
+
"follow-redirects": "^1.15.11",
|
|
32
33
|
"https-proxy-agent": "^7.0.6",
|
|
33
|
-
"node-fetch": "^2.7.0",
|
|
34
34
|
"string-split-by": "^1.0.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
@@ -70,15 +70,15 @@
|
|
|
70
70
|
"rust"
|
|
71
71
|
],
|
|
72
72
|
"prebuild": {
|
|
73
|
-
"aws-lambda-arm64.zip": "sha256:
|
|
74
|
-
"aws-lambda-x64.zip": "sha256:
|
|
75
|
-
"darwin-arm64.gz": "sha256:
|
|
76
|
-
"darwin-x64.gz": "sha256:
|
|
77
|
-
"linux-arm64-glibc.gz": "sha256:
|
|
78
|
-
"linux-arm64-musl.gz": "sha256:
|
|
79
|
-
"linux-x64-glibc.gz": "sha256:
|
|
80
|
-
"linux-x64-musl.gz": "sha256:
|
|
81
|
-
"win32-arm64.gz": "sha256:
|
|
82
|
-
"win32-x64.gz": "sha256:
|
|
73
|
+
"aws-lambda-arm64.zip": "sha256:7cd7d3347a8ed5a7a6a00a3dc7a05b3556a39eebd4a82c18def146dbcad415d3",
|
|
74
|
+
"aws-lambda-x64.zip": "sha256:8cd71fae702245258bca77fae284793f0ee1760d44ff88ffb622200418ca48c6",
|
|
75
|
+
"darwin-arm64.gz": "sha256:d20eaf98437640f0d25dae9dd1007176ccce7a473f1ecb6294fb86de8b08901a",
|
|
76
|
+
"darwin-x64.gz": "sha256:11aa8f5fb42c79ddbf63d4e0f3e5774d2d5b9fc9d831cd267b88408379d0c163",
|
|
77
|
+
"linux-arm64-glibc.gz": "sha256:d2d70378f797972463bab191a952a5b16c126e1b951aa47f16404bea2e2042ce",
|
|
78
|
+
"linux-arm64-musl.gz": "sha256:f035ff50ada62106669deadc0e859ab07987ab1632e0176fd37cf9b68e05a575",
|
|
79
|
+
"linux-x64-glibc.gz": "sha256:b133ce5c3ddc177078d41e1570423407345f162915acbb5f68dc657df75552ba",
|
|
80
|
+
"linux-x64-musl.gz": "sha256:577ba30287b89c492d97e7af8417d613368418b068b3eb800c281f3bb69f01ec",
|
|
81
|
+
"win32-arm64.gz": "sha256:480b9598d5b1d4c1dfd13947f7d5042218851493a79470a59e5b47943941de6c",
|
|
82
|
+
"win32-x64.gz": "sha256:1bdfced1fc24e1e1af0f94809db6277b84aecb73b8aa258d42cf232fb79bc3d3"
|
|
83
83
|
}
|
|
84
84
|
}
|
package/lib/fetch.js
DELETED