@svg-rs/svgo 0.0.3 → 0.0.5

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 N-API for Rust
3
+ Copyright (c) 2025 Jacob
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,105 +1,108 @@
1
- # `@napi-rs/package-template`
1
+ # svgo-rs
2
2
 
3
- ![https://github.com/napi-rs/package-template/actions](https://github.com/napi-rs/package-template/workflows/CI/badge.svg)
3
+ `svgo-rs` is a high-performance SVG optimizer written in Rust, designed to process and optimize SVG files efficiently. It provides bindings for Node.js through NAPI-RS, making it accessible for JavaScript and TypeScript developers.
4
4
 
5
- > Template project for writing node packages with napi-rs.
5
+ ## Features
6
6
 
7
- # Usage
7
+ - Written in Rust for high performance.
8
+ - Provides plugins for various SVG optimizations, such as removing metadata, comments, and unnecessary elements.
9
+ - Supports multiple platforms with precompiled binaries.
10
+ - Easy integration with Node.js projects.
8
11
 
9
- 1. Click **Use this template**.
10
- 2. **Clone** your project.
11
- 3. Run `yarn install` to install dependencies.
12
- 4. Run `npx napi rename -n [name]` command under the project folder to rename your package.
12
+ ## Installation
13
13
 
14
- ## Install this test package
14
+ Install the package via npm:
15
15
 
16
+ ```bash
17
+ npm install @svg-rs/svgo
16
18
  ```
17
- yarn add @napi-rs/package-template
18
- ```
19
-
20
- ## Support matrix
21
-
22
- ### Operating Systems
23
-
24
- | | node14 | node16 | node18 |
25
- | ---------------- | ------ | ------ | ------ |
26
- | Windows x64 | ✓ | ✓ | ✓ |
27
- | Windows x32 | ✓ | ✓ | ✓ |
28
- | Windows arm64 | ✓ | ✓ | ✓ |
29
- | macOS x64 | ✓ | ✓ | ✓ |
30
- | macOS arm64 | ✓ | ✓ | ✓ |
31
- | Linux x64 gnu | ✓ | ✓ | ✓ |
32
- | Linux x64 musl | ✓ | ✓ | ✓ |
33
- | Linux arm gnu | ✓ | ✓ | ✓ |
34
- | Linux arm64 gnu | ✓ | ✓ | ✓ |
35
- | Linux arm64 musl | ✓ | ✓ | ✓ |
36
- | Android arm64 | ✓ | ✓ | ✓ |
37
- | Android armv7 | ✓ | ✓ | ✓ |
38
- | FreeBSD x64 | ✓ | ✓ | ✓ |
39
-
40
- ## Ability
41
-
42
- ### Build
43
-
44
- After `yarn build/npm run build` command, you can see `package-template.[darwin|win32|linux].node` file in project root. This is the native addon built from [lib.rs](./src/lib.rs).
45
-
46
- ### Test
47
-
48
- With [ava](https://github.com/avajs/ava), run `yarn test/npm run test` to testing native addon. You can also switch to another testing framework if you want.
49
-
50
- ### CI
51
-
52
- With GitHub Actions, each commit and pull request will be built and tested automatically in [`node@14`, `node@16`, `@node18`] x [`macOS`, `Linux`, `Windows`] matrix. You will never be afraid of the native addon broken in these platforms.
53
-
54
- ### Release
55
19
 
56
- Release native package is very difficult in old days. Native packages may ask developers who use it to install `build toolchain` like `gcc/llvm`, `node-gyp` or something more.
20
+ ## Usage
57
21
 
58
- With `GitHub actions`, we can easily prebuild a `binary` for major platforms. And with `N-API`, we should never be afraid of **ABI Compatible**.
22
+ ### Node.js
59
23
 
60
- The other problem is how to deliver prebuild `binary` to users. Downloading it in `postinstall` script is a common way that most packages do it right now. The problem with this solution is it introduced many other packages to download binary that has not been used by `runtime codes`. The other problem is some users may not easily download the binary from `GitHub/CDN` if they are behind a private network (But in most cases, they have a private NPM mirror).
24
+ ```javascript
25
+ const { optimize } = require('@svg-rs/svgo')
61
26
 
62
- In this package, we choose a better way to solve this problem. We release different `npm packages` for different platforms. And add it to `optionalDependencies` before releasing the `Major` package to npm.
27
+ const inputSvg = `<svg xmlns="http://www.w3.org/2000/svg">
28
+ <g attr1="val1">
29
+ <desc>Example</desc>
30
+ <circle cx="50" cy="50" r="40"/>
31
+ </g>
32
+ </svg>`
63
33
 
64
- `NPM` will choose which native package should download from `registry` automatically. You can see [npm](./npm) dir for details. And you can also run `yarn add @napi-rs/package-template` to see how it works.
65
-
66
- ## Develop requirements
67
-
68
- - Install the latest `Rust`
69
- - Install `Node.js@10+` which fully supported `Node-API`
70
- - Install `yarn@1.x`
71
-
72
- ## Test in local
73
-
74
- - yarn
75
- - yarn build
76
- - yarn test
34
+ const optimizedSvg = optimize(inputSvg)
35
+ console.log(optimizedSvg)
36
+ ```
77
37
 
78
- And you will see:
38
+ ## Plugins
39
+
40
+ - [] ddAttributesToSVGElement
41
+ - [] addClassesToSVGElement
42
+ - [] cleanupAttrs
43
+ - [] cleanupEnableBackground
44
+ - [] cleanupIds
45
+ - [] cleanupListOfValues
46
+ - [] cleanupNumericValues
47
+ - [] collapseGroups
48
+ - [] convertColors
49
+ - [] convertEllipseToCircle
50
+ - [] convertOneStopGradients
51
+ - [] convertPathData
52
+ - [] convertShapeToPath
53
+ - [] convertStyleToAttrs
54
+ - [] convertTransform
55
+ - [] inlineStyles
56
+ - [] mergePaths
57
+ - [] mergeStyles
58
+ - [] minifyStyles
59
+ - [x] moveElemsAttrsToGroup
60
+ - [] moveGroupAttrsToElems
61
+ - [] prefixIds
62
+ - [] removeAttributesBySelector
63
+ - [] removeAttrs
64
+ - [x] removeComments
65
+ - [] removeDeprecatedAttrs
66
+ - [x] removeDesc
67
+ - [] removeDimensions
68
+ - [x] removeDoctype
69
+ - [x] removeEditorsNSData
70
+ - [] removeElementsByAttr
71
+ - [] removeEmptyAttrs
72
+ - [] removeEmptyContainers
73
+ - [] removeEmptyText
74
+ - [] removeHiddenElems
75
+ - [x] removeMetadata
76
+ - [] removeNonInheritableGroupAttrs
77
+ - [] removeOffCanvasPaths
78
+ - [] removeRasterImages
79
+ - [] removeScripts
80
+ - [] removeStyleElement
81
+ - [x] removeTitle
82
+ - [] removeUnknownsAndDefaults
83
+ - [] removeUnusedNS
84
+ - [] removeUselessDefs
85
+ - [] removeUselessStrokeAndFill
86
+ - [] removeViewBox
87
+ - [] removeXMLNS
88
+ - [x] removeXMLProcInst
89
+ - [] removeXlink
90
+ - [] reusePaths
91
+ - [] sortAttrs
92
+ - [] sortDefsChildren
93
+
94
+ ## Benchmarks
95
+
96
+ `svgo-rs` provides significant performance improvements over JavaScript-based SVG optimizers. Run the benchmarks in the `benchmark/` directory to compare:
79
97
 
80
98
  ```bash
81
- $ ava --verbose
82
-
83
- ✔ sync function from native code
84
- ✔ sleep function from native code (201ms)
85
-
86
-
87
- 2 tests passed
88
- ✨ Done in 1.12s.
99
+ yarn bench
89
100
  ```
90
101
 
91
- ## Release package
92
-
93
- Ensure you have set your **NPM_TOKEN** in the `GitHub` project setting.
94
-
95
- In `Settings -> Secrets`, add **NPM_TOKEN** into it.
102
+ ## License
96
103
 
97
- When you want to release the package:
104
+ This project is licensed under the MIT License. See the [LICENSE](./LICENSE) file for details.
98
105
 
99
- ```
100
- npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=<prerelease-id>] | from-git]
101
-
102
- git push
103
- ```
106
+ ## Contributing
104
107
 
105
- GitHub actions will do the rest job for you.
108
+ Contributions are welcome! Please open an issue or submit a pull request on [GitHub](https://github.com/oxidized-world/svgo-rs).
package/README.zh.md ADDED
@@ -0,0 +1,109 @@
1
+ # svgo-rs
2
+
3
+ `svgo-rs` 是一个用 Rust 编写的高性能 SVG 优化器,旨在高效地处理和优化 SVG 文件。它通过 NAPI-RS 提供 Node.js 的绑定,使 JavaScript 和 TypeScript 开发者可以轻松使用。
4
+
5
+ ## 特性
6
+
7
+ - 使用 Rust 编写,性能卓越。
8
+ - 提供多种 SVG 优化插件,例如移除元数据、注释和不必要的元素。
9
+ - 支持多个平台,并提供预编译的二进制文件。
10
+ - 可轻松集成到 Node.js 项目中。
11
+
12
+ ## 安装
13
+
14
+ 通过 npm 安装此包:
15
+
16
+ ```bash
17
+ npm install @svg-rs/svgo
18
+ ```
19
+
20
+ ## 使用方法
21
+
22
+ ### Node.js
23
+
24
+ ```javascript
25
+ const { optimize } = require('@svg-rs/svgo')
26
+
27
+ const inputSvg = `<svg xmlns="http://www.w3.org/2000/svg">
28
+ <g attr1="val1">
29
+ <desc>Example</desc>
30
+ <circle cx="50" cy="50" r="40"/>
31
+ </g>
32
+ </svg>`
33
+
34
+ const optimizedSvg = optimize(inputSvg)
35
+ console.log(optimizedSvg)
36
+ ```
37
+
38
+
39
+ ## 插件
40
+
41
+ - [] ddAttributesToSVGElement
42
+ - [] addClassesToSVGElement
43
+ - [] cleanupAttrs
44
+ - [] cleanupEnableBackground
45
+ - [] cleanupIds
46
+ - [] cleanupListOfValues
47
+ - [] cleanupNumericValues
48
+ - [] collapseGroups
49
+ - [] convertColors
50
+ - [] convertEllipseToCircle
51
+ - [] convertOneStopGradients
52
+ - [] convertPathData
53
+ - [] convertShapeToPath
54
+ - [] convertStyleToAttrs
55
+ - [] convertTransform
56
+ - [] inlineStyles
57
+ - [] mergePaths
58
+ - [] mergeStyles
59
+ - [] minifyStyles
60
+ - [x] moveElemsAttrsToGroup
61
+ - [] moveGroupAttrsToElems
62
+ - [] prefixIds
63
+ - [] removeAttributesBySelector
64
+ - [] removeAttrs
65
+ - [x] removeComments
66
+ - [] removeDeprecatedAttrs
67
+ - [x] removeDesc
68
+ - [] removeDimensions
69
+ - [x] removeDoctype
70
+ - [x] removeEditorsNSData
71
+ - [] removeElementsByAttr
72
+ - [] removeEmptyAttrs
73
+ - [] removeEmptyContainers
74
+ - [] removeEmptyText
75
+ - [] removeHiddenElems
76
+ - [x] removeMetadata
77
+ - [] removeNonInheritableGroupAttrs
78
+ - [] removeOffCanvasPaths
79
+ - [] removeRasterImages
80
+ - [] removeScripts
81
+ - [] removeStyleElement
82
+ - [x] removeTitle
83
+ - [] removeUnknownsAndDefaults
84
+ - [] removeUnusedNS
85
+ - [] removeUselessDefs
86
+ - [] removeUselessStrokeAndFill
87
+ - [] removeViewBox
88
+ - [] removeXMLNS
89
+ - [x] removeXMLProcInst
90
+ - [] removeXlink
91
+ - [] reusePaths
92
+ - [] sortAttrs
93
+ - [] sortDefsChildren
94
+
95
+ ## 基准测试
96
+
97
+ `svgo-rs` 相较于基于 JavaScript 的 SVG 优化器提供了显著的性能提升。可以在 `benchmark/` 目录中运行基准测试进行比较:
98
+
99
+ ```bash
100
+ yarn bench
101
+ ```
102
+
103
+ ## 许可证
104
+
105
+ 此项目基于 MIT 许可证授权。详情请参阅 [LICENSE](./LICENSE) 文件。
106
+
107
+ ## 贡献
108
+
109
+ 欢迎贡献!请在 [GitHub](https://github.com/oxidized-world/svgo-rs) 上提交 issue 或 pull request。
package/index.d.ts CHANGED
@@ -1,16 +1,3 @@
1
- /* tslint:disable */
2
- /* eslint-disable */
3
-
4
1
  /* auto-generated by NAPI-RS */
5
-
6
- export interface RemoveDescOptions {
7
- /** Remove any `desc` elements, even if they have children. */
8
- removeAny: boolean
9
- }
10
- export interface PluginConfig {
11
- removeDesc: RemoveDescOptions
12
- }
13
- export interface OptimizeOptions {
14
- plugins: PluginConfig
15
- }
16
- export declare function optimize(inputXml: string, options: OptimizeOptions): string
2
+ /* eslint-disable */
3
+ export declare function optimize(inputXml: string): string
package/index.js CHANGED
@@ -1,289 +1,396 @@
1
- /* tslint:disable */
1
+ // prettier-ignore
2
2
  /* eslint-disable */
3
- /* prettier-ignore */
4
-
3
+ // @ts-nocheck
5
4
  /* auto-generated by NAPI-RS */
6
5
 
7
- const { existsSync, readFileSync } = require('fs')
8
- const { join } = require('path')
9
-
10
- const { platform, arch } = process
6
+ const { createRequire } = require('node:module')
7
+ require = createRequire(__filename)
11
8
 
9
+ const { readFileSync } = require('node:fs')
12
10
  let nativeBinding = null
13
- let localFileExisted = false
14
- let loadError = null
11
+ const loadErrors = []
15
12
 
16
- function isMusl() {
17
- // For Node 10
18
- if (!process.report || typeof process.report.getReport !== 'function') {
19
- try {
20
- const lddPath = require('child_process').execSync('which ldd').toString().trim()
21
- return readFileSync(lddPath, 'utf8').includes('musl')
22
- } catch (e) {
13
+ const isMusl = () => {
14
+ let musl = false
15
+ if (process.platform === 'linux') {
16
+ musl = isMuslFromFilesystem()
17
+ if (musl === null) {
18
+ musl = isMuslFromReport()
19
+ }
20
+ if (musl === null) {
21
+ musl = isMuslFromChildProcess()
22
+ }
23
+ }
24
+ return musl
25
+ }
26
+
27
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
28
+
29
+ const isMuslFromFilesystem = () => {
30
+ try {
31
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
32
+ } catch {
33
+ return null
34
+ }
35
+ }
36
+
37
+ const isMuslFromReport = () => {
38
+ let report = null
39
+ if (typeof process.report?.getReport === 'function') {
40
+ process.report.excludeNetwork = true
41
+ report = process.report.getReport()
42
+ }
43
+ if (!report) {
44
+ return null
45
+ }
46
+ if (report.header && report.header.glibcVersionRuntime) {
47
+ return false
48
+ }
49
+ if (Array.isArray(report.sharedObjects)) {
50
+ if (report.sharedObjects.some(isFileMusl)) {
23
51
  return true
24
52
  }
25
- } else {
26
- const { glibcVersionRuntime } = process.report.getReport().header
27
- return !glibcVersionRuntime
28
53
  }
54
+ return false
29
55
  }
30
56
 
31
- switch (platform) {
32
- case 'android':
33
- switch (arch) {
34
- case 'arm64':
35
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.android-arm64.node'))
57
+ const isMuslFromChildProcess = () => {
58
+ try {
59
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
60
+ } catch (e) {
61
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
62
+ return false
63
+ }
64
+ }
65
+
66
+ function requireNative() {
67
+ if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
68
+ try {
69
+ nativeBinding = require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH);
70
+ } catch (err) {
71
+ loadErrors.push(err)
72
+ }
73
+ } else if (process.platform === 'android') {
74
+ if (process.arch === 'arm64') {
75
+ try {
76
+ return require('./svgo-rs.android-arm64.node')
77
+ } catch (e) {
78
+ loadErrors.push(e)
79
+ }
80
+ try {
81
+ return require('@svg-rs/svgo-android-arm64')
82
+ } catch (e) {
83
+ loadErrors.push(e)
84
+ }
85
+ } else if (process.arch === 'arm') {
86
+ try {
87
+ return require('./svgo-rs.android-arm-eabi.node')
88
+ } catch (e) {
89
+ loadErrors.push(e)
90
+ }
91
+ try {
92
+ return require('@svg-rs/svgo-android-arm-eabi')
93
+ } catch (e) {
94
+ loadErrors.push(e)
95
+ }
96
+ } else {
97
+ loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`))
98
+ }
99
+ } else if (process.platform === 'win32') {
100
+ if (process.arch === 'x64') {
101
+ try {
102
+ return require('./svgo-rs.win32-x64-msvc.node')
103
+ } catch (e) {
104
+ loadErrors.push(e)
105
+ }
106
+ try {
107
+ return require('@svg-rs/svgo-win32-x64-msvc')
108
+ } catch (e) {
109
+ loadErrors.push(e)
110
+ }
111
+ } else if (process.arch === 'ia32') {
112
+ try {
113
+ return require('./svgo-rs.win32-ia32-msvc.node')
114
+ } catch (e) {
115
+ loadErrors.push(e)
116
+ }
117
+ try {
118
+ return require('@svg-rs/svgo-win32-ia32-msvc')
119
+ } catch (e) {
120
+ loadErrors.push(e)
121
+ }
122
+ } else if (process.arch === 'arm64') {
123
+ try {
124
+ return require('./svgo-rs.win32-arm64-msvc.node')
125
+ } catch (e) {
126
+ loadErrors.push(e)
127
+ }
128
+ try {
129
+ return require('@svg-rs/svgo-win32-arm64-msvc')
130
+ } catch (e) {
131
+ loadErrors.push(e)
132
+ }
133
+ } else {
134
+ loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`))
135
+ }
136
+ } else if (process.platform === 'darwin') {
137
+ try {
138
+ return require('./svgo-rs.darwin-universal.node')
139
+ } catch (e) {
140
+ loadErrors.push(e)
141
+ }
142
+ try {
143
+ return require('@svg-rs/svgo-darwin-universal')
144
+ } catch (e) {
145
+ loadErrors.push(e)
146
+ }
147
+ if (process.arch === 'x64') {
148
+ try {
149
+ return require('./svgo-rs.darwin-x64.node')
150
+ } catch (e) {
151
+ loadErrors.push(e)
152
+ }
153
+ try {
154
+ return require('@svg-rs/svgo-darwin-x64')
155
+ } catch (e) {
156
+ loadErrors.push(e)
157
+ }
158
+ } else if (process.arch === 'arm64') {
159
+ try {
160
+ return require('./svgo-rs.darwin-arm64.node')
161
+ } catch (e) {
162
+ loadErrors.push(e)
163
+ }
164
+ try {
165
+ return require('@svg-rs/svgo-darwin-arm64')
166
+ } catch (e) {
167
+ loadErrors.push(e)
168
+ }
169
+ } else {
170
+ loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`))
171
+ }
172
+ } else if (process.platform === 'freebsd') {
173
+ if (process.arch === 'x64') {
174
+ try {
175
+ return require('./svgo-rs.freebsd-x64.node')
176
+ } catch (e) {
177
+ loadErrors.push(e)
178
+ }
179
+ try {
180
+ return require('@svg-rs/svgo-freebsd-x64')
181
+ } catch (e) {
182
+ loadErrors.push(e)
183
+ }
184
+ } else if (process.arch === 'arm64') {
185
+ try {
186
+ return require('./svgo-rs.freebsd-arm64.node')
187
+ } catch (e) {
188
+ loadErrors.push(e)
189
+ }
190
+ try {
191
+ return require('@svg-rs/svgo-freebsd-arm64')
192
+ } catch (e) {
193
+ loadErrors.push(e)
194
+ }
195
+ } else {
196
+ loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`))
197
+ }
198
+ } else if (process.platform === 'linux') {
199
+ if (process.arch === 'x64') {
200
+ if (isMusl()) {
36
201
  try {
37
- if (localFileExisted) {
38
- nativeBinding = require('./svgo-rs.android-arm64.node')
39
- } else {
40
- nativeBinding = require('@svg-rs/svgo-android-arm64')
41
- }
202
+ return require('./svgo-rs.linux-x64-musl.node')
42
203
  } catch (e) {
43
- loadError = e
204
+ loadErrors.push(e)
44
205
  }
45
- break
46
- case 'arm':
47
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.android-arm-eabi.node'))
48
206
  try {
49
- if (localFileExisted) {
50
- nativeBinding = require('./svgo-rs.android-arm-eabi.node')
51
- } else {
52
- nativeBinding = require('@svg-rs/svgo-android-arm-eabi')
53
- }
207
+ return require('@svg-rs/svgo-linux-x64-musl')
54
208
  } catch (e) {
55
- loadError = e
209
+ loadErrors.push(e)
56
210
  }
57
- break
58
- default:
59
- throw new Error(`Unsupported architecture on Android ${arch}`)
60
- }
61
- break
62
- case 'win32':
63
- switch (arch) {
64
- case 'x64':
65
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.win32-x64-msvc.node'))
211
+ } else {
66
212
  try {
67
- if (localFileExisted) {
68
- nativeBinding = require('./svgo-rs.win32-x64-msvc.node')
69
- } else {
70
- nativeBinding = require('@svg-rs/svgo-win32-x64-msvc')
71
- }
213
+ return require('./svgo-rs.linux-x64-gnu.node')
72
214
  } catch (e) {
73
- loadError = e
215
+ loadErrors.push(e)
74
216
  }
75
- break
76
- case 'ia32':
77
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.win32-ia32-msvc.node'))
78
217
  try {
79
- if (localFileExisted) {
80
- nativeBinding = require('./svgo-rs.win32-ia32-msvc.node')
81
- } else {
82
- nativeBinding = require('@svg-rs/svgo-win32-ia32-msvc')
83
- }
218
+ return require('@svg-rs/svgo-linux-x64-gnu')
84
219
  } catch (e) {
85
- loadError = e
220
+ loadErrors.push(e)
86
221
  }
87
- break
88
- case 'arm64':
89
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.win32-arm64-msvc.node'))
222
+ }
223
+ } else if (process.arch === 'arm64') {
224
+ if (isMusl()) {
90
225
  try {
91
- if (localFileExisted) {
92
- nativeBinding = require('./svgo-rs.win32-arm64-msvc.node')
93
- } else {
94
- nativeBinding = require('@svg-rs/svgo-win32-arm64-msvc')
95
- }
226
+ return require('./svgo-rs.linux-arm64-musl.node')
96
227
  } catch (e) {
97
- loadError = e
228
+ loadErrors.push(e)
229
+ }
230
+ try {
231
+ return require('@svg-rs/svgo-linux-arm64-musl')
232
+ } catch (e) {
233
+ loadErrors.push(e)
98
234
  }
99
- break
100
- default:
101
- throw new Error(`Unsupported architecture on Windows: ${arch}`)
102
- }
103
- break
104
- case 'darwin':
105
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.darwin-universal.node'))
106
- try {
107
- if (localFileExisted) {
108
- nativeBinding = require('./svgo-rs.darwin-universal.node')
109
235
  } else {
110
- nativeBinding = require('@svg-rs/svgo-darwin-universal')
236
+ try {
237
+ return require('./svgo-rs.linux-arm64-gnu.node')
238
+ } catch (e) {
239
+ loadErrors.push(e)
240
+ }
241
+ try {
242
+ return require('@svg-rs/svgo-linux-arm64-gnu')
243
+ } catch (e) {
244
+ loadErrors.push(e)
245
+ }
111
246
  }
112
- break
113
- } catch {}
114
- switch (arch) {
115
- case 'x64':
116
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.darwin-x64.node'))
247
+ } else if (process.arch === 'arm') {
248
+ if (isMusl()) {
117
249
  try {
118
- if (localFileExisted) {
119
- nativeBinding = require('./svgo-rs.darwin-x64.node')
120
- } else {
121
- nativeBinding = require('@svg-rs/svgo-darwin-x64')
122
- }
250
+ return require('./svgo-rs.linux-arm-musleabihf.node')
123
251
  } catch (e) {
124
- loadError = e
252
+ loadErrors.push(e)
125
253
  }
126
- break
127
- case 'arm64':
128
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.darwin-arm64.node'))
129
254
  try {
130
- if (localFileExisted) {
131
- nativeBinding = require('./svgo-rs.darwin-arm64.node')
132
- } else {
133
- nativeBinding = require('@svg-rs/svgo-darwin-arm64')
134
- }
255
+ return require('@svg-rs/svgo-linux-arm-musleabihf')
135
256
  } catch (e) {
136
- loadError = e
257
+ loadErrors.push(e)
137
258
  }
138
- break
139
- default:
140
- throw new Error(`Unsupported architecture on macOS: ${arch}`)
141
- }
142
- break
143
- case 'freebsd':
144
- if (arch !== 'x64') {
145
- throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
146
- }
147
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.freebsd-x64.node'))
148
- try {
149
- if (localFileExisted) {
150
- nativeBinding = require('./svgo-rs.freebsd-x64.node')
151
259
  } else {
152
- nativeBinding = require('@svg-rs/svgo-freebsd-x64')
153
- }
154
- } catch (e) {
155
- loadError = e
156
- }
157
- break
158
- case 'linux':
159
- switch (arch) {
160
- case 'x64':
161
- if (isMusl()) {
162
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.linux-x64-musl.node'))
163
- try {
164
- if (localFileExisted) {
165
- nativeBinding = require('./svgo-rs.linux-x64-musl.node')
166
- } else {
167
- nativeBinding = require('@svg-rs/svgo-linux-x64-musl')
168
- }
169
- } catch (e) {
170
- loadError = e
171
- }
172
- } else {
173
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.linux-x64-gnu.node'))
174
- try {
175
- if (localFileExisted) {
176
- nativeBinding = require('./svgo-rs.linux-x64-gnu.node')
177
- } else {
178
- nativeBinding = require('@svg-rs/svgo-linux-x64-gnu')
179
- }
180
- } catch (e) {
181
- loadError = e
182
- }
260
+ try {
261
+ return require('./svgo-rs.linux-arm-gnueabihf.node')
262
+ } catch (e) {
263
+ loadErrors.push(e)
183
264
  }
184
- break
185
- case 'arm64':
186
- if (isMusl()) {
187
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.linux-arm64-musl.node'))
188
- try {
189
- if (localFileExisted) {
190
- nativeBinding = require('./svgo-rs.linux-arm64-musl.node')
191
- } else {
192
- nativeBinding = require('@svg-rs/svgo-linux-arm64-musl')
193
- }
194
- } catch (e) {
195
- loadError = e
196
- }
197
- } else {
198
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.linux-arm64-gnu.node'))
199
- try {
200
- if (localFileExisted) {
201
- nativeBinding = require('./svgo-rs.linux-arm64-gnu.node')
202
- } else {
203
- nativeBinding = require('@svg-rs/svgo-linux-arm64-gnu')
204
- }
205
- } catch (e) {
206
- loadError = e
207
- }
265
+ try {
266
+ return require('@svg-rs/svgo-linux-arm-gnueabihf')
267
+ } catch (e) {
268
+ loadErrors.push(e)
208
269
  }
209
- break
210
- case 'arm':
211
- if (isMusl()) {
212
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.linux-arm-musleabihf.node'))
213
- try {
214
- if (localFileExisted) {
215
- nativeBinding = require('./svgo-rs.linux-arm-musleabihf.node')
216
- } else {
217
- nativeBinding = require('@svg-rs/svgo-linux-arm-musleabihf')
218
- }
219
- } catch (e) {
220
- loadError = e
221
- }
222
- } else {
223
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.linux-arm-gnueabihf.node'))
224
- try {
225
- if (localFileExisted) {
226
- nativeBinding = require('./svgo-rs.linux-arm-gnueabihf.node')
227
- } else {
228
- nativeBinding = require('@svg-rs/svgo-linux-arm-gnueabihf')
229
- }
230
- } catch (e) {
231
- loadError = e
232
- }
270
+ }
271
+ } else if (process.arch === 'riscv64') {
272
+ if (isMusl()) {
273
+ try {
274
+ return require('./svgo-rs.linux-riscv64-musl.node')
275
+ } catch (e) {
276
+ loadErrors.push(e)
233
277
  }
234
- break
235
- case 'riscv64':
236
- if (isMusl()) {
237
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.linux-riscv64-musl.node'))
238
- try {
239
- if (localFileExisted) {
240
- nativeBinding = require('./svgo-rs.linux-riscv64-musl.node')
241
- } else {
242
- nativeBinding = require('@svg-rs/svgo-linux-riscv64-musl')
243
- }
244
- } catch (e) {
245
- loadError = e
246
- }
247
- } else {
248
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.linux-riscv64-gnu.node'))
249
- try {
250
- if (localFileExisted) {
251
- nativeBinding = require('./svgo-rs.linux-riscv64-gnu.node')
252
- } else {
253
- nativeBinding = require('@svg-rs/svgo-linux-riscv64-gnu')
254
- }
255
- } catch (e) {
256
- loadError = e
257
- }
278
+ try {
279
+ return require('@svg-rs/svgo-linux-riscv64-musl')
280
+ } catch (e) {
281
+ loadErrors.push(e)
258
282
  }
259
- break
260
- case 's390x':
261
- localFileExisted = existsSync(join(__dirname, 'svgo-rs.linux-s390x-gnu.node'))
283
+ } else {
262
284
  try {
263
- if (localFileExisted) {
264
- nativeBinding = require('./svgo-rs.linux-s390x-gnu.node')
265
- } else {
266
- nativeBinding = require('@svg-rs/svgo-linux-s390x-gnu')
267
- }
285
+ return require('./svgo-rs.linux-riscv64-gnu.node')
268
286
  } catch (e) {
269
- loadError = e
287
+ loadErrors.push(e)
270
288
  }
271
- break
272
- default:
273
- throw new Error(`Unsupported architecture on Linux: ${arch}`)
289
+ try {
290
+ return require('@svg-rs/svgo-linux-riscv64-gnu')
291
+ } catch (e) {
292
+ loadErrors.push(e)
293
+ }
294
+ }
295
+ } else if (process.arch === 'ppc64') {
296
+ try {
297
+ return require('./svgo-rs.linux-ppc64-gnu.node')
298
+ } catch (e) {
299
+ loadErrors.push(e)
300
+ }
301
+ try {
302
+ return require('@svg-rs/svgo-linux-ppc64-gnu')
303
+ } catch (e) {
304
+ loadErrors.push(e)
305
+ }
306
+ } else if (process.arch === 's390x') {
307
+ try {
308
+ return require('./svgo-rs.linux-s390x-gnu.node')
309
+ } catch (e) {
310
+ loadErrors.push(e)
311
+ }
312
+ try {
313
+ return require('@svg-rs/svgo-linux-s390x-gnu')
314
+ } catch (e) {
315
+ loadErrors.push(e)
316
+ }
317
+ } else {
318
+ loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
319
+ }
320
+ } else if (process.platform === 'openharmony') {
321
+ if (process.arch === 'arm64') {
322
+ try {
323
+ return require('./svgo-rs.linux-arm64-ohos.node')
324
+ } catch (e) {
325
+ loadErrors.push(e)
326
+ }
327
+ try {
328
+ return require('@svg-rs/svgo-linux-arm64-ohos')
329
+ } catch (e) {
330
+ loadErrors.push(e)
331
+ }
332
+ } else if (process.arch === 'x64') {
333
+ try {
334
+ return require('./svgo-rs.linux-x64-ohos.node')
335
+ } catch (e) {
336
+ loadErrors.push(e)
337
+ }
338
+ try {
339
+ return require('@svg-rs/svgo-linux-x64-ohos')
340
+ } catch (e) {
341
+ loadErrors.push(e)
342
+ }
343
+ } else if (process.arch === 'arm') {
344
+ try {
345
+ return require('./svgo-rs.linux-arm-ohos.node')
346
+ } catch (e) {
347
+ loadErrors.push(e)
348
+ }
349
+ try {
350
+ return require('@svg-rs/svgo-linux-arm-ohos')
351
+ } catch (e) {
352
+ loadErrors.push(e)
353
+ }
354
+ } else {
355
+ loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`))
274
356
  }
275
- break
276
- default:
277
- throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
357
+ } else {
358
+ loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
359
+ }
360
+ }
361
+
362
+ nativeBinding = requireNative()
363
+
364
+ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
365
+ try {
366
+ nativeBinding = require('./svgo-rs.wasi.cjs')
367
+ } catch (err) {
368
+ if (process.env.NAPI_RS_FORCE_WASI) {
369
+ loadErrors.push(err)
370
+ }
371
+ }
372
+ if (!nativeBinding) {
373
+ try {
374
+ nativeBinding = require('@svg-rs/svgo-wasm32-wasi')
375
+ } catch (err) {
376
+ if (process.env.NAPI_RS_FORCE_WASI) {
377
+ loadErrors.push(err)
378
+ }
379
+ }
380
+ }
278
381
  }
279
382
 
280
383
  if (!nativeBinding) {
281
- if (loadError) {
282
- throw loadError
384
+ if (loadErrors.length > 0) {
385
+ throw new Error(
386
+ `Cannot find native binding. ` +
387
+ `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
388
+ 'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
389
+ { cause: loadErrors }
390
+ )
283
391
  }
284
392
  throw new Error(`Failed to load native binding`)
285
393
  }
286
394
 
287
- const { optimize } = nativeBinding
288
-
289
- module.exports.optimize = optimize
395
+ module.exports = nativeBinding
396
+ module.exports.optimize = nativeBinding.optimize
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svg-rs/svgo",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Node.js tool for optimizing SVG files by Rust.",
5
5
  "main": "index.js",
6
6
  "repository": "https://github.com/oxidized-world/svgo-rs",
@@ -8,32 +8,32 @@
8
8
  "keywords": [
9
9
  "napi-rs",
10
10
  "NAPI",
11
- "N-API",
12
11
  "Rust",
13
- "node-addon",
14
- "node-addon-api"
12
+ "svgo",
13
+ "svg optimizing"
15
14
  ],
16
15
  "files": [
17
16
  "index.d.ts",
18
17
  "index.js"
19
18
  ],
20
19
  "napi": {
21
- "name": "svgo-rs",
22
- "triples": {
23
- "defaults": true,
24
- "additional": [
25
- "x86_64-unknown-linux-musl",
26
- "aarch64-unknown-linux-gnu",
27
- "i686-pc-windows-msvc",
28
- "armv7-unknown-linux-gnueabihf",
29
- "aarch64-apple-darwin",
30
- "aarch64-linux-android",
31
- "x86_64-unknown-freebsd",
32
- "aarch64-unknown-linux-musl",
33
- "aarch64-pc-windows-msvc",
34
- "armv7-linux-androideabi"
35
- ]
36
- }
20
+ "binaryName": "svgo-rs",
21
+ "targets": [
22
+ "x86_64-pc-windows-msvc",
23
+ "x86_64-apple-darwin",
24
+ "x86_64-unknown-linux-gnu",
25
+ "x86_64-unknown-linux-musl",
26
+ "aarch64-unknown-linux-gnu",
27
+ "i686-pc-windows-msvc",
28
+ "armv7-unknown-linux-gnueabihf",
29
+ "aarch64-apple-darwin",
30
+ "aarch64-linux-android",
31
+ "x86_64-unknown-freebsd",
32
+ "aarch64-unknown-linux-musl",
33
+ "aarch64-pc-windows-msvc",
34
+ "armv7-linux-androideabi",
35
+ "wasm32-wasip1-threads"
36
+ ]
37
37
  },
38
38
  "engines": {
39
39
  "node": ">= 10"
@@ -44,42 +44,35 @@
44
44
  },
45
45
  "scripts": {
46
46
  "artifacts": "napi artifacts",
47
- "bench": "node --import @swc-node/register/esm-register benchmark/bench.ts",
47
+ "bench": "node --import @oxc-node/core/register benchmark/bench.ts",
48
48
  "build": "napi build --platform --release",
49
49
  "build:debug": "napi build --platform",
50
- "format": "run-p format:prettier format:rs format:toml",
51
- "format:prettier": "prettier . -w",
50
+ "format": "format:rs && format:toml",
52
51
  "format:toml": "taplo format",
53
52
  "format:rs": "cargo fmt",
54
- "lint": "oxlint .",
53
+ "lint": "biome lint --write",
55
54
  "prepublishOnly": "napi prepublish -t npm",
56
55
  "test": "vitest run",
57
56
  "test:watch": "vitest",
58
57
  "version": "napi version",
59
- "postinstall": "husky"
58
+ "prepare": "husky"
60
59
  },
61
60
  "devDependencies": {
62
- "@napi-rs/cli": "^2.18.4",
63
- "@swc-node/register": "^1.10.6",
64
- "@swc/core": "^1.6.13",
61
+ "@biomejs/biome": "^1.9.4",
62
+ "@napi-rs/cli": "^3.0.0",
63
+ "@oxc-node/core": "^0.0.29",
65
64
  "@taplo/cli": "^0.7.0",
66
- "chalk": "^5.3.0",
67
- "husky": "^9.0.11",
68
- "lint-staged": "^15.2.7",
69
- "npm-run-all2": "^7.0.0",
70
- "oxlint": "^0.15.0",
71
- "prettier": "^3.3.3",
65
+ "@tybys/wasm-util": "^0.10.0",
66
+ "husky": "^9.1.7",
67
+ "lint-staged": "^15.5.1",
72
68
  "svgo": "^3.3.2",
73
- "tinybench": "^3.0.0",
74
- "typescript": "^5.5.3",
75
- "vitest": "^3.0.4"
69
+ "tinybench": "^4.0.1",
70
+ "typescript": "^5.8.3",
71
+ "vitest": "^3.2.4"
76
72
  },
77
73
  "lint-staged": {
78
- "*.@(js|ts|tsx)": [
79
- "oxlint --fix"
80
- ],
81
- "*.@(js|ts|tsx|yml|yaml|md|json)": [
82
- "prettier --write"
74
+ "*.@(js|ts|tsx|yml|yaml|json)": [
75
+ "biome lint --write"
83
76
  ],
84
77
  "*.toml": [
85
78
  "taplo format"
@@ -88,27 +81,21 @@
88
81
  "cargo fmt --"
89
82
  ]
90
83
  },
91
- "prettier": {
92
- "printWidth": 120,
93
- "semi": false,
94
- "trailingComma": "all",
95
- "singleQuote": true,
96
- "arrowParens": "always"
97
- },
98
- "packageManager": "yarn@4.6.0",
84
+ "packageManager": "yarn@4.9.2",
99
85
  "optionalDependencies": {
100
- "@svg-rs/svgo-win32-x64-msvc": "0.0.3",
101
- "@svg-rs/svgo-darwin-x64": "0.0.3",
102
- "@svg-rs/svgo-linux-x64-gnu": "0.0.3",
103
- "@svg-rs/svgo-linux-x64-musl": "0.0.3",
104
- "@svg-rs/svgo-linux-arm64-gnu": "0.0.3",
105
- "@svg-rs/svgo-win32-ia32-msvc": "0.0.3",
106
- "@svg-rs/svgo-linux-arm-gnueabihf": "0.0.3",
107
- "@svg-rs/svgo-darwin-arm64": "0.0.3",
108
- "@svg-rs/svgo-android-arm64": "0.0.3",
109
- "@svg-rs/svgo-freebsd-x64": "0.0.3",
110
- "@svg-rs/svgo-linux-arm64-musl": "0.0.3",
111
- "@svg-rs/svgo-win32-arm64-msvc": "0.0.3",
112
- "@svg-rs/svgo-android-arm-eabi": "0.0.3"
86
+ "@svg-rs/svgo-win32-x64-msvc": "0.0.5",
87
+ "@svg-rs/svgo-darwin-x64": "0.0.5",
88
+ "@svg-rs/svgo-linux-x64-gnu": "0.0.5",
89
+ "@svg-rs/svgo-linux-x64-musl": "0.0.5",
90
+ "@svg-rs/svgo-linux-arm64-gnu": "0.0.5",
91
+ "@svg-rs/svgo-win32-ia32-msvc": "0.0.5",
92
+ "@svg-rs/svgo-linux-arm-gnueabihf": "0.0.5",
93
+ "@svg-rs/svgo-darwin-arm64": "0.0.5",
94
+ "@svg-rs/svgo-android-arm64": "0.0.5",
95
+ "@svg-rs/svgo-freebsd-x64": "0.0.5",
96
+ "@svg-rs/svgo-linux-arm64-musl": "0.0.5",
97
+ "@svg-rs/svgo-win32-arm64-msvc": "0.0.5",
98
+ "@svg-rs/svgo-android-arm-eabi": "0.0.5",
99
+ "@svg-rs/svgo-wasm32-wasi": "0.0.5"
113
100
  }
114
101
  }