generator-jscad 3.0.1 → 4.0.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/README.md +72 -2
- package/generators/app/index.js +204 -51
- package/generators/app/templates/README.md +42 -20
- package/generators/app/templates/_gitignore +1 -0
- package/generators/app/templates/_gitlab-ci.yml +1 -1
- package/generators/app/templates/_vitepress/config.mjs +10 -1
- package/generators/app/templates/gulpfile.js +1 -1
- package/generators/app/templates/main-checkbox.jscad +26 -11
- package/generators/app/templates/main-list.jscad +31 -1
- package/generators/app/templates/main.jscad +26 -0
- package/generators/app/templates/package.json +1 -1
- package/generators/app/templates/start-dev.sh +37 -0
- package/package.json +33 -40
package/README.md
CHANGED
|
@@ -27,11 +27,74 @@ You can also create a VitePress site with a live viewer.
|
|
|
27
27
|
|
|
28
28
|
## Running
|
|
29
29
|
|
|
30
|
-
The jscad project uses gulp to create a `dist` directory and
|
|
30
|
+
The jscad project uses gulp to create a `dist` directory and watches your source for changes. To view your model during development, you can use one of the following options:
|
|
31
|
+
|
|
32
|
+
### Development Environment (tmux)
|
|
33
|
+
|
|
34
|
+
If you have [tmux] and [jscad1-server] installed globally, `start-dev.sh` launches both panes in a single tmux session — `npm start` on the left watching for file changes, and `jscad1-server` on the right serving the model:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
./start-dev.sh
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The script will error with install instructions if either `tmux` or `jscad1-server` is missing. To install the global dependency:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install -g jscad1-server
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Once running, open `http://localhost:3000` and load the `dist` file. Any time you save a source file, gulp rebuilds the dist file automatically.
|
|
47
|
+
|
|
48
|
+
### Local JSCAD Server (Recommended)
|
|
49
|
+
|
|
50
|
+
Run [jscad1-server] locally to preview your model in real-time:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install -g jscad1-server
|
|
54
|
+
jscad1-server
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Then navigate to `http://localhost:3000` and load the `dist` file by dragging it into the OpenJsCad browser.
|
|
58
|
+
|
|
59
|
+
### VitePress Documentation Preview
|
|
60
|
+
|
|
61
|
+
Alternatively, you can build and preview the documentation site with a live model viewer:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm run docs:build && npm run docs:preview
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### start
|
|
68
|
+
|
|
69
|
+
`npm start` or `npm run start` will launch gulp and watch for file changes, recreating the dist file on each save.
|
|
70
|
+
|
|
71
|
+
### clean
|
|
72
|
+
|
|
73
|
+
Deletes the `dist` directory when you run `npm run clean`.
|
|
74
|
+
|
|
75
|
+
### inject
|
|
76
|
+
|
|
77
|
+
Run gulp to combine the source files and inject the dependent libraries with `npm run inject`. Libraries are found using a gulp plugin that looks for a `jscad.json` file in a package. These files are combined and minimized before injecting into the dist file.
|
|
78
|
+
|
|
79
|
+
### build
|
|
80
|
+
|
|
81
|
+
Build the [VitePress] static site by running `npm run build`. This script combines the readme with a [vue-openjscad] component to display a live view of the model. When hosted on [GitLab], the `.gitlab-ci.yml` CICD file uses this script to publish to [GitLab Pages].
|
|
82
|
+
|
|
83
|
+
### serve
|
|
84
|
+
|
|
85
|
+
Run [VitePress] in dev mode with `npm run serve`. This script watches for file changes and hot reloads changes made to the README file. Changes to the model are not automatically reloaded; a manual reload is required.
|
|
31
86
|
|
|
32
87
|
## jscad-utils
|
|
33
88
|
|
|
34
|
-
The example project uses [jscad-utils]
|
|
89
|
+
The example project uses [jscad-utils]. This is a set of utilities that make object creation and alignment easier. To remove it, `npm uninstall --save jscad-utils`.
|
|
90
|
+
|
|
91
|
+
## Sharing Your Model
|
|
92
|
+
|
|
93
|
+
To share your model publicly, publish the [VitePress] site by running `npm run build` and deploying the generated output. This produces a static site with a live interactive viewer embedded directly in the page.
|
|
94
|
+
|
|
95
|
+
Hosting on [GitLab Pages] is handled automatically by the included `.gitlab-ci.yml` CICD pipeline. For GitHub, the build output can be deployed via GitHub Pages.
|
|
96
|
+
|
|
97
|
+
jscad1-server is a local development tool only and cannot be used to share models.
|
|
35
98
|
|
|
36
99
|
## License
|
|
37
100
|
|
|
@@ -39,3 +102,10 @@ MIT © [John Cole](https://jwc.dev/)
|
|
|
39
102
|
|
|
40
103
|
[npm-image]: https://badge.fury.io/js/generator-jscad.svg
|
|
41
104
|
[npm-url]: https://npmjs.org/package/generator-jscad
|
|
105
|
+
[tmux]: https://github.com/tmux/tmux/wiki
|
|
106
|
+
[jscad1-server]: https://www.npmjs.com/package/jscad1-server
|
|
107
|
+
[jscad-utils]: https://www.npmjs.com/package/jscad-utils
|
|
108
|
+
[VitePress]: https://vitepress.dev/
|
|
109
|
+
[GitLab]: https://gitlab.com/
|
|
110
|
+
[GitLab Pages]: https://gitlab.com/help/user/project/pages/index.md
|
|
111
|
+
[vue-openjscad]: https://gitlab.com/johnwebbcole/vue-openjscad
|
package/generators/app/index.js
CHANGED
|
@@ -1,21 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { camelCase } from 'lodash-es';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import Generator from 'yeoman-generator';
|
|
6
|
+
import yosay from 'yosay';
|
|
7
|
+
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const { sync: commandExists } = require('command-exists');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* JSCAD Project Generator
|
|
13
|
+
*
|
|
14
|
+
* A Yeoman generator for scaffolding JSCAD projects with support for single
|
|
15
|
+
* and multiple part configurations.
|
|
16
|
+
*
|
|
17
|
+
* @extends Generator
|
|
18
|
+
* @property {Object} props - Prompt responses
|
|
19
|
+
* @property {string} props.name - Project name
|
|
20
|
+
* @property {string} props.description - Project description
|
|
21
|
+
* @property {string} props.author - Project author
|
|
22
|
+
* @property {string} props.homepage - Project homepage
|
|
23
|
+
* @property {string} props.projectType - Type of project (single, multi-list, multi-checkbox)
|
|
24
|
+
* @property {Object} gitc - Git configuration
|
|
25
|
+
* @property {Object} gitc.user - Git user info
|
|
26
|
+
* @property {string} gitc.user.name - Git user name
|
|
27
|
+
* @property {string} gitc.user.email - Git user email
|
|
28
|
+
*/
|
|
29
|
+
export default class JscadGenerator extends Generator {
|
|
30
|
+
/**
|
|
31
|
+
* Initialize the generator by setting up git configuration
|
|
32
|
+
*
|
|
33
|
+
* @returns {void}
|
|
34
|
+
*/
|
|
10
35
|
initializing() {
|
|
11
|
-
|
|
12
|
-
user
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
36
|
+
try {
|
|
37
|
+
// @ts-ignore - user property exists on Yeoman generator context
|
|
38
|
+
const gitUser = this.user.git;
|
|
39
|
+
this.gitc = {
|
|
40
|
+
user: {
|
|
41
|
+
name: gitUser.name(),
|
|
42
|
+
email: gitUser.email()
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
} catch {
|
|
46
|
+
// Git config not available (e.g., in test environment)
|
|
47
|
+
this.gitc = {
|
|
48
|
+
user: {
|
|
49
|
+
name: 'Test User',
|
|
50
|
+
email: 'test@example.com'
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
17
54
|
}
|
|
18
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Prompt user for project configuration
|
|
58
|
+
*
|
|
59
|
+
* @returns {Promise<void>}
|
|
60
|
+
*/
|
|
19
61
|
prompting() {
|
|
20
62
|
// Have Yeoman greet the user.
|
|
21
63
|
this.log(
|
|
@@ -28,12 +70,14 @@ module.exports = class extends Generator {
|
|
|
28
70
|
{
|
|
29
71
|
name: 'name',
|
|
30
72
|
message: 'Your project name',
|
|
31
|
-
default: this.config.get('name') || path.basename(process.cwd())
|
|
73
|
+
default: this.config.get('name') || path.basename(process.cwd()),
|
|
74
|
+
type: 'input'
|
|
32
75
|
},
|
|
33
76
|
{
|
|
34
77
|
name: 'description',
|
|
35
78
|
message: 'Description',
|
|
36
|
-
default: this.config.get('description')
|
|
79
|
+
default: this.config.get('description'),
|
|
80
|
+
type: 'input'
|
|
37
81
|
},
|
|
38
82
|
{
|
|
39
83
|
name: 'projectType',
|
|
@@ -52,17 +96,53 @@ module.exports = class extends Generator {
|
|
|
52
96
|
{
|
|
53
97
|
name: 'author',
|
|
54
98
|
message: 'Author',
|
|
55
|
-
|
|
99
|
+
type: 'input',
|
|
100
|
+
// @ts-ignore - gitc is guaranteed to exist after initializing()
|
|
101
|
+
default:
|
|
102
|
+
this.config.get('author') || (this.gitc?.user?.name ?? 'Unknown')
|
|
56
103
|
},
|
|
57
104
|
{
|
|
58
105
|
name: 'homepage',
|
|
59
106
|
message: 'Do you have a homepage?',
|
|
107
|
+
type: 'input',
|
|
60
108
|
default: this.config.get('homepage') || 'http://github.com'
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: 'githubUser',
|
|
112
|
+
message: 'GitHub username or org (leave blank to skip)',
|
|
113
|
+
type: 'input',
|
|
114
|
+
default: this.config.get('githubUser') || ''
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: 'gitlabUser',
|
|
118
|
+
message: 'GitLab username or group (leave blank to skip)',
|
|
119
|
+
type: 'input',
|
|
120
|
+
default: this.config.get('gitlabUser') || ''
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'twitterUser',
|
|
124
|
+
message: 'Twitter/X username (leave blank to skip)',
|
|
125
|
+
type: 'input',
|
|
126
|
+
default: this.config.get('twitterUser') || ''
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: 'linkedinUser',
|
|
130
|
+
message: 'LinkedIn username (leave blank to skip)',
|
|
131
|
+
type: 'input',
|
|
132
|
+
default: this.config.get('linkedinUser') || ''
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: 'blueskyUser',
|
|
136
|
+
message: 'Bluesky handle, e.g. user.bsky.social (leave blank to skip)',
|
|
137
|
+
type: 'input',
|
|
138
|
+
default: this.config.get('blueskyUser') || ''
|
|
61
139
|
}
|
|
62
140
|
];
|
|
63
141
|
|
|
142
|
+
// @ts-ignore - Yeoman prompt type definitions are overly strict
|
|
64
143
|
return this.prompt(prompts).then((props) => {
|
|
65
144
|
// To access props later use this.props.someAnswer;
|
|
145
|
+
// @ts-ignore - props type is valid from prompts
|
|
66
146
|
this.props = props;
|
|
67
147
|
|
|
68
148
|
this.config.set('name', this.props.name);
|
|
@@ -70,18 +150,31 @@ module.exports = class extends Generator {
|
|
|
70
150
|
this.config.set('projectType', this.props.projectType);
|
|
71
151
|
this.config.set('author', this.props.author);
|
|
72
152
|
this.config.set('homepage', this.props.homepage);
|
|
153
|
+
this.config.set('githubUser', this.props.githubUser);
|
|
154
|
+
this.config.set('gitlabUser', this.props.gitlabUser);
|
|
155
|
+
this.config.set('twitterUser', this.props.twitterUser);
|
|
156
|
+
this.config.set('linkedinUser', this.props.linkedinUser);
|
|
157
|
+
this.config.set('blueskyUser', this.props.blueskyUser);
|
|
73
158
|
});
|
|
74
159
|
}
|
|
75
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Write template files to destination directory
|
|
163
|
+
*
|
|
164
|
+
* @returns {void}
|
|
165
|
+
*/
|
|
76
166
|
writing() {
|
|
167
|
+
// @ts-ignore - props is guaranteed to exist after prompting()
|
|
168
|
+
/** @type {any} */
|
|
169
|
+
const props = this.props || {};
|
|
77
170
|
this.fs.copyTpl(
|
|
78
171
|
this.templatePath('gulpfile.js'),
|
|
79
172
|
this.destinationPath('gulpfile.js'),
|
|
80
173
|
{
|
|
81
|
-
name:
|
|
82
|
-
description:
|
|
83
|
-
author:
|
|
84
|
-
nameslug: camelCase(
|
|
174
|
+
name: props.name,
|
|
175
|
+
description: props.description,
|
|
176
|
+
author: props.author,
|
|
177
|
+
nameslug: camelCase(props.name)
|
|
85
178
|
}
|
|
86
179
|
);
|
|
87
180
|
|
|
@@ -99,11 +192,11 @@ module.exports = class extends Generator {
|
|
|
99
192
|
this.templatePath('package.json'),
|
|
100
193
|
this.destinationPath('package.json'),
|
|
101
194
|
{
|
|
102
|
-
name:
|
|
103
|
-
description:
|
|
104
|
-
author:
|
|
105
|
-
nameslug: camelCase(
|
|
106
|
-
homepage:
|
|
195
|
+
name: props.name,
|
|
196
|
+
description: props.description,
|
|
197
|
+
author: props.author,
|
|
198
|
+
nameslug: camelCase(props.name),
|
|
199
|
+
homepage: props.homepage
|
|
107
200
|
}
|
|
108
201
|
);
|
|
109
202
|
|
|
@@ -111,33 +204,36 @@ module.exports = class extends Generator {
|
|
|
111
204
|
this.templatePath('README.md'),
|
|
112
205
|
this.destinationPath('README.md'),
|
|
113
206
|
{
|
|
114
|
-
name:
|
|
115
|
-
description:
|
|
116
|
-
author:
|
|
117
|
-
nameslug: camelCase(
|
|
118
|
-
homepage:
|
|
207
|
+
name: props.name,
|
|
208
|
+
description: props.description,
|
|
209
|
+
author: props.author,
|
|
210
|
+
nameslug: camelCase(props.name),
|
|
211
|
+
homepage: props.homepage
|
|
119
212
|
}
|
|
120
213
|
);
|
|
121
214
|
|
|
122
215
|
/**
|
|
123
216
|
* Do not overwrite the main code file.
|
|
124
217
|
*/
|
|
125
|
-
if (!this.fs.exists(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
218
|
+
if (!this.fs.exists(props.name + '.jscad')) {
|
|
219
|
+
let template;
|
|
220
|
+
if (props.projectType === 'single') {
|
|
221
|
+
template = 'main.jscad';
|
|
222
|
+
} else if (props.projectType === 'multi-list') {
|
|
223
|
+
template = 'main-list.jscad';
|
|
224
|
+
} else {
|
|
225
|
+
template = 'main-checkbox.jscad';
|
|
226
|
+
}
|
|
227
|
+
|
|
132
228
|
this.fs.copyTpl(
|
|
133
229
|
this.templatePath(template),
|
|
134
|
-
this.destinationPath(
|
|
230
|
+
this.destinationPath(props.name + '.jscad'),
|
|
135
231
|
{
|
|
136
|
-
name:
|
|
137
|
-
description:
|
|
138
|
-
author:
|
|
139
|
-
nameslug: camelCase(
|
|
140
|
-
homepage:
|
|
232
|
+
name: props.name,
|
|
233
|
+
description: props.description,
|
|
234
|
+
author: props.author,
|
|
235
|
+
nameslug: camelCase(props.name),
|
|
236
|
+
homepage: props.homepage
|
|
141
237
|
}
|
|
142
238
|
);
|
|
143
239
|
}
|
|
@@ -158,8 +254,53 @@ module.exports = class extends Generator {
|
|
|
158
254
|
);
|
|
159
255
|
|
|
160
256
|
this.fs.copy(
|
|
257
|
+
this.templatePath('start-dev.sh'),
|
|
258
|
+
this.destinationPath('start-dev.sh')
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
const socialLinks = [];
|
|
262
|
+
if (props.githubUser) {
|
|
263
|
+
socialLinks.push({
|
|
264
|
+
icon: 'github',
|
|
265
|
+
link: `https://github.com/${props.githubUser}`
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
if (props.gitlabUser) {
|
|
269
|
+
socialLinks.push({
|
|
270
|
+
icon: 'gitlab',
|
|
271
|
+
link: `https://gitlab.com/${props.gitlabUser}`
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
if (props.twitterUser) {
|
|
275
|
+
socialLinks.push({
|
|
276
|
+
icon: 'x',
|
|
277
|
+
link: `https://x.com/${props.twitterUser}`
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
if (props.linkedinUser) {
|
|
281
|
+
socialLinks.push({
|
|
282
|
+
icon: 'linkedin',
|
|
283
|
+
link: `https://www.linkedin.com/in/${props.linkedinUser}`
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
if (props.blueskyUser) {
|
|
287
|
+
socialLinks.push({
|
|
288
|
+
icon: 'bluesky',
|
|
289
|
+
link: `https://bsky.app/profile/${props.blueskyUser}`
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
this.fs.copyTpl(
|
|
161
294
|
this.templatePath('_vitepress/config.mjs'),
|
|
162
|
-
this.destinationPath('.vitepress/config.mjs')
|
|
295
|
+
this.destinationPath('.vitepress/config.mjs'),
|
|
296
|
+
{
|
|
297
|
+
name: props.name,
|
|
298
|
+
description: props.description,
|
|
299
|
+
author: props.author,
|
|
300
|
+
nameslug: camelCase(props.name),
|
|
301
|
+
homepage: props.homepage,
|
|
302
|
+
socialLinks
|
|
303
|
+
}
|
|
163
304
|
);
|
|
164
305
|
|
|
165
306
|
this.fs.copy(
|
|
@@ -173,22 +314,34 @@ module.exports = class extends Generator {
|
|
|
173
314
|
);
|
|
174
315
|
}
|
|
175
316
|
|
|
317
|
+
/**
|
|
318
|
+
* Install dependencies and compose with other generators
|
|
319
|
+
*
|
|
320
|
+
* @returns {void}
|
|
321
|
+
*/
|
|
176
322
|
install() {
|
|
177
|
-
this.npmInstall();
|
|
178
|
-
|
|
179
323
|
if (commandExists('git')) {
|
|
180
|
-
|
|
324
|
+
const gitInitPath = require.resolve('generator-git-init');
|
|
325
|
+
this.composeWith(gitInitPath, {});
|
|
181
326
|
}
|
|
182
327
|
}
|
|
183
328
|
|
|
329
|
+
/**
|
|
330
|
+
* Display final message with available npm scripts
|
|
331
|
+
*
|
|
332
|
+
* @returns {void}
|
|
333
|
+
*/
|
|
184
334
|
end() {
|
|
335
|
+
// @ts-ignore - props is guaranteed to exist after prompting()
|
|
336
|
+
/** @type {any} */
|
|
337
|
+
const props = this.props || {};
|
|
185
338
|
this.log(`
|
|
186
339
|
|
|
187
340
|
jscad generator is finished.
|
|
188
341
|
|
|
189
342
|
Available scripts:
|
|
190
343
|
|
|
191
|
-
Bundle the '${
|
|
344
|
+
Bundle the '${props.name + '.jscad'}' file into the 'dist' directory.
|
|
192
345
|
npm start
|
|
193
346
|
|
|
194
347
|
Run the development VuePress site.
|
|
@@ -199,4 +352,4 @@ npm run build
|
|
|
199
352
|
|
|
200
353
|
`);
|
|
201
354
|
}
|
|
202
|
-
}
|
|
355
|
+
}
|
|
@@ -6,7 +6,42 @@
|
|
|
6
6
|
|
|
7
7
|
## Running
|
|
8
8
|
|
|
9
|
-
The jscad project `<%= name %>` uses gulp to create a `dist/<%= name %>.jscad` file and watches your source for changes.
|
|
9
|
+
The jscad project `<%= name %>` uses gulp to create a `dist/<%= name %>.jscad` file and watches your source for changes. To view your model during development, you can use one of the following options:
|
|
10
|
+
|
|
11
|
+
### Development Environment (tmux)
|
|
12
|
+
|
|
13
|
+
If you have [tmux] and [jscad1-server] installed globally, `start-dev.sh` launches both panes in a single tmux session — `npm start` on the left watching for file changes, and `jscad1-server` on the right serving the model:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
./start-dev.sh
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The script will error with install instructions if either `tmux` or `jscad1-server` is missing. To install the global dependency:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g jscad1-server
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Once running, open `http://localhost:3000` and load `dist/<%= name %>.jscad`. Any time you save a source file, gulp rebuilds the dist file automatically.
|
|
26
|
+
|
|
27
|
+
### Local JSCAD Server (Recommended)
|
|
28
|
+
|
|
29
|
+
Run the [jscad1-server](https://www.npmjs.com/package/jscad1-server) locally to preview your model in real-time:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install -g jscad1-server
|
|
33
|
+
jscad1-server
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Then navigate to `http://localhost:3000` and load the `dist/<%= name %>.jscad` file by dragging the file into the OpenJsCad browser.
|
|
37
|
+
|
|
38
|
+
### VitePress Documentation Preview
|
|
39
|
+
|
|
40
|
+
Alternatively, you can build and preview the documentation site with a live model viewer:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm run docs:build && npm run docs:preview
|
|
44
|
+
```
|
|
10
45
|
|
|
11
46
|
### start
|
|
12
47
|
|
|
@@ -56,34 +91,21 @@ main() {
|
|
|
56
91
|
// endinject
|
|
57
92
|
```
|
|
58
93
|
|
|
59
|
-
##
|
|
60
|
-
|
|
61
|
-
If you publish the `dist/<%= name %>.jscad` file, you can open it directly in
|
|
62
|
-
[openjscad.org](http://openjscad.org) by using the following URL:
|
|
63
|
-
|
|
64
|
-
<code>
|
|
65
|
-
<a href="http://openjscad.org/#">http://openjscad.org/#</a>
|
|
66
|
-
</code> + the url to your file.
|
|
67
|
-
|
|
68
|
-
### Gist
|
|
69
|
-
|
|
70
|
-
You can save your file to a GitHub [gist](https://gist.github.com/) and append the URL to the raw gist.
|
|
71
|
-
|
|
72
|
-
For example <http://openjscad.org/#https://gist.githubusercontent.com/johnwebbcole/43f2ef58532a204c694e5ada16888ecd/raw/d0972463f70222e6d4c6c6196a1c759bb3e2362a/snap.jscad>
|
|
73
|
-
|
|
74
|
-
### Gitlab Snippet
|
|
94
|
+
## Sharing Your Model
|
|
75
95
|
|
|
76
|
-
|
|
96
|
+
To share your model publicly, publish the [VitePress] site by running `npm run build` and deploying the generated output. This produces a static site with a live interactive viewer embedded directly in the page.
|
|
77
97
|
|
|
78
|
-
|
|
98
|
+
Hosting on [GitLab] is handled automatically by the included `.gitlab-ci.yml` CICD pipeline. For GitHub, the build output can be deployed via GitHub Pages.
|
|
79
99
|
|
|
80
|
-
|
|
100
|
+
jscad1-server is a local development tool only and cannot be used to share models.
|
|
81
101
|
|
|
82
102
|
## License
|
|
83
103
|
|
|
84
104
|
ISC © [<%= author %>](<%= homepage %>)
|
|
85
105
|
|
|
86
106
|
[raspberrypi jscad library]: https://gitlab.com/johnwebbcole/jscad-raspberrypi
|
|
107
|
+
[tmux]: https://github.com/tmux/tmux/wiki
|
|
108
|
+
[jscad1-server]: https://www.npmjs.com/package/jscad1-server
|
|
87
109
|
[vuepress]: https://vuepress.vuejs.org/
|
|
88
110
|
[jscad-utils]: https://www.npmjs.com/package/jscad-utils
|
|
89
111
|
[gitlab]: https://gitlab.com/
|
|
@@ -5,6 +5,15 @@ export default defineConfig({
|
|
|
5
5
|
title: "<%= name %>",
|
|
6
6
|
description: "<%= description %>",
|
|
7
7
|
srcDir: '.',
|
|
8
|
+
head: [
|
|
9
|
+
['link', { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
|
|
10
|
+
['link', { rel: 'shortcut icon', href: '/favicon.ico' }],
|
|
11
|
+
['link', { rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png' }],
|
|
12
|
+
['link', { rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png' }],
|
|
13
|
+
['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }],
|
|
14
|
+
['link', { rel: 'manifest', href: '/site.webmanifest' }],
|
|
15
|
+
['meta', { name: 'theme-color', content: '#ffffff' }]
|
|
16
|
+
],
|
|
8
17
|
rewrites: {
|
|
9
18
|
'README.md': 'index.md'
|
|
10
19
|
},
|
|
@@ -15,7 +24,7 @@ export default defineConfig({
|
|
|
15
24
|
],
|
|
16
25
|
|
|
17
26
|
socialLinks: [
|
|
18
|
-
{ icon: '
|
|
27
|
+
<% - socialLinks.map(l => ` { icon: '${l.icon}', link: '${l.link}' }`).join(',\n') %>
|
|
19
28
|
]
|
|
20
29
|
},
|
|
21
30
|
vite: {
|
|
@@ -4,10 +4,20 @@
|
|
|
4
4
|
// file : <%= nameslug %>.jscad
|
|
5
5
|
|
|
6
6
|
/* exported main, getParameterDefinitions */
|
|
7
|
+
/** @typedef { import("@jwc/jscad-utils/src/group").JsCadUtilsGroup } JsCadUtilsGroup */
|
|
7
8
|
|
|
8
9
|
/** @type {import('@jwc/jscad-utils')} JscadUtils */
|
|
9
10
|
var util;
|
|
10
11
|
|
|
12
|
+
/** @type {import('@jwc/jscad-utils/src/parts')} Parts */
|
|
13
|
+
var Parts;
|
|
14
|
+
|
|
15
|
+
/** @type {import('@jwc/jscad-hardware/src/hardware')} Hardware */
|
|
16
|
+
var Hardware;
|
|
17
|
+
|
|
18
|
+
/** @type {import('@jwc/jscad-utils/src/boxes')} Boxes */
|
|
19
|
+
var Boxes;
|
|
20
|
+
|
|
11
21
|
function getParameterDefinitions() {
|
|
12
22
|
/**
|
|
13
23
|
* Add the keys to the `Parts` object
|
|
@@ -15,7 +25,7 @@ function getParameterDefinitions() {
|
|
|
15
25
|
* parameters.
|
|
16
26
|
* @type {Record<string, boolean>}
|
|
17
27
|
*/
|
|
18
|
-
|
|
28
|
+
const ENABLED = {
|
|
19
29
|
example1: true,
|
|
20
30
|
example2: false
|
|
21
31
|
};
|
|
@@ -67,15 +77,19 @@ function getParameterDefinitions() {
|
|
|
67
77
|
];
|
|
68
78
|
}
|
|
69
79
|
|
|
80
|
+
/**
|
|
81
|
+
* @typedef {Object} Params
|
|
82
|
+
* @property {boolean} example1
|
|
83
|
+
* @property {boolean} example2
|
|
84
|
+
* @property {"0"|"1"|"2"|"3"|"4"} resolution
|
|
85
|
+
* @property {boolean} center
|
|
86
|
+
* @property {boolean} cutawayEnable
|
|
87
|
+
* @property {'x'|'y'|'z'} cutawayAxis
|
|
88
|
+
*/
|
|
89
|
+
|
|
70
90
|
/**
|
|
71
91
|
*
|
|
72
|
-
* @param {
|
|
73
|
-
* @param {boolean} params.example1
|
|
74
|
-
* @param {boolean} params.example2
|
|
75
|
-
* @param {"0"|"1"|"2"|"3"|"4"} params.resolution
|
|
76
|
-
* @param {boolean} params.center
|
|
77
|
-
* @param {boolean} params.cutawayEnable
|
|
78
|
-
* @param {'x'|'y'|'z'} params.cutawayAxis
|
|
92
|
+
* @param {Params} params
|
|
79
93
|
* @returns {CSG[]}
|
|
80
94
|
*/
|
|
81
95
|
function main(params) {
|
|
@@ -87,9 +101,8 @@ function main(params) {
|
|
|
87
101
|
[24, 64],
|
|
88
102
|
[48, 128]
|
|
89
103
|
];
|
|
90
|
-
var [defaultResolution3D, defaultResolution2D] =
|
|
91
|
-
parseInt(params.resolution)
|
|
92
|
-
];
|
|
104
|
+
var [defaultResolution3D, defaultResolution2D] =
|
|
105
|
+
resolutions[Number.parseInt(params.resolution)];
|
|
93
106
|
CSG.defaultResolution3D = defaultResolution3D;
|
|
94
107
|
CSG.defaultResolution2D = defaultResolution2D;
|
|
95
108
|
util.init(CSG);
|
|
@@ -98,11 +111,13 @@ function main(params) {
|
|
|
98
111
|
* The `Parts` object needs to contain
|
|
99
112
|
* the values from the `ENABLED` object.
|
|
100
113
|
*/
|
|
114
|
+
/** @type {Object<string, () => CSG>} */
|
|
101
115
|
var Parts = {
|
|
102
116
|
example1: () => example1(),
|
|
103
117
|
example2: () => example2()
|
|
104
118
|
};
|
|
105
119
|
|
|
120
|
+
/** @type {Array<CSG>} */
|
|
106
121
|
var selectedParts = Object.entries(Parts)
|
|
107
122
|
.filter(([key, value]) => {
|
|
108
123
|
return params[key];
|
|
@@ -4,12 +4,26 @@
|
|
|
4
4
|
// file : <%= nameslug %>.jscad
|
|
5
5
|
|
|
6
6
|
/* exported main, getParameterDefinitions */
|
|
7
|
+
/** @typedef { import("@jwc/jscad-utils/src/group").JsCadUtilsGroup } JsCadUtilsGroup */
|
|
8
|
+
|
|
9
|
+
/** @type {import('@jwc/jscad-utils')} JscadUtils */
|
|
10
|
+
var util;
|
|
11
|
+
|
|
12
|
+
/** @type {import('@jwc/jscad-utils/src/parts')} Parts */
|
|
13
|
+
var Parts;
|
|
14
|
+
|
|
15
|
+
/** @type {import('@jwc/jscad-hardware/src/hardware')} Hardware */
|
|
16
|
+
var Hardware;
|
|
17
|
+
|
|
18
|
+
/** @type {import('@jwc/jscad-utils/src/boxes')} Boxes */
|
|
19
|
+
var Boxes;
|
|
7
20
|
|
|
8
21
|
function getParameterDefinitions() {
|
|
9
22
|
/**
|
|
10
23
|
* Add the keys to the `Parts` object
|
|
11
24
|
* here and they will be listed in the
|
|
12
25
|
* parameters.
|
|
26
|
+
* @type {Record<string, boolean>}
|
|
13
27
|
*/
|
|
14
28
|
var ENABLED = {
|
|
15
29
|
example1: true,
|
|
@@ -63,6 +77,21 @@ function getParameterDefinitions() {
|
|
|
63
77
|
}
|
|
64
78
|
];
|
|
65
79
|
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @typedef {Object} Params
|
|
83
|
+
* @property {"example1"|"example2"} Parts
|
|
84
|
+
* @property {"0"|"1"|"2"|"3"|"4"} resolution
|
|
85
|
+
* @property {boolean} center
|
|
86
|
+
* @property {boolean} cutawayEnable
|
|
87
|
+
* @property {'x'|'y'|'z'} cutawayAxis
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
*
|
|
92
|
+
* @param {Params} params
|
|
93
|
+
* @returns {CSG[]}
|
|
94
|
+
*/
|
|
66
95
|
function main(params) {
|
|
67
96
|
var start = performance.now();
|
|
68
97
|
var resolutions = [
|
|
@@ -81,8 +110,9 @@ function main(params) {
|
|
|
81
110
|
|
|
82
111
|
/**
|
|
83
112
|
* The `Parts` object needs to contain
|
|
84
|
-
* the values from the `
|
|
113
|
+
* the values from the `ENABLED` object.
|
|
85
114
|
*/
|
|
115
|
+
/** @type {Object<string, () => CSG>} */
|
|
86
116
|
var Parts = {
|
|
87
117
|
example1: () => example1(),
|
|
88
118
|
example2: () => example2()
|
|
@@ -4,6 +4,19 @@
|
|
|
4
4
|
// file : <%= nameslug %>.jscad
|
|
5
5
|
|
|
6
6
|
/* exported main, getParameterDefinitions */
|
|
7
|
+
/** @typedef { import("@jwc/jscad-utils/src/group").JsCadUtilsGroup } JsCadUtilsGroup */
|
|
8
|
+
|
|
9
|
+
/** @type {import('@jwc/jscad-utils')} JscadUtils */
|
|
10
|
+
var util;
|
|
11
|
+
|
|
12
|
+
/** @type {import('@jwc/jscad-utils/src/parts')} Parts */
|
|
13
|
+
var Parts;
|
|
14
|
+
|
|
15
|
+
/** @type {import('@jwc/jscad-hardware/src/hardware')} Hardware */
|
|
16
|
+
var Hardware;
|
|
17
|
+
|
|
18
|
+
/** @type {import('@jwc/jscad-utils/src/boxes')} Boxes */
|
|
19
|
+
var Boxes;
|
|
7
20
|
|
|
8
21
|
function getParameterDefinitions() {
|
|
9
22
|
return [
|
|
@@ -25,6 +38,19 @@ function getParameterDefinitions() {
|
|
|
25
38
|
];
|
|
26
39
|
}
|
|
27
40
|
|
|
41
|
+
/**
|
|
42
|
+
* @typedef {Object} Params
|
|
43
|
+
* @property {"0"|"1"|"2"|"3"|"4"} resolution
|
|
44
|
+
* @property {boolean} center
|
|
45
|
+
* @property {boolean} cutawayEnable
|
|
46
|
+
* @property {'x'|'y'|'z'} cutawayAxis
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
* @param {Params} params
|
|
52
|
+
* @returns {CSG[]}
|
|
53
|
+
*/
|
|
28
54
|
function main(params) {
|
|
29
55
|
var resolutions = [
|
|
30
56
|
[6, 16],
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
ROOT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
6
|
+
SESSION_NAME="pipiece-dev"
|
|
7
|
+
WINDOW_NAME="dev"
|
|
8
|
+
|
|
9
|
+
if ! command -v tmux >/dev/null 2>&1; then
|
|
10
|
+
echo "tmux is required but was not found in PATH." >&2
|
|
11
|
+
exit 1
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
if ! command -v jscad1-server >/dev/null 2>&1; then
|
|
15
|
+
echo "jscad1-server is required but was not found in PATH." >&2
|
|
16
|
+
echo "Install it with: npm install -g jscad1-server" >&2
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
|
|
21
|
+
tmux kill-session -t "$SESSION_NAME"
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
tmux new-session -d -s "$SESSION_NAME" -n "$WINDOW_NAME" -c "$ROOT_DIR" "npm start"
|
|
25
|
+
tmux split-window -h -t "$SESSION_NAME:$WINDOW_NAME" -c "$ROOT_DIR" "jscad1-server"
|
|
26
|
+
tmux select-layout -t "$SESSION_NAME:$WINDOW_NAME" even-horizontal
|
|
27
|
+
|
|
28
|
+
tmux setw -t "$SESSION_NAME:$WINDOW_NAME" pane-border-status top
|
|
29
|
+
tmux select-pane -t "$SESSION_NAME:$WINDOW_NAME".0 -T "npm start"
|
|
30
|
+
tmux select-pane -t "$SESSION_NAME:$WINDOW_NAME".1 -T "jscad1-server"
|
|
31
|
+
tmux select-pane -t "$SESSION_NAME:$WINDOW_NAME".0
|
|
32
|
+
|
|
33
|
+
if [[ -n "${TMUX:-}" ]]; then
|
|
34
|
+
tmux switch-client -t "$SESSION_NAME"
|
|
35
|
+
else
|
|
36
|
+
exec tmux attach-session -t "$SESSION_NAME"
|
|
37
|
+
fi
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "generator-jscad",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Create a jscad project",
|
|
5
5
|
"homepage": "https://gitlab.com/johnwebbcole/generator-jscad",
|
|
6
6
|
"author": {
|
|
@@ -11,39 +11,45 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"generators"
|
|
13
13
|
],
|
|
14
|
-
"
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "generators/app/index.js",
|
|
15
16
|
"keywords": [
|
|
16
17
|
"jscad",
|
|
17
18
|
"yeoman-generator"
|
|
18
19
|
],
|
|
19
20
|
"devDependencies": {
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"eslint
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
21
|
+
"@eslint/eslintrc": "^2.1.4",
|
|
22
|
+
"@eslint/js": "^9.0.0",
|
|
23
|
+
"@vitest/coverage-v8": "4.1.2",
|
|
24
|
+
"conventional-changelog-cli": "^5.0.0",
|
|
25
|
+
"coveralls": "^3.1.1",
|
|
26
|
+
"eslint": "^10.1.0",
|
|
27
|
+
"eslint-config-prettier": "^10.1.8",
|
|
28
|
+
"eslint-config-xo": "^0.51.0",
|
|
29
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
30
|
+
"husky": "^9.1.7",
|
|
31
|
+
"lint-staged": "^16.4.0",
|
|
32
|
+
"np": "^11.0.2",
|
|
33
|
+
"prettier": "^3.8.1",
|
|
34
|
+
"vitest": "4.1.2",
|
|
35
|
+
"yeoman-assert": "^3.1.1",
|
|
36
|
+
"yeoman-test": "^11.3.1"
|
|
33
37
|
},
|
|
34
38
|
"engines": {
|
|
35
|
-
"npm": ">=
|
|
39
|
+
"npm": ">= 11.0.0",
|
|
40
|
+
"node": ">= 24.0.0"
|
|
36
41
|
},
|
|
37
42
|
"dependencies": {
|
|
38
|
-
"chalk": "^
|
|
43
|
+
"chalk": "^5.6.2",
|
|
39
44
|
"command-exists": "^1.2.9",
|
|
40
45
|
"generator-git-init": "^1.1.3",
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
46
|
+
"globals": "^15.11.0",
|
|
47
|
+
"lodash-es": "^4.17.23",
|
|
48
|
+
"yeoman-generator": "^8.1.2",
|
|
49
|
+
"yosay": "^3.0.0"
|
|
44
50
|
},
|
|
45
|
-
"
|
|
46
|
-
"
|
|
51
|
+
"vitest": {
|
|
52
|
+
"environment": "node"
|
|
47
53
|
},
|
|
48
54
|
"lint-staged": {
|
|
49
55
|
"*.js": [
|
|
@@ -55,28 +61,15 @@
|
|
|
55
61
|
"git add"
|
|
56
62
|
]
|
|
57
63
|
},
|
|
58
|
-
"eslintConfig": {
|
|
59
|
-
"extends": [
|
|
60
|
-
"xo",
|
|
61
|
-
"prettier"
|
|
62
|
-
],
|
|
63
|
-
"env": {
|
|
64
|
-
"jest": true,
|
|
65
|
-
"node": true
|
|
66
|
-
},
|
|
67
|
-
"rules": {
|
|
68
|
-
"prettier/prettier": "error"
|
|
69
|
-
},
|
|
70
|
-
"plugins": [
|
|
71
|
-
"prettier"
|
|
72
|
-
]
|
|
73
|
-
},
|
|
74
64
|
"scripts": {
|
|
75
65
|
"pretest": "eslint .",
|
|
76
|
-
"test": "
|
|
66
|
+
"test": "vitest --coverage",
|
|
77
67
|
"version": "conventional-changelog -r 0 -o CHANGELOG.md && git add CHANGELOG.md",
|
|
78
68
|
"release": "np --no-yarn"
|
|
79
69
|
},
|
|
80
|
-
"repository":
|
|
70
|
+
"repository": {
|
|
71
|
+
"type": "git",
|
|
72
|
+
"url": "git+https://gitlab.com/johnwebbcole/generator-jscad.git"
|
|
73
|
+
},
|
|
81
74
|
"license": "MIT"
|
|
82
75
|
}
|