@tinysandbox/tinysandbox 0.3.0
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/index.d.ts +132 -0
- package/index.js +225 -0
- package/native.cjs +594 -0
- package/native.d.ts +140 -0
- package/package.json +49 -0
- package/tinysandbox-node.darwin-arm64.node +0 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CommandTiming,
|
|
3
|
+
DirEntryJs,
|
|
4
|
+
ExecResult,
|
|
5
|
+
FileStat,
|
|
6
|
+
NativeSandbox,
|
|
7
|
+
OpenModeJs,
|
|
8
|
+
SandboxFs,
|
|
9
|
+
SandboxStats,
|
|
10
|
+
VfsStatsJs
|
|
11
|
+
} from './native'
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
CommandTiming,
|
|
15
|
+
DirEntryJs,
|
|
16
|
+
ExecResult,
|
|
17
|
+
FileStat,
|
|
18
|
+
NativeSandbox,
|
|
19
|
+
OpenModeJs,
|
|
20
|
+
SandboxFs,
|
|
21
|
+
SandboxStats,
|
|
22
|
+
VfsStatsJs
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export declare class Sandbox extends NativeSandbox {
|
|
26
|
+
constructor(options?: SandboxOptions | null)
|
|
27
|
+
override get fs(): SandboxFs
|
|
28
|
+
override stats(): Promise<SandboxStats>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface SandboxOptions {
|
|
32
|
+
limits?: LimitsOptions
|
|
33
|
+
env?: Record<string, string>
|
|
34
|
+
cwd?: string
|
|
35
|
+
persistSession?: boolean
|
|
36
|
+
commands?: Record<string, JsCommand>
|
|
37
|
+
vfs?: JsVfs
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface LimitsOptions {
|
|
41
|
+
/** Milliseconds; must be finite and non-negative. */
|
|
42
|
+
wallTimeMs?: number
|
|
43
|
+
/** Byte counts must be non-negative integers at or below Number.MAX_SAFE_INTEGER. */
|
|
44
|
+
stdoutBytes?: number
|
|
45
|
+
stderrBytes?: number
|
|
46
|
+
maxCommands?: number
|
|
47
|
+
sortInputBytes?: number
|
|
48
|
+
wasmMemoryBytes?: number
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type JsCommand = (call: CommandCall) => Promise<CommandOutput> | CommandOutput
|
|
52
|
+
|
|
53
|
+
export interface CommandCall {
|
|
54
|
+
args: Array<string>
|
|
55
|
+
env: Record<string, string>
|
|
56
|
+
cwd: string
|
|
57
|
+
stdin: Buffer
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface CommandOutput {
|
|
61
|
+
exitCode?: number
|
|
62
|
+
stdout?: Buffer | Uint8Array | string
|
|
63
|
+
stderr?: Buffer | Uint8Array | string
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface JsVfs {
|
|
67
|
+
stat(request: VfsRequest): Promise<VfsResponse> | VfsResponse
|
|
68
|
+
readdir(request: VfsRequest): Promise<Array<DirEntryJs> | VfsResponse> | Array<DirEntryJs> | VfsResponse
|
|
69
|
+
mkdir(request: VfsRequest): Promise<VfsResponse | void> | VfsResponse | void
|
|
70
|
+
rename(request: VfsRequest): Promise<VfsResponse | void> | VfsResponse | void
|
|
71
|
+
unlink(request: VfsRequest): Promise<VfsResponse | void> | VfsResponse | void
|
|
72
|
+
rmdir(request: VfsRequest): Promise<VfsResponse | void> | VfsResponse | void
|
|
73
|
+
open(request: VfsRequest): Promise<number | VfsResponse> | number | VfsResponse
|
|
74
|
+
readAt(request: VfsRequest): Promise<Buffer | VfsResponse> | Buffer | VfsResponse
|
|
75
|
+
writeAt(request: VfsRequest): Promise<number | VfsResponse> | number | VfsResponse
|
|
76
|
+
truncate(request: VfsRequest): Promise<VfsResponse | void> | VfsResponse | void
|
|
77
|
+
close(request: VfsRequest): Promise<VfsResponse | void> | VfsResponse | void
|
|
78
|
+
stats?(request: VfsRequest): Promise<VfsResponse> | VfsResponse
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface VfsRequest {
|
|
82
|
+
path?: string
|
|
83
|
+
from?: string
|
|
84
|
+
to?: string
|
|
85
|
+
mode?: OpenModeJs
|
|
86
|
+
handle?: number
|
|
87
|
+
/** Handle, offset, and len values must be safe JS integers. */
|
|
88
|
+
offset?: number
|
|
89
|
+
len?: number
|
|
90
|
+
data?: Buffer
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface VfsResponse {
|
|
94
|
+
fileType?: 'file' | 'directory'
|
|
95
|
+
len?: number
|
|
96
|
+
entries?: Array<DirEntryJs>
|
|
97
|
+
handle?: number
|
|
98
|
+
bytesRead?: number
|
|
99
|
+
bytesWritten?: number
|
|
100
|
+
data?: Buffer
|
|
101
|
+
usedBytes?: number
|
|
102
|
+
fileCount?: number
|
|
103
|
+
error?: VfsCallbackError
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface VfsCallbackError {
|
|
107
|
+
/** Unknown codes are treated as EINVAL by the native adapter. */
|
|
108
|
+
code?: VfsErrno
|
|
109
|
+
message?: string
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export type VfsErrno =
|
|
113
|
+
| 'EBADF'
|
|
114
|
+
| 'EBUSY'
|
|
115
|
+
| 'EACCES'
|
|
116
|
+
| 'EEXIST'
|
|
117
|
+
| 'EINVAL'
|
|
118
|
+
| 'EISDIR'
|
|
119
|
+
| 'ENOENT'
|
|
120
|
+
| 'ENOSPC'
|
|
121
|
+
| 'ENOTDIR'
|
|
122
|
+
| 'ENOTEMPTY'
|
|
123
|
+
|
|
124
|
+
export declare function runConformance(
|
|
125
|
+
vfsFactory: (quota: VfsQuota) => JsVfs | Promise<JsVfs>
|
|
126
|
+
): Promise<{ ok: true; snapshots: 'unsupported' }>
|
|
127
|
+
|
|
128
|
+
export interface VfsQuota {
|
|
129
|
+
maxBytes: number
|
|
130
|
+
maxFiles: number
|
|
131
|
+
maxFileSize: number
|
|
132
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
const native = require('./native.cjs')
|
|
2
|
+
|
|
3
|
+
class Sandbox extends native.NativeSandbox {
|
|
4
|
+
constructor(options = undefined) {
|
|
5
|
+
super(normalizeOptions(options))
|
|
6
|
+
this._fs = undefined
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
get fs() {
|
|
10
|
+
this._fs ??= new SandboxFs(super.fs)
|
|
11
|
+
return this._fs
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function runConformance(vfsFactory) {
|
|
16
|
+
return native.runConformance(async (quota) => native.createJsVfs(wrapVfs(await vfsFactory(firstArgument(quota)))))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function normalizeOptions(options) {
|
|
20
|
+
if (!options) return options
|
|
21
|
+
const normalized = { ...options }
|
|
22
|
+
if (options.commands) normalized.commands = wrapCommands(options.commands)
|
|
23
|
+
else delete normalized.commands
|
|
24
|
+
if (options.vfs) normalized.vfs = wrapVfs(options.vfs)
|
|
25
|
+
else delete normalized.vfs
|
|
26
|
+
return normalized
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function wrapCommands(commands) {
|
|
30
|
+
return Object.fromEntries(
|
|
31
|
+
Object.entries(commands).map(([name, command]) => [
|
|
32
|
+
name,
|
|
33
|
+
async (call) => {
|
|
34
|
+
try {
|
|
35
|
+
const payload = firstArgument(call)
|
|
36
|
+
return normalizeCommandOutput(await command(payload))
|
|
37
|
+
} catch (err) {
|
|
38
|
+
return {
|
|
39
|
+
exitCode: 1,
|
|
40
|
+
stderr: Buffer.from(`${err?.message ?? err}\n`)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
])
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function wrapVfs(vfs) {
|
|
49
|
+
return Object.fromEntries(
|
|
50
|
+
vfsOperations.map((name) => [
|
|
51
|
+
name,
|
|
52
|
+
async (request) => {
|
|
53
|
+
try {
|
|
54
|
+
return normalizeVfsResponse(name, await vfs[name](normalizeVfsRequest(request)))
|
|
55
|
+
} catch (err) {
|
|
56
|
+
return { error: errorPayload(err) }
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
]).concat(
|
|
60
|
+
typeof vfs.stats === 'function'
|
|
61
|
+
? [[
|
|
62
|
+
'stats',
|
|
63
|
+
async (request) => {
|
|
64
|
+
try {
|
|
65
|
+
return normalizeVfsResponse('stats', await vfs.stats(normalizeVfsRequest(request)))
|
|
66
|
+
} catch (err) {
|
|
67
|
+
return { error: errorPayload(err) }
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
]]
|
|
71
|
+
: []
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function normalizeVfsRequest(request) {
|
|
77
|
+
return firstArgument(request)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function firstArgument(value) {
|
|
81
|
+
// napi-rs TSFN callbacks marshal tuple arguments as an object with numeric
|
|
82
|
+
// keys, while direct wrapper calls already pass the request object.
|
|
83
|
+
return value && typeof value === 'object' && Object.hasOwn(value, '0') ? value[0] : value
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function normalizeCommandOutput(output = {}) {
|
|
87
|
+
return {
|
|
88
|
+
exitCode: output.exitCode ?? 0,
|
|
89
|
+
stdout: output.stdout ? Buffer.from(output.stdout) : undefined,
|
|
90
|
+
stderr: output.stderr ? Buffer.from(output.stderr) : undefined
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function normalizeVfsResponse(name, response) {
|
|
95
|
+
if (response === undefined || response === null) return {}
|
|
96
|
+
if (response.error) return response
|
|
97
|
+
if (Buffer.isBuffer(response)) return { data: response, bytesRead: response.length }
|
|
98
|
+
if (Array.isArray(response)) return { entries: response }
|
|
99
|
+
if (typeof response === 'number') {
|
|
100
|
+
if (name === 'open') return { handle: response }
|
|
101
|
+
if (name === 'writeAt') return { bytesWritten: response }
|
|
102
|
+
}
|
|
103
|
+
return response
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function errorPayload(err) {
|
|
107
|
+
return {
|
|
108
|
+
code: normalizeErrnoCode(err?.code),
|
|
109
|
+
message: err?.message ?? String(err)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function normalizeErrnoCode(code) {
|
|
114
|
+
return errnos.includes(code) ? code : 'EINVAL'
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const vfsOperations = [
|
|
118
|
+
'stat',
|
|
119
|
+
'readdir',
|
|
120
|
+
'mkdir',
|
|
121
|
+
'rename',
|
|
122
|
+
'unlink',
|
|
123
|
+
'rmdir',
|
|
124
|
+
'open',
|
|
125
|
+
'readAt',
|
|
126
|
+
'writeAt',
|
|
127
|
+
'truncate',
|
|
128
|
+
'close'
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
const errnos = [
|
|
132
|
+
'EBADF',
|
|
133
|
+
'EBUSY',
|
|
134
|
+
'EACCES',
|
|
135
|
+
'EEXIST',
|
|
136
|
+
'EINVAL',
|
|
137
|
+
'EISDIR',
|
|
138
|
+
'ENOENT',
|
|
139
|
+
'ENOSPC',
|
|
140
|
+
'ENOTDIR',
|
|
141
|
+
'ENOTEMPTY'
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
class SandboxFs {
|
|
145
|
+
constructor(inner) {
|
|
146
|
+
this.inner = inner
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
stat(path) {
|
|
150
|
+
return decorateFsPromise(this.inner.stat(path))
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
readdir(path) {
|
|
154
|
+
return decorateFsPromise(this.inner.readdir(path))
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
mkdir(path) {
|
|
158
|
+
return decorateFsPromise(this.inner.mkdir(path))
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
rename(from, to) {
|
|
162
|
+
return decorateFsPromise(this.inner.rename(from, to))
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
unlink(path) {
|
|
166
|
+
return decorateFsPromise(this.inner.unlink(path))
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
rmdir(path) {
|
|
170
|
+
return decorateFsPromise(this.inner.rmdir(path))
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
readFile(path) {
|
|
174
|
+
return decorateFsPromise(this.inner.readFile(path))
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
writeFile(path, data) {
|
|
178
|
+
return decorateFsPromise(this.inner.writeFile(path, data))
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
appendFile(path, data) {
|
|
182
|
+
return decorateFsPromise(this.inner.appendFile(path, data))
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
open(path, mode) {
|
|
186
|
+
return decorateFsPromise(this.inner.open(path, mode))
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
readAt(handle, offset, len) {
|
|
190
|
+
return decorateFsPromise(this.inner.readAt(handle, offset, len))
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
writeAt(handle, offset, data) {
|
|
194
|
+
return decorateFsPromise(this.inner.writeAt(handle, offset, data))
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
truncate(handle, len) {
|
|
198
|
+
return decorateFsPromise(this.inner.truncate(handle, len))
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
close(handle) {
|
|
202
|
+
return decorateFsPromise(this.inner.close(handle))
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async function decorateFsPromise(promise) {
|
|
207
|
+
try {
|
|
208
|
+
return await promise
|
|
209
|
+
} catch (err) {
|
|
210
|
+
if (!err || typeof err !== 'object') throw err
|
|
211
|
+
err.code = normalizeNativeErrno(err)
|
|
212
|
+
throw err
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function normalizeNativeErrno(err) {
|
|
217
|
+
if (errnos.includes(err.code)) return err.code
|
|
218
|
+
const [prefix] = String(err.message ?? '').split(':', 1)
|
|
219
|
+
return errnos.includes(prefix) ? prefix : 'EINVAL'
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
exports.NativeSandbox = native.NativeSandbox
|
|
223
|
+
exports.SandboxFs = SandboxFs
|
|
224
|
+
exports.Sandbox = Sandbox
|
|
225
|
+
exports.runConformance = runConformance
|
package/native.cjs
ADDED
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
// prettier-ignore
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
// @ts-nocheck
|
|
4
|
+
/* auto-generated by NAPI-RS */
|
|
5
|
+
|
|
6
|
+
const { readFileSync } = require('fs')
|
|
7
|
+
let nativeBinding = null
|
|
8
|
+
const loadErrors = []
|
|
9
|
+
|
|
10
|
+
const isMusl = () => {
|
|
11
|
+
let musl = false
|
|
12
|
+
if (process.platform === 'linux') {
|
|
13
|
+
musl = isMuslFromFilesystem()
|
|
14
|
+
if (musl === null) {
|
|
15
|
+
musl = isMuslFromReport()
|
|
16
|
+
}
|
|
17
|
+
if (musl === null) {
|
|
18
|
+
musl = isMuslFromChildProcess()
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return musl
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
|
|
25
|
+
|
|
26
|
+
const isMuslFromFilesystem = () => {
|
|
27
|
+
try {
|
|
28
|
+
return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
|
|
29
|
+
} catch {
|
|
30
|
+
return null
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const isMuslFromReport = () => {
|
|
35
|
+
let report = null
|
|
36
|
+
if (process.report && typeof process.report.getReport === 'function') {
|
|
37
|
+
process.report.excludeNetwork = true
|
|
38
|
+
report = process.report.getReport()
|
|
39
|
+
}
|
|
40
|
+
if (!report) {
|
|
41
|
+
return null
|
|
42
|
+
}
|
|
43
|
+
if (report.header && report.header.glibcVersionRuntime) {
|
|
44
|
+
return false
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(report.sharedObjects)) {
|
|
47
|
+
if (report.sharedObjects.some(isFileMusl)) {
|
|
48
|
+
return true
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return false
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const isMuslFromChildProcess = () => {
|
|
55
|
+
try {
|
|
56
|
+
return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
|
|
57
|
+
} catch (e) {
|
|
58
|
+
// If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
|
|
59
|
+
return false
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function requireNative() {
|
|
64
|
+
if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
|
|
65
|
+
try {
|
|
66
|
+
return require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH);
|
|
67
|
+
} catch (err) {
|
|
68
|
+
loadErrors.push(err)
|
|
69
|
+
}
|
|
70
|
+
} else if (process.platform === 'android') {
|
|
71
|
+
if (process.arch === 'arm64') {
|
|
72
|
+
try {
|
|
73
|
+
return require('./tinysandbox-node.android-arm64.node')
|
|
74
|
+
} catch (e) {
|
|
75
|
+
loadErrors.push(e)
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const binding = require('tinysandbox-android-arm64')
|
|
79
|
+
const bindingPackageVersion = require('tinysandbox-android-arm64/package.json').version
|
|
80
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
81
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
82
|
+
}
|
|
83
|
+
return binding
|
|
84
|
+
} catch (e) {
|
|
85
|
+
loadErrors.push(e)
|
|
86
|
+
}
|
|
87
|
+
} else if (process.arch === 'arm') {
|
|
88
|
+
try {
|
|
89
|
+
return require('./tinysandbox-node.android-arm-eabi.node')
|
|
90
|
+
} catch (e) {
|
|
91
|
+
loadErrors.push(e)
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const binding = require('tinysandbox-android-arm-eabi')
|
|
95
|
+
const bindingPackageVersion = require('tinysandbox-android-arm-eabi/package.json').version
|
|
96
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
97
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
98
|
+
}
|
|
99
|
+
return binding
|
|
100
|
+
} catch (e) {
|
|
101
|
+
loadErrors.push(e)
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`))
|
|
105
|
+
}
|
|
106
|
+
} else if (process.platform === 'win32') {
|
|
107
|
+
if (process.arch === 'x64') {
|
|
108
|
+
if ((process.config && process.config.variables && process.config.variables.shlib_suffix === 'dll.a') || (process.config && process.config.variables && process.config.variables.node_target_type === 'shared_library')) {
|
|
109
|
+
try {
|
|
110
|
+
return require('./tinysandbox-node.win32-x64-gnu.node')
|
|
111
|
+
} catch (e) {
|
|
112
|
+
loadErrors.push(e)
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
const binding = require('tinysandbox-win32-x64-gnu')
|
|
116
|
+
const bindingPackageVersion = require('tinysandbox-win32-x64-gnu/package.json').version
|
|
117
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
118
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
119
|
+
}
|
|
120
|
+
return binding
|
|
121
|
+
} catch (e) {
|
|
122
|
+
loadErrors.push(e)
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
try {
|
|
126
|
+
return require('./tinysandbox-node.win32-x64-msvc.node')
|
|
127
|
+
} catch (e) {
|
|
128
|
+
loadErrors.push(e)
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const binding = require('tinysandbox-win32-x64-msvc')
|
|
132
|
+
const bindingPackageVersion = require('tinysandbox-win32-x64-msvc/package.json').version
|
|
133
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
134
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
135
|
+
}
|
|
136
|
+
return binding
|
|
137
|
+
} catch (e) {
|
|
138
|
+
loadErrors.push(e)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
} else if (process.arch === 'ia32') {
|
|
142
|
+
try {
|
|
143
|
+
return require('./tinysandbox-node.win32-ia32-msvc.node')
|
|
144
|
+
} catch (e) {
|
|
145
|
+
loadErrors.push(e)
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
const binding = require('tinysandbox-win32-ia32-msvc')
|
|
149
|
+
const bindingPackageVersion = require('tinysandbox-win32-ia32-msvc/package.json').version
|
|
150
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
151
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
152
|
+
}
|
|
153
|
+
return binding
|
|
154
|
+
} catch (e) {
|
|
155
|
+
loadErrors.push(e)
|
|
156
|
+
}
|
|
157
|
+
} else if (process.arch === 'arm64') {
|
|
158
|
+
try {
|
|
159
|
+
return require('./tinysandbox-node.win32-arm64-msvc.node')
|
|
160
|
+
} catch (e) {
|
|
161
|
+
loadErrors.push(e)
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const binding = require('tinysandbox-win32-arm64-msvc')
|
|
165
|
+
const bindingPackageVersion = require('tinysandbox-win32-arm64-msvc/package.json').version
|
|
166
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
167
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
168
|
+
}
|
|
169
|
+
return binding
|
|
170
|
+
} catch (e) {
|
|
171
|
+
loadErrors.push(e)
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`))
|
|
175
|
+
}
|
|
176
|
+
} else if (process.platform === 'darwin') {
|
|
177
|
+
try {
|
|
178
|
+
return require('./tinysandbox-node.darwin-universal.node')
|
|
179
|
+
} catch (e) {
|
|
180
|
+
loadErrors.push(e)
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
const binding = require('tinysandbox-darwin-universal')
|
|
184
|
+
const bindingPackageVersion = require('tinysandbox-darwin-universal/package.json').version
|
|
185
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
186
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
187
|
+
}
|
|
188
|
+
return binding
|
|
189
|
+
} catch (e) {
|
|
190
|
+
loadErrors.push(e)
|
|
191
|
+
}
|
|
192
|
+
if (process.arch === 'x64') {
|
|
193
|
+
try {
|
|
194
|
+
return require('./tinysandbox-node.darwin-x64.node')
|
|
195
|
+
} catch (e) {
|
|
196
|
+
loadErrors.push(e)
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
const binding = require('tinysandbox-darwin-x64')
|
|
200
|
+
const bindingPackageVersion = require('tinysandbox-darwin-x64/package.json').version
|
|
201
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
202
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
203
|
+
}
|
|
204
|
+
return binding
|
|
205
|
+
} catch (e) {
|
|
206
|
+
loadErrors.push(e)
|
|
207
|
+
}
|
|
208
|
+
} else if (process.arch === 'arm64') {
|
|
209
|
+
try {
|
|
210
|
+
return require('./tinysandbox-node.darwin-arm64.node')
|
|
211
|
+
} catch (e) {
|
|
212
|
+
loadErrors.push(e)
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
const binding = require('tinysandbox-darwin-arm64')
|
|
216
|
+
const bindingPackageVersion = require('tinysandbox-darwin-arm64/package.json').version
|
|
217
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
218
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
219
|
+
}
|
|
220
|
+
return binding
|
|
221
|
+
} catch (e) {
|
|
222
|
+
loadErrors.push(e)
|
|
223
|
+
}
|
|
224
|
+
} else {
|
|
225
|
+
loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`))
|
|
226
|
+
}
|
|
227
|
+
} else if (process.platform === 'freebsd') {
|
|
228
|
+
if (process.arch === 'x64') {
|
|
229
|
+
try {
|
|
230
|
+
return require('./tinysandbox-node.freebsd-x64.node')
|
|
231
|
+
} catch (e) {
|
|
232
|
+
loadErrors.push(e)
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
const binding = require('tinysandbox-freebsd-x64')
|
|
236
|
+
const bindingPackageVersion = require('tinysandbox-freebsd-x64/package.json').version
|
|
237
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
238
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
239
|
+
}
|
|
240
|
+
return binding
|
|
241
|
+
} catch (e) {
|
|
242
|
+
loadErrors.push(e)
|
|
243
|
+
}
|
|
244
|
+
} else if (process.arch === 'arm64') {
|
|
245
|
+
try {
|
|
246
|
+
return require('./tinysandbox-node.freebsd-arm64.node')
|
|
247
|
+
} catch (e) {
|
|
248
|
+
loadErrors.push(e)
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
const binding = require('tinysandbox-freebsd-arm64')
|
|
252
|
+
const bindingPackageVersion = require('tinysandbox-freebsd-arm64/package.json').version
|
|
253
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
254
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
255
|
+
}
|
|
256
|
+
return binding
|
|
257
|
+
} catch (e) {
|
|
258
|
+
loadErrors.push(e)
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`))
|
|
262
|
+
}
|
|
263
|
+
} else if (process.platform === 'linux') {
|
|
264
|
+
if (process.arch === 'x64') {
|
|
265
|
+
if (isMusl()) {
|
|
266
|
+
try {
|
|
267
|
+
return require('./tinysandbox-node.linux-x64-musl.node')
|
|
268
|
+
} catch (e) {
|
|
269
|
+
loadErrors.push(e)
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
const binding = require('tinysandbox-linux-x64-musl')
|
|
273
|
+
const bindingPackageVersion = require('tinysandbox-linux-x64-musl/package.json').version
|
|
274
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
275
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
276
|
+
}
|
|
277
|
+
return binding
|
|
278
|
+
} catch (e) {
|
|
279
|
+
loadErrors.push(e)
|
|
280
|
+
}
|
|
281
|
+
} else {
|
|
282
|
+
try {
|
|
283
|
+
return require('./tinysandbox-node.linux-x64-gnu.node')
|
|
284
|
+
} catch (e) {
|
|
285
|
+
loadErrors.push(e)
|
|
286
|
+
}
|
|
287
|
+
try {
|
|
288
|
+
const binding = require('tinysandbox-linux-x64-gnu')
|
|
289
|
+
const bindingPackageVersion = require('tinysandbox-linux-x64-gnu/package.json').version
|
|
290
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
291
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
292
|
+
}
|
|
293
|
+
return binding
|
|
294
|
+
} catch (e) {
|
|
295
|
+
loadErrors.push(e)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
} else if (process.arch === 'arm64') {
|
|
299
|
+
if (isMusl()) {
|
|
300
|
+
try {
|
|
301
|
+
return require('./tinysandbox-node.linux-arm64-musl.node')
|
|
302
|
+
} catch (e) {
|
|
303
|
+
loadErrors.push(e)
|
|
304
|
+
}
|
|
305
|
+
try {
|
|
306
|
+
const binding = require('tinysandbox-linux-arm64-musl')
|
|
307
|
+
const bindingPackageVersion = require('tinysandbox-linux-arm64-musl/package.json').version
|
|
308
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
309
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
310
|
+
}
|
|
311
|
+
return binding
|
|
312
|
+
} catch (e) {
|
|
313
|
+
loadErrors.push(e)
|
|
314
|
+
}
|
|
315
|
+
} else {
|
|
316
|
+
try {
|
|
317
|
+
return require('./tinysandbox-node.linux-arm64-gnu.node')
|
|
318
|
+
} catch (e) {
|
|
319
|
+
loadErrors.push(e)
|
|
320
|
+
}
|
|
321
|
+
try {
|
|
322
|
+
const binding = require('tinysandbox-linux-arm64-gnu')
|
|
323
|
+
const bindingPackageVersion = require('tinysandbox-linux-arm64-gnu/package.json').version
|
|
324
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
325
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
326
|
+
}
|
|
327
|
+
return binding
|
|
328
|
+
} catch (e) {
|
|
329
|
+
loadErrors.push(e)
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
} else if (process.arch === 'arm') {
|
|
333
|
+
if (isMusl()) {
|
|
334
|
+
try {
|
|
335
|
+
return require('./tinysandbox-node.linux-arm-musleabihf.node')
|
|
336
|
+
} catch (e) {
|
|
337
|
+
loadErrors.push(e)
|
|
338
|
+
}
|
|
339
|
+
try {
|
|
340
|
+
const binding = require('tinysandbox-linux-arm-musleabihf')
|
|
341
|
+
const bindingPackageVersion = require('tinysandbox-linux-arm-musleabihf/package.json').version
|
|
342
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
343
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
344
|
+
}
|
|
345
|
+
return binding
|
|
346
|
+
} catch (e) {
|
|
347
|
+
loadErrors.push(e)
|
|
348
|
+
}
|
|
349
|
+
} else {
|
|
350
|
+
try {
|
|
351
|
+
return require('./tinysandbox-node.linux-arm-gnueabihf.node')
|
|
352
|
+
} catch (e) {
|
|
353
|
+
loadErrors.push(e)
|
|
354
|
+
}
|
|
355
|
+
try {
|
|
356
|
+
const binding = require('tinysandbox-linux-arm-gnueabihf')
|
|
357
|
+
const bindingPackageVersion = require('tinysandbox-linux-arm-gnueabihf/package.json').version
|
|
358
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
359
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
360
|
+
}
|
|
361
|
+
return binding
|
|
362
|
+
} catch (e) {
|
|
363
|
+
loadErrors.push(e)
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
} else if (process.arch === 'loong64') {
|
|
367
|
+
if (isMusl()) {
|
|
368
|
+
try {
|
|
369
|
+
return require('./tinysandbox-node.linux-loong64-musl.node')
|
|
370
|
+
} catch (e) {
|
|
371
|
+
loadErrors.push(e)
|
|
372
|
+
}
|
|
373
|
+
try {
|
|
374
|
+
const binding = require('tinysandbox-linux-loong64-musl')
|
|
375
|
+
const bindingPackageVersion = require('tinysandbox-linux-loong64-musl/package.json').version
|
|
376
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
377
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
378
|
+
}
|
|
379
|
+
return binding
|
|
380
|
+
} catch (e) {
|
|
381
|
+
loadErrors.push(e)
|
|
382
|
+
}
|
|
383
|
+
} else {
|
|
384
|
+
try {
|
|
385
|
+
return require('./tinysandbox-node.linux-loong64-gnu.node')
|
|
386
|
+
} catch (e) {
|
|
387
|
+
loadErrors.push(e)
|
|
388
|
+
}
|
|
389
|
+
try {
|
|
390
|
+
const binding = require('tinysandbox-linux-loong64-gnu')
|
|
391
|
+
const bindingPackageVersion = require('tinysandbox-linux-loong64-gnu/package.json').version
|
|
392
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
393
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
394
|
+
}
|
|
395
|
+
return binding
|
|
396
|
+
} catch (e) {
|
|
397
|
+
loadErrors.push(e)
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
} else if (process.arch === 'riscv64') {
|
|
401
|
+
if (isMusl()) {
|
|
402
|
+
try {
|
|
403
|
+
return require('./tinysandbox-node.linux-riscv64-musl.node')
|
|
404
|
+
} catch (e) {
|
|
405
|
+
loadErrors.push(e)
|
|
406
|
+
}
|
|
407
|
+
try {
|
|
408
|
+
const binding = require('tinysandbox-linux-riscv64-musl')
|
|
409
|
+
const bindingPackageVersion = require('tinysandbox-linux-riscv64-musl/package.json').version
|
|
410
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
411
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
412
|
+
}
|
|
413
|
+
return binding
|
|
414
|
+
} catch (e) {
|
|
415
|
+
loadErrors.push(e)
|
|
416
|
+
}
|
|
417
|
+
} else {
|
|
418
|
+
try {
|
|
419
|
+
return require('./tinysandbox-node.linux-riscv64-gnu.node')
|
|
420
|
+
} catch (e) {
|
|
421
|
+
loadErrors.push(e)
|
|
422
|
+
}
|
|
423
|
+
try {
|
|
424
|
+
const binding = require('tinysandbox-linux-riscv64-gnu')
|
|
425
|
+
const bindingPackageVersion = require('tinysandbox-linux-riscv64-gnu/package.json').version
|
|
426
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
427
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
428
|
+
}
|
|
429
|
+
return binding
|
|
430
|
+
} catch (e) {
|
|
431
|
+
loadErrors.push(e)
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
} else if (process.arch === 'ppc64') {
|
|
435
|
+
try {
|
|
436
|
+
return require('./tinysandbox-node.linux-ppc64-gnu.node')
|
|
437
|
+
} catch (e) {
|
|
438
|
+
loadErrors.push(e)
|
|
439
|
+
}
|
|
440
|
+
try {
|
|
441
|
+
const binding = require('tinysandbox-linux-ppc64-gnu')
|
|
442
|
+
const bindingPackageVersion = require('tinysandbox-linux-ppc64-gnu/package.json').version
|
|
443
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
444
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
445
|
+
}
|
|
446
|
+
return binding
|
|
447
|
+
} catch (e) {
|
|
448
|
+
loadErrors.push(e)
|
|
449
|
+
}
|
|
450
|
+
} else if (process.arch === 's390x') {
|
|
451
|
+
try {
|
|
452
|
+
return require('./tinysandbox-node.linux-s390x-gnu.node')
|
|
453
|
+
} catch (e) {
|
|
454
|
+
loadErrors.push(e)
|
|
455
|
+
}
|
|
456
|
+
try {
|
|
457
|
+
const binding = require('tinysandbox-linux-s390x-gnu')
|
|
458
|
+
const bindingPackageVersion = require('tinysandbox-linux-s390x-gnu/package.json').version
|
|
459
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
460
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
461
|
+
}
|
|
462
|
+
return binding
|
|
463
|
+
} catch (e) {
|
|
464
|
+
loadErrors.push(e)
|
|
465
|
+
}
|
|
466
|
+
} else {
|
|
467
|
+
loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
|
|
468
|
+
}
|
|
469
|
+
} else if (process.platform === 'openharmony') {
|
|
470
|
+
if (process.arch === 'arm64') {
|
|
471
|
+
try {
|
|
472
|
+
return require('./tinysandbox-node.openharmony-arm64.node')
|
|
473
|
+
} catch (e) {
|
|
474
|
+
loadErrors.push(e)
|
|
475
|
+
}
|
|
476
|
+
try {
|
|
477
|
+
const binding = require('tinysandbox-openharmony-arm64')
|
|
478
|
+
const bindingPackageVersion = require('tinysandbox-openharmony-arm64/package.json').version
|
|
479
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
480
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
481
|
+
}
|
|
482
|
+
return binding
|
|
483
|
+
} catch (e) {
|
|
484
|
+
loadErrors.push(e)
|
|
485
|
+
}
|
|
486
|
+
} else if (process.arch === 'x64') {
|
|
487
|
+
try {
|
|
488
|
+
return require('./tinysandbox-node.openharmony-x64.node')
|
|
489
|
+
} catch (e) {
|
|
490
|
+
loadErrors.push(e)
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
const binding = require('tinysandbox-openharmony-x64')
|
|
494
|
+
const bindingPackageVersion = require('tinysandbox-openharmony-x64/package.json').version
|
|
495
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
496
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
497
|
+
}
|
|
498
|
+
return binding
|
|
499
|
+
} catch (e) {
|
|
500
|
+
loadErrors.push(e)
|
|
501
|
+
}
|
|
502
|
+
} else if (process.arch === 'arm') {
|
|
503
|
+
try {
|
|
504
|
+
return require('./tinysandbox-node.openharmony-arm.node')
|
|
505
|
+
} catch (e) {
|
|
506
|
+
loadErrors.push(e)
|
|
507
|
+
}
|
|
508
|
+
try {
|
|
509
|
+
const binding = require('tinysandbox-openharmony-arm')
|
|
510
|
+
const bindingPackageVersion = require('tinysandbox-openharmony-arm/package.json').version
|
|
511
|
+
if (bindingPackageVersion !== '0.3.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
512
|
+
throw new Error(`Native binding package version mismatch, expected 0.3.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
513
|
+
}
|
|
514
|
+
return binding
|
|
515
|
+
} catch (e) {
|
|
516
|
+
loadErrors.push(e)
|
|
517
|
+
}
|
|
518
|
+
} else {
|
|
519
|
+
loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`))
|
|
520
|
+
}
|
|
521
|
+
} else {
|
|
522
|
+
loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
nativeBinding = requireNative()
|
|
527
|
+
|
|
528
|
+
// NAPI_RS_FORCE_WASI is a tri-state flag:
|
|
529
|
+
// unset / any other value → native binding preferred, WASI is only a fallback
|
|
530
|
+
// 'true' → force WASI fallback even if native loaded
|
|
531
|
+
// 'error' → force WASI and throw if no WASI binding is found
|
|
532
|
+
// Treating any non-empty string as truthy (the historical behavior) meant
|
|
533
|
+
// NAPI_RS_FORCE_WASI=false, NAPI_RS_FORCE_WASI=0, etc. inadvertently triggered
|
|
534
|
+
// the WASI path, causing ENOENT for packages shipped without a .wasi.cjs file.
|
|
535
|
+
const forceWasi =
|
|
536
|
+
process.env.NAPI_RS_FORCE_WASI === 'true' || process.env.NAPI_RS_FORCE_WASI === 'error'
|
|
537
|
+
|
|
538
|
+
if (!nativeBinding || forceWasi) {
|
|
539
|
+
let wasiBinding = null
|
|
540
|
+
let wasiBindingError = null
|
|
541
|
+
try {
|
|
542
|
+
wasiBinding = require('./tinysandbox-node.wasi.cjs')
|
|
543
|
+
nativeBinding = wasiBinding
|
|
544
|
+
} catch (err) {
|
|
545
|
+
if (forceWasi) {
|
|
546
|
+
wasiBindingError = err
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
if (!nativeBinding || forceWasi) {
|
|
550
|
+
try {
|
|
551
|
+
wasiBinding = require('tinysandbox-wasm32-wasi')
|
|
552
|
+
nativeBinding = wasiBinding
|
|
553
|
+
} catch (err) {
|
|
554
|
+
if (forceWasi) {
|
|
555
|
+
if (!wasiBindingError) {
|
|
556
|
+
wasiBindingError = err
|
|
557
|
+
} else {
|
|
558
|
+
wasiBindingError.cause = err
|
|
559
|
+
}
|
|
560
|
+
loadErrors.push(err)
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
if (process.env.NAPI_RS_FORCE_WASI === 'error' && !wasiBinding) {
|
|
565
|
+
const error = new Error('WASI binding not found and NAPI_RS_FORCE_WASI is set to error')
|
|
566
|
+
error.cause = wasiBindingError
|
|
567
|
+
throw error
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
if (!nativeBinding) {
|
|
572
|
+
if (loadErrors.length > 0) {
|
|
573
|
+
const error = new Error(
|
|
574
|
+
`Cannot find native binding. ` +
|
|
575
|
+
`npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
|
|
576
|
+
'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
|
|
577
|
+
)
|
|
578
|
+
// assign instead of the `new Error(message, { cause })` options form,
|
|
579
|
+
// which Node < 16.9 silently ignores
|
|
580
|
+
error.cause = loadErrors.reduce((err, cur) => {
|
|
581
|
+
cur.cause = err
|
|
582
|
+
return cur
|
|
583
|
+
})
|
|
584
|
+
throw error
|
|
585
|
+
}
|
|
586
|
+
throw new Error(`Failed to load native binding`)
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
module.exports = nativeBinding
|
|
590
|
+
module.exports.NativeSandbox = nativeBinding.NativeSandbox
|
|
591
|
+
module.exports.Sandbox = nativeBinding.Sandbox
|
|
592
|
+
module.exports.SandboxFs = nativeBinding.SandboxFs
|
|
593
|
+
module.exports.createJsVfs = nativeBinding.createJsVfs
|
|
594
|
+
module.exports.runConformance = nativeBinding.runConformance
|
package/native.d.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/* auto-generated by NAPI-RS */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
export declare class ExternalObject<T> {
|
|
5
|
+
readonly '': {
|
|
6
|
+
readonly '': unique symbol
|
|
7
|
+
[K: symbol]: T
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export declare class NativeSandbox {
|
|
11
|
+
constructor(options?: object | undefined | null)
|
|
12
|
+
exec(script: string): Promise<ExecResult>
|
|
13
|
+
get fs(): SandboxFs
|
|
14
|
+
stats(): Promise<SandboxStats>
|
|
15
|
+
}
|
|
16
|
+
export type Sandbox = NativeSandbox
|
|
17
|
+
|
|
18
|
+
export declare class SandboxFs {
|
|
19
|
+
stat(path: string): Promise<FileStat>
|
|
20
|
+
readdir(path: string): Promise<Array<DirEntryJs>>
|
|
21
|
+
mkdir(path: string): Promise<void>
|
|
22
|
+
rename(from: string, to: string): Promise<void>
|
|
23
|
+
unlink(path: string): Promise<void>
|
|
24
|
+
rmdir(path: string): Promise<void>
|
|
25
|
+
readFile(path: string): Promise<Buffer>
|
|
26
|
+
writeFile(path: string, data: Buffer): Promise<void>
|
|
27
|
+
appendFile(path: string, data: Buffer): Promise<void>
|
|
28
|
+
open(path: string, mode: OpenModeJs): Promise<number>
|
|
29
|
+
readAt(handle: number, offset: number, len: number): Promise<Buffer>
|
|
30
|
+
writeAt(handle: number, offset: number, data: Buffer): Promise<number>
|
|
31
|
+
truncate(handle: number, len: number): Promise<void>
|
|
32
|
+
close(handle: number): Promise<void>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface CommandCall {
|
|
36
|
+
args: Array<string>
|
|
37
|
+
env: Record<string, string>
|
|
38
|
+
cwd: string
|
|
39
|
+
stdin: Buffer
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface CommandOutput {
|
|
43
|
+
exitCode?: number
|
|
44
|
+
stdout?: Buffer
|
|
45
|
+
stderr?: Buffer
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface CommandTiming {
|
|
49
|
+
name: string
|
|
50
|
+
durationMs: number
|
|
51
|
+
exitCode: number
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface ConformanceResult {
|
|
55
|
+
ok: boolean
|
|
56
|
+
snapshots: string
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export declare function createJsVfs(vfs: object): ExternalObject<JsVfsExternal>
|
|
60
|
+
|
|
61
|
+
export interface DirEntryJs {
|
|
62
|
+
name: string
|
|
63
|
+
fileType: string
|
|
64
|
+
len: number
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface ExecResult {
|
|
68
|
+
stdout: string
|
|
69
|
+
stderr: string
|
|
70
|
+
exitCode: number
|
|
71
|
+
wallTimeMs: number
|
|
72
|
+
stdoutTruncated: boolean
|
|
73
|
+
stderrTruncated: boolean
|
|
74
|
+
pipeBytes: Array<number>
|
|
75
|
+
commands: Array<CommandTiming>
|
|
76
|
+
peakWasmMemoryBytes?: number
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface FileStat {
|
|
80
|
+
fileType: string
|
|
81
|
+
len: number
|
|
82
|
+
isFile: boolean
|
|
83
|
+
isDir: boolean
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface OpenModeJs {
|
|
87
|
+
read?: boolean
|
|
88
|
+
write?: boolean
|
|
89
|
+
create?: boolean
|
|
90
|
+
createNew?: boolean
|
|
91
|
+
truncate?: boolean
|
|
92
|
+
append?: boolean
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export declare function runConformance(factory: (arg: [VfsQuotaJs]) => Promise<JsVfsHandle>): Promise<unknown>
|
|
96
|
+
|
|
97
|
+
export interface SandboxStats {
|
|
98
|
+
commandsRun: number
|
|
99
|
+
vfs?: VfsStatsJs
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface VfsCallbackError {
|
|
103
|
+
code?: string
|
|
104
|
+
message?: string
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface VfsQuotaJs {
|
|
108
|
+
maxBytes: number
|
|
109
|
+
maxFiles: number
|
|
110
|
+
maxFileSize: number
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface VfsRequest {
|
|
114
|
+
path?: string
|
|
115
|
+
from?: string
|
|
116
|
+
to?: string
|
|
117
|
+
mode?: OpenModeJs
|
|
118
|
+
handle?: number
|
|
119
|
+
offset?: number
|
|
120
|
+
len?: number
|
|
121
|
+
data?: Buffer
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface VfsResponse {
|
|
125
|
+
fileType?: string
|
|
126
|
+
len?: number
|
|
127
|
+
entries?: Array<DirEntryJs>
|
|
128
|
+
handle?: number
|
|
129
|
+
bytesRead?: number
|
|
130
|
+
bytesWritten?: number
|
|
131
|
+
data?: Buffer
|
|
132
|
+
usedBytes?: number
|
|
133
|
+
fileCount?: number
|
|
134
|
+
error?: VfsCallbackError
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface VfsStatsJs {
|
|
138
|
+
usedBytes: number
|
|
139
|
+
fileCount: number
|
|
140
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tinysandbox/tinysandbox",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Node.js bindings for the tinysandbox in-process AI agent sandbox",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "napi build --platform --release --js native.cjs --dts native.d.ts",
|
|
9
|
+
"test": "npm run build && node --import tsx --test __test__/*.mjs",
|
|
10
|
+
"examples": "tsx examples/quickstart.ts && tsx examples/custom_command.ts && tsx examples/js_scripts.ts && tsx examples/js_vfs.ts"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/danthegoodman1/tinysandbox.git",
|
|
15
|
+
"directory": "tinysandbox-node"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"sandbox",
|
|
19
|
+
"agent",
|
|
20
|
+
"shell",
|
|
21
|
+
"vfs",
|
|
22
|
+
"quickjs"
|
|
23
|
+
],
|
|
24
|
+
"author": "Dan Goodman",
|
|
25
|
+
"license": "MIT OR Apache-2.0",
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=20"
|
|
28
|
+
},
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/danthegoodman1/tinysandbox/issues"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/danthegoodman1/tinysandbox#readme",
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@napi-rs/cli": "^3.7.2",
|
|
35
|
+
"@types/node": "^26.1.0",
|
|
36
|
+
"tsx": "^4.23.0"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"index.js",
|
|
40
|
+
"index.d.ts",
|
|
41
|
+
"native.cjs",
|
|
42
|
+
"native.d.ts",
|
|
43
|
+
"*.node"
|
|
44
|
+
],
|
|
45
|
+
"napi": {
|
|
46
|
+
"binaryName": "tinysandbox-node",
|
|
47
|
+
"packageName": "tinysandbox"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
Binary file
|