@napi-rs/canvas 0.1.28 → 0.1.30

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # `skr canvas`
2
2
 
3
3
  ![CI](https://github.com/Brooooooklyn/canvas/workflows/CI/badge.svg)
4
- ![Skia Version](https://img.shields.io/badge/Skia-chrome%2Fm105-hotpink)
4
+ ![Skia Version](https://img.shields.io/badge/Skia-chrome%2Fm106-hotpink)
5
5
  [![install size](https://packagephobia.com/badge?p=@napi-rs/canvas)](https://packagephobia.com/result?p=@napi-rs/canvas)
6
6
  [![Downloads](https://img.shields.io/npm/dm/@napi-rs/canvas.svg?sanitize=true)](https://npmcharts.com/compare/@napi-rs/canvas?minimal=true)
7
7
 
@@ -41,12 +41,16 @@ npm install @napi-rs/canvas
41
41
 
42
42
  [**_cortex-a57_**](https://en.wikipedia.org/wiki/ARM_Cortex-A57) or newer CPU architecture on **Linux**.
43
43
 
44
- All `m` chips on **macOS**.
44
+ All Apple M chips on **macOS**.
45
45
 
46
46
  ### `armv7`
47
47
 
48
48
  [**_cortex-a7_**](https://en.wikipedia.org/wiki/ARM_Cortex-A7) or newer CPU architecture.
49
49
 
50
+ ### glibc
51
+
52
+ Since Skia relies on the [glibc](https://www.gnu.org/software/libc/) 2.18 API, you need to have at least glibc version >= 2.18 on your system.
53
+
50
54
  # Usage
51
55
 
52
56
  ```js
@@ -92,7 +96,7 @@ main()
92
96
  const { writeFileSync } = require('fs')
93
97
  const { join } = require('path')
94
98
 
95
- const { createCanvas, GlobalFonts } = require('../index.js')
99
+ const { createCanvas, GlobalFonts } = require('@napi-rs/canvas')
96
100
 
97
101
  GlobalFonts.registerFromPath(join(__dirname, '..', 'fonts', 'AppleColorEmoji@2x.ttf'), 'Apple Emoji')
98
102
  GlobalFonts.registerFromPath(join(__dirname, '..', '__test__', 'fonts', 'COLRv1.ttf'), 'COLRv1')
@@ -324,7 +328,7 @@ $ node scripts/build-skia.js
324
328
 
325
329
  # Install NPM packages, build the Node.js addon:
326
330
  $ npm install -g yarn
327
- $ yarn install --mode=skip=build # Here are modules are used for benchmarking and hard to install, you can skip it by specifying `--mode=skip=build`
331
+ $ yarn install --mode=skip-build # Here are modules that are used for benchmarking and are hard to install, you can skip it by specifying `--mode=skip-build`
328
332
  $ sudo dnf install clang # https://fedora.pkgs.org/34/fedora-x86_64/clang-12.0.0-0.3.rc1.fc34.x86_64.rpm.html
329
333
  $ yarn build
330
334
 
package/index.d.ts CHANGED
@@ -1,5 +1,3 @@
1
- /// <reference lib="dom" />
2
-
3
1
  // Clear all type of caches in Skia
4
2
  export function clearAllCache(): void
5
3
 
@@ -302,9 +300,58 @@ export interface SvgCanvas {
302
300
  }
303
301
 
304
302
  export interface AvifConfig {
303
+ /** 0-100 scale, 100 is lossless */
305
304
  quality?: number
305
+ /** 0-100 scale */
306
+ alphaQuality?: number
307
+ /** rav1e preset 1 (slow) 10 (fast but crappy), default is 4 */
306
308
  speed?: number
309
+ /** How many threads should be used (0 = match core count) */
307
310
  threads?: number
311
+ /** set to '4:2:0' to use chroma subsampling, default '4:4:4' */
312
+ chromaSubsampling?: ChromaSubsampling
313
+ }
314
+ /**
315
+ * https://en.wikipedia.org/wiki/Chroma_subsampling#Types_of_sampling_and_subsampling
316
+ * https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_concepts
317
+ */
318
+ export enum ChromaSubsampling {
319
+ /**
320
+ * Each of the three Y'CbCr components has the same sample rate, thus there is no chroma subsampling. This scheme is sometimes used in high-end film scanners and cinematic post-production.
321
+ * Note that "4:4:4" may instead be wrongly referring to R'G'B' color space, which implicitly also does not have any chroma subsampling (except in JPEG R'G'B' can be subsampled).
322
+ * Formats such as HDCAM SR can record 4:4:4 R'G'B' over dual-link HD-SDI.
323
+ */
324
+ Yuv444 = 0,
325
+ /**
326
+ * The two chroma components are sampled at half the horizontal sample rate of luma: the horizontal chroma resolution is halved. This reduces the bandwidth of an uncompressed video signal by one-third.
327
+ * Many high-end digital video formats and interfaces use this scheme:
328
+ * - [AVC-Intra 100](https://en.wikipedia.org/wiki/AVC-Intra)
329
+ * - [Digital Betacam](https://en.wikipedia.org/wiki/Betacam#Digital_Betacam)
330
+ * - [Betacam SX](https://en.wikipedia.org/wiki/Betacam#Betacam_SX)
331
+ * - [DVCPRO50](https://en.wikipedia.org/wiki/DV#DVCPRO) and [DVCPRO HD](https://en.wikipedia.org/wiki/DV#DVCPRO_HD)
332
+ * - [Digital-S](https://en.wikipedia.org/wiki/Digital-S)
333
+ * - [CCIR 601](https://en.wikipedia.org/wiki/Rec._601) / [Serial Digital Interface](https://en.wikipedia.org/wiki/Serial_digital_interface) / [D1](https://en.wikipedia.org/wiki/D-1_(Sony))
334
+ * - [ProRes (HQ, 422, LT, and Proxy)](https://en.wikipedia.org/wiki/Apple_ProRes)
335
+ * - [XDCAM HD422](https://en.wikipedia.org/wiki/XDCAM)
336
+ * - [Canon MXF HD422](https://en.wikipedia.org/wiki/Canon_XF-300)
337
+ */
338
+ Yuv422 = 1,
339
+ /**
340
+ * n 4:2:0, the horizontal sampling is doubled compared to 4:1:1,
341
+ * but as the **Cb** and **Cr** channels are only sampled on each alternate line in this scheme, the vertical resolution is halved.
342
+ * The data rate is thus the same.
343
+ * This fits reasonably well with the PAL color encoding system, since this has only half the vertical chrominance resolution of [NTSC](https://en.wikipedia.org/wiki/NTSC).
344
+ * It would also fit extremely well with the [SECAM](https://en.wikipedia.org/wiki/SECAM) color encoding system,
345
+ * since like that format, 4:2:0 only stores and transmits one color channel per line (the other channel being recovered from the previous line).
346
+ * However, little equipment has actually been produced that outputs a SECAM analogue video signal.
347
+ * In general, SECAM territories either have to use a PAL-capable display or a [transcoder](https://en.wikipedia.org/wiki/Transcoding) to convert the PAL signal to SECAM for display.
348
+ */
349
+ Yuv420 = 2,
350
+ /**
351
+ * What if the chroma subsampling model is 4:0:0?
352
+ * That says to use every pixel of luma data, but that each row has 0 chroma samples applied to it. The resulting image, then, is comprised solely of the luminance data—a greyscale image.
353
+ */
354
+ Yuv400 = 3,
308
355
  }
309
356
 
310
357
  export class Canvas {
package/index.js CHANGED
@@ -5,9 +5,8 @@ const {
5
5
  clearAllCache,
6
6
  CanvasRenderingContext2D,
7
7
  CanvasElement,
8
- createContext,
9
8
  SVGCanvas,
10
- Path2D,
9
+ Path: Path2D,
11
10
  ImageData,
12
11
  Image,
13
12
  CanvasPattern,
@@ -47,128 +46,9 @@ Object.defineProperty(GlobalFonts, 'has', {
47
46
  writable: false,
48
47
  })
49
48
 
50
- CanvasRenderingContext2D.prototype.createPattern = function createPattern(image, repetition) {
51
- if (image instanceof ImageData) {
52
- const pattern = new CanvasPattern(image, repetition, 0)
53
- Object.defineProperty(pattern, '_imageData', {
54
- writable: true,
55
- configurable: false,
56
- enumerable: false,
57
- value: null,
58
- })
59
- return pattern
60
- } else if (image instanceof Image) {
61
- return new CanvasPattern(image, repetition, 1)
62
- } else if (image instanceof CanvasElement || image instanceof SVGCanvas) {
63
- return new CanvasPattern(image, repetition, 2)
64
- }
65
- throw TypeError('Image should be instance of ImageData or Image')
66
- }
67
-
68
- CanvasRenderingContext2D.prototype.getImageData = function getImageData(x, y, w, h) {
69
- const data = this._getImageData(x, y, w, h)
70
- return new ImageData(data, w, h)
71
- }
72
-
73
49
  function createCanvas(width, height, flag) {
74
50
  const isSvgBackend = typeof flag !== 'undefined'
75
- const canvasElement = isSvgBackend ? new SVGCanvas(width, height) : new CanvasElement(width, height)
76
-
77
- let ctx
78
- canvasElement.getContext = function getContext(type, attr = {}) {
79
- if (type !== '2d') {
80
- throw new Error('Unsupported type')
81
- }
82
- const attrs = { alpha: true, colorSpace: 'srgb', ...attr }
83
- ctx = ctx
84
- ? ctx
85
- : isSvgBackend
86
- ? new CanvasRenderingContext2D(this.width, this.height, attrs.colorSpace, flag)
87
- : new CanvasRenderingContext2D(this.width, this.height, attrs.colorSpace)
88
- createContext(ctx, this.width, this.height, attrs)
89
-
90
- // napi can not define writable: true but enumerable: false property
91
- Object.defineProperty(ctx, '_fillStyle', {
92
- value: '#000',
93
- configurable: false,
94
- enumerable: false,
95
- writable: true,
96
- })
97
-
98
- Object.defineProperty(ctx, '_strokeStyle', {
99
- value: '#000',
100
- configurable: false,
101
- enumerable: false,
102
- writable: true,
103
- })
104
-
105
- Object.defineProperty(ctx, 'createImageData', {
106
- value: function createImageData(widthOrImage, height, attrs = {}) {
107
- if (widthOrImage instanceof ImageData) {
108
- return new ImageData(widthOrImage.data, widthOrImage.width, widthOrImage.height)
109
- }
110
- return new ImageData(widthOrImage, height, { colorSpace: 'srgb', ...attrs })
111
- },
112
- configurable: true,
113
- enumerable: false,
114
- writable: true,
115
- })
116
-
117
- Object.defineProperty(canvasElement, 'ctx', {
118
- value: ctx,
119
- enumerable: false,
120
- configurable: false,
121
- })
122
-
123
- ctx.canvas = canvasElement
124
-
125
- return ctx
126
- }
127
-
128
- const {
129
- encode: canvasEncode,
130
- encodeSync: canvasEncodeSync,
131
- toBuffer: canvasToBuffer,
132
- toDataURL: canvasToDataURL,
133
- toDataURLAsync: canvasToDataURLAsync,
134
- } = Object.getPrototypeOf(canvasElement)
135
-
136
- canvasElement.encode = function encode(type, qualityOrConfig = {}) {
137
- if (type === 'avif') {
138
- return canvasEncode.call(this, type, JSON.stringify(qualityOrConfig))
139
- }
140
- return canvasEncode.call(this, type, qualityOrConfig)
141
- }
142
-
143
- canvasElement.encodeSync = function encodeSync(type, qualityOrConfig = {}) {
144
- if (type === 'avif') {
145
- return canvasEncodeSync.call(this, type, JSON.stringify(qualityOrConfig))
146
- }
147
- return canvasEncodeSync.call(this, type, qualityOrConfig)
148
- }
149
-
150
- canvasElement.toBuffer = function toBuffer(type = 'image/png', qualityOrConfig = {}) {
151
- if (type === 'avif') {
152
- return canvasToBuffer.call(this, type, JSON.stringify(qualityOrConfig))
153
- }
154
- return canvasToBuffer.call(this, type, qualityOrConfig)
155
- }
156
-
157
- canvasElement.toDataURL = function toDataURL(type = 'image/png', qualityOrConfig = {}) {
158
- if (type === 'avif') {
159
- return canvasToDataURL.call(this, type, JSON.stringify(qualityOrConfig))
160
- }
161
- return canvasToDataURL.call(this, type, qualityOrConfig)
162
- }
163
-
164
- canvasElement.toDataURLAsync = function toDataURLAsync(type = 'image/png', qualityOrConfig = {}) {
165
- if (type === 'avif') {
166
- return canvasToDataURLAsync.call(this, type, JSON.stringify(qualityOrConfig))
167
- }
168
- return canvasToDataURLAsync.call(this, type, qualityOrConfig)
169
- }
170
-
171
- return canvasElement
51
+ return isSvgBackend ? new SVGCanvas(width, height, flag) : new CanvasElement(width, height)
172
52
  }
173
53
 
174
54
  class Canvas {
package/js-binding.js CHANGED
@@ -5,27 +5,54 @@ const { platform, arch } = process
5
5
 
6
6
  let nativeBinding = null
7
7
  let localFileExisted = false
8
- let isMusl = false
9
8
  let loadError = null
10
9
 
11
- switch (platform) {
12
- case 'android':
13
- if (arch !== 'arm64') {
14
- throw new Error(`Unsupported architecture on Android ${arch}`)
15
- }
16
- localFileExisted = existsSync(join(__dirname, 'skia.android-arm64.node'))
10
+ function isMusl() {
11
+ // For Node 10
12
+ if (!process.report || typeof process.report.getReport !== 'function') {
17
13
  try {
18
- if (localFileExisted) {
19
- nativeBinding = require('./skia.android-arm64.node')
20
- } else {
21
- nativeBinding = require('@napi-rs/canvas-android-arm64')
22
- }
14
+ return readFileSync('/usr/bin/ldd', 'utf8').includes('musl')
23
15
  } catch (e) {
24
- loadError = e
16
+ return true
17
+ }
18
+ } else {
19
+ const { glibcVersionRuntime } = process.report.getReport().header
20
+ return !glibcVersionRuntime
21
+ }
22
+ }
23
+
24
+ switch (platform) {
25
+ case 'android':
26
+ switch (arch) {
27
+ case 'arm64':
28
+ localFileExisted = existsSync(join(__dirname, 'skia.android-arm64.node'))
29
+ try {
30
+ if (localFileExisted) {
31
+ nativeBinding = require('./skia.android-arm64.node')
32
+ } else {
33
+ nativeBinding = require('@napi-rs/canvas-android-arm64')
34
+ }
35
+ } catch (e) {
36
+ loadError = e
37
+ }
38
+ break
39
+ case 'arm':
40
+ localFileExisted = existsSync(join(__dirname, 'skia.android-arm-eabi.node'))
41
+ try {
42
+ if (localFileExisted) {
43
+ nativeBinding = require('./skia.android-arm-eabi.node')
44
+ } else {
45
+ nativeBinding = require('@napi-rs/canvas-android-arm-eabi')
46
+ }
47
+ } catch (e) {
48
+ loadError = e
49
+ }
50
+ break
51
+ default:
52
+ throw new Error(`Unsupported architecture on Android ${arch}`)
25
53
  }
26
54
  break
27
55
  case 'win32':
28
- // eslint-disable-next-line sonarjs/no-nested-switch
29
56
  switch (arch) {
30
57
  case 'x64':
31
58
  localFileExisted = existsSync(join(__dirname, 'skia.win32-x64-msvc.node'))
@@ -68,7 +95,6 @@ switch (platform) {
68
95
  }
69
96
  break
70
97
  case 'darwin':
71
- // eslint-disable-next-line sonarjs/no-nested-switch
72
98
  switch (arch) {
73
99
  case 'x64':
74
100
  localFileExisted = existsSync(join(__dirname, 'skia.darwin-x64.node'))
@@ -114,11 +140,9 @@ switch (platform) {
114
140
  }
115
141
  break
116
142
  case 'linux':
117
- // eslint-disable-next-line sonarjs/no-nested-switch
118
143
  switch (arch) {
119
144
  case 'x64':
120
- isMusl = readFileSync('/usr/bin/ldd', 'utf8').includes('musl')
121
- if (isMusl) {
145
+ if (isMusl()) {
122
146
  localFileExisted = existsSync(join(__dirname, 'skia.linux-x64-musl.node'))
123
147
  try {
124
148
  if (localFileExisted) {
@@ -143,8 +167,7 @@ switch (platform) {
143
167
  }
144
168
  break
145
169
  case 'arm64':
146
- isMusl = readFileSync('/usr/bin/ldd', 'utf8').includes('musl')
147
- if (isMusl) {
170
+ if (isMusl()) {
148
171
  localFileExisted = existsSync(join(__dirname, 'skia.linux-arm64-musl.node'))
149
172
  try {
150
173
  if (localFileExisted) {
@@ -196,35 +219,39 @@ if (!nativeBinding) {
196
219
  }
197
220
 
198
221
  const {
199
- clearAllCache,
222
+ ChromaSubsampling,
223
+ SvgExportFlag,
200
224
  CanvasRenderingContext2D,
201
- CanvasElement,
202
- createContext,
203
- SVGCanvas,
204
- Path,
225
+ CanvasGradient,
205
226
  ImageData,
206
227
  Image,
207
- CanvasPattern,
208
- GlobalFonts,
209
- convertSVGTextToPath,
210
228
  PathOp,
211
229
  FillType,
212
- StrokeJoin,
213
230
  StrokeCap,
231
+ StrokeJoin,
232
+ Path,
233
+ CanvasPattern,
234
+ convertSVGTextToPath,
235
+ CanvasElement,
236
+ SVGCanvas,
237
+ clearAllCache,
238
+ GlobalFonts,
214
239
  } = nativeBinding
215
240
 
216
- module.exports.clearAllCache = clearAllCache
241
+ module.exports.ChromaSubsampling = ChromaSubsampling
242
+ module.exports.SvgExportFlag = SvgExportFlag
217
243
  module.exports.CanvasRenderingContext2D = CanvasRenderingContext2D
218
- module.exports.CanvasElement = CanvasElement
219
- module.exports.createContext = createContext
220
- module.exports.SVGCanvas = SVGCanvas
221
- module.exports.Path2D = Path
244
+ module.exports.CanvasGradient = CanvasGradient
222
245
  module.exports.ImageData = ImageData
223
246
  module.exports.Image = Image
224
- module.exports.CanvasPattern = CanvasPattern
225
- module.exports.GlobalFonts = GlobalFonts
226
- module.exports.convertSVGTextToPath = convertSVGTextToPath
227
247
  module.exports.PathOp = PathOp
228
248
  module.exports.FillType = FillType
229
- module.exports.StrokeJoin = StrokeJoin
230
249
  module.exports.StrokeCap = StrokeCap
250
+ module.exports.StrokeJoin = StrokeJoin
251
+ module.exports.Path = Path
252
+ module.exports.CanvasPattern = CanvasPattern
253
+ module.exports.convertSVGTextToPath = convertSVGTextToPath
254
+ module.exports.CanvasElement = CanvasElement
255
+ module.exports.SVGCanvas = SVGCanvas
256
+ module.exports.clearAllCache = clearAllCache
257
+ module.exports.GlobalFonts = GlobalFonts
package/load-image.js CHANGED
@@ -39,7 +39,13 @@ module.exports = async function loadImage(source, options = {}) {
39
39
  source = !(source instanceof URL) ? new URL(source) : source
40
40
  // attempt to download the remote source and construct image
41
41
  const data = await new Promise((resolve, reject) =>
42
- makeRequest(source, resolve, reject, options.maxRedirects ?? MAX_REDIRECTS, options.requestOptions),
42
+ makeRequest(
43
+ source,
44
+ resolve,
45
+ reject,
46
+ typeof options.maxRedirects === 'number' && options.maxRedirects >= 0 ? options.maxRedirects : MAX_REDIRECTS,
47
+ options.requestOptions,
48
+ ),
43
49
  )
44
50
  return createImage(data, options.alt)
45
51
  }
@@ -54,16 +60,18 @@ function makeRequest(url, resolve, reject, redirectCount, requestOptions) {
54
60
  // lazy load the lib
55
61
  const lib = isHttps ? (!https ? (https = require('https')) : https) : !http ? (http = require('http')) : http
56
62
 
57
- lib.get(url, requestOptions ?? {}, (res) => {
58
- const shouldRedirect = REDIRECT_STATUSES.has(res.statusCode) && typeof res.headers.location === 'string'
59
- if (shouldRedirect && redirectCount > 0)
60
- return makeRequest(new URL(res.headers.location), resolve, reject, redirectCount - 1, requestOptions)
61
- if (typeof res.statusCode === 'number' && (res.statusCode < 200 || res.statusCode >= 300)) {
62
- return reject(new Error(`remote source rejected with status code ${res.statusCode}`))
63
- }
63
+ lib
64
+ .get(url, requestOptions || {}, (res) => {
65
+ const shouldRedirect = REDIRECT_STATUSES.has(res.statusCode) && typeof res.headers.location === 'string'
66
+ if (shouldRedirect && redirectCount > 0)
67
+ return makeRequest(new URL(res.headers.location), resolve, reject, redirectCount - 1, requestOptions)
68
+ if (typeof res.statusCode === 'number' && (res.statusCode < 200 || res.statusCode >= 300)) {
69
+ return reject(new Error(`remote source rejected with status code ${res.statusCode}`))
70
+ }
64
71
 
65
- consumeStream(res).then(resolve, reject)
66
- })
72
+ consumeStream(res).then(resolve, reject)
73
+ })
74
+ .on('error', reject)
67
75
  }
68
76
 
69
77
  // use stream/consumers in the future?
@@ -86,6 +94,7 @@ function createImage(src, alt) {
86
94
 
87
95
  function isBufferLike(src) {
88
96
  return (
97
+ (src && src.type === 'Buffer') ||
89
98
  Array.isArray(src) ||
90
99
  src instanceof ArrayBuffer ||
91
100
  src instanceof SharedArrayBuffer ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@napi-rs/canvas",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "description": "Canvas for Node.js with skia backend",
5
5
  "main": "index.js",
6
6
  "repository": "https://github.com/Brooooooklyn/canvas.git",
@@ -49,8 +49,8 @@
49
49
  "scripts": {
50
50
  "artifacts": "napi artifacts",
51
51
  "bench": "node -r @swc-node/register benchmark/bench.ts",
52
- "build": "napi build --platform --release",
53
- "build:debug": "napi build --platform",
52
+ "build": "napi build --platform --release --js js-binding.js",
53
+ "build:debug": "napi build --platform --js js-binding.js",
54
54
  "format": "run-p format:source format:rs",
55
55
  "format:rs": "cargo fmt",
56
56
  "format:source": "prettier . -w",
@@ -65,36 +65,36 @@
65
65
  "@jimp/custom": "^0.16.1",
66
66
  "@jimp/jpeg": "^0.16.1",
67
67
  "@jimp/png": "^0.16.1",
68
- "@napi-rs/cli": "^2.9.0",
69
- "@octokit/rest": "^19.0.0",
68
+ "@napi-rs/cli": "^2.11.4",
69
+ "@octokit/rest": "^19.0.4",
70
70
  "@swc-node/register": "^1.5.1",
71
- "@types/lodash": "^4.14.182",
72
- "@types/node": "^17.0.35",
73
- "@typescript-eslint/eslint-plugin": "^5.26.0",
74
- "@typescript-eslint/parser": "^5.26.0",
75
- "ava": "^4.2.0",
71
+ "@types/lodash": "^4.14.184",
72
+ "@types/node": "^18.7.13",
73
+ "@typescript-eslint/eslint-plugin": "^5.35.1",
74
+ "@typescript-eslint/parser": "^5.35.1",
75
+ "ava": "^4.3.3",
76
76
  "benny": "^3.7.1",
77
- "canvas": "^2.9.1",
78
- "canvaskit-wasm": "^0.35.0",
77
+ "canvas": "^2.9.3",
78
+ "canvaskit-wasm": "^0.37.0",
79
79
  "colorette": "^2.0.19",
80
80
  "conventional-changelog-cli": "^2.2.2",
81
- "echarts": "^5.3.2",
82
- "eslint": "^8.16.0",
81
+ "echarts": "^5.3.3",
82
+ "eslint": "^8.22.0",
83
83
  "eslint-config-prettier": "^8.5.0",
84
84
  "eslint-plugin-import": "^2.26.0",
85
- "eslint-plugin-prettier": "^4.0.0",
85
+ "eslint-plugin-prettier": "^4.2.1",
86
86
  "eslint-plugin-sonarjs": "^0.15.0",
87
87
  "husky": "^8.0.1",
88
- "lint-staged": "^13.0.0",
88
+ "lint-staged": "^13.0.3",
89
89
  "lodash": "^4.17.21",
90
90
  "npm-run-all": "^4.1.5",
91
91
  "pinst": "^3.0.0",
92
92
  "png.js": "^0.2.1",
93
- "prettier": "^2.6.2",
93
+ "prettier": "^2.7.1",
94
94
  "pretty-bytes": "^6.0.0",
95
95
  "skia-canvas": "^1.0.0",
96
96
  "table": "^6.8.0",
97
- "typescript": "^4.7.2"
97
+ "typescript": "^4.7.4"
98
98
  },
99
99
  "lint-staged": {
100
100
  "*.@(js|ts|tsx|yml|yaml|md|json|html)": [
@@ -130,16 +130,16 @@
130
130
  "singleQuote": true,
131
131
  "arrowParens": "always"
132
132
  },
133
- "packageManager": "yarn@3.2.2",
133
+ "packageManager": "yarn@3.2.3",
134
134
  "optionalDependencies": {
135
- "@napi-rs/canvas-win32-x64-msvc": "0.1.28",
136
- "@napi-rs/canvas-darwin-x64": "0.1.28",
137
- "@napi-rs/canvas-linux-x64-gnu": "0.1.28",
138
- "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.28",
139
- "@napi-rs/canvas-linux-x64-musl": "0.1.28",
140
- "@napi-rs/canvas-linux-arm64-gnu": "0.1.28",
141
- "@napi-rs/canvas-linux-arm64-musl": "0.1.28",
142
- "@napi-rs/canvas-darwin-arm64": "0.1.28",
143
- "@napi-rs/canvas-android-arm64": "0.1.28"
135
+ "@napi-rs/canvas-win32-x64-msvc": "0.1.30",
136
+ "@napi-rs/canvas-darwin-x64": "0.1.30",
137
+ "@napi-rs/canvas-linux-x64-gnu": "0.1.30",
138
+ "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.30",
139
+ "@napi-rs/canvas-linux-x64-musl": "0.1.30",
140
+ "@napi-rs/canvas-linux-arm64-gnu": "0.1.30",
141
+ "@napi-rs/canvas-linux-arm64-musl": "0.1.30",
142
+ "@napi-rs/canvas-darwin-arm64": "0.1.30",
143
+ "@napi-rs/canvas-android-arm64": "0.1.30"
144
144
  }
145
145
  }