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 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 watch for changes. You can drag the `dist` directory into the drop area on [openjscad.org](http://openjscad.org). Make sure you check `Auto Reload` and any time you save, glup will recreate the `dist` directory files and your model should refresh.
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](https://www.npmjs.com/package/jscad-utils). This is a set of utilities that make object creation and alignment easier. To remove it, `npm uninstall --save 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
@@ -1,21 +1,63 @@
1
- 'use strict';
2
- const Generator = require('yeoman-generator');
3
- const chalk = require('chalk');
4
- const yosay = require('yosay');
5
- const path = require('path');
6
- const camelCase = require('lodash/camelCase');
7
- const commandExists = require('command-exists').sync;
8
-
9
- module.exports = class extends Generator {
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
- this.gitc = {
12
- user: {
13
- name: this.user.git.name(),
14
- email: this.user.git.email()
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
- default: this.config.get('author') || this.gitc.user.name
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: this.props.name,
82
- description: this.props.description,
83
- author: this.props.author,
84
- nameslug: camelCase(this.props.name)
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: this.props.name,
103
- description: this.props.description,
104
- author: this.props.author,
105
- nameslug: camelCase(this.props.name),
106
- homepage: this.props.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: this.props.name,
115
- description: this.props.description,
116
- author: this.props.author,
117
- nameslug: camelCase(this.props.name),
118
- homepage: this.props.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(this.props.name + '.jscad')) {
126
- var template =
127
- this.props.projectType == 'single'
128
- ? 'main.jscad'
129
- : this.props.projectType == 'multi-list'
130
- ? 'main-list.jscad'
131
- : 'main-checkbox.jscad';
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(this.props.name + '.jscad'),
230
+ this.destinationPath(props.name + '.jscad'),
135
231
  {
136
- name: this.props.name,
137
- description: this.props.description,
138
- author: this.props.author,
139
- nameslug: camelCase(this.props.name),
140
- homepage: this.props.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
- this.composeWith(require.resolve('generator-git-init'), {});
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 '${this.props.name + '.jscad'}' file into the 'dist' directory.
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. You can drag the `dist/<%= name %>.jscad` directory into the drop area on [openjscad.org](http://openjscad.org). Make sure you check `Auto Reload` and any time you save, gulp creates the `dist/<%= name %>.jscad` file, and your model should refresh.
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
- ## OpenJSCAD.org
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
- If you save to a gitlab public snippet, you can open it using the following URL:
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
- <https://openjscad.org/#https://gitlab.com/snippets/1795323/raw.jscad>
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
- Make sure you change the snippet id to the correct value and add `.jscad` at the end.
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/
@@ -23,3 +23,4 @@ public
23
23
 
24
24
  .vitepress/dist
25
25
  .vitepress/cache
26
+ !.vitepress/public
@@ -12,4 +12,4 @@ pages:
12
12
  paths:
13
13
  - public
14
14
  only:
15
- - master
15
+ - main
@@ -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: 'gitlab', link: 'https://gitlab.com/johnwebbcole/<%= name %>' }
27
+ <% - socialLinks.map(l => ` { icon: '${l.icon}', link: '${l.link}' }`).join(',\n') %>
19
28
  ]
20
29
  },
21
30
  vite: {
@@ -38,7 +38,7 @@ gulp.task('inject', function () {
38
38
  mangle: false,
39
39
  compress: false,
40
40
  output: {
41
- beautify: false,
41
+ beautify: true,
42
42
  max_line_len: 80
43
43
  }
44
44
  })
@@ -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
- var ENABLED = {
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 {object} params
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] = resolutions[
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 `ENALBED` object.
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],
@@ -34,7 +34,7 @@
34
34
  "dependencies": {
35
35
  "@jscad/scad-api": "0.5.1",
36
36
  "@jwc/jscad-hardware": "3.3.0",
37
- "@jwc/jscad-raspberrypi": "3.2.1",
37
+ "@jwc/jscad-raspberrypi": "3.3.0",
38
38
  "@jwc/jscad-utils": "4.9.0"
39
39
  }
40
40
  }
@@ -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.0.1",
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
- "main": "generators/index.js",
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
- "conventional-changelog-cli": "^2.0.34",
21
- "coveralls": "^3.1.0",
22
- "eslint": "^7.3.0",
23
- "eslint-config-prettier": "^6.11.0",
24
- "eslint-config-xo": "^0.31.0",
25
- "eslint-plugin-prettier": "^3.1.4",
26
- "husky": "^4.2.5",
27
- "jest": "^26.0.1",
28
- "lint-staged": "^10.2.11",
29
- "np": "^6.2.4",
30
- "prettier": "^2.0.5",
31
- "yeoman-assert": "^3.1.0",
32
- "yeoman-test": "^2.6.0"
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": ">= 4.0.0"
39
+ "npm": ">= 11.0.0",
40
+ "node": ">= 24.0.0"
36
41
  },
37
42
  "dependencies": {
38
- "chalk": "^4.1.0",
43
+ "chalk": "^5.6.2",
39
44
  "command-exists": "^1.2.9",
40
45
  "generator-git-init": "^1.1.3",
41
- "lodash": "^4.17.15",
42
- "yeoman-generator": "^4.10.1",
43
- "yosay": "^2.0.1"
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
- "jest": {
46
- "testEnvironment": "node"
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": "jest --coverage",
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": "https://gitlab.com/johnwebbcole/generator-jscad",
70
+ "repository": {
71
+ "type": "git",
72
+ "url": "git+https://gitlab.com/johnwebbcole/generator-jscad.git"
73
+ },
81
74
  "license": "MIT"
82
75
  }