@rulecad/cad 0.3.1 → 0.3.3

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.
Files changed (3) hide show
  1. package/README.md +3 -0
  2. package/bin/cad.mjs +29 -3
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -69,6 +69,9 @@ fragment, which never reaches the web host, so the public page can open private
69
69
  which version it holds (`keyboard/keycap@0.1.0`, or `+changes` if it isn't a release). The page is to become `@rulecad/viewer`;
70
70
  `scripts/publish-view.sh "message"` publishes it (only that folder) to the public repo.
71
71
 
72
+ - **Rules:** a link carries the model's values and the rules they use (value, source, kind, date checked) for the
73
+ page's Rules panel; estimates are marked there. A rule set with `"private": true` stays out of links, and
74
+ `--no-rules` leaves the list out altogether. Anyone with a link can read what it carries.
72
75
  - **Short links** (`--short`, and the default for `--md`, once `"shorten": "gist"` is in `cad.config.json`'s
73
76
  `targets`): the link's data goes in a secret GitHub Gist (unlisted, but anyone with the link can open it) and the
74
77
  link carries only its ID: `…/#s=<id>`. The page fetches it from GitHub's API. The same model reuses its Gist
package/bin/cad.mjs CHANGED
@@ -12,7 +12,7 @@ import { git, tags, bump, bigger, newer, compare, snapshot, materialise, files,
12
12
  import { check } from '@rulecad/printcheck';
13
13
  import { preview } from '../lib/preview.mjs';
14
14
  import { isAssembly, buildAssembly, checkAssembly, shapes } from '../lib/assembly.mjs';
15
- import { fromParts, fromShapes, encode } from '@rulecad/model-link';
15
+ import { fromParts, fromShapes, encode, check as checkLink, expand } from '@rulecad/model-link';
16
16
  import { threemf, slotOf } from '../lib/threemf.mjs';
17
17
 
18
18
  // The project's filaments: { base: { slot: 1, … }, legend: { slot: 2, … } } in project.json
@@ -31,6 +31,12 @@ function filamentNotes(parts, fil) {
31
31
  const openInSlicer = (f) => (process.platform === 'darwin' ? execFileSync('open', ['-a', 'Bambu Studio', f])
32
32
  : execFileSync(process.platform === 'win32' ? 'explorer' : 'xdg-open', [f]));
33
33
  const VIEW = process.env.CAD_VIEW_URL || config.viewUrl;
34
+ // A link to the model page; one the page would turn away is an error here, not when someone opens it
35
+ async function linkTo(model) {
36
+ const errors = checkLink(model.shapes ? expand(model) : model);
37
+ if (errors.length) throw new Error(`no link: ${errors[0]}`);
38
+ return `${VIEW}#m=${await encode(model)}`;
39
+ }
34
40
 
35
41
  const HELP = `cad: JSCAD designs you can trace, check, share and print (rulecad)
36
42
 
@@ -45,6 +51,7 @@ const HELP = `cad: JSCAD designs you can trace, check, share and print (rulecad)
45
51
  cad link <project>/<object> links to open the model in a browser, and to download its STL or 3MF
46
52
  [--md: one labelled Markdown link, for chat (the page downloads any parts): short unless --long]
47
53
  [--short: the model's data in a secret GitHub Gist, so links are ~80 characters]
54
+ [--no-rules: leave out the Rules panel's list of values and their sources]
48
55
 
49
56
  cad status [project] each object's version, and whether it has changes since its last release
50
57
  cad release <project>/<object> -m "what changed" [--bump major|minor|patch] [--dry-run] [--push]
@@ -264,6 +271,7 @@ async function assembly(cmd, ref) {
264
271
  const model = {
265
272
  title, version: versions, src: `${s.project}/${s.name}`, // object versions are in version: the file name stays short orientation: a.note || (a.kind === 'plate' ? 'A print plate: print everything together.' : 'A fit check: references are faint.'),
266
273
  rules: [],
274
+ ...sheet([...new Map(s.objects.filter((o) => o.built?.entries).map((o) => [o.objName, o.built.entries])).entries()]),
267
275
  // Its boards' 2D views (copper, schematic), so one link holds the whole build: tabs over the 3D model
268
276
  ...(await (async () => {
269
277
  const boards = [...new Map(s.objects.filter((o) => o.built?.circuit).map((o) => [o.objName, o])).values()];
@@ -278,7 +286,7 @@ async function assembly(cmd, ref) {
278
286
  return placed.place.map(([i, ...m], n) => { const p = placed.shapes[i].part; return { shape: i, role: p.role, label: p.object || p.label, slot: slotOf(fil, p.filament), triangles: tri(placed.shapes[i].triangles), matrix: m, name: s.parts[n].name }; });
279
287
  })() : []),
280
288
  };
281
- const url = `${VIEW}#m=${await encode(model)}`;
289
+ const url = await linkTo(model);
282
290
  return { view: url, stl: `${url}&get=stl`, '3mf': `${url}&get=3mf`, src: model.src, size: url.length, title, version: '' };
283
291
  };
284
292
  if (cmd === 'link') return await printLinks(await link());
@@ -297,6 +305,23 @@ async function assembly(cmd, ref) {
297
305
  }
298
306
 
299
307
  // ---------- links ----------
308
+ // The rules sheet a link carries, for the page's Rules panel: a row for each of an object's own values, then each rule
309
+ // they use, as [group, name, value, unit, rule, expr, kind, source, checked] (group: the object, or the rule's set).
310
+ // A rule set marked "private" stays out, and --no-rules leaves the sheet out altogether.
311
+ function sheet(objects) {
312
+ if (opt('no-rules')) return {};
313
+ const rows = [], seen = new Set(), trim = (r) => { while (r.length && (r[r.length - 1] === '' || r[r.length - 1] == null)) r.pop(); return r; };
314
+ for (const [obj, entries] of objects) for (const e of entries) {
315
+ if (!e.name.includes('.')) rows.push(trim([obj, e.label || e.name, fmt(e.value), e.unit || '', e.rule || '', e.expr || '']));
316
+ }
317
+ for (const [, entries] of objects) for (const e of entries) {
318
+ if (!e.name.includes('.') || !e.used || e.private || seen.has(e.name)) continue;
319
+ seen.add(e.name);
320
+ const [set, name] = e.name.split('.');
321
+ rows.push(trim([set, name, fmt(e.value), e.unit || '', e.rule || '', e.expr || '', e.kind || '', e.source || '', e.checked || '']));
322
+ }
323
+ return rows.length ? { sheet: rows } : {};
324
+ }
300
325
  // The model as a link: full print precision (triangles), the rules card, and exactly which version it is.
301
326
  async function links(d, b, set) {
302
327
  const s = d.tag ? { kind: null } : await since(d), fil = filaments(d.project);
@@ -306,10 +331,11 @@ async function links(d, b, set) {
306
331
  title: `${b.object.title || b.object.name}${d.variant ? ` (${d.variant})` : ''}`, version, src, ...(Object.keys(set).length ? { set: suffix(set).slice(1).replace(/-(?=\w+=)/g, ',') } : {}),
307
332
  material: b.object.material, orientation: b.object.orientation,
308
333
  rules: b.entries.filter((e) => e.show).map((e) => [e.label || e.name, fmt(e.value), e.unit || '']),
334
+ ...sheet([[b.object.name, b.entries]]),
309
335
  ...(b.circuit ? { views: await (await pcbEngine()).views(b.circuit) } : {}), // boards: the 2D board and schematic
310
336
  ...fromParts(b.parts.map((p) => ({ name: p.name, role: p.role, label: p.label, slot: slotOf(fil, p.filament), triangles: p.triangles.flatMap((t) => t.slice(1, -1).map((_, i) => [t[0], t[i + 1], t[i + 2]])) }))),
311
337
  };
312
- const url = `${VIEW}#m=${await encode(model)}`;
338
+ const url = await linkTo(model);
313
339
  return { view: url, stl: `${url}&get=stl`, '3mf': `${url}&get=3mf`, src, size: url.length, title: model.title, version };
314
340
  }
315
341
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulecad/cad",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "The cad command: JSCAD designs from traceable rules, checked for printing and fit, versioned by what fits, shared as links and exported as Bambu 3MF.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -43,11 +43,11 @@
43
43
  "directory": "packages/cad"
44
44
  },
45
45
  "dependencies": {
46
- "@rulecad/variables": "^0.1.4",
46
+ "@rulecad/variables": "^0.1.6",
47
47
  "@rulecad/keyboard-layout": "^0.1.2",
48
48
  "@rulecad/printcheck": "^0.1.0",
49
49
  "@rulecad/fit": "^0.2.0",
50
- "@rulecad/model-link": "^0.1.2",
50
+ "@rulecad/model-link": "^0.1.5",
51
51
  "@rulecad/versions": "^0.1.0",
52
52
  "@rulecad/shapes": "^0.2.0",
53
53
  "@rulecad/rules": "^0.2.0",