@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.
- package/README.md +3 -0
- package/bin/cad.mjs +29 -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 =
|
|
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 =
|
|
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.
|
|
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.
|
|
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.
|
|
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",
|