@jscad/cli 2.2.26 → 3.0.0-alpha.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/CHANGELOG.md +15 -224
- package/README.md +11 -1
- package/cli.conversions.test.js +31 -64
- package/cli.js +67 -15
- package/cli.parameters.test.js +123 -27
- package/package.json +12 -9
- package/src/determineOutputNameAndFormat.js +2 -4
- package/src/env.js +5 -8
- package/src/generateOutputData.js +48 -32
- package/src/parseArgs.js +30 -10
- package/src/writeOutput.js +2 -6
package/cli.conversions.test.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import { cwd } from 'process'
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
import test from 'ava'
|
|
6
|
+
|
|
7
|
+
import { execSync } from 'child_process'
|
|
6
8
|
|
|
7
9
|
test.afterEach.always((t) => {
|
|
8
10
|
// remove files
|
|
@@ -26,7 +28,7 @@ test.afterEach.always((t) => {
|
|
|
26
28
|
test.beforeEach((t) => {
|
|
27
29
|
const cliName = './cli.js'
|
|
28
30
|
t.context = {
|
|
29
|
-
cliPath: path.resolve(
|
|
31
|
+
cliPath: path.resolve(cwd(), cliName)
|
|
30
32
|
}
|
|
31
33
|
})
|
|
32
34
|
|
|
@@ -38,32 +40,30 @@ test.beforeEach((t) => {
|
|
|
38
40
|
// the script should produce ALL geometry types
|
|
39
41
|
const createJscad = (id) => {
|
|
40
42
|
const jscadScript = `// test script ${id}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
import { flatten } from '@jscad/array-utils'
|
|
44
|
+
import { arc, ellipse, ellipsoid } from '@jscad/modeling'
|
|
43
45
|
|
|
44
|
-
const getParameterDefinitions = () => {
|
|
46
|
+
export const getParameterDefinitions = () => {
|
|
45
47
|
return flatten([
|
|
46
48
|
{ name: 'segments', caption: 'Segements:', type: 'int', initial: 10, min: 5, max: 20, step: 1 }
|
|
47
49
|
])
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
const main = (params) => {
|
|
52
|
+
export const main = (params) => {
|
|
51
53
|
// parameters
|
|
52
54
|
let segments = params.segments || 16
|
|
53
55
|
|
|
54
56
|
// shapes
|
|
55
|
-
let apath2 =
|
|
56
|
-
let ageom2 =
|
|
57
|
-
let ageom3 =
|
|
57
|
+
let apath2 = arc()
|
|
58
|
+
let ageom2 = ellipse()
|
|
59
|
+
let ageom3 = ellipsoid()
|
|
58
60
|
|
|
59
61
|
return [apath2, ageom2, ageom3]
|
|
60
62
|
}
|
|
61
|
-
|
|
62
|
-
module.exports = { main, getParameterDefinitions }
|
|
63
63
|
`
|
|
64
64
|
|
|
65
|
-
const fileName = `./
|
|
66
|
-
const filePath = path.resolve(
|
|
65
|
+
const fileName = `./base${id}.js`
|
|
66
|
+
const filePath = path.resolve(cwd(), fileName)
|
|
67
67
|
fs.writeFileSync(filePath, jscadScript)
|
|
68
68
|
return filePath
|
|
69
69
|
}
|
|
@@ -78,20 +78,20 @@ test('cli (conversions STL)', (t) => {
|
|
|
78
78
|
t.context.file1Path = file1Path
|
|
79
79
|
|
|
80
80
|
const file2Name = `./test${testID}.stl`
|
|
81
|
-
const file2Path = path.resolve(
|
|
81
|
+
const file2Path = path.resolve(cwd(), file2Name)
|
|
82
82
|
t.false(fs.existsSync(file2Path))
|
|
83
83
|
|
|
84
84
|
t.context.file2Path = file2Path
|
|
85
85
|
|
|
86
86
|
const cliPath = t.context.cliPath
|
|
87
87
|
|
|
88
|
-
let cmd = `node ${cliPath} ${file1Path}`
|
|
88
|
+
let cmd = `node ${cliPath} ${file1Path} -o ${file2Path}`
|
|
89
89
|
execSync(cmd, { stdio: [0, 1, 2] })
|
|
90
90
|
t.true(fs.existsSync(file2Path))
|
|
91
91
|
|
|
92
92
|
// convert from STL to JSCAD script
|
|
93
93
|
const file3Name = `./test${testID}.js`
|
|
94
|
-
const file3Path = path.resolve(
|
|
94
|
+
const file3Path = path.resolve(cwd(), file3Name)
|
|
95
95
|
t.false(fs.existsSync(file3Path))
|
|
96
96
|
|
|
97
97
|
t.context.file3Path = file3Path
|
|
@@ -111,53 +111,20 @@ test('cli (conversions DXF)', (t) => {
|
|
|
111
111
|
t.context.file1Path = file1Path
|
|
112
112
|
|
|
113
113
|
const file2Name = `./test${testID}.dxf`
|
|
114
|
-
const file2Path = path.resolve(
|
|
114
|
+
const file2Path = path.resolve(cwd(), file2Name)
|
|
115
115
|
t.false(fs.existsSync(file2Path))
|
|
116
116
|
|
|
117
117
|
t.context.file2Path = file2Path
|
|
118
118
|
|
|
119
119
|
const cliPath = t.context.cliPath
|
|
120
120
|
|
|
121
|
-
let cmd = `node ${cliPath} ${file1Path} -
|
|
121
|
+
let cmd = `node ${cliPath} ${file1Path} -o ${file2Path}`
|
|
122
122
|
execSync(cmd, { stdio: [0, 1, 2] })
|
|
123
123
|
t.true(fs.existsSync(file2Path))
|
|
124
124
|
|
|
125
125
|
// convert from DXF to JS
|
|
126
126
|
const file3Name = `./test${testID}.js`
|
|
127
|
-
const file3Path = path.resolve(
|
|
128
|
-
t.false(fs.existsSync(file3Path))
|
|
129
|
-
|
|
130
|
-
t.context.file3Path = file3Path
|
|
131
|
-
|
|
132
|
-
cmd = `node ${cliPath} ${file2Path} -of js`
|
|
133
|
-
execSync(cmd, { stdio: [0, 1, 2] })
|
|
134
|
-
t.true(fs.existsSync(file3Path))
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
test('cli (conversions AMF)', (t) => {
|
|
138
|
-
const testID = 13
|
|
139
|
-
|
|
140
|
-
// convert from JSCAD to AMF
|
|
141
|
-
const file1Path = createJscad(testID)
|
|
142
|
-
t.true(fs.existsSync(file1Path))
|
|
143
|
-
|
|
144
|
-
t.context.file1Path = file1Path
|
|
145
|
-
|
|
146
|
-
const file2Name = `./test${testID}.amf`
|
|
147
|
-
const file2Path = path.resolve(__dirname, file2Name)
|
|
148
|
-
t.false(fs.existsSync(file2Path))
|
|
149
|
-
|
|
150
|
-
t.context.file2Path = file2Path
|
|
151
|
-
|
|
152
|
-
const cliPath = t.context.cliPath
|
|
153
|
-
|
|
154
|
-
let cmd = `node ${cliPath} ${file1Path} -of amf`
|
|
155
|
-
execSync(cmd, { stdio: [0, 1, 2] })
|
|
156
|
-
t.true(fs.existsSync(file2Path))
|
|
157
|
-
|
|
158
|
-
// convert from AMF to JS
|
|
159
|
-
const file3Name = `./test${testID}.js`
|
|
160
|
-
const file3Path = path.resolve(__dirname, file3Name)
|
|
127
|
+
const file3Path = path.resolve(cwd(), file3Name)
|
|
161
128
|
t.false(fs.existsSync(file3Path))
|
|
162
129
|
|
|
163
130
|
t.context.file3Path = file3Path
|
|
@@ -177,20 +144,20 @@ test('cli (conversions JSON)', (t) => {
|
|
|
177
144
|
t.context.file1Path = file1Path
|
|
178
145
|
|
|
179
146
|
const file2Name = `./test${testID}.json`
|
|
180
|
-
const file2Path = path.resolve(
|
|
147
|
+
const file2Path = path.resolve(cwd(), file2Name)
|
|
181
148
|
t.false(fs.existsSync(file2Path))
|
|
182
149
|
|
|
183
150
|
t.context.file2Path = file2Path
|
|
184
151
|
|
|
185
152
|
const cliPath = t.context.cliPath
|
|
186
153
|
|
|
187
|
-
let cmd = `node ${cliPath} ${file1Path} -
|
|
154
|
+
let cmd = `node ${cliPath} ${file1Path} -o ${file2Path}`
|
|
188
155
|
execSync(cmd, { stdio: [0, 1, 2] })
|
|
189
156
|
t.true(fs.existsSync(file2Path))
|
|
190
157
|
|
|
191
158
|
// convert from JSON to JS
|
|
192
159
|
const file3Name = `./test${testID}.js`
|
|
193
|
-
const file3Path = path.resolve(
|
|
160
|
+
const file3Path = path.resolve(cwd(), file3Name)
|
|
194
161
|
t.false(fs.existsSync(file3Path))
|
|
195
162
|
|
|
196
163
|
t.context.file3Path = file3Path
|
|
@@ -210,20 +177,20 @@ test('cli (conversions SVG)', (t) => {
|
|
|
210
177
|
t.context.file1Path = file1Path
|
|
211
178
|
|
|
212
179
|
const file2Name = `./test${testID}.svg`
|
|
213
|
-
const file2Path = path.resolve(
|
|
180
|
+
const file2Path = path.resolve(cwd(), file2Name)
|
|
214
181
|
t.false(fs.existsSync(file2Path))
|
|
215
182
|
|
|
216
183
|
t.context.file2Path = file2Path
|
|
217
184
|
|
|
218
185
|
const cliPath = t.context.cliPath
|
|
219
186
|
|
|
220
|
-
let cmd = `node ${cliPath} ${file1Path} -
|
|
187
|
+
let cmd = `node ${cliPath} ${file1Path} -o ${file2Path}`
|
|
221
188
|
execSync(cmd, { stdio: [0, 1, 2] })
|
|
222
189
|
t.true(fs.existsSync(file2Path))
|
|
223
190
|
|
|
224
191
|
// convert from SVG to JS
|
|
225
192
|
const file3Name = `./test${testID}.js`
|
|
226
|
-
const file3Path = path.resolve(
|
|
193
|
+
const file3Path = path.resolve(cwd(), file3Name)
|
|
227
194
|
t.false(fs.existsSync(file3Path))
|
|
228
195
|
|
|
229
196
|
t.context.file3Path = file3Path
|
|
@@ -243,20 +210,20 @@ test('cli (conversions X3D)', (t) => {
|
|
|
243
210
|
t.context.file1Path = file1Path
|
|
244
211
|
|
|
245
212
|
const file2Name = `./test${testID}.x3d`
|
|
246
|
-
const file2Path = path.resolve(
|
|
213
|
+
const file2Path = path.resolve(cwd(), file2Name)
|
|
247
214
|
t.false(fs.existsSync(file2Path))
|
|
248
215
|
|
|
249
216
|
t.context.file2Path = file2Path
|
|
250
217
|
|
|
251
218
|
const cliPath = t.context.cliPath
|
|
252
219
|
|
|
253
|
-
let cmd = `node ${cliPath} ${file1Path} -
|
|
220
|
+
let cmd = `node ${cliPath} ${file1Path} -o ${file2Path}`
|
|
254
221
|
execSync(cmd, { stdio: [0, 1, 2] })
|
|
255
222
|
t.true(fs.existsSync(file2Path))
|
|
256
223
|
|
|
257
224
|
// convert from X3D to JS
|
|
258
225
|
const file3Name = `./test${testID}.js`
|
|
259
|
-
const file3Path = path.resolve(
|
|
226
|
+
const file3Path = path.resolve(cwd(), file3Name)
|
|
260
227
|
t.false(fs.existsSync(file3Path))
|
|
261
228
|
|
|
262
229
|
t.context.file3Path = file3Path
|
package/cli.js
CHANGED
|
@@ -21,19 +21,21 @@
|
|
|
21
21
|
// jscad test.jscad -of stl
|
|
22
22
|
// jscad name_plate.jscad --name "Just Me" --title "CEO" -o amf test.amf
|
|
23
23
|
//
|
|
24
|
-
|
|
24
|
+
import fs from 'fs'
|
|
25
|
+
import JSZip from 'jszip'
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
import { supportedFormats } from '@jscad/io'
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
import { generateOutputData } from './src/generateOutputData.js'
|
|
30
|
+
import { determineOutputNameAndFormat } from './src/determineOutputNameAndFormat.js'
|
|
31
|
+
import { writeOutput } from './src/writeOutput.js'
|
|
32
|
+
import { parseArgs } from './src/parseArgs.js'
|
|
33
|
+
|
|
34
|
+
const version = '[VI]{version}[/VI]' // version is injected by rollup
|
|
33
35
|
|
|
34
36
|
// handle arguments (inputs, outputs, etc)
|
|
35
37
|
const args = process.argv.splice(2)
|
|
36
|
-
let { inputFile, inputFormat, outputFile, outputFormat, params, addMetaData, inputIsDirectory } = parseArgs(args)
|
|
38
|
+
let { inputFile, inputFormat, outputFile, outputFormat, generateParts, zip, params, addMetaData, inputIsDirectory } = parseArgs(args)
|
|
37
39
|
|
|
38
40
|
// outputs
|
|
39
41
|
const output = determineOutputNameAndFormat(outputFormat, outputFile, inputFile)
|
|
@@ -48,18 +50,68 @@ const clicolors = {
|
|
|
48
50
|
black: '\u{1b}[0m'
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
const logFileOutput = (outputFile) => {
|
|
54
|
+
console.log(`${clicolors.blue}JSCAD: generating output ${clicolors.red}
|
|
55
|
+
from: ${clicolors.green} ${inputFile} ${clicolors.red}
|
|
56
|
+
to: ${clicolors.green} ${outputFile} ${clicolors.yellow}(${supportedFormats[outputFormat].description}) ${clicolors.black}
|
|
57
|
+
`)
|
|
58
|
+
}
|
|
55
59
|
|
|
56
60
|
// read input data
|
|
57
|
-
|
|
61
|
+
let encoding = 'UTF8'
|
|
62
|
+
if (inputFile.match(/\.stl$/i)) encoding = 'binary'
|
|
63
|
+
if (inputFile.match(/\.3mf$/i)) encoding = null // force raw buffer
|
|
64
|
+
|
|
65
|
+
const src = fs.readFileSync(inputFile, encoding)
|
|
58
66
|
|
|
59
67
|
// -- convert from JSCAD script into the desired output format
|
|
60
68
|
// -- and write it to disk
|
|
61
|
-
generateOutputData(src, params, { outputFile, outputFormat, inputFile, inputFormat, version, addMetaData, inputIsDirectory })
|
|
62
|
-
.then((outputData) =>
|
|
69
|
+
generateOutputData(src, params, { outputFile, outputFormat, inputFile, inputFormat, generateParts, version, addMetaData, inputIsDirectory })
|
|
70
|
+
.then((outputData) => {
|
|
71
|
+
if (outputData instanceof Array) {
|
|
72
|
+
if (zip) {
|
|
73
|
+
const zip = new JSZip()
|
|
74
|
+
for (let i = 0; i < outputData.length; i++) {
|
|
75
|
+
const filename = outputFile.replace(/\.(\w+)$/, `-part-${i + 1}-of-${outputData.length}.$1`)
|
|
76
|
+
zip.file(filename, outputData[i].asBuffer())
|
|
77
|
+
}
|
|
78
|
+
zip.generateAsync({ type: 'nodebuffer' }).then((content) => {
|
|
79
|
+
const zipFilename = outputFile.replace(/\.(\w+)$/, '.zip')
|
|
80
|
+
fs.writeFile(zipFilename, content, (err) => {
|
|
81
|
+
if (err) {
|
|
82
|
+
console.error(err)
|
|
83
|
+
} else {
|
|
84
|
+
logFileOutput(zipFilename)
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
} else {
|
|
89
|
+
for (let i = 0; i < outputData.length; i++) {
|
|
90
|
+
const filename = outputFile.replace(/\.(\w+)$/, `-part-${i + 1}-of-${outputData.length}.$1`)
|
|
91
|
+
logFileOutput(filename)
|
|
92
|
+
writeOutput(filename, outputData[i])
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
if (zip) {
|
|
97
|
+
const zip = new JSZip()
|
|
98
|
+
zip.file(outputFile, outputData.asBuffer())
|
|
99
|
+
zip.generateAsync({ type: 'nodebuffer' }).then((content) => {
|
|
100
|
+
const zipFilename = outputFile.replace(/\.(\w+)$/, '.zip')
|
|
101
|
+
fs.writeFile(zipFilename, content, (err) => {
|
|
102
|
+
if (err) {
|
|
103
|
+
console.error(err)
|
|
104
|
+
} else {
|
|
105
|
+
logFileOutput(zipFilename)
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
} else {
|
|
110
|
+
logFileOutput(outputFile)
|
|
111
|
+
writeOutput(outputFile, outputData)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
})
|
|
63
115
|
.catch((error) => {
|
|
64
116
|
console.error(error)
|
|
65
117
|
process.exit(1)
|
package/cli.parameters.test.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import { dirname, resolve } from 'path'
|
|
3
|
+
import { execSync } from 'child_process'
|
|
4
|
+
import { cwd } from 'process'
|
|
5
|
+
import { fileURLToPath } from 'url'
|
|
2
6
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
7
|
+
import JSZip from 'jszip'
|
|
8
|
+
|
|
9
|
+
import test from 'ava'
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
12
|
+
const __dirname = dirname(__filename)
|
|
6
13
|
|
|
7
14
|
test.afterEach.always((t) => {
|
|
8
15
|
// remove files
|
|
@@ -13,6 +20,12 @@ test.afterEach.always((t) => {
|
|
|
13
20
|
try {
|
|
14
21
|
if (t.context.outputPath) fs.unlinkSync(t.context.outputPath)
|
|
15
22
|
} catch (err) {}
|
|
23
|
+
try {
|
|
24
|
+
if (t.context.outputPath2) fs.unlinkSync(t.context.outputPath2)
|
|
25
|
+
} catch (err) {}
|
|
26
|
+
try {
|
|
27
|
+
if (t.context.outputPath3) fs.unlinkSync(t.context.outputPath3)
|
|
28
|
+
} catch (err) {}
|
|
16
29
|
|
|
17
30
|
try {
|
|
18
31
|
if (t.context.folderPath) fs.rmdirSync(t.context.folderPath, { recursive: false })
|
|
@@ -22,7 +35,7 @@ test.afterEach.always((t) => {
|
|
|
22
35
|
test.beforeEach((t) => {
|
|
23
36
|
const cliName = './cli.js'
|
|
24
37
|
t.context = {
|
|
25
|
-
cliPath:
|
|
38
|
+
cliPath: resolve(cwd(), cliName)
|
|
26
39
|
}
|
|
27
40
|
})
|
|
28
41
|
|
|
@@ -32,33 +45,31 @@ test.beforeEach((t) => {
|
|
|
32
45
|
|
|
33
46
|
// create a simple JSCAD script for input
|
|
34
47
|
// the script should produce ALL geometry types
|
|
35
|
-
const createJscad = (id) => {
|
|
48
|
+
const createJscad = (id, multipart = false) => {
|
|
36
49
|
const jscadScript = `// test script ${id}
|
|
37
|
-
|
|
50
|
+
import { arc, ellipse, ellipsoid } from '@jscad/modeling'
|
|
38
51
|
|
|
39
|
-
const getParameterDefinitions = () => {
|
|
52
|
+
export const getParameterDefinitions = () => {
|
|
40
53
|
return [
|
|
41
|
-
{ name: 'segments', caption: '
|
|
54
|
+
{ name: 'segments', caption: 'Segments:', type: 'int', initial: 10, min: 5, max: 20, step: 1 }
|
|
42
55
|
]
|
|
43
56
|
}
|
|
44
57
|
|
|
45
|
-
const main = (params) => {
|
|
58
|
+
export const main = (params) => {
|
|
46
59
|
// parameters
|
|
47
60
|
let segments = params.segments || 16
|
|
48
61
|
|
|
49
62
|
// shapes
|
|
50
|
-
let apath2 =
|
|
51
|
-
let ageom2 =
|
|
52
|
-
let ageom3 =
|
|
63
|
+
let apath2 = arc()
|
|
64
|
+
let ageom2 = ellipse()
|
|
65
|
+
let ageom3 = ellipsoid()
|
|
53
66
|
|
|
54
|
-
return [apath2, ageom2, ageom3]
|
|
67
|
+
${multipart ? 'return [ageom3, ageom3, ageom3]' : 'return [apath2, ageom2, ageom3]'}
|
|
55
68
|
}
|
|
56
|
-
|
|
57
|
-
module.exports = { main, getParameterDefinitions }
|
|
58
69
|
`
|
|
59
70
|
|
|
60
|
-
const fileName = `./test${id}.
|
|
61
|
-
const filePath =
|
|
71
|
+
const fileName = `./test${id}.js`
|
|
72
|
+
const filePath = resolve(cwd(), fileName)
|
|
62
73
|
fs.writeFileSync(filePath, jscadScript)
|
|
63
74
|
return filePath
|
|
64
75
|
}
|
|
@@ -72,7 +83,7 @@ test('cli (single input file)', (t) => {
|
|
|
72
83
|
t.context.inputPath = inputPath
|
|
73
84
|
|
|
74
85
|
const outputName = `./test${testID}.stl`
|
|
75
|
-
const outputPath =
|
|
86
|
+
const outputPath = resolve(cwd(), outputName)
|
|
76
87
|
t.false(fs.existsSync(outputPath))
|
|
77
88
|
|
|
78
89
|
t.context.outputPath = outputPath
|
|
@@ -93,7 +104,7 @@ test('cli (single input file, output format)', (t) => {
|
|
|
93
104
|
t.context.inputPath = inputPath
|
|
94
105
|
|
|
95
106
|
const outputName = `./test${testID}.dxf`
|
|
96
|
-
const outputPath =
|
|
107
|
+
const outputPath = resolve(cwd(), outputName)
|
|
97
108
|
t.false(fs.existsSync(outputPath))
|
|
98
109
|
|
|
99
110
|
t.context.outputPath = outputPath
|
|
@@ -113,8 +124,8 @@ test('cli (single input file, output filename)', (t) => {
|
|
|
113
124
|
|
|
114
125
|
t.context.inputPath = inputPath
|
|
115
126
|
|
|
116
|
-
const outputName = `./test${testID}.
|
|
117
|
-
const outputPath =
|
|
127
|
+
const outputName = `./test${testID}.obj`
|
|
128
|
+
const outputPath = resolve(cwd(), outputName)
|
|
118
129
|
t.false(fs.existsSync(outputPath))
|
|
119
130
|
|
|
120
131
|
t.context.outputPath = outputPath
|
|
@@ -134,7 +145,7 @@ test('cli (folder, output format)', (t) => {
|
|
|
134
145
|
|
|
135
146
|
t.context.inputPath = inputPath
|
|
136
147
|
|
|
137
|
-
const folderPath =
|
|
148
|
+
const folderPath = resolve(cwd(), './test-folder')
|
|
138
149
|
t.false(fs.existsSync(folderPath))
|
|
139
150
|
|
|
140
151
|
fs.mkdirSync(folderPath)
|
|
@@ -142,14 +153,14 @@ test('cli (folder, output format)', (t) => {
|
|
|
142
153
|
|
|
143
154
|
t.context.folderPath = folderPath
|
|
144
155
|
|
|
145
|
-
const mainPath =
|
|
156
|
+
const mainPath = resolve(cwd(), './test-folder/main.js')
|
|
146
157
|
fs.renameSync(inputPath, mainPath)
|
|
147
158
|
t.true(fs.existsSync(mainPath))
|
|
148
159
|
|
|
149
160
|
t.context.inputPath = mainPath
|
|
150
161
|
|
|
151
162
|
const outputName = './test-folder/main.dxf'
|
|
152
|
-
const outputPath =
|
|
163
|
+
const outputPath = resolve(cwd(), outputName)
|
|
153
164
|
t.false(fs.existsSync(outputPath))
|
|
154
165
|
|
|
155
166
|
t.context.outputPath = outputPath
|
|
@@ -170,7 +181,7 @@ test('cli (single input file, parameters)', (t) => {
|
|
|
170
181
|
t.context.inputPath = inputPath
|
|
171
182
|
|
|
172
183
|
const outputName = `./test${testID}.stl`
|
|
173
|
-
const outputPath =
|
|
184
|
+
const outputPath = resolve(cwd(), outputName)
|
|
174
185
|
t.false(fs.existsSync(outputPath))
|
|
175
186
|
|
|
176
187
|
t.context.outputPath = outputPath
|
|
@@ -182,7 +193,7 @@ test('cli (single input file, parameters)', (t) => {
|
|
|
182
193
|
t.true(fs.existsSync(outputPath))
|
|
183
194
|
})
|
|
184
195
|
|
|
185
|
-
test('cli (no parameters)', (t) => {
|
|
196
|
+
test('cli (no parameters, out help)', (t) => {
|
|
186
197
|
const cliPath = t.context.cliPath
|
|
187
198
|
|
|
188
199
|
const cmd = `node ${cliPath}`
|
|
@@ -207,3 +218,88 @@ test('cli (single input file, invalid jscad)', (t) => {
|
|
|
207
218
|
execSync(cmd, { stdio: [0, 1, 2] })
|
|
208
219
|
})
|
|
209
220
|
})
|
|
221
|
+
|
|
222
|
+
test('cli (single input file, multiple output files)', (t) => {
|
|
223
|
+
const testID = 7
|
|
224
|
+
|
|
225
|
+
const inputPath = createJscad(testID, true)
|
|
226
|
+
t.true(fs.existsSync(inputPath))
|
|
227
|
+
|
|
228
|
+
t.context.inputPath = inputPath
|
|
229
|
+
|
|
230
|
+
const outputName = (partNum) => `./test${testID}-part-${partNum}-of-3.stl`
|
|
231
|
+
const outputPath1 = resolve(__dirname, outputName(1))
|
|
232
|
+
const outputPath2 = resolve(__dirname, outputName(2))
|
|
233
|
+
const outputPath3 = resolve(__dirname, outputName(3))
|
|
234
|
+
t.false(fs.existsSync(outputPath1))
|
|
235
|
+
t.false(fs.existsSync(outputPath2))
|
|
236
|
+
t.false(fs.existsSync(outputPath3))
|
|
237
|
+
|
|
238
|
+
t.context.outputPath = outputPath1
|
|
239
|
+
t.context.outputPath2 = outputPath2
|
|
240
|
+
t.context.outputPath3 = outputPath3
|
|
241
|
+
|
|
242
|
+
const cliPath = t.context.cliPath
|
|
243
|
+
|
|
244
|
+
const cmd = `node ${cliPath} ${inputPath} -gp`
|
|
245
|
+
execSync(cmd, { stdio: [0, 1, 2] })
|
|
246
|
+
t.true(fs.existsSync(outputPath1))
|
|
247
|
+
t.true(fs.existsSync(outputPath2))
|
|
248
|
+
t.true(fs.existsSync(outputPath3))
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
test('cli (single multipart input file, zipped output file)', async (t) => {
|
|
252
|
+
const testID = 8
|
|
253
|
+
|
|
254
|
+
const inputPath = createJscad(testID, true)
|
|
255
|
+
t.true(fs.existsSync(inputPath))
|
|
256
|
+
|
|
257
|
+
t.context.inputPath = inputPath
|
|
258
|
+
|
|
259
|
+
const outputName = `./test${testID}.zip`
|
|
260
|
+
const outputPath = resolve(__dirname, outputName)
|
|
261
|
+
|
|
262
|
+
t.false(fs.existsSync(outputPath))
|
|
263
|
+
|
|
264
|
+
t.context.outputPath = outputPath
|
|
265
|
+
|
|
266
|
+
const cliPath = t.context.cliPath
|
|
267
|
+
|
|
268
|
+
const cmd = `node ${cliPath} ${inputPath} -gp -z`
|
|
269
|
+
execSync(cmd, { stdio: [0, 1, 2] })
|
|
270
|
+
t.true(fs.existsSync(outputPath))
|
|
271
|
+
|
|
272
|
+
// check contents of zip file
|
|
273
|
+
const data = await fs.promises.readFile(outputPath)
|
|
274
|
+
const content = await JSZip.loadAsync(data)
|
|
275
|
+
t.true(content.files[resolve(__dirname, `./test${testID}-part-1-of-3.stl`)] !== undefined)
|
|
276
|
+
t.true(content.files[resolve(__dirname, `./test${testID}-part-2-of-3.stl`)] !== undefined)
|
|
277
|
+
t.true(content.files[resolve(__dirname, `./test${testID}-part-3-of-3.stl`)] !== undefined)
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
test('cli (single input file, zipped output file)', async (t) => {
|
|
281
|
+
const testID = 9
|
|
282
|
+
|
|
283
|
+
const inputPath = createJscad(testID, true)
|
|
284
|
+
t.true(fs.existsSync(inputPath))
|
|
285
|
+
|
|
286
|
+
t.context.inputPath = inputPath
|
|
287
|
+
|
|
288
|
+
const outputName = `./test${testID}.zip`
|
|
289
|
+
const outputPath = resolve(__dirname, outputName)
|
|
290
|
+
|
|
291
|
+
t.false(fs.existsSync(outputPath))
|
|
292
|
+
|
|
293
|
+
t.context.outputPath = outputPath
|
|
294
|
+
|
|
295
|
+
const cliPath = t.context.cliPath
|
|
296
|
+
|
|
297
|
+
const cmd = `node ${cliPath} ${inputPath} -z`
|
|
298
|
+
execSync(cmd, { stdio: [0, 1, 2] })
|
|
299
|
+
t.true(fs.existsSync(outputPath))
|
|
300
|
+
|
|
301
|
+
// check contents of zip file
|
|
302
|
+
const data = await fs.promises.readFile(outputPath)
|
|
303
|
+
const content = await JSZip.loadAsync(data)
|
|
304
|
+
t.true(content.files[resolve(__dirname, `./test${testID}.stl`)] !== undefined)
|
|
305
|
+
})
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jscad/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-alpha.0",
|
|
4
4
|
"description": "Command Line Interface (CLI) for JSCAD",
|
|
5
5
|
"homepage": "https://openjscad.xyz/",
|
|
6
6
|
"repository": "https://github.com/jscad/OpenJSCAD.org",
|
|
7
|
+
"type": "module",
|
|
7
8
|
"bin": {
|
|
8
9
|
"jscad": "./cli.js"
|
|
9
10
|
},
|
|
10
11
|
"scripts": {
|
|
11
|
-
"coverage": "
|
|
12
|
+
"coverage": "c8 --all --reporter=html --reporter=text npm test",
|
|
12
13
|
"test": "ava '*.test.js' --serial --verbose --timeout 2m",
|
|
13
14
|
"postinstall": "node -e \"console.log('\\u001b[35m\\u001b[1mLove JSCAD? You can now donate to our open collective:\\u001b[22m\\u001b[39m\\n > \\u001b[34mhttps://opencollective.com/openjscad/donate\\u001b[0m')\""
|
|
14
15
|
},
|
|
@@ -35,19 +36,21 @@
|
|
|
35
36
|
],
|
|
36
37
|
"license": "MIT",
|
|
37
38
|
"dependencies": {
|
|
38
|
-
"@jscad/array-utils": "
|
|
39
|
-
"@jscad/core": "
|
|
40
|
-
"@jscad/io": "
|
|
41
|
-
"@jscad/
|
|
39
|
+
"@jscad/array-utils": "3.0.0-alpha.0",
|
|
40
|
+
"@jscad/core": "3.0.0-alpha.0",
|
|
41
|
+
"@jscad/io": "3.0.0-alpha.0",
|
|
42
|
+
"@jscad/io-utils": "3.0.0-alpha.0",
|
|
43
|
+
"@jscad/modeling": "3.0.0-alpha.0",
|
|
44
|
+
"jszip": "^3.10.1"
|
|
42
45
|
},
|
|
43
46
|
"devDependencies": {
|
|
44
|
-
"ava": "3.
|
|
45
|
-
"
|
|
47
|
+
"ava": "^4.3.3",
|
|
48
|
+
"c8": "^8.0.0"
|
|
46
49
|
},
|
|
47
50
|
"collective": {
|
|
48
51
|
"type": "opencollective",
|
|
49
52
|
"url": "https://opencollective.com/openjscad",
|
|
50
53
|
"logo": "https://opencollective.com/openjscad/logo.txt"
|
|
51
54
|
},
|
|
52
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "3656d36ed9cd738ab884e86aae5a2ce08d52adf7"
|
|
53
56
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { supportedOutputExtensions, supportedOutputFormats } from '@jscad/io'
|
|
2
2
|
|
|
3
|
-
const determineOutputNameAndFormat = (outputFormat, outputFile, inputFile) => {
|
|
3
|
+
export const determineOutputNameAndFormat = (outputFormat, outputFile, inputFile) => {
|
|
4
4
|
const extReg = new RegExp(`\\.(${supportedOutputExtensions().join('|')})$`)
|
|
5
5
|
const forReg = new RegExp(`(${supportedOutputFormats().join('|')})`, 'i')
|
|
6
6
|
|
|
@@ -22,5 +22,3 @@ const determineOutputNameAndFormat = (outputFormat, outputFile, inputFile) => {
|
|
|
22
22
|
}
|
|
23
23
|
return { outputFormat, outputFile }
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
module.exports = determineOutputNameAndFormat
|
package/src/env.js
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import os from 'os'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const version = '[VI]{version}[/VI]' // version is injected by rollup
|
|
4
|
+
|
|
5
|
+
export const env = () => {
|
|
4
6
|
let env = 'JSCAD ' + version
|
|
5
7
|
if (typeof document !== 'undefined') {
|
|
6
8
|
const w = document.defaultView
|
|
7
9
|
env = env + ' [' + w.navigator.userAgent + ']'
|
|
8
10
|
} else {
|
|
9
|
-
|
|
10
|
-
const os = require('os')
|
|
11
|
-
env = env + ' [' + os.type() + ':' + os.release() + ',' + os.platform() + ':' + os.arch() + ']'
|
|
12
|
-
}
|
|
11
|
+
env = env + ' [' + os.type() + ':' + os.release() + ',' + os.platform() + ':' + os.arch() + ']'
|
|
13
12
|
}
|
|
14
13
|
console.log(env)
|
|
15
14
|
}
|
|
16
|
-
|
|
17
|
-
module.exports = env
|