@miclivs/cadcli 0.1.2 → 0.2.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 +22 -13
- package/dist/commands/edit.d.ts +42 -2
- package/dist/commands/edit.js +281 -7
- package/dist/commands/json.js +0 -1
- package/dist/commands/shared.d.ts +0 -1
- package/dist/commands/shared.js +0 -1
- package/dist/commands/svg.js +0 -1
- package/dist/commands/thumbnail.js +0 -1
- package/dist/commands/view.d.ts +0 -1
- package/dist/commands/view.js +5 -7
- package/dist/core/acad-edit.d.ts +142 -0
- package/dist/core/acad-edit.js +234 -0
- package/dist/core/acad-view.d.ts +6 -0
- package/dist/core/acad-view.js +22 -0
- package/dist/core/acad.d.ts +11 -0
- package/dist/core/acad.js +82 -0
- package/dist/core/adapter.d.ts +0 -6
- package/dist/core/adapter.js +0 -13
- package/dist/core/drawing.d.ts +0 -1
- package/dist/index.d.ts +2 -1
- package/dist/main.js +82 -7
- package/dist/sdk.d.ts +5 -7
- package/dist/sdk.js +6 -6
- package/package.json +1 -2
- package/skills/cadcli/SKILL.md +21 -4
- package/dist/core/libredwg.d.ts +0 -37
- package/dist/core/libredwg.js +0 -86
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Agent-friendly CAD inspection, search, viewing, and editing for DWG/DXF files.
|
|
|
6
6
|
npm install -g @miclivs/cadcli
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Inspection, search, viewing, and editing use the pure TypeScript `acad-ts` backend. No native CAD tools are required.
|
|
10
10
|
|
|
11
11
|
## Why cadcli
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@ cadcli info floorplan.dwg --json
|
|
|
17
17
|
cadcli overview floorplan.dwg
|
|
18
18
|
cadcli search floorplan.dwg "conference" --layer A-TEXT --json
|
|
19
19
|
cadcli view floorplan.dwg -o preview.svg
|
|
20
|
-
cadcli edit floorplan.dwg --
|
|
20
|
+
cadcli edit floorplan.dwg --set-text "Conference" --text-id 2A -o edited.dwg
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## Workflow
|
|
@@ -42,8 +42,17 @@ cadcli entities <file> # entities, optionally filtered
|
|
|
42
42
|
cadcli search <file> [query] # search IDs, types, layers, text, raw fields
|
|
43
43
|
--query "door" --type TEXT --layer A-TEXT --limit 10 --score --no-snippets
|
|
44
44
|
|
|
45
|
-
cadcli view <file> [-o preview.svg] #
|
|
46
|
-
cadcli edit <file> --
|
|
45
|
+
cadcli view <file> [-o preview.svg] # SVG preview
|
|
46
|
+
cadcli edit <file> --set-text <text> --text-id <id> -o out.dwg
|
|
47
|
+
cadcli edit <file> --set-layer <layer> --layer-id <id> -o out.dwg
|
|
48
|
+
cadcli edit <file> --set-color '#ff0000' --color-id <id> -o out.dwg
|
|
49
|
+
cadcli edit <file> --move <id> --dx 10 --dy 0 -o out.dwg
|
|
50
|
+
cadcli edit <file> --rotate <id> --angle 90 --origin 0,0 -o out.dwg
|
|
51
|
+
cadcli edit <file> --scale <id> --factor 2 -o out.dwg
|
|
52
|
+
cadcli edit <file> --copy <id> --dx 10 --dy 0 -o out.dwg
|
|
53
|
+
cadcli edit <file> --delete <id> -o out.dwg
|
|
54
|
+
cadcli edit <file> --add-line 0,0:10,0 --new-layer A-WALL -o out.dwg
|
|
55
|
+
cadcli edit <file> --add-text "Label" --at 5,5 --height 2.5 -o out.dwg
|
|
47
56
|
cadcli json <file> [-o drawing.json] # normalized JSON
|
|
48
57
|
cadcli svg <file> [-o sketch.svg] # best-effort SVG from normalized JSON
|
|
49
58
|
cadcli thumbnail <file> [-o thumb.png] # embedded thumbnail when available
|
|
@@ -74,22 +83,24 @@ SEARCH HINTS
|
|
|
74
83
|
|
|
75
84
|
## Viewing vs SVG export
|
|
76
85
|
|
|
77
|
-
`cadcli view`
|
|
86
|
+
`cadcli view` renders SVG through acad-ts directly from the CAD document.
|
|
78
87
|
|
|
79
|
-
`cadcli svg` renders a lightweight SVG from cadcli’s normalized JSON model. It is useful for quick agent previews and debugging,
|
|
88
|
+
`cadcli svg` renders a lightweight SVG from cadcli’s normalized JSON model. It is useful for quick agent previews and debugging, while `view` preserves more of acad-ts’ CAD model semantics.
|
|
80
89
|
|
|
81
90
|
## Editing
|
|
82
91
|
|
|
83
|
-
Editing is intentionally copy-first
|
|
92
|
+
Editing is intentionally copy-first and typed. You can update text, layers, color, linetype, lineweight, transparency, visibility, block attributes, transforms, copies, and deletion; you can also add point, line, circle, arc, text, mtext, and lightweight polyline entities.
|
|
84
93
|
|
|
85
94
|
```bash
|
|
86
|
-
cadcli edit drawing.dwg --
|
|
95
|
+
cadcli edit drawing.dwg --set-text "New label" --text-id 2A -o edited.dwg
|
|
96
|
+
cadcli edit drawing.dwg --set-attr ROOM=204 --insert-id 3F -o edited.dwg
|
|
97
|
+
cadcli edit drawing.dwg --points '0,0;10,0;10,5' --closed --new-layer A-WALL -o edited.dwg
|
|
87
98
|
```
|
|
88
99
|
|
|
89
100
|
In-place edits are refused unless you explicitly pass `--overwrite`:
|
|
90
101
|
|
|
91
102
|
```bash
|
|
92
|
-
cadcli edit drawing.dwg --
|
|
103
|
+
cadcli edit drawing.dwg --set-text "New label" --text-id 2A --overwrite
|
|
93
104
|
```
|
|
94
105
|
|
|
95
106
|
## SDK
|
|
@@ -107,7 +118,7 @@ const preview = drawing.view();
|
|
|
107
118
|
console.log(preview.svg);
|
|
108
119
|
```
|
|
109
120
|
|
|
110
|
-
The public SDK is intentionally small: `Dwg` plus stable CAD/result types.
|
|
121
|
+
The public SDK is intentionally small: `Dwg` plus stable CAD/result types.
|
|
111
122
|
|
|
112
123
|
## Cache
|
|
113
124
|
|
|
@@ -123,9 +134,7 @@ Set `CADCLI_CACHE_DIR` to override this location.
|
|
|
123
134
|
|
|
124
135
|
## Requirements
|
|
125
136
|
|
|
126
|
-
Inspection, overview, layers, blocks, entities, search, JSON,
|
|
127
|
-
|
|
128
|
-
Install native LibreDWG tools for advanced workflows: `dwgread` for high-fidelity `view`, and `dwgfilter` for edits.
|
|
137
|
+
Inspection, overview, layers, blocks, entities, search, JSON, SVG export, viewing, and editing work through the default pure TypeScript acad-ts backend.
|
|
129
138
|
|
|
130
139
|
## License
|
|
131
140
|
|
package/dist/commands/edit.d.ts
CHANGED
|
@@ -1,8 +1,48 @@
|
|
|
1
1
|
import type { OutputOptions } from "../utils/output.js";
|
|
2
2
|
export interface EditOptions extends OutputOptions {
|
|
3
|
-
jq?: string;
|
|
4
3
|
output?: string;
|
|
5
4
|
overwrite?: boolean;
|
|
6
|
-
|
|
5
|
+
setText?: string;
|
|
6
|
+
textId?: string;
|
|
7
|
+
delete?: string;
|
|
8
|
+
move?: string;
|
|
9
|
+
dx?: string;
|
|
10
|
+
dy?: string;
|
|
11
|
+
dz?: string;
|
|
12
|
+
setLayer?: string;
|
|
13
|
+
layerId?: string;
|
|
14
|
+
setColor?: string;
|
|
15
|
+
colorId?: string;
|
|
16
|
+
setLinetype?: string;
|
|
17
|
+
linetypeId?: string;
|
|
18
|
+
setLineweight?: string;
|
|
19
|
+
lineweightId?: string;
|
|
20
|
+
setTransparency?: string;
|
|
21
|
+
transparencyId?: string;
|
|
22
|
+
hide?: string;
|
|
23
|
+
show?: string;
|
|
24
|
+
rotate?: string;
|
|
25
|
+
angle?: string;
|
|
26
|
+
origin?: string;
|
|
27
|
+
scale?: string;
|
|
28
|
+
factor?: string;
|
|
29
|
+
copy?: string;
|
|
30
|
+
matchProperties?: string;
|
|
31
|
+
sourceId?: string;
|
|
32
|
+
setAttr?: string;
|
|
33
|
+
insertId?: string;
|
|
34
|
+
addPoint?: string;
|
|
35
|
+
addLine?: string;
|
|
36
|
+
addCircle?: string;
|
|
37
|
+
addArc?: string;
|
|
38
|
+
addText?: string;
|
|
39
|
+
addMtext?: string;
|
|
40
|
+
at?: string;
|
|
41
|
+
height?: string;
|
|
42
|
+
width?: string;
|
|
43
|
+
closed?: boolean;
|
|
44
|
+
points?: string;
|
|
45
|
+
newLayer?: string;
|
|
46
|
+
newColor?: string;
|
|
7
47
|
}
|
|
8
48
|
export declare function edit(file: string, options: EditOptions): Promise<void>;
|
package/dist/commands/edit.js
CHANGED
|
@@ -1,21 +1,295 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { editWithAcadTs, } from "../core/acad-edit.js";
|
|
2
2
|
import { output, success } from "../utils/output.js";
|
|
3
3
|
import { handleCommandError, userError } from "./shared.js";
|
|
4
|
+
function numberOption(value, name) {
|
|
5
|
+
const parsed = Number(value);
|
|
6
|
+
if (!Number.isFinite(parsed)) {
|
|
7
|
+
throw userError(`Invalid ${name}: ${value}`, "INVALID_NUMBER");
|
|
8
|
+
}
|
|
9
|
+
return parsed;
|
|
10
|
+
}
|
|
11
|
+
function pointOption(value, name) {
|
|
12
|
+
if (!value)
|
|
13
|
+
throw userError(`${name} requires x,y[,z].`, "INVALID_POINT");
|
|
14
|
+
const parts = value.split(",").map((part) => numberOption(part, name));
|
|
15
|
+
if (parts.length < 2 || parts.length > 3) {
|
|
16
|
+
throw userError(`${name} requires x,y[,z].`, "INVALID_POINT");
|
|
17
|
+
}
|
|
18
|
+
return { x: parts[0], y: parts[1], z: parts[2] };
|
|
19
|
+
}
|
|
20
|
+
function pointsOption(value, name) {
|
|
21
|
+
if (!value)
|
|
22
|
+
throw userError(`${name} requires x,y pairs.`, "INVALID_POINT");
|
|
23
|
+
const points = value.split(/[;|]/).map((part) => pointOption(part, name));
|
|
24
|
+
if (points.length < 2) {
|
|
25
|
+
throw userError(`${name} requires at least two points.`, "INVALID_POINT");
|
|
26
|
+
}
|
|
27
|
+
return points;
|
|
28
|
+
}
|
|
29
|
+
function colorOption(value, name) {
|
|
30
|
+
if (!value)
|
|
31
|
+
throw userError(`${name} requires a color.`, "INVALID_COLOR");
|
|
32
|
+
const normalized = value.toLowerCase();
|
|
33
|
+
if (normalized === "bylayer")
|
|
34
|
+
return { mode: "byLayer" };
|
|
35
|
+
if (normalized === "byblock")
|
|
36
|
+
return { mode: "byBlock" };
|
|
37
|
+
if (/^#?[0-9a-f]{6}$/i.test(value)) {
|
|
38
|
+
const hex = value.replace("#", "");
|
|
39
|
+
return {
|
|
40
|
+
mode: "rgb",
|
|
41
|
+
r: Number.parseInt(hex.slice(0, 2), 16),
|
|
42
|
+
g: Number.parseInt(hex.slice(2, 4), 16),
|
|
43
|
+
b: Number.parseInt(hex.slice(4, 6), 16),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (value.includes(",")) {
|
|
47
|
+
const [r, g, b] = value.split(",").map((part) => numberOption(part, name));
|
|
48
|
+
return { mode: "rgb", r, g, b };
|
|
49
|
+
}
|
|
50
|
+
return { mode: "index", index: numberOption(value, name) };
|
|
51
|
+
}
|
|
52
|
+
function createOptions(options) {
|
|
53
|
+
return {
|
|
54
|
+
layer: options.newLayer,
|
|
55
|
+
color: options.newColor
|
|
56
|
+
? colorOption(options.newColor, "--new-color")
|
|
57
|
+
: undefined,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function acadOperations(options) {
|
|
61
|
+
const operations = [];
|
|
62
|
+
if (options.setText !== undefined) {
|
|
63
|
+
if (!options.textId) {
|
|
64
|
+
throw userError("--set-text requires --text-id <id>.", "MISSING_TEXT_ID");
|
|
65
|
+
}
|
|
66
|
+
operations.push({
|
|
67
|
+
kind: "setText",
|
|
68
|
+
entityId: options.textId,
|
|
69
|
+
text: options.setText,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (options.setLayer !== undefined) {
|
|
73
|
+
if (!options.layerId) {
|
|
74
|
+
throw userError("--set-layer requires --layer-id <id>.", "MISSING_LAYER_ID");
|
|
75
|
+
}
|
|
76
|
+
operations.push({
|
|
77
|
+
kind: "setLayer",
|
|
78
|
+
entityId: options.layerId,
|
|
79
|
+
layer: options.setLayer,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if (options.setColor !== undefined) {
|
|
83
|
+
if (!options.colorId) {
|
|
84
|
+
throw userError("--set-color requires --color-id <id>.", "MISSING_COLOR_ID");
|
|
85
|
+
}
|
|
86
|
+
operations.push({
|
|
87
|
+
kind: "setColor",
|
|
88
|
+
entityId: options.colorId,
|
|
89
|
+
color: colorOption(options.setColor, "--set-color"),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (options.setLinetype !== undefined) {
|
|
93
|
+
if (!options.linetypeId) {
|
|
94
|
+
throw userError("--set-linetype requires --linetype-id <id>.", "MISSING_LINETYPE_ID");
|
|
95
|
+
}
|
|
96
|
+
operations.push({
|
|
97
|
+
kind: "setLineType",
|
|
98
|
+
entityId: options.linetypeId,
|
|
99
|
+
lineType: options.setLinetype,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (options.setLineweight !== undefined) {
|
|
103
|
+
if (!options.lineweightId) {
|
|
104
|
+
throw userError("--set-lineweight requires --lineweight-id <id>.", "MISSING_LINEWEIGHT_ID");
|
|
105
|
+
}
|
|
106
|
+
operations.push({
|
|
107
|
+
kind: "setLineWeight",
|
|
108
|
+
entityId: options.lineweightId,
|
|
109
|
+
weight: numberOption(options.setLineweight, "--set-lineweight"),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (options.setTransparency !== undefined) {
|
|
113
|
+
if (!options.transparencyId) {
|
|
114
|
+
throw userError("--set-transparency requires --transparency-id <id>.", "MISSING_TRANSPARENCY_ID");
|
|
115
|
+
}
|
|
116
|
+
operations.push({
|
|
117
|
+
kind: "setTransparency",
|
|
118
|
+
entityId: options.transparencyId,
|
|
119
|
+
alpha: numberOption(options.setTransparency, "--set-transparency"),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
if (options.hide !== undefined) {
|
|
123
|
+
operations.push({
|
|
124
|
+
kind: "setVisibility",
|
|
125
|
+
entityId: options.hide,
|
|
126
|
+
visible: false,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
if (options.show !== undefined) {
|
|
130
|
+
operations.push({
|
|
131
|
+
kind: "setVisibility",
|
|
132
|
+
entityId: options.show,
|
|
133
|
+
visible: true,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
if (options.move !== undefined) {
|
|
137
|
+
operations.push({
|
|
138
|
+
kind: "move",
|
|
139
|
+
entityId: options.move,
|
|
140
|
+
dx: numberOption(options.dx ?? "0", "--dx"),
|
|
141
|
+
dy: numberOption(options.dy ?? "0", "--dy"),
|
|
142
|
+
dz: options.dz === undefined ? undefined : numberOption(options.dz, "--dz"),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (options.rotate !== undefined) {
|
|
146
|
+
operations.push({
|
|
147
|
+
kind: "rotate",
|
|
148
|
+
entityId: options.rotate,
|
|
149
|
+
angleDegrees: numberOption(options.angle, "--angle"),
|
|
150
|
+
origin: options.origin
|
|
151
|
+
? pointOption(options.origin, "--origin")
|
|
152
|
+
: undefined,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
if (options.scale !== undefined) {
|
|
156
|
+
operations.push({
|
|
157
|
+
kind: "scale",
|
|
158
|
+
entityId: options.scale,
|
|
159
|
+
factor: numberOption(options.factor, "--factor"),
|
|
160
|
+
origin: options.origin
|
|
161
|
+
? pointOption(options.origin, "--origin")
|
|
162
|
+
: undefined,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (options.copy !== undefined) {
|
|
166
|
+
operations.push({
|
|
167
|
+
kind: "copy",
|
|
168
|
+
entityId: options.copy,
|
|
169
|
+
dx: options.dx === undefined ? undefined : numberOption(options.dx, "--dx"),
|
|
170
|
+
dy: options.dy === undefined ? undefined : numberOption(options.dy, "--dy"),
|
|
171
|
+
dz: options.dz === undefined ? undefined : numberOption(options.dz, "--dz"),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
if (options.matchProperties !== undefined) {
|
|
175
|
+
if (!options.sourceId) {
|
|
176
|
+
throw userError("--match-properties requires --source-id <id>.", "MISSING_SOURCE_ID");
|
|
177
|
+
}
|
|
178
|
+
operations.push({
|
|
179
|
+
kind: "matchProperties",
|
|
180
|
+
entityId: options.matchProperties,
|
|
181
|
+
sourceId: options.sourceId,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
if (options.setAttr !== undefined) {
|
|
185
|
+
if (!options.insertId) {
|
|
186
|
+
throw userError("--set-attr requires --insert-id <id>.", "MISSING_INSERT_ID");
|
|
187
|
+
}
|
|
188
|
+
const [tag, ...valueParts] = options.setAttr.split("=");
|
|
189
|
+
if (!tag || valueParts.length === 0) {
|
|
190
|
+
throw userError("--set-attr requires TAG=VALUE.", "INVALID_ATTRIBUTE_EDIT");
|
|
191
|
+
}
|
|
192
|
+
operations.push({
|
|
193
|
+
kind: "setAttribute",
|
|
194
|
+
entityId: options.insertId,
|
|
195
|
+
tag,
|
|
196
|
+
value: valueParts.join("="),
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (options.delete !== undefined) {
|
|
200
|
+
operations.push({ kind: "delete", entityId: options.delete });
|
|
201
|
+
}
|
|
202
|
+
const common = createOptions(options);
|
|
203
|
+
if (options.addPoint !== undefined) {
|
|
204
|
+
operations.push({
|
|
205
|
+
kind: "addPoint",
|
|
206
|
+
at: pointOption(options.addPoint, "--add-point"),
|
|
207
|
+
...common,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
if (options.addLine !== undefined) {
|
|
211
|
+
const [from, to] = options.addLine.split(":");
|
|
212
|
+
operations.push({
|
|
213
|
+
kind: "addLine",
|
|
214
|
+
from: pointOption(from, "--add-line"),
|
|
215
|
+
to: pointOption(to, "--add-line"),
|
|
216
|
+
...common,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
if (options.addCircle !== undefined) {
|
|
220
|
+
const [center, radius] = options.addCircle.split(":");
|
|
221
|
+
operations.push({
|
|
222
|
+
kind: "addCircle",
|
|
223
|
+
center: pointOption(center, "--add-circle"),
|
|
224
|
+
radius: numberOption(radius, "--add-circle radius"),
|
|
225
|
+
...common,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
if (options.addArc !== undefined) {
|
|
229
|
+
const [center, radius, start, end] = options.addArc.split(":");
|
|
230
|
+
operations.push({
|
|
231
|
+
kind: "addArc",
|
|
232
|
+
center: pointOption(center, "--add-arc"),
|
|
233
|
+
radius: numberOption(radius, "--add-arc radius"),
|
|
234
|
+
startAngleDegrees: numberOption(start, "--add-arc start angle"),
|
|
235
|
+
endAngleDegrees: numberOption(end, "--add-arc end angle"),
|
|
236
|
+
...common,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
if (options.addText !== undefined) {
|
|
240
|
+
operations.push({
|
|
241
|
+
kind: "addText",
|
|
242
|
+
text: options.addText,
|
|
243
|
+
at: pointOption(options.at, "--at"),
|
|
244
|
+
height: options.height
|
|
245
|
+
? numberOption(options.height, "--height")
|
|
246
|
+
: undefined,
|
|
247
|
+
rotationDegrees: options.angle
|
|
248
|
+
? numberOption(options.angle, "--angle")
|
|
249
|
+
: undefined,
|
|
250
|
+
...common,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
if (options.addMtext !== undefined) {
|
|
254
|
+
operations.push({
|
|
255
|
+
kind: "addMText",
|
|
256
|
+
text: options.addMtext,
|
|
257
|
+
at: pointOption(options.at, "--at"),
|
|
258
|
+
height: options.height
|
|
259
|
+
? numberOption(options.height, "--height")
|
|
260
|
+
: undefined,
|
|
261
|
+
width: options.width ? numberOption(options.width, "--width") : undefined,
|
|
262
|
+
rotationDegrees: options.angle
|
|
263
|
+
? numberOption(options.angle, "--angle")
|
|
264
|
+
: undefined,
|
|
265
|
+
...common,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
if (options.points !== undefined) {
|
|
269
|
+
operations.push({
|
|
270
|
+
kind: "addPolyline",
|
|
271
|
+
points: pointsOption(options.points, "--points"),
|
|
272
|
+
closed: options.closed,
|
|
273
|
+
...common,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
return operations;
|
|
277
|
+
}
|
|
4
278
|
export async function edit(file, options) {
|
|
5
279
|
try {
|
|
6
|
-
|
|
7
|
-
|
|
280
|
+
const operations = acadOperations(options);
|
|
281
|
+
if (operations.length === 0) {
|
|
282
|
+
throw userError("No edit operation specified. Use --set-text, --set-layer, --move, --delete, or an add-* operation.", "MISSING_EDIT_OPERATION");
|
|
8
283
|
}
|
|
9
|
-
const result =
|
|
284
|
+
const result = editWithAcadTs({
|
|
10
285
|
input: file,
|
|
11
286
|
output: options.output ?? file,
|
|
12
|
-
|
|
287
|
+
operations,
|
|
13
288
|
overwrite: options.overwrite,
|
|
14
|
-
toolDir: options.toolDir,
|
|
15
289
|
});
|
|
16
290
|
output(options, {
|
|
17
291
|
json: () => ({ success: true, ...result }),
|
|
18
|
-
human: () => success(`Edited ${result.output} with
|
|
292
|
+
human: () => success(`Edited ${result.output} with acad-ts`),
|
|
19
293
|
});
|
|
20
294
|
}
|
|
21
295
|
catch (err) {
|
package/dist/commands/json.js
CHANGED
|
@@ -4,7 +4,6 @@ import type { DrawingReader } from "../types.js";
|
|
|
4
4
|
import type { OutputOptions } from "../utils/output.js";
|
|
5
5
|
export interface DrawingCommandOptions extends OutputOptions {
|
|
6
6
|
reader?: DrawingReader;
|
|
7
|
-
toolDir?: string;
|
|
8
7
|
}
|
|
9
8
|
export interface OutputFileOptions extends OutputOptions {
|
|
10
9
|
output?: string;
|
package/dist/commands/shared.js
CHANGED
package/dist/commands/svg.js
CHANGED
package/dist/commands/view.d.ts
CHANGED
package/dist/commands/view.js
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { renderSvgWithAcadTs } from "../core/acad-view.js";
|
|
2
2
|
import { handleCommandError, writeCommandOutput } from "./shared.js";
|
|
3
3
|
export async function view(file, options) {
|
|
4
4
|
try {
|
|
5
|
-
const result =
|
|
5
|
+
const result = renderSvgWithAcadTs(file);
|
|
6
6
|
const svg = result.svg;
|
|
7
|
-
const tool = result.tool;
|
|
8
7
|
if (options.output) {
|
|
9
8
|
writeCommandOutput(options, svg, () => ({
|
|
10
9
|
success: true,
|
|
11
10
|
file: options.output,
|
|
12
|
-
backend: "
|
|
13
|
-
|
|
14
|
-
}), `Wrote ${options.output} with ${tool}`);
|
|
11
|
+
backend: "acad-ts",
|
|
12
|
+
}), `Wrote ${options.output} with acad-ts`);
|
|
15
13
|
return;
|
|
16
14
|
}
|
|
17
15
|
if (options.json) {
|
|
18
|
-
console.log(JSON.stringify({ backend: "
|
|
16
|
+
console.log(JSON.stringify({ backend: "acad-ts", svg }, null, 2));
|
|
19
17
|
}
|
|
20
18
|
else {
|
|
21
19
|
console.log(svg.trimEnd());
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
export type AcadPoint = {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
z?: number;
|
|
5
|
+
};
|
|
6
|
+
export type AcadColor = {
|
|
7
|
+
mode: "byLayer";
|
|
8
|
+
} | {
|
|
9
|
+
mode: "byBlock";
|
|
10
|
+
} | {
|
|
11
|
+
mode: "index";
|
|
12
|
+
index: number;
|
|
13
|
+
} | {
|
|
14
|
+
mode: "rgb";
|
|
15
|
+
r: number;
|
|
16
|
+
g: number;
|
|
17
|
+
b: number;
|
|
18
|
+
};
|
|
19
|
+
export type AcadEditOperation = {
|
|
20
|
+
kind: "setText";
|
|
21
|
+
entityId: string;
|
|
22
|
+
text: string;
|
|
23
|
+
} | {
|
|
24
|
+
kind: "setLayer";
|
|
25
|
+
entityId: string;
|
|
26
|
+
layer: string;
|
|
27
|
+
} | {
|
|
28
|
+
kind: "setColor";
|
|
29
|
+
entityId: string;
|
|
30
|
+
color: AcadColor;
|
|
31
|
+
} | {
|
|
32
|
+
kind: "setLineType";
|
|
33
|
+
entityId: string;
|
|
34
|
+
lineType: string;
|
|
35
|
+
} | {
|
|
36
|
+
kind: "setLineWeight";
|
|
37
|
+
entityId: string;
|
|
38
|
+
weight: number;
|
|
39
|
+
} | {
|
|
40
|
+
kind: "setTransparency";
|
|
41
|
+
entityId: string;
|
|
42
|
+
alpha: number;
|
|
43
|
+
} | {
|
|
44
|
+
kind: "setVisibility";
|
|
45
|
+
entityId: string;
|
|
46
|
+
visible: boolean;
|
|
47
|
+
} | {
|
|
48
|
+
kind: "move";
|
|
49
|
+
entityId: string;
|
|
50
|
+
dx: number;
|
|
51
|
+
dy: number;
|
|
52
|
+
dz?: number;
|
|
53
|
+
} | {
|
|
54
|
+
kind: "rotate";
|
|
55
|
+
entityId: string;
|
|
56
|
+
angleDegrees: number;
|
|
57
|
+
origin?: AcadPoint;
|
|
58
|
+
} | {
|
|
59
|
+
kind: "scale";
|
|
60
|
+
entityId: string;
|
|
61
|
+
factor: number;
|
|
62
|
+
origin?: AcadPoint;
|
|
63
|
+
} | {
|
|
64
|
+
kind: "copy";
|
|
65
|
+
entityId: string;
|
|
66
|
+
dx?: number;
|
|
67
|
+
dy?: number;
|
|
68
|
+
dz?: number;
|
|
69
|
+
} | {
|
|
70
|
+
kind: "matchProperties";
|
|
71
|
+
entityId: string;
|
|
72
|
+
sourceId: string;
|
|
73
|
+
} | {
|
|
74
|
+
kind: "setAttribute";
|
|
75
|
+
entityId: string;
|
|
76
|
+
tag: string;
|
|
77
|
+
value: string;
|
|
78
|
+
} | {
|
|
79
|
+
kind: "delete";
|
|
80
|
+
entityId: string;
|
|
81
|
+
} | {
|
|
82
|
+
kind: "addPoint";
|
|
83
|
+
at: AcadPoint;
|
|
84
|
+
layer?: string;
|
|
85
|
+
color?: AcadColor;
|
|
86
|
+
} | {
|
|
87
|
+
kind: "addLine";
|
|
88
|
+
from: AcadPoint;
|
|
89
|
+
to: AcadPoint;
|
|
90
|
+
layer?: string;
|
|
91
|
+
color?: AcadColor;
|
|
92
|
+
} | {
|
|
93
|
+
kind: "addCircle";
|
|
94
|
+
center: AcadPoint;
|
|
95
|
+
radius: number;
|
|
96
|
+
layer?: string;
|
|
97
|
+
color?: AcadColor;
|
|
98
|
+
} | {
|
|
99
|
+
kind: "addArc";
|
|
100
|
+
center: AcadPoint;
|
|
101
|
+
radius: number;
|
|
102
|
+
startAngleDegrees: number;
|
|
103
|
+
endAngleDegrees: number;
|
|
104
|
+
layer?: string;
|
|
105
|
+
color?: AcadColor;
|
|
106
|
+
} | {
|
|
107
|
+
kind: "addText";
|
|
108
|
+
text: string;
|
|
109
|
+
at: AcadPoint;
|
|
110
|
+
height?: number;
|
|
111
|
+
rotationDegrees?: number;
|
|
112
|
+
layer?: string;
|
|
113
|
+
color?: AcadColor;
|
|
114
|
+
} | {
|
|
115
|
+
kind: "addMText";
|
|
116
|
+
text: string;
|
|
117
|
+
at: AcadPoint;
|
|
118
|
+
height?: number;
|
|
119
|
+
width?: number;
|
|
120
|
+
rotationDegrees?: number;
|
|
121
|
+
layer?: string;
|
|
122
|
+
color?: AcadColor;
|
|
123
|
+
} | {
|
|
124
|
+
kind: "addPolyline";
|
|
125
|
+
points: AcadPoint[];
|
|
126
|
+
closed?: boolean;
|
|
127
|
+
layer?: string;
|
|
128
|
+
color?: AcadColor;
|
|
129
|
+
};
|
|
130
|
+
export interface AcadEditResult {
|
|
131
|
+
input: string;
|
|
132
|
+
output: string;
|
|
133
|
+
backend: "acad-ts";
|
|
134
|
+
operations: AcadEditOperation[];
|
|
135
|
+
changed: number;
|
|
136
|
+
}
|
|
137
|
+
export declare function editWithAcadTs(opts: {
|
|
138
|
+
input: string;
|
|
139
|
+
output: string;
|
|
140
|
+
operations: AcadEditOperation[];
|
|
141
|
+
overwrite?: boolean;
|
|
142
|
+
}): AcadEditResult;
|