@rulecad/cad 0.3.0 → 0.3.2

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/AGENTS.md CHANGED
@@ -50,8 +50,8 @@ variable says which rule it comes from. Follow these steps; they're what makes a
50
50
  - A part is named in fits as `<item>.<part>`; an object that returns one unnamed shape has one part, `body`.
51
51
  - A gap fit can't tell whether holes line up. Where a board screws into a part, add a holes fit
52
52
  (`{ "holes": "pcb.board", "into": "case.body", "depth": "m2.insert_length" }`).
53
- - A part built around another (a case around its board) reads it: `"uses": ["node/carrier"]`, then
54
- `carrier.board_w` and `v.carrier.board_holes`. Never copy another object's numbers by hand.
53
+ - A part built around another (a case around its board) reads it: `"uses": ["macropad/pcb"]`, then
54
+ `pcb.board_w` and `v.pcb.board_holes`. Never copy another object's numbers by hand.
55
55
 
56
56
  ## Circuit boards
57
57
  - `"engine": "pcb"` in the .json; `main(v)` returns a board built with `v.pcb` (see @rulecad/pcb's README).
package/README.md CHANGED
@@ -96,12 +96,12 @@ which version it holds (`keyboard/keycap@0.1.0`, or `+changes` if it isn't a rel
96
96
 
97
97
  - `value`: a number, or arithmetic over numbers and names (`+ - * /`, brackets, `min`, `max`, `round`). Rule sets are
98
98
  `<namespace>.<rule>`; the object's own variables are bare names. Parsed, never evaluated as code.
99
- - **Other objects' numbers:** `"uses": ["node/carrier"]` reads another object as a rule set named after it:
100
- `carrier.board_w` in an expression, `v.carrier.board_w` in code. It gets the object's variables and, from a board, its
101
- outline (`board_x`, `board_y`, `board_w`, `board_d`) and, in code, where each of its parts is (`v.carrier.board_parts`),
102
- a shaped board's outline (`board_outline`) and its mounting holes (`v.carrier.board_holes`, each
103
- `{ x, y, d }`). So a case follows its board: change the board and the case rebuilds around it. `"node/carrier@^0.2.0"`
104
- also checks the version; `"node/carrier@0.2.0"` reads that release. `cad rules` shows each borrowed number with the
99
+ - **Other objects' numbers:** `"uses": ["macropad/pcb"]` reads another object as a rule set named after it:
100
+ `pcb.board_w` in an expression, `v.pcb.board_w` in code. It gets the object's variables and, from a board, its
101
+ outline (`board_x`, `board_y`, `board_w`, `board_d`) and, in code, where each of its parts is (`v.pcb.board_parts`),
102
+ a shaped board's outline (`board_outline`) and its mounting holes (`v.pcb.board_holes`, each
103
+ `{ x, y, d }`). So a case follows its board: change the board and the case rebuilds around it. `"macropad/pcb@^0.2.0"`
104
+ also checks the version; `"macropad/pcb@0.2.0"` reads that release. `cad rules` shows each borrowed number with the
105
105
  object and version it came from; two objects can't read each other.
106
106
  - `show`: on the rules card `cad show` hands its target (six at most). `interface`: other parts depend on it (versioning will compare these).
107
107
  - `tweak: { min, max }`: may be changed with `--set`. Variables without one are fixed by their rule.
@@ -124,7 +124,7 @@ which version it holds (`keyboard/keycap@0.1.0`, or `+changes` if it isn't a rel
124
124
  only touches a's faces near b; JSCAD's own splits every face along b's planes, which can leave slivers far away).
125
125
  - A rule set can also carry `"footprints"` (pad data from @rulecad/pcb's `fromKicad`, with its source), which a
126
126
  board's code reads as `v.parts.footprints.usb_c`.
127
- - An object or rule set named with a hyphen (`pod-th`) is read with an underscore in expressions (`pod_th.width`),
127
+ - An object or rule set named with a hyphen (`mx-switch`) is read with an underscore in expressions (`mx_switch.housing_top`),
128
128
  since a hyphen there is a minus.
129
129
  - Rules carry `kind`: spec (manufacturer), default (slicer), community (rule of thumb) or measured (your own test
130
130
  print, which beats the rest), plus `source` and `checked`.
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
 
@@ -278,7 +284,7 @@ async function assembly(cmd, ref) {
278
284
  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
285
  })() : []),
280
286
  };
281
- const url = `${VIEW}#m=${await encode(model)}`;
287
+ const url = await linkTo(model);
282
288
  return { view: url, stl: `${url}&get=stl`, '3mf': `${url}&get=3mf`, src: model.src, size: url.length, title, version: '' };
283
289
  };
284
290
  if (cmd === 'link') return await printLinks(await link());
@@ -309,7 +315,7 @@ async function links(d, b, set) {
309
315
  ...(b.circuit ? { views: await (await pcbEngine()).views(b.circuit) } : {}), // boards: the 2D board and schematic
310
316
  ...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
317
  };
312
- const url = `${VIEW}#m=${await encode(model)}`;
318
+ const url = await linkTo(model);
313
319
  return { view: url, stl: `${url}&get=stl`, '3mf': `${url}&get=3mf`, src, size: url.length, title: model.title, version };
314
320
  }
315
321
 
package/lib/design.mjs CHANGED
@@ -46,10 +46,10 @@ export function locate(ref) {
46
46
  }
47
47
 
48
48
  // ---------- objects that read each other ----------
49
- // "uses": ["node/carrier"] reads another object's numbers as a rule set named after it (carrier.board_w in an
50
- // expression, v.carrier.board_w in code): its variables, and what a board tells the parts around it (board_x, board_y,
51
- // board_w, board_d, and for code board_holes, board_parts (where each part is) and board_outline, for a shaped board). The object is built (cached) first. "node/carrier@^0.2.0" also checks
52
- // its version; "node/carrier@0.2.0" reads that release instead of the working copy.
49
+ // "uses": ["macropad/pcb"] reads another object's numbers as a rule set named after it (pcb.board_w in an
50
+ // expression, v.pcb.board_w in code): its variables, and what a board tells the parts around it (board_x, board_y,
51
+ // board_w, board_d, and for code board_holes, board_parts (where each part is) and board_outline, for a shaped board). The object is built (cached) first. "macropad/pcb@^0.2.0" also checks
52
+ // its version; "macropad/pcb@0.2.0" reads that release instead of the working copy.
53
53
  export const isObjectRef = (u) => String(u).includes('/');
54
54
  const building = new Set();
55
55
  export async function objectSets(d, object) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulecad/cad",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
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": {
@@ -47,7 +47,7 @@
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.4",
51
51
  "@rulecad/versions": "^0.1.0",
52
52
  "@rulecad/shapes": "^0.2.0",
53
53
  "@rulecad/rules": "^0.2.0",