@miclivs/cadcli 0.1.2 → 0.3.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.
@@ -0,0 +1,232 @@
1
+ import { EXIT_UNAVAILABLE, EXIT_USER_ERROR } from "../utils/exit-codes.js";
2
+ import { DwgCliError } from "./errors.js";
3
+ const QUERY_SCHEMA_TABLES = [
4
+ {
5
+ name: "summary",
6
+ description: "One-row drawing summary.",
7
+ columns: [
8
+ { name: "file", type: "text" },
9
+ { name: "format", type: "text" },
10
+ { name: "version", type: "text" },
11
+ { name: "entity_count", type: "integer" },
12
+ { name: "layer_count", type: "integer" },
13
+ { name: "block_count", type: "integer" },
14
+ { name: "unsupported_count", type: "integer" },
15
+ ],
16
+ },
17
+ {
18
+ name: "metadata",
19
+ description: "Document metadata and normalization notes.",
20
+ columns: [
21
+ { name: "key", type: "text" },
22
+ { name: "value", type: "text" },
23
+ ],
24
+ },
25
+ {
26
+ name: "layers",
27
+ description: "Drawing layers and entity counts.",
28
+ columns: [
29
+ { name: "name", type: "text" },
30
+ { name: "entity_count", type: "integer" },
31
+ ],
32
+ },
33
+ {
34
+ name: "blocks",
35
+ description: "Block definitions and definition entity counts.",
36
+ columns: [
37
+ { name: "name", type: "text" },
38
+ { name: "entity_count", type: "integer" },
39
+ ],
40
+ },
41
+ {
42
+ name: "entities",
43
+ description: "All normalized model-space entities, projected narrowly.",
44
+ columns: [
45
+ { name: "id", type: "text" },
46
+ { name: "type", type: "text" },
47
+ { name: "layer", type: "text" },
48
+ { name: "color", type: "text" },
49
+ ],
50
+ },
51
+ {
52
+ name: "texts",
53
+ description: "TEXT and MTEXT entities with normalized text and insertion points.",
54
+ columns: [
55
+ { name: "id", type: "text" },
56
+ { name: "type", type: "text" },
57
+ { name: "layer", type: "text" },
58
+ { name: "text", type: "text" },
59
+ { name: "x", type: "real" },
60
+ { name: "y", type: "real" },
61
+ { name: "text_style", type: "text" },
62
+ { name: "text_style_file", type: "text" },
63
+ ],
64
+ },
65
+ {
66
+ name: "inserts",
67
+ description: "Placed block instances with insertion points.",
68
+ columns: [
69
+ { name: "id", type: "text" },
70
+ { name: "layer", type: "text" },
71
+ { name: "block_name", type: "text" },
72
+ { name: "x", type: "real" },
73
+ { name: "y", type: "real" },
74
+ ],
75
+ },
76
+ ];
77
+ export function querySchema() {
78
+ return QUERY_SCHEMA_TABLES.map((table) => `${table.name}(${table.columns.map((column) => column.name).join(", ")})`).join("\n");
79
+ }
80
+ export function querySchemaTables() {
81
+ return QUERY_SCHEMA_TABLES;
82
+ }
83
+ async function openMemoryDatabase() {
84
+ try {
85
+ const { default: Database } = await import("better-sqlite3");
86
+ return new Database(":memory:");
87
+ }
88
+ catch {
89
+ throw new DwgCliError("cadcli query requires the optional better-sqlite3 dependency.", "QUERY_UNAVAILABLE", EXIT_UNAVAILABLE);
90
+ }
91
+ }
92
+ function sqlValue(value) {
93
+ if (value === undefined || value === null)
94
+ return null;
95
+ if (typeof value === "number" || typeof value === "string")
96
+ return value;
97
+ return String(value);
98
+ }
99
+ function point(entity) {
100
+ const value = entity.data.insertionPoint ?? entity.data.position ?? entity.data.point;
101
+ if (!value || typeof value !== "object")
102
+ return { x: null, y: null };
103
+ const rec = value;
104
+ const x = Number(rec.x ?? rec.X);
105
+ const y = Number(rec.y ?? rec.Y);
106
+ return {
107
+ x: Number.isFinite(x) ? x : null,
108
+ y: Number.isFinite(y) ? y : null,
109
+ };
110
+ }
111
+ function textValue(entity) {
112
+ const value = entity.data.text ?? entity.data.value ?? entity.data.Text;
113
+ return typeof value === "string" && value.length > 0 ? value : null;
114
+ }
115
+ function blockName(entity) {
116
+ const value = entity.data.blockName ?? entity.data.block_name ?? entity.data.name;
117
+ return typeof value === "string" && value.length > 0 ? value : null;
118
+ }
119
+ function createSchema(db) {
120
+ db.exec(`
121
+ CREATE TABLE summary (
122
+ file TEXT,
123
+ format TEXT,
124
+ version TEXT,
125
+ entity_count INTEGER,
126
+ layer_count INTEGER,
127
+ block_count INTEGER,
128
+ unsupported_count INTEGER
129
+ );
130
+ CREATE TABLE metadata (key TEXT PRIMARY KEY, value TEXT);
131
+ CREATE TABLE layers (name TEXT PRIMARY KEY, entity_count INTEGER);
132
+ CREATE TABLE blocks (name TEXT PRIMARY KEY, entity_count INTEGER);
133
+ CREATE TABLE entities (id TEXT PRIMARY KEY, type TEXT, layer TEXT, color TEXT);
134
+ CREATE TABLE texts (
135
+ id TEXT PRIMARY KEY,
136
+ type TEXT,
137
+ layer TEXT,
138
+ text TEXT,
139
+ x REAL,
140
+ y REAL,
141
+ text_style TEXT,
142
+ text_style_file TEXT
143
+ );
144
+ CREATE TABLE inserts (
145
+ id TEXT PRIMARY KEY,
146
+ layer TEXT,
147
+ block_name TEXT,
148
+ x REAL,
149
+ y REAL
150
+ );
151
+ `);
152
+ }
153
+ function registerFunctions(db) {
154
+ db.function("regexp", (pattern, value) => {
155
+ if (typeof pattern !== "string" || value === null || value === undefined) {
156
+ return 0;
157
+ }
158
+ try {
159
+ return new RegExp(pattern, "u").test(String(value)) ? 1 : 0;
160
+ }
161
+ catch {
162
+ return 0;
163
+ }
164
+ });
165
+ }
166
+ function insertDocument(db, doc) {
167
+ db.prepare("INSERT INTO summary VALUES (?, ?, ?, ?, ?, ?, ?)").run(doc.summary.file, doc.summary.format, doc.summary.version ?? null, doc.summary.counts.entities, doc.summary.counts.layers, doc.summary.counts.blocks, doc.summary.counts.unsupported);
168
+ const insertMetadata = db.prepare("INSERT INTO metadata VALUES (?, ?)");
169
+ if (doc.metadata.codePage)
170
+ insertMetadata.run("code_page", doc.metadata.codePage);
171
+ if (doc.metadata.textNormalization) {
172
+ insertMetadata.run("text_normalization_applied", doc.metadata.textNormalization.applied.join(","));
173
+ insertMetadata.run("text_normalization_entities_changed", doc.metadata.textNormalization.entitiesChanged);
174
+ }
175
+ const insertLayer = db.prepare("INSERT INTO layers VALUES (?, ?)");
176
+ const insertBlock = db.prepare("INSERT INTO blocks VALUES (?, ?)");
177
+ const insertEntity = db.prepare("INSERT INTO entities VALUES (?, ?, ?, ?)");
178
+ const insertText = db.prepare("INSERT INTO texts VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
179
+ const insertInsert = db.prepare("INSERT INTO inserts VALUES (?, ?, ?, ?, ?)");
180
+ db.exec("BEGIN");
181
+ try {
182
+ for (const layer of doc.layers)
183
+ insertLayer.run(layer.name, layer.entityCount);
184
+ for (const block of doc.blocks)
185
+ insertBlock.run(block.name, block.entityCount);
186
+ for (const entity of doc.entities) {
187
+ insertEntity.run(entity.id, entity.type, entity.layer ?? null, sqlValue(entity.color));
188
+ const { x, y } = point(entity);
189
+ const text = textValue(entity);
190
+ if ((entity.type === "TEXT" || entity.type === "MTEXT") && text) {
191
+ insertText.run(entity.id, entity.type, entity.layer ?? null, text, x, y, sqlValue(entity.data.textStyle), sqlValue(entity.data.textStyleFile));
192
+ }
193
+ if (entity.type === "INSERT") {
194
+ insertInsert.run(entity.id, entity.layer ?? null, blockName(entity), x, y);
195
+ }
196
+ }
197
+ db.exec("COMMIT");
198
+ }
199
+ catch (error) {
200
+ db.exec("ROLLBACK");
201
+ throw error;
202
+ }
203
+ }
204
+ function ensureSelectQuery(sql) {
205
+ const trimmed = sql.trim();
206
+ if (!/^(select|with)\b/i.test(trimmed)) {
207
+ throw new DwgCliError("Query SQL must be a SELECT statement.", "INVALID_QUERY_SQL", EXIT_USER_ERROR);
208
+ }
209
+ }
210
+ function ensureReadOnlyStatement(statement) {
211
+ if (statement.readonly === false) {
212
+ throw new DwgCliError("Query SQL must be read-only.", "INVALID_QUERY_SQL", EXIT_USER_ERROR);
213
+ }
214
+ }
215
+ export async function queryDrawing(doc, sql) {
216
+ ensureSelectQuery(sql);
217
+ const db = await openMemoryDatabase();
218
+ try {
219
+ createSchema(db);
220
+ registerFunctions(db);
221
+ insertDocument(db, doc);
222
+ const statement = db.prepare(sql);
223
+ ensureReadOnlyStatement(statement);
224
+ const rows = statement.all();
225
+ const columns = statement.columns?.().map((column) => column.name) ??
226
+ Object.keys(rows[0] ?? {});
227
+ return { columns, rows };
228
+ }
229
+ finally {
230
+ db.close();
231
+ }
232
+ }
@@ -0,0 +1,3 @@
1
+ import type { DwgDocument } from "../types.js";
2
+ export declare function normalizeHebrewKeyboardText(text: string): string;
3
+ export declare function normalizeTextAuto(doc: DwgDocument): DwgDocument;
@@ -0,0 +1,104 @@
1
+ import hebrewLayout from "convert-layout/he.js";
2
+ const TEXT_NORMALIZATION_ROUTES = [
3
+ {
4
+ name: "hebrew-keyboard",
5
+ codePages: ["ansi_1255"],
6
+ textStyleFiles: ["gil.shx", "narkism$.shx", "heb.shx", "oron", "oron1"],
7
+ fromLatinKeyboard: hebrewLayout.fromEn,
8
+ targetScript: "hebrew",
9
+ },
10
+ ];
11
+ function asText(value) {
12
+ return typeof value === "string" && value.length > 0 ? value : undefined;
13
+ }
14
+ function normalizedToken(value) {
15
+ return value?.trim().toLowerCase();
16
+ }
17
+ function textStyleFile(entity) {
18
+ return normalizedToken(asText(entity.data.textStyleFile));
19
+ }
20
+ function isTextEntity(entity) {
21
+ return entity.type === "TEXT" || entity.type === "MTEXT";
22
+ }
23
+ function hasTargetScript(text, script) {
24
+ switch (script) {
25
+ case "hebrew":
26
+ return /[\u0590-\u05ff]/u.test(text);
27
+ }
28
+ }
29
+ function targetScriptCount(text, script) {
30
+ switch (script) {
31
+ case "hebrew":
32
+ return text.match(/[\u0590-\u05ff]/gu)?.length ?? 0;
33
+ }
34
+ }
35
+ function mostlyLatinKeyboardText(text, targetScript) {
36
+ const latinLetters = text.match(/[A-Za-z]/g)?.length ?? 0;
37
+ return latinLetters > 0 && targetScriptCount(text, targetScript) === 0;
38
+ }
39
+ function routeMatches(route, doc, entity) {
40
+ const codePage = normalizedToken(doc.metadata.codePage);
41
+ const styleFile = textStyleFile(entity);
42
+ return Boolean(codePage &&
43
+ styleFile &&
44
+ route.codePages.includes(codePage) &&
45
+ route.textStyleFiles.includes(styleFile));
46
+ }
47
+ function routeFor(doc, entity) {
48
+ return TEXT_NORMALIZATION_ROUTES.find((route) => routeMatches(route, doc, entity));
49
+ }
50
+ function normalizeEntityText(doc, entity) {
51
+ if (!isTextEntity(entity))
52
+ return { entity };
53
+ const route = routeFor(doc, entity);
54
+ if (!route)
55
+ return { entity };
56
+ const text = asText(entity.data.text);
57
+ if (!text || !mostlyLatinKeyboardText(text, route.targetScript)) {
58
+ return { entity };
59
+ }
60
+ const normalized = route.fromLatinKeyboard(text);
61
+ if (normalized === text || !hasTargetScript(normalized, route.targetScript)) {
62
+ return { entity };
63
+ }
64
+ return {
65
+ normalizer: route.name,
66
+ entity: {
67
+ ...entity,
68
+ data: {
69
+ ...entity.data,
70
+ text: normalized,
71
+ },
72
+ },
73
+ };
74
+ }
75
+ export function normalizeHebrewKeyboardText(text) {
76
+ return hebrewLayout.fromEn(text);
77
+ }
78
+ export function normalizeTextAuto(doc) {
79
+ const applied = new Set();
80
+ let entitiesChanged = 0;
81
+ const entities = doc.entities.map((entity) => {
82
+ const result = normalizeEntityText(doc, entity);
83
+ if (!result.normalizer)
84
+ return entity;
85
+ entitiesChanged++;
86
+ applied.add(result.normalizer);
87
+ return result.entity;
88
+ });
89
+ if (entitiesChanged === 0)
90
+ return doc;
91
+ const unsupportedIds = new Set(doc.unsupported.map((entity) => entity.id));
92
+ return {
93
+ ...doc,
94
+ entities,
95
+ unsupported: entities.filter((entity) => unsupportedIds.has(entity.id)),
96
+ metadata: {
97
+ ...doc.metadata,
98
+ textNormalization: {
99
+ applied: [...applied],
100
+ entitiesChanged,
101
+ },
102
+ },
103
+ };
104
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export type { LibreDwgEditResult, LibreDwgJsonResult, LibreDwgViewResult, } from "./core/libredwg.js";
1
+ export type { AcadColor, AcadEditOperation, AcadEditResult, AcadPoint, } from "./core/acad-edit.js";
2
+ export type { AcadSvgViewResult } from "./core/acad-view.js";
2
3
  export type { DrawingOverview, DrawingOverviewOptions, OverviewBlock, OverviewEntityType, OverviewLayer, OverviewText, } from "./core/overview.js";
3
4
  export type { DwgSearchOptions, DwgSearchResult } from "./core/search.js";
4
5
  export { Dwg } from "./sdk.js";
package/dist/main.js CHANGED
@@ -9,6 +9,7 @@ import { info } from "./commands/info.js";
9
9
  import { json } from "./commands/json.js";
10
10
  import { layers } from "./commands/layers.js";
11
11
  import { overview } from "./commands/overview.js";
12
+ import { query } from "./commands/query.js";
12
13
  import { search } from "./commands/search.js";
13
14
  import { svg } from "./commands/svg.js";
14
15
  import { thumbnail } from "./commands/thumbnail.js";
@@ -27,8 +28,10 @@ Examples:
27
28
  $ cadcli layers drawing.dwg --json List layers for scripts/agents
28
29
  $ cadcli entities drawing.dwg --type LINE --limit 20
29
30
  $ cadcli search drawing.dwg "conference" --layer A-TEXT
31
+ $ cadcli query drawing.dwg --sql "select text, x, y from texts"
30
32
  $ cadcli view drawing.dwg -o drawing.svg
31
- $ cadcli edit drawing.dwg --jq '.OBJECTS[]' -o edited.dwg
33
+ $ cadcli edit drawing.dwg --set-text "Office" --text-id 2A -o edited.dwg
34
+ $ cadcli edit drawing.dwg --add-line 0,0:10,0 --new-layer A-WALL -o edited.dwg
32
35
 
33
36
  Workflow: info → overview → search/entities → view/edit
34
37
 
@@ -39,16 +42,23 @@ Inspecting:
39
42
  blocks <file> List blocks
40
43
  entities <file> List/filter entities
41
44
  search <file> Search entities by text, type, layer, and raw fields
45
+ query <file> Query normalized CAD tables with SQL
42
46
 
43
47
  Viewing and editing:
44
- view <file> Render a high-fidelity SVG preview
45
- edit <file> Edit DWG/DXF with jq-style expressions
48
+ view <file> Render an SVG preview
49
+ edit <file> Edit DWG/DXF with acad-ts operations
46
50
 
47
51
  Conversion:
48
52
  json <file> Export normalized JSON
49
53
  svg <file> Render best-effort SVG from normalized JSON
50
54
  thumbnail <file> Extract embedded thumbnail when available
51
55
 
56
+ Querying:
57
+ query <file> Query normalized CAD tables with SQL
58
+ --schema Show available query tables
59
+ --sql <query> Run an inline SELECT query
60
+ --file <path> Read a SELECT query from a file
61
+
52
62
  Options:
53
63
  --json Output as JSON
54
64
  -q, --quiet Suppress non-essential output
@@ -118,17 +128,98 @@ program
118
128
  root.query = root.query || queryWords.join(" ");
119
129
  await search(file, root);
120
130
  });
131
+ program
132
+ .command("query <file>")
133
+ .description("Query normalized CAD tables with SQL")
134
+ .option("--sql <query>", "SQL SELECT query to run")
135
+ .option("--file <path>", "Read SQL query from a file")
136
+ .option("--schema", "Show available query tables")
137
+ .action(async (file, opts, cmd) => query(file, { ...cmd.optsWithGlobals(), ...opts }));
121
138
  program
122
139
  .command("view <file>")
123
- .description("Render a high-fidelity SVG preview")
140
+ .description("Render an SVG preview")
124
141
  .option("-o, --output <path>", "Output SVG file")
125
142
  .action(async (file, opts, cmd) => view(file, { ...cmd.optsWithGlobals(), ...opts }));
126
143
  program
127
144
  .command("edit <file>")
128
- .description("Edit DWG/DXF with jq-style expressions")
129
- .requiredOption("--jq <expression>", "dwgfilter jq expression")
130
- .option("-o, --output <path>", "Output file; defaults to input with --overwrite")
145
+ .description("Edit DWG/DXF with acad-ts operations")
146
+ .option("--set-text <text>", "Set TEXT/MTEXT content")
147
+ .option("--text-id <id>", "Entity id/handle for --set-text")
148
+ .option("--set-layer <name>", "Move an entity to a layer")
149
+ .option("--layer-id <id>", "Entity id/handle for --set-layer")
150
+ .option("--set-color <color>", "Set entity color: bylayer, byblock, index, #rrggbb, or r,g,b")
151
+ .option("--color-id <id>", "Entity id/handle for --set-color")
152
+ .option("--set-linetype <name>", "Set entity line type")
153
+ .option("--linetype-id <id>", "Entity id/handle for --set-linetype")
154
+ .option("--set-lineweight <n>", "Set entity line weight enum value")
155
+ .option("--lineweight-id <id>", "Entity id/handle for --set-lineweight")
156
+ .option("--set-transparency <alpha>", "Set transparency alpha value")
157
+ .option("--transparency-id <id>", "Entity id/handle for --set-transparency")
158
+ .option("--hide <id>", "Hide an entity")
159
+ .option("--show <id>", "Show an entity")
160
+ .option("--move <id>", "Move an entity by --dx/--dy/--dz")
161
+ .option("--rotate <id>", "Rotate an entity around Z by --angle degrees")
162
+ .option("--scale <id>", "Scale an entity by --factor")
163
+ .option("--copy <id>", "Copy an entity, optionally offset by --dx/--dy/--dz")
164
+ .option("--match-properties <id>", "Copy visual properties from --source-id")
165
+ .option("--source-id <id>", "Source entity id for --match-properties")
166
+ .option("--set-attr <tag=value>", "Set a block insert attribute")
167
+ .option("--insert-id <id>", "Block insert id for --set-attr")
168
+ .option("--dx <n>", "X delta")
169
+ .option("--dy <n>", "Y delta")
170
+ .option("--dz <n>", "Z delta")
171
+ .option("--angle <degrees>", "Angle in degrees")
172
+ .option("--origin <x,y,z>", "Origin for rotate/scale")
173
+ .option("--factor <n>", "Scale factor")
174
+ .option("--add-point <x,y,z>", "Add a POINT")
175
+ .option("--add-line <from:to>", "Add a LINE, e.g. 0,0:10,0")
176
+ .option("--add-circle <center:radius>", "Add a CIRCLE, e.g. 5,5:2")
177
+ .option("--add-arc <center:radius:start:end>", "Add an ARC with degree angles")
178
+ .option("--add-text <text>", "Add TEXT at --at")
179
+ .option("--add-mtext <text>", "Add MTEXT at --at")
180
+ .option("--points <p1;p2[;p3]>", "Add an LWPOLYLINE from x,y points")
181
+ .option("--closed", "Close a polyline added with --points")
182
+ .option("--at <x,y,z>", "Insertion point for text")
183
+ .option("--height <n>", "Text height")
184
+ .option("--width <n>", "MText width")
185
+ .option("--new-layer <name>", "Layer for add-* entities")
186
+ .option("--new-color <color>", "Color for add-* entities")
187
+ .option("--delete <id>", "Delete an entity")
188
+ .option("-o, --output <path>", "Write edited copy to this file; required unless --overwrite")
131
189
  .option("--overwrite", "Allow editing the input file in place")
190
+ .addHelpText("after", `
191
+
192
+ Examples:
193
+ Find ids first:
194
+ $ cadcli entities drawing.dwg --type TEXT --json
195
+ $ cadcli search drawing.dwg "office" --json
196
+
197
+ Update existing entities:
198
+ $ cadcli edit drawing.dwg --set-text "Office" --text-id 2A -o edited.dwg
199
+ $ cadcli edit drawing.dwg --set-color '#ff0000' --color-id 2A -o edited.dwg
200
+ $ cadcli edit drawing.dwg --move 2A --dx 10 --dy 0 -o edited.dwg
201
+ $ cadcli edit drawing.dwg --rotate 2A --angle 90 --origin 0,0 -o edited.dwg
202
+ $ cadcli edit drawing.dwg --copy 2A --dx 10 --dy 0 -o edited.dwg
203
+ $ cadcli edit drawing.dwg --delete 2A -o edited.dwg
204
+
205
+ Add new entities:
206
+ $ cadcli edit drawing.dwg --add-line 0,0:10,0 --new-layer A-WALL -o edited.dwg
207
+ $ cadcli edit drawing.dwg --add-circle 5,5:2 -o edited.dwg
208
+ $ cadcli edit drawing.dwg --add-text "Label" --at 5,5 --height 2.5 -o edited.dwg
209
+ $ cadcli edit drawing.dwg --points '0,0;10,0;10,5' --closed -o edited.dwg
210
+
211
+ Formats:
212
+ points: x,y or x,y,z
213
+ line: from:to, e.g. 0,0:10,0
214
+ circle: center:radius, e.g. 5,5:2
215
+ arc: center:radius:startAngle:endAngle, e.g. 5,5:2:0:90
216
+ color: bylayer, byblock, AutoCAD color index, #rrggbb, or r,g,b
217
+
218
+ Safety:
219
+ cadcli refuses to modify the input file by default.
220
+ Use -o/--output to write an edited copy.
221
+ Use --overwrite only when you intentionally want to edit the input file in place.
222
+ `)
132
223
  .action(async (file, opts, cmd) => edit(file, { ...cmd.optsWithGlobals(), ...opts }));
133
224
  program
134
225
  .command("json <file>")
package/dist/sdk.d.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import { type AcadEditOperation, type AcadEditResult } from "./core/acad-edit.js";
2
+ import { type AcadSvgViewResult } from "./core/acad-view.js";
1
3
  import { type LoadOptions } from "./core/drawing.js";
2
- import { type LibreDwgEditResult, type LibreDwgViewResult } from "./core/libredwg.js";
3
4
  import { type DrawingOverview, type DrawingOverviewOptions } from "./core/overview.js";
4
5
  import { type DwgSearchOptions, type DwgSearchResult } from "./core/search.js";
5
6
  import type { DwgBlock, DwgDocument, DwgEntity, DwgLayer, DwgSummary, EntityFilter, SvgResult, ThumbnailResult } from "./types.js";
@@ -16,15 +17,12 @@ export declare class Dwg {
16
17
  overview(opts?: DrawingOverviewOptions): Promise<DrawingOverview>;
17
18
  json(): Promise<DwgDocument>;
18
19
  svg(): Promise<SvgResult>;
19
- view(opts?: {
20
- toolDir?: string;
21
- }): LibreDwgViewResult;
20
+ view(): AcadSvgViewResult;
22
21
  edit(opts: {
23
22
  output: string;
24
- expression: string;
23
+ operations: AcadEditOperation[];
25
24
  overwrite?: boolean;
26
- toolDir?: string;
27
- }): LibreDwgEditResult;
25
+ }): AcadEditResult;
28
26
  thumbnail(): Promise<ThumbnailResult>;
29
27
  static open(file: string, opts?: LoadOptions): Dwg;
30
28
  }
package/dist/sdk.js CHANGED
@@ -1,5 +1,6 @@
1
+ import { editWithAcadTs, } from "./core/acad-edit.js";
2
+ import { renderSvgWithAcadTs, } from "./core/acad-view.js";
1
3
  import { getBlocks, getEntities, getInfo, getLayers, getThumbnail, loadDrawing, toJson, toSvg, } from "./core/drawing.js";
2
- import { editWithLibreDwgFilter, renderSvgWithLibreDwg, } from "./core/libredwg.js";
3
4
  import { getOverview, } from "./core/overview.js";
4
5
  import { searchDrawing, } from "./core/search.js";
5
6
  export class Dwg {
@@ -36,16 +37,15 @@ export class Dwg {
36
37
  svg() {
37
38
  return toSvg(this.file, this.opts);
38
39
  }
39
- view(opts = {}) {
40
- return renderSvgWithLibreDwg(this.file, opts);
40
+ view() {
41
+ return renderSvgWithAcadTs(this.file);
41
42
  }
42
43
  edit(opts) {
43
- return editWithLibreDwgFilter({
44
+ return editWithAcadTs({
44
45
  input: this.file,
45
46
  output: opts.output,
46
- expression: opts.expression,
47
+ operations: opts.operations,
47
48
  overwrite: opts.overwrite,
48
- toolDir: opts.toolDir,
49
49
  });
50
50
  }
51
51
  thumbnail() {
package/dist/types.d.ts CHANGED
@@ -35,8 +35,17 @@ export interface DwgSummary {
35
35
  };
36
36
  bounds?: DwgBounds;
37
37
  }
38
+ export interface DwgTextNormalizationMetadata {
39
+ applied: string[];
40
+ entitiesChanged: number;
41
+ }
42
+ export interface DwgMetadata {
43
+ codePage?: string;
44
+ textNormalization?: DwgTextNormalizationMetadata;
45
+ }
38
46
  export interface DwgDocument {
39
47
  summary: DwgSummary;
48
+ metadata: DwgMetadata;
40
49
  layers: DwgLayer[];
41
50
  blocks: DwgBlock[];
42
51
  entities: DwgEntity[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miclivs/cadcli",
3
- "version": "0.1.2",
3
+ "version": "0.3.0",
4
4
  "description": "Agent-friendly CAD inspection, search, viewing, and editing for DWG/DXF files.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -49,7 +49,6 @@
49
49
  "cad",
50
50
  "cli",
51
51
  "sdk",
52
- "libredwg",
53
52
  "svg",
54
53
  "conversion",
55
54
  "pi-package"
@@ -69,6 +68,7 @@
69
68
  "@node-projects/acad-ts": "2.3.0",
70
69
  "chalk": "^5.6.2",
71
70
  "commander": "^14.0.3",
71
+ "convert-layout": "^0.11.1",
72
72
  "nanoid": "^5.1.6"
73
73
  },
74
74
  "optionalDependencies": {