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.
@@ -5,10 +5,9 @@
5
5
  "use strict"
6
6
 
7
7
  const {RustClass, core, readOnly, inspect, neon, argc, REPR} = require('./neon'),
8
- {fetch} = require('../fetch'),
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 = expandURLs(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 = expandURLs(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 decodeDataURL = (dataURL, ok, fail) => {
225
- if (typeof dataURL!='string') return fail(TypeError(`Expected a data URL string (got ${typeof dataURL})`))
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, fetchOpts,
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 {fetch} from "./fetch.js"
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 = process.env.http_proxy || process.env.HTTP_PROXY || process.env.npm_config_proxy
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(proxy) : undefined
86
+ agent = PROXY_URL ? new HttpsProxyAgent(PROXY_URL) : undefined
84
87
 
85
88
  try{
86
- let {ok, status, body} = await fetch(url, {agent})
87
- if (!ok){
88
- if (status==404) throw Error(`Prebuilt library not found at "${url}" (HTTP error ${status})`)
89
- else throw Error(`Failed to load prebuilt binary from "${url}" (HTTP error ${status})`)
90
- }else{
91
- console.log(`Fetching prebuilt libary from "${url}"`)
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('generic') || args.includes('dev') ? '' : "--release",
117
- features = args.includes('generic') ? '' : `--features ${CARGO_FEATURES}`,
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.2",
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:c9b4d687110cc2a9246cfa0688f20100828cc2f4e239ffdccb4efe45fdec0b84",
74
- "aws-lambda-x64.zip": "sha256:bdd29bf8be43f1b1d106d30e36a916406cbb0ba755d58b75dfb11f2eb2acc1dd",
75
- "darwin-arm64.gz": "sha256:4a4c3aa2729aa77faa189815354ce917361c00f99d69afde3b30ac45894eaeab",
76
- "darwin-x64.gz": "sha256:4ad7daa6d6236fe5a241ad3bf404d36b06418cb4e0f9e741deb2be2a590da52a",
77
- "linux-arm64-glibc.gz": "sha256:73b66d5a9e5cf8841b94462f313323c4bad755d7a0e8202393fac6cdb31e4db8",
78
- "linux-arm64-musl.gz": "sha256:3b704353a36428f31eaefe0870da29a1ad433272b81c1088efe770850b812609",
79
- "linux-x64-glibc.gz": "sha256:80f9f5a54c92d99cb0cc6da23d7e0c12011b2e53f3c8540864007e1e83e82f65",
80
- "linux-x64-musl.gz": "sha256:82fd698d543347ba49a531acad350dd146473c8bbac3e2c6fd137de7cdb02b01",
81
- "win32-arm64.gz": "sha256:4b7cb850e87b084c785d7412b0c466daffcd5c7e89f359aa6ee23a36ae87abbb",
82
- "win32-x64.gz": "sha256:95fdd138d2863f5fa1cf2e34947da3374f64df86eb88d0de0b3d8bee81d2a5c3"
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
@@ -1,4 +0,0 @@
1
- // rapper that exports either native fetch (on node v18+) or node-fetch (for older systems)
2
- module.exports = {
3
- fetch: global.fetch || require('node-fetch')
4
- }