@mlightcad/cad-simple-viewer-cli 1.5.11

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,281 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
3
+ import { createServer } from 'node:http';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { chromium } from 'playwright';
7
+ /**
8
+ * Resolves the `@mlightcad/cad-simple-viewer-cli` package root
9
+ * (parent of the compiled `dist/` directory).
10
+ *
11
+ * @returns Absolute package root path
12
+ */
13
+ function packageRoot() {
14
+ return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
15
+ }
16
+ /**
17
+ * Directory that holds the built Playwright runner (`index.html`, assets, workers).
18
+ *
19
+ * @returns Absolute path to `dist-runner`
20
+ */
21
+ function runnerDistDir() {
22
+ return path.join(packageRoot(), 'dist-runner');
23
+ }
24
+ /**
25
+ * Appends one line to the optional CLI logfile.
26
+ *
27
+ * No-ops when `logfile` is omitted. Creates parent directories as needed.
28
+ *
29
+ * @param logfile - Absolute or relative log path, or `undefined` to skip
30
+ * @param line - Text line to append (without trailing newline)
31
+ */
32
+ async function appendLog(logfile, line) {
33
+ if (!logfile) {
34
+ return;
35
+ }
36
+ await mkdir(path.dirname(path.resolve(logfile)), { recursive: true });
37
+ await writeFile(logfile, `${line}\n`, { flag: 'a', encoding: 'utf8' });
38
+ }
39
+ /**
40
+ * Picks a non-colliding path under `outputDir` for a downloaded file name.
41
+ *
42
+ * If `fileName` already exists, appends `-2`, `-3`, … before the extension.
43
+ *
44
+ * @param outputDir - Destination directory
45
+ * @param fileName - Suggested file name from the browser download
46
+ * @returns Absolute unique path inside `outputDir`
47
+ */
48
+ function uniqueOutputPath(outputDir, fileName) {
49
+ const base = path.basename(fileName);
50
+ let candidate = path.join(outputDir, base);
51
+ if (!existsSync(candidate)) {
52
+ return candidate;
53
+ }
54
+ const ext = path.extname(base);
55
+ const stem = path.basename(base, ext);
56
+ let index = 2;
57
+ while (existsSync(candidate)) {
58
+ candidate = path.join(outputDir, `${stem}-${index}${ext}`);
59
+ index++;
60
+ }
61
+ return candidate;
62
+ }
63
+ /**
64
+ * Returns whether `value` looks like an `http:` / `https:` drawing URL.
65
+ */
66
+ function isHttpUrl(value) {
67
+ return /^https?:\/\//i.test(value.trim());
68
+ }
69
+ /**
70
+ * File name used for format detection when opening a remote drawing.
71
+ */
72
+ function drawingNameFromUrl(urlString) {
73
+ try {
74
+ const pathname = new URL(urlString).pathname;
75
+ const base = path.basename(pathname);
76
+ if (base && path.extname(base)) {
77
+ return base;
78
+ }
79
+ }
80
+ catch {
81
+ // fall through
82
+ }
83
+ return 'drawing.dwg';
84
+ }
85
+ /**
86
+ * Loads drawing bytes from a local path or remote URL.
87
+ */
88
+ async function loadDrawingInput(inputPath) {
89
+ if (isHttpUrl(inputPath)) {
90
+ const fileName = drawingNameFromUrl(inputPath);
91
+ const ext = path.extname(fileName).toLowerCase();
92
+ if (ext !== '.dxf' && ext !== '.dwg') {
93
+ throw new Error(`Unsupported remote drawing "${fileName}". URL path must end with .dxf or .dwg.`);
94
+ }
95
+ const response = await fetch(inputPath);
96
+ if (!response.ok) {
97
+ throw new Error(`Failed to download drawing (${response.status} ${response.statusText}): ${inputPath}`);
98
+ }
99
+ const bytes = Buffer.from(await response.arrayBuffer());
100
+ return {
101
+ label: inputPath,
102
+ fileName,
103
+ base64: bytes.toString('base64')
104
+ };
105
+ }
106
+ const absoluteInput = path.resolve(inputPath);
107
+ const ext = path.extname(absoluteInput).toLowerCase();
108
+ if (ext !== '.dxf' && ext !== '.dwg') {
109
+ throw new Error(`Unsupported file type "${ext}". Only .dxf and .dwg are supported.`);
110
+ }
111
+ if (!existsSync(absoluteInput)) {
112
+ throw new Error(`Input drawing not found: ${absoluteInput}`);
113
+ }
114
+ const fileBytes = await readFile(absoluteInput);
115
+ return {
116
+ label: absoluteInput,
117
+ fileName: path.basename(absoluteInput),
118
+ base64: fileBytes.toString('base64')
119
+ };
120
+ }
121
+ /**
122
+ * Starts a loopback HTTP server that serves static files from `root`.
123
+ *
124
+ * Used to load the Vite-built runner page into Playwright without packing
125
+ * assets into a `file://` URL.
126
+ *
127
+ * @param root - Absolute directory to serve (typically {@link runnerDistDir})
128
+ * @returns Server base URL and a `close` function that shuts the listener down
129
+ */
130
+ function startStaticServer(root) {
131
+ return new Promise((resolve, reject) => {
132
+ const server = createServer((req, res) => {
133
+ try {
134
+ const urlPath = decodeURIComponent((req.url ?? '/').split('?')[0]);
135
+ const relative = urlPath === '/' ? 'index.html' : urlPath.replace(/^\//, '');
136
+ const filePath = path.join(root, relative);
137
+ if (!filePath.startsWith(root)) {
138
+ res.writeHead(403);
139
+ res.end();
140
+ return;
141
+ }
142
+ if (!existsSync(filePath)) {
143
+ res.writeHead(404);
144
+ res.end();
145
+ return;
146
+ }
147
+ const ext = path.extname(filePath).toLowerCase();
148
+ const types = {
149
+ '.html': 'text/html; charset=utf-8',
150
+ '.js': 'text/javascript; charset=utf-8',
151
+ '.css': 'text/css; charset=utf-8',
152
+ '.json': 'application/json',
153
+ '.wasm': 'application/wasm'
154
+ };
155
+ res.setHeader('Content-Type', types[ext] ?? 'application/octet-stream');
156
+ void readFile(filePath).then(body => {
157
+ res.writeHead(200);
158
+ res.end(body);
159
+ });
160
+ }
161
+ catch (error) {
162
+ res.writeHead(500);
163
+ res.end(String(error));
164
+ }
165
+ });
166
+ server.listen(0, '127.0.0.1', () => {
167
+ const address = server.address();
168
+ if (!address || typeof address === 'string') {
169
+ reject(new Error('Failed to start static server for CLI runner.'));
170
+ return;
171
+ }
172
+ resolve({
173
+ url: `http://127.0.0.1:${address.port}`,
174
+ close: () => new Promise((closeResolve, closeReject) => {
175
+ server.close(err => (err ? closeReject(err) : closeResolve()));
176
+ })
177
+ });
178
+ });
179
+ });
180
+ }
181
+ /**
182
+ * Runs a `.scr` command script in headless Chromium and writes captured
183
+ * export downloads into `outputDir`.
184
+ *
185
+ * When `inputPath` is omitted, the runner starts from a blank ISO template
186
+ * (write mode) so scripts can create geometry from scratch. The page waits for
187
+ * entity convert / deferred font geometry before executing the script so
188
+ * exports such as `pngout` include rendered text.
189
+ *
190
+ * @param options - Script path, optional input drawing, output dir, locale, mode, logfile
191
+ * @returns Absolute output directory and list of saved file paths
192
+ * @throws If the script or input file is missing, the file type is unsupported,
193
+ * the runner build is missing, or the in-page script fails
194
+ */
195
+ export async function runHeadless(options) {
196
+ const absoluteScript = path.resolve(options.scriptPath);
197
+ if (!existsSync(absoluteScript)) {
198
+ throw new Error(`Script not found: ${absoluteScript}`);
199
+ }
200
+ let absoluteInput;
201
+ let fileName = null;
202
+ let base64 = null;
203
+ if (options.inputPath) {
204
+ const drawing = await loadDrawingInput(options.inputPath);
205
+ absoluteInput = drawing.label;
206
+ fileName = drawing.fileName;
207
+ base64 = drawing.base64;
208
+ }
209
+ const outputDir = path.resolve(options.outputDir ??
210
+ (absoluteInput && !isHttpUrl(absoluteInput)
211
+ ? path.dirname(absoluteInput)
212
+ : process.cwd()));
213
+ await mkdir(outputDir, { recursive: true });
214
+ const runnerDir = runnerDistDir();
215
+ if (!existsSync(path.join(runnerDir, 'index.html'))) {
216
+ throw new Error('CLI runner is not built. Run "pnpm --filter @mlightcad/cad-simple-viewer-cli build".');
217
+ }
218
+ const scriptText = await readFile(absoluteScript, 'utf8');
219
+ const mode = options.mode ?? (absoluteInput ? 'read' : 'write');
220
+ const logfile = options.logfile ? path.resolve(options.logfile) : undefined;
221
+ await appendLog(logfile, `[cad-simple-viewer-cli] input=${absoluteInput ?? '(blank)'} script=${absoluteScript} output=${outputDir}`);
222
+ const server = await startStaticServer(runnerDir);
223
+ const channel = process.env.PLAYWRIGHT_BROWSER_CHANNEL;
224
+ const browser = await chromium.launch({
225
+ headless: true,
226
+ ...(channel ? { channel } : {})
227
+ });
228
+ const savedFiles = [];
229
+ try {
230
+ const context = await browser.newContext({ acceptDownloads: true });
231
+ const page = await context.newPage();
232
+ await page.goto(`${server.url}/index.html`, { waitUntil: 'networkidle' });
233
+ let result;
234
+ try {
235
+ result = await page.evaluate(async ({ name, data, script, locale, mode: openMode, startBlank }) => {
236
+ if (data == null || name == null) {
237
+ return window.runCadScript(null, null, script, {
238
+ locale,
239
+ mode: openMode,
240
+ startBlank
241
+ });
242
+ }
243
+ const binary = atob(data);
244
+ const bytes = new Uint8Array(binary.length);
245
+ for (let i = 0; i < binary.length; i++) {
246
+ bytes[i] = binary.charCodeAt(i);
247
+ }
248
+ return window.runCadScript(name, bytes, script, {
249
+ locale,
250
+ mode: openMode,
251
+ startBlank: false
252
+ });
253
+ }, {
254
+ name: fileName,
255
+ data: base64,
256
+ script: scriptText,
257
+ locale: options.locale,
258
+ mode,
259
+ startBlank: !absoluteInput
260
+ });
261
+ }
262
+ catch (error) {
263
+ const message = error instanceof Error ? error.message : String(error);
264
+ await appendLog(logfile, `[cad-simple-viewer-cli] script failed: ${message}`);
265
+ throw error;
266
+ }
267
+ for (const file of result.files) {
268
+ const dest = uniqueOutputPath(outputDir, file.fileName);
269
+ await writeFile(dest, Buffer.from(file.base64, 'base64'));
270
+ savedFiles.push(dest);
271
+ await appendLog(logfile, `[cad-simple-viewer-cli] saved ${dest}`);
272
+ }
273
+ await appendLog(logfile, `[cad-simple-viewer-cli] done saved=${savedFiles.length}`);
274
+ return { outputDir, savedFiles };
275
+ }
276
+ finally {
277
+ await browser.close();
278
+ await server.close();
279
+ }
280
+ }
281
+ //# sourceMappingURL=runHeadless.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runHeadless.js","sourceRoot":"","sources":["../src/runHeadless.ts"],"names":[],"mappings":"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"}