@masumdev/markforge 0.2.2 → 0.2.4

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/dist/index.d.mts CHANGED
@@ -333,7 +333,7 @@ declare const DEFAULT_CONFIG: Required<Omit<MarkforgeConfig, "outputDir" | "css"
333
333
  /**
334
334
  * Resolves and loads markforge configuration from disk.
335
335
  */
336
- declare function loadConfig(customPath?: string, cwd?: string): Promise<{
336
+ declare function loadConfig(customPath?: string, startDir?: string): Promise<{
337
337
  config: MarkforgeConfig;
338
338
  configPath: string | null;
339
339
  }>;
package/dist/index.d.ts CHANGED
@@ -333,7 +333,7 @@ declare const DEFAULT_CONFIG: Required<Omit<MarkforgeConfig, "outputDir" | "css"
333
333
  /**
334
334
  * Resolves and loads markforge configuration from disk.
335
335
  */
336
- declare function loadConfig(customPath?: string, cwd?: string): Promise<{
336
+ declare function loadConfig(customPath?: string, startDir?: string): Promise<{
337
337
  config: MarkforgeConfig;
338
338
  configPath: string | null;
339
339
  }>;
package/dist/index.js CHANGED
@@ -1,3 +1,11 @@
1
+ try {
2
+ if (typeof globalThis !== "undefined" && (!globalThis.localStorage || typeof globalThis.localStorage.getItem !== "function")) {
3
+ Object.defineProperty(globalThis, "localStorage", {
4
+ value: { getItem: () => null, setItem: () => {}, removeItem: () => {}, clear: () => {}, key: () => null, length: 0 },
5
+ configurable: true, writable: true,
6
+ });
7
+ }
8
+ } catch {}
1
9
  "use strict";
2
10
  var __create = Object.create;
3
11
  var __defProp = Object.defineProperty;
@@ -847,11 +855,13 @@ var import_node_child_process2 = require("child_process");
847
855
  var fs4 = __toESM(require("fs"));
848
856
  var os2 = __toESM(require("os"));
849
857
  var path4 = __toESM(require("path"));
858
+ var import_node_url2 = require("url");
850
859
 
851
860
  // src/core/pdf/pdfBuilder.ts
852
861
  var fs3 = __toESM(require("fs"));
853
862
  var path3 = __toESM(require("path"));
854
863
  var os = __toESM(require("os"));
864
+ var import_node_url = require("url");
855
865
  var import_node_child_process = require("child_process");
856
866
 
857
867
  // src/core/html/htmlBuilder.ts
@@ -1303,11 +1313,13 @@ function findChromeExecutable() {
1303
1313
  "/snap/bin/chromium",
1304
1314
  "/usr/bin/microsoft-edge",
1305
1315
  "/usr/bin/microsoft-edge-stable",
1316
+ "/usr/bin/brave-browser",
1306
1317
  // macOS
1307
1318
  "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
1308
1319
  "/Applications/Chromium.app/Contents/MacOS/Chromium",
1309
1320
  "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
1310
- // Windows — Program Files (env-var resolved)
1321
+ "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
1322
+ // Windows — Google Chrome
1311
1323
  `${winProgramFiles}\\Google\\Chrome\\Application\\chrome.exe`,
1312
1324
  `${winProgramFilesX86}\\Google\\Chrome\\Application\\chrome.exe`,
1313
1325
  `${winLocalAppData}\\Google\\Chrome\\Application\\chrome.exe`,
@@ -1315,6 +1327,10 @@ function findChromeExecutable() {
1315
1327
  `${winProgramFiles}\\Microsoft\\Edge\\Application\\msedge.exe`,
1316
1328
  `${winProgramFilesX86}\\Microsoft\\Edge\\Application\\msedge.exe`,
1317
1329
  `${winLocalAppData}\\Microsoft\\Edge\\Application\\msedge.exe`,
1330
+ // Windows — Brave Browser
1331
+ `${winProgramFiles}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
1332
+ `${winProgramFilesX86}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
1333
+ `${winLocalAppData}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
1318
1334
  // Windows — Chromium
1319
1335
  `${winLocalAppData}\\Chromium\\Application\\chrome.exe`
1320
1336
  ].filter(Boolean);
@@ -1328,7 +1344,7 @@ function findChromeExecutable() {
1328
1344
  }
1329
1345
  try {
1330
1346
  const cmd = isWin ? "where" : "which";
1331
- const names = isWin ? ["chrome", "msedge", "google-chrome", "chromium", "chromium-browser"] : ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser", "microsoft-edge"];
1347
+ const names = isWin ? ["chrome", "msedge", "brave", "google-chrome", "chromium", "chromium-browser"] : ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser", "microsoft-edge", "brave-browser"];
1332
1348
  for (const name of names) {
1333
1349
  const res = (0, import_node_child_process.spawnSync)(cmd, [name], { encoding: "utf-8" });
1334
1350
  if (res.status === 0 && res.stdout.trim()) {
@@ -1433,6 +1449,7 @@ async function buildPdfDocument(doc, config, baseDir = process.cwd()) {
1433
1449
  const tmpPdf = path3.join(tmpDir, `markforge_${tmpId}.pdf`);
1434
1450
  try {
1435
1451
  fs3.writeFileSync(tmpHtml, pagedHtml, "utf-8");
1452
+ const fileUrl = (0, import_node_url.pathToFileURL)(tmpHtml).href;
1436
1453
  let res = (0, import_node_child_process.spawnSync)(
1437
1454
  chromePath,
1438
1455
  [
@@ -1441,12 +1458,13 @@ async function buildPdfDocument(doc, config, baseDir = process.cwd()) {
1441
1458
  "--no-sandbox",
1442
1459
  "--disable-setuid-sandbox",
1443
1460
  "--allow-file-access-from-files",
1461
+ "--disable-web-security",
1444
1462
  "--force-color-profile=srgb",
1445
1463
  "--run-all-compositor-stages-before-draw",
1446
1464
  "--virtual-time-budget=8000",
1447
1465
  "--no-pdf-header-footer",
1448
1466
  `--print-to-pdf=${tmpPdf}`,
1449
- tmpHtml
1467
+ fileUrl
1450
1468
  ],
1451
1469
  { timeout: 3e4 }
1452
1470
  );
@@ -1459,10 +1477,11 @@ async function buildPdfDocument(doc, config, baseDir = process.cwd()) {
1459
1477
  "--no-sandbox",
1460
1478
  "--disable-setuid-sandbox",
1461
1479
  "--allow-file-access-from-files",
1480
+ "--disable-web-security",
1462
1481
  "--force-color-profile=srgb",
1463
1482
  "--no-pdf-header-footer",
1464
1483
  `--print-to-pdf=${tmpPdf}`,
1465
- tmpHtml
1484
+ fileUrl
1466
1485
  ],
1467
1486
  { timeout: 3e4 }
1468
1487
  );
@@ -1532,6 +1551,7 @@ ${mermaidCode}
1532
1551
  </html>`;
1533
1552
  try {
1534
1553
  fs4.writeFileSync(tmpHtml, htmlContent, "utf-8");
1554
+ const fileUrl = (0, import_node_url2.pathToFileURL)(tmpHtml).href;
1535
1555
  const res = (0, import_node_child_process2.spawnSync)(
1536
1556
  chromePath,
1537
1557
  [
@@ -1539,11 +1559,13 @@ ${mermaidCode}
1539
1559
  "--disable-gpu",
1540
1560
  "--no-sandbox",
1541
1561
  "--disable-setuid-sandbox",
1562
+ "--allow-file-access-from-files",
1563
+ "--disable-web-security",
1542
1564
  "--disable-software-rasterizer",
1543
1565
  "--window-size=1200,800",
1544
1566
  "--virtual-time-budget=5000",
1545
1567
  `--screenshot=${tmpScreenshot}`,
1546
- tmpHtml
1568
+ fileUrl
1547
1569
  ],
1548
1570
  { timeout: 15e3 }
1549
1571
  );
@@ -2237,7 +2259,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
2237
2259
  // src/config/loadConfig.ts
2238
2260
  var fs5 = __toESM(require("fs"));
2239
2261
  var path5 = __toESM(require("path"));
2240
- var import_node_url = require("url");
2262
+ var import_node_url3 = require("url");
2241
2263
  var YAML = __toESM(require("yaml"));
2242
2264
  var DEFAULT_CONFIG_FILENAMES = [
2243
2265
  "markforge.config.json",
@@ -2280,21 +2302,43 @@ var DEFAULT_CONFIG = {
2280
2302
  bundleHtml: true,
2281
2303
  syntaxTheme: "github-dark"
2282
2304
  };
2283
- async function loadConfig(customPath, cwd = process.cwd()) {
2305
+ function discoverConfigFile(startDir) {
2306
+ const dirsToCheck = [];
2307
+ let curr = path5.resolve(startDir);
2308
+ while (curr) {
2309
+ dirsToCheck.push(curr);
2310
+ const parent = path5.dirname(curr);
2311
+ if (parent === curr) break;
2312
+ curr = parent;
2313
+ }
2314
+ const cwd = path5.resolve(process.cwd());
2315
+ if (!dirsToCheck.includes(cwd)) {
2316
+ dirsToCheck.push(cwd);
2317
+ }
2318
+ for (const dir of dirsToCheck) {
2319
+ for (const filename of DEFAULT_CONFIG_FILENAMES) {
2320
+ const candidate = path5.join(dir, filename);
2321
+ if (fs5.existsSync(candidate) && fs5.statSync(candidate).isFile()) {
2322
+ return candidate;
2323
+ }
2324
+ }
2325
+ }
2326
+ return null;
2327
+ }
2328
+ async function loadConfig(customPath, startDir = process.cwd()) {
2284
2329
  let resolvedPath = null;
2285
2330
  if (customPath) {
2286
- resolvedPath = path5.isAbsolute(customPath) ? customPath : path5.resolve(cwd, customPath);
2331
+ resolvedPath = path5.isAbsolute(customPath) ? customPath : path5.resolve(process.cwd(), customPath);
2287
2332
  if (!fs5.existsSync(resolvedPath)) {
2288
- throw new Error(`Configuration file not found: ${resolvedPath}`);
2289
- }
2290
- } else {
2291
- for (const filename of DEFAULT_CONFIG_FILENAMES) {
2292
- const candidate = path5.resolve(cwd, filename);
2293
- if (fs5.existsSync(candidate)) {
2294
- resolvedPath = candidate;
2295
- break;
2333
+ const altPath = path5.resolve(startDir, customPath);
2334
+ if (fs5.existsSync(altPath)) {
2335
+ resolvedPath = altPath;
2336
+ } else {
2337
+ throw new Error(`Configuration file not found: ${resolvedPath}`);
2296
2338
  }
2297
2339
  }
2340
+ } else {
2341
+ resolvedPath = discoverConfigFile(startDir);
2298
2342
  }
2299
2343
  if (!resolvedPath) {
2300
2344
  return {
@@ -2304,32 +2348,55 @@ async function loadConfig(customPath, cwd = process.cwd()) {
2304
2348
  }
2305
2349
  const ext = path5.extname(resolvedPath).toLowerCase();
2306
2350
  let userConfig = {};
2307
- if (ext === ".json" || resolvedPath.endsWith(".markforgerc")) {
2308
- const raw = fs5.readFileSync(resolvedPath, "utf-8");
2309
- userConfig = JSON.parse(raw);
2310
- } else if (ext === ".yaml" || ext === ".yml") {
2311
- const raw = fs5.readFileSync(resolvedPath, "utf-8");
2312
- userConfig = YAML.parse(raw);
2313
- } else if (ext === ".ts" || ext === ".js" || ext === ".mjs" || ext === ".cjs") {
2314
- try {
2315
- const fileUrl = (0, import_node_url.pathToFileURL)(resolvedPath).href;
2316
- const mod = await import(fileUrl);
2317
- userConfig = mod.default || mod;
2318
- } catch {
2319
- const required = require(resolvedPath);
2320
- userConfig = required.default || required;
2351
+ try {
2352
+ if (ext === ".json" || ext === "" || resolvedPath.endsWith(".markforgerc")) {
2353
+ const raw = fs5.readFileSync(resolvedPath, "utf-8").trim();
2354
+ try {
2355
+ userConfig = JSON.parse(raw);
2356
+ } catch {
2357
+ userConfig = YAML.parse(raw) || {};
2358
+ }
2359
+ } else if (ext === ".yaml" || ext === ".yml") {
2360
+ const raw = fs5.readFileSync(resolvedPath, "utf-8");
2361
+ userConfig = YAML.parse(raw) || {};
2362
+ } else if (ext === ".ts" || ext === ".js" || ext === ".mjs" || ext === ".cjs") {
2363
+ try {
2364
+ const fileUrl = `${(0, import_node_url3.pathToFileURL)(resolvedPath).href}?t=${Date.now()}`;
2365
+ const mod = await import(fileUrl);
2366
+ const rawExport = mod.default ?? mod.config ?? mod;
2367
+ userConfig = (typeof rawExport === "function" ? await rawExport() : rawExport) || {};
2368
+ } catch (importErr) {
2369
+ try {
2370
+ const mod = require(resolvedPath);
2371
+ const rawExport = mod.default ?? mod.config ?? mod;
2372
+ userConfig = (typeof rawExport === "function" ? await rawExport() : rawExport) || {};
2373
+ } catch {
2374
+ throw importErr;
2375
+ }
2376
+ }
2321
2377
  }
2378
+ } catch (err) {
2379
+ throw new Error(
2380
+ `Failed to parse configuration file at ${resolvedPath}: ${err instanceof Error ? err.message : String(err)}`
2381
+ );
2382
+ }
2383
+ if (userConfig && typeof userConfig === "object" && "$schema" in userConfig) {
2384
+ delete userConfig.$schema;
2322
2385
  }
2386
+ const parsedConfig = userConfig;
2323
2387
  const mergedConfig = {
2324
2388
  ...DEFAULT_CONFIG,
2325
- ...userConfig,
2389
+ ...parsedConfig,
2326
2390
  margins: {
2327
2391
  ...DEFAULT_CONFIG.margins,
2328
- ...userConfig.margins
2392
+ ...parsedConfig.margins || {}
2329
2393
  },
2330
- header: userConfig.header || DEFAULT_CONFIG.header,
2331
- footer: userConfig.footer || DEFAULT_CONFIG.footer,
2332
- metadata: userConfig.metadata
2394
+ header: parsedConfig.header !== void 0 ? parsedConfig.header : DEFAULT_CONFIG.header,
2395
+ footer: parsedConfig.footer !== void 0 ? parsedConfig.footer : DEFAULT_CONFIG.footer,
2396
+ metadata: {
2397
+ ...DEFAULT_CONFIG.metadata || {},
2398
+ ...parsedConfig.metadata || {}
2399
+ }
2333
2400
  };
2334
2401
  return {
2335
2402
  config: mergedConfig,
@@ -2437,7 +2504,29 @@ function defineConfig(config) {
2437
2504
  // src/version.ts
2438
2505
  var fs7 = __toESM(require("fs"));
2439
2506
  var path7 = __toESM(require("path"));
2440
- var FALLBACK_VERSION = "0.2.1";
2507
+ var import_node_url4 = require("url");
2508
+ var import_meta = {};
2509
+ try {
2510
+ if (typeof globalThis !== "undefined" && (!globalThis.localStorage || typeof globalThis.localStorage.getItem !== "function")) {
2511
+ Object.defineProperty(globalThis, "localStorage", {
2512
+ value: {
2513
+ getItem: () => null,
2514
+ setItem: () => {
2515
+ },
2516
+ removeItem: () => {
2517
+ },
2518
+ clear: () => {
2519
+ },
2520
+ key: () => null,
2521
+ length: 0
2522
+ },
2523
+ configurable: true,
2524
+ writable: true
2525
+ });
2526
+ }
2527
+ } catch {
2528
+ }
2529
+ var FALLBACK_VERSION = "0.2.2";
2441
2530
  function readVersionFromPackageJson(fromDir) {
2442
2531
  let currentDir = fromDir;
2443
2532
  for (let i = 0; i < 6; i++) {
@@ -2457,11 +2546,18 @@ function readVersionFromPackageJson(fromDir) {
2457
2546
  }
2458
2547
  return FALLBACK_VERSION;
2459
2548
  }
2460
- var MARKFORGE_VERSION = readVersionFromPackageJson(
2461
- // __dirname points to dist/ after build; walk up to find the package root
2462
- typeof __dirname !== "undefined" ? __dirname : process.cwd()
2463
- );
2464
- function getMarkforgeVersion(fromDir = process.cwd()) {
2549
+ function getPackageDir() {
2550
+ if (typeof __dirname !== "undefined") {
2551
+ return __dirname;
2552
+ }
2553
+ try {
2554
+ return path7.dirname((0, import_node_url4.fileURLToPath)(import_meta.url));
2555
+ } catch {
2556
+ return process.cwd();
2557
+ }
2558
+ }
2559
+ var MARKFORGE_VERSION = readVersionFromPackageJson(getPackageDir());
2560
+ function getMarkforgeVersion(fromDir = getPackageDir()) {
2465
2561
  return readVersionFromPackageJson(fromDir);
2466
2562
  }
2467
2563
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.mjs CHANGED
@@ -1,3 +1,11 @@
1
+ try {
2
+ if (typeof globalThis !== "undefined" && (!globalThis.localStorage || typeof globalThis.localStorage.getItem !== "function")) {
3
+ Object.defineProperty(globalThis, "localStorage", {
4
+ value: { getItem: () => null, setItem: () => {}, removeItem: () => {}, clear: () => {}, key: () => null, length: 0 },
5
+ configurable: true, writable: true,
6
+ });
7
+ }
8
+ } catch {}
1
9
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
10
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
11
  }) : x)(function(x) {
@@ -812,11 +820,13 @@ import { spawnSync as spawnSync2 } from "child_process";
812
820
  import * as fs4 from "fs";
813
821
  import * as os2 from "os";
814
822
  import * as path4 from "path";
823
+ import { pathToFileURL as pathToFileURL2 } from "url";
815
824
 
816
825
  // src/core/pdf/pdfBuilder.ts
817
826
  import * as fs3 from "fs";
818
827
  import * as path3 from "path";
819
828
  import * as os from "os";
829
+ import { pathToFileURL } from "url";
820
830
  import { spawnSync } from "child_process";
821
831
 
822
832
  // src/core/html/htmlBuilder.ts
@@ -1268,11 +1278,13 @@ function findChromeExecutable() {
1268
1278
  "/snap/bin/chromium",
1269
1279
  "/usr/bin/microsoft-edge",
1270
1280
  "/usr/bin/microsoft-edge-stable",
1281
+ "/usr/bin/brave-browser",
1271
1282
  // macOS
1272
1283
  "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
1273
1284
  "/Applications/Chromium.app/Contents/MacOS/Chromium",
1274
1285
  "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
1275
- // Windows — Program Files (env-var resolved)
1286
+ "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
1287
+ // Windows — Google Chrome
1276
1288
  `${winProgramFiles}\\Google\\Chrome\\Application\\chrome.exe`,
1277
1289
  `${winProgramFilesX86}\\Google\\Chrome\\Application\\chrome.exe`,
1278
1290
  `${winLocalAppData}\\Google\\Chrome\\Application\\chrome.exe`,
@@ -1280,6 +1292,10 @@ function findChromeExecutable() {
1280
1292
  `${winProgramFiles}\\Microsoft\\Edge\\Application\\msedge.exe`,
1281
1293
  `${winProgramFilesX86}\\Microsoft\\Edge\\Application\\msedge.exe`,
1282
1294
  `${winLocalAppData}\\Microsoft\\Edge\\Application\\msedge.exe`,
1295
+ // Windows — Brave Browser
1296
+ `${winProgramFiles}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
1297
+ `${winProgramFilesX86}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
1298
+ `${winLocalAppData}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
1283
1299
  // Windows — Chromium
1284
1300
  `${winLocalAppData}\\Chromium\\Application\\chrome.exe`
1285
1301
  ].filter(Boolean);
@@ -1293,7 +1309,7 @@ function findChromeExecutable() {
1293
1309
  }
1294
1310
  try {
1295
1311
  const cmd = isWin ? "where" : "which";
1296
- const names = isWin ? ["chrome", "msedge", "google-chrome", "chromium", "chromium-browser"] : ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser", "microsoft-edge"];
1312
+ const names = isWin ? ["chrome", "msedge", "brave", "google-chrome", "chromium", "chromium-browser"] : ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser", "microsoft-edge", "brave-browser"];
1297
1313
  for (const name of names) {
1298
1314
  const res = spawnSync(cmd, [name], { encoding: "utf-8" });
1299
1315
  if (res.status === 0 && res.stdout.trim()) {
@@ -1398,6 +1414,7 @@ async function buildPdfDocument(doc, config, baseDir = process.cwd()) {
1398
1414
  const tmpPdf = path3.join(tmpDir, `markforge_${tmpId}.pdf`);
1399
1415
  try {
1400
1416
  fs3.writeFileSync(tmpHtml, pagedHtml, "utf-8");
1417
+ const fileUrl = pathToFileURL(tmpHtml).href;
1401
1418
  let res = spawnSync(
1402
1419
  chromePath,
1403
1420
  [
@@ -1406,12 +1423,13 @@ async function buildPdfDocument(doc, config, baseDir = process.cwd()) {
1406
1423
  "--no-sandbox",
1407
1424
  "--disable-setuid-sandbox",
1408
1425
  "--allow-file-access-from-files",
1426
+ "--disable-web-security",
1409
1427
  "--force-color-profile=srgb",
1410
1428
  "--run-all-compositor-stages-before-draw",
1411
1429
  "--virtual-time-budget=8000",
1412
1430
  "--no-pdf-header-footer",
1413
1431
  `--print-to-pdf=${tmpPdf}`,
1414
- tmpHtml
1432
+ fileUrl
1415
1433
  ],
1416
1434
  { timeout: 3e4 }
1417
1435
  );
@@ -1424,10 +1442,11 @@ async function buildPdfDocument(doc, config, baseDir = process.cwd()) {
1424
1442
  "--no-sandbox",
1425
1443
  "--disable-setuid-sandbox",
1426
1444
  "--allow-file-access-from-files",
1445
+ "--disable-web-security",
1427
1446
  "--force-color-profile=srgb",
1428
1447
  "--no-pdf-header-footer",
1429
1448
  `--print-to-pdf=${tmpPdf}`,
1430
- tmpHtml
1449
+ fileUrl
1431
1450
  ],
1432
1451
  { timeout: 3e4 }
1433
1452
  );
@@ -1497,6 +1516,7 @@ ${mermaidCode}
1497
1516
  </html>`;
1498
1517
  try {
1499
1518
  fs4.writeFileSync(tmpHtml, htmlContent, "utf-8");
1519
+ const fileUrl = pathToFileURL2(tmpHtml).href;
1500
1520
  const res = spawnSync2(
1501
1521
  chromePath,
1502
1522
  [
@@ -1504,11 +1524,13 @@ ${mermaidCode}
1504
1524
  "--disable-gpu",
1505
1525
  "--no-sandbox",
1506
1526
  "--disable-setuid-sandbox",
1527
+ "--allow-file-access-from-files",
1528
+ "--disable-web-security",
1507
1529
  "--disable-software-rasterizer",
1508
1530
  "--window-size=1200,800",
1509
1531
  "--virtual-time-budget=5000",
1510
1532
  `--screenshot=${tmpScreenshot}`,
1511
- tmpHtml
1533
+ fileUrl
1512
1534
  ],
1513
1535
  { timeout: 15e3 }
1514
1536
  );
@@ -2202,7 +2224,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
2202
2224
  // src/config/loadConfig.ts
2203
2225
  import * as fs5 from "fs";
2204
2226
  import * as path5 from "path";
2205
- import { pathToFileURL } from "url";
2227
+ import { pathToFileURL as pathToFileURL3 } from "url";
2206
2228
  import * as YAML from "yaml";
2207
2229
  var DEFAULT_CONFIG_FILENAMES = [
2208
2230
  "markforge.config.json",
@@ -2245,21 +2267,43 @@ var DEFAULT_CONFIG = {
2245
2267
  bundleHtml: true,
2246
2268
  syntaxTheme: "github-dark"
2247
2269
  };
2248
- async function loadConfig(customPath, cwd = process.cwd()) {
2270
+ function discoverConfigFile(startDir) {
2271
+ const dirsToCheck = [];
2272
+ let curr = path5.resolve(startDir);
2273
+ while (curr) {
2274
+ dirsToCheck.push(curr);
2275
+ const parent = path5.dirname(curr);
2276
+ if (parent === curr) break;
2277
+ curr = parent;
2278
+ }
2279
+ const cwd = path5.resolve(process.cwd());
2280
+ if (!dirsToCheck.includes(cwd)) {
2281
+ dirsToCheck.push(cwd);
2282
+ }
2283
+ for (const dir of dirsToCheck) {
2284
+ for (const filename of DEFAULT_CONFIG_FILENAMES) {
2285
+ const candidate = path5.join(dir, filename);
2286
+ if (fs5.existsSync(candidate) && fs5.statSync(candidate).isFile()) {
2287
+ return candidate;
2288
+ }
2289
+ }
2290
+ }
2291
+ return null;
2292
+ }
2293
+ async function loadConfig(customPath, startDir = process.cwd()) {
2249
2294
  let resolvedPath = null;
2250
2295
  if (customPath) {
2251
- resolvedPath = path5.isAbsolute(customPath) ? customPath : path5.resolve(cwd, customPath);
2296
+ resolvedPath = path5.isAbsolute(customPath) ? customPath : path5.resolve(process.cwd(), customPath);
2252
2297
  if (!fs5.existsSync(resolvedPath)) {
2253
- throw new Error(`Configuration file not found: ${resolvedPath}`);
2254
- }
2255
- } else {
2256
- for (const filename of DEFAULT_CONFIG_FILENAMES) {
2257
- const candidate = path5.resolve(cwd, filename);
2258
- if (fs5.existsSync(candidate)) {
2259
- resolvedPath = candidate;
2260
- break;
2298
+ const altPath = path5.resolve(startDir, customPath);
2299
+ if (fs5.existsSync(altPath)) {
2300
+ resolvedPath = altPath;
2301
+ } else {
2302
+ throw new Error(`Configuration file not found: ${resolvedPath}`);
2261
2303
  }
2262
2304
  }
2305
+ } else {
2306
+ resolvedPath = discoverConfigFile(startDir);
2263
2307
  }
2264
2308
  if (!resolvedPath) {
2265
2309
  return {
@@ -2269,32 +2313,55 @@ async function loadConfig(customPath, cwd = process.cwd()) {
2269
2313
  }
2270
2314
  const ext = path5.extname(resolvedPath).toLowerCase();
2271
2315
  let userConfig = {};
2272
- if (ext === ".json" || resolvedPath.endsWith(".markforgerc")) {
2273
- const raw = fs5.readFileSync(resolvedPath, "utf-8");
2274
- userConfig = JSON.parse(raw);
2275
- } else if (ext === ".yaml" || ext === ".yml") {
2276
- const raw = fs5.readFileSync(resolvedPath, "utf-8");
2277
- userConfig = YAML.parse(raw);
2278
- } else if (ext === ".ts" || ext === ".js" || ext === ".mjs" || ext === ".cjs") {
2279
- try {
2280
- const fileUrl = pathToFileURL(resolvedPath).href;
2281
- const mod = await import(fileUrl);
2282
- userConfig = mod.default || mod;
2283
- } catch {
2284
- const required = __require(resolvedPath);
2285
- userConfig = required.default || required;
2316
+ try {
2317
+ if (ext === ".json" || ext === "" || resolvedPath.endsWith(".markforgerc")) {
2318
+ const raw = fs5.readFileSync(resolvedPath, "utf-8").trim();
2319
+ try {
2320
+ userConfig = JSON.parse(raw);
2321
+ } catch {
2322
+ userConfig = YAML.parse(raw) || {};
2323
+ }
2324
+ } else if (ext === ".yaml" || ext === ".yml") {
2325
+ const raw = fs5.readFileSync(resolvedPath, "utf-8");
2326
+ userConfig = YAML.parse(raw) || {};
2327
+ } else if (ext === ".ts" || ext === ".js" || ext === ".mjs" || ext === ".cjs") {
2328
+ try {
2329
+ const fileUrl = `${pathToFileURL3(resolvedPath).href}?t=${Date.now()}`;
2330
+ const mod = await import(fileUrl);
2331
+ const rawExport = mod.default ?? mod.config ?? mod;
2332
+ userConfig = (typeof rawExport === "function" ? await rawExport() : rawExport) || {};
2333
+ } catch (importErr) {
2334
+ try {
2335
+ const mod = __require(resolvedPath);
2336
+ const rawExport = mod.default ?? mod.config ?? mod;
2337
+ userConfig = (typeof rawExport === "function" ? await rawExport() : rawExport) || {};
2338
+ } catch {
2339
+ throw importErr;
2340
+ }
2341
+ }
2286
2342
  }
2343
+ } catch (err) {
2344
+ throw new Error(
2345
+ `Failed to parse configuration file at ${resolvedPath}: ${err instanceof Error ? err.message : String(err)}`
2346
+ );
2347
+ }
2348
+ if (userConfig && typeof userConfig === "object" && "$schema" in userConfig) {
2349
+ delete userConfig.$schema;
2287
2350
  }
2351
+ const parsedConfig = userConfig;
2288
2352
  const mergedConfig = {
2289
2353
  ...DEFAULT_CONFIG,
2290
- ...userConfig,
2354
+ ...parsedConfig,
2291
2355
  margins: {
2292
2356
  ...DEFAULT_CONFIG.margins,
2293
- ...userConfig.margins
2357
+ ...parsedConfig.margins || {}
2294
2358
  },
2295
- header: userConfig.header || DEFAULT_CONFIG.header,
2296
- footer: userConfig.footer || DEFAULT_CONFIG.footer,
2297
- metadata: userConfig.metadata
2359
+ header: parsedConfig.header !== void 0 ? parsedConfig.header : DEFAULT_CONFIG.header,
2360
+ footer: parsedConfig.footer !== void 0 ? parsedConfig.footer : DEFAULT_CONFIG.footer,
2361
+ metadata: {
2362
+ ...DEFAULT_CONFIG.metadata || {},
2363
+ ...parsedConfig.metadata || {}
2364
+ }
2298
2365
  };
2299
2366
  return {
2300
2367
  config: mergedConfig,
@@ -2402,7 +2469,28 @@ function defineConfig(config) {
2402
2469
  // src/version.ts
2403
2470
  import * as fs7 from "fs";
2404
2471
  import * as path7 from "path";
2405
- var FALLBACK_VERSION = "0.2.1";
2472
+ import { fileURLToPath as fileURLToPath2 } from "url";
2473
+ try {
2474
+ if (typeof globalThis !== "undefined" && (!globalThis.localStorage || typeof globalThis.localStorage.getItem !== "function")) {
2475
+ Object.defineProperty(globalThis, "localStorage", {
2476
+ value: {
2477
+ getItem: () => null,
2478
+ setItem: () => {
2479
+ },
2480
+ removeItem: () => {
2481
+ },
2482
+ clear: () => {
2483
+ },
2484
+ key: () => null,
2485
+ length: 0
2486
+ },
2487
+ configurable: true,
2488
+ writable: true
2489
+ });
2490
+ }
2491
+ } catch {
2492
+ }
2493
+ var FALLBACK_VERSION = "0.2.2";
2406
2494
  function readVersionFromPackageJson(fromDir) {
2407
2495
  let currentDir = fromDir;
2408
2496
  for (let i = 0; i < 6; i++) {
@@ -2422,11 +2510,18 @@ function readVersionFromPackageJson(fromDir) {
2422
2510
  }
2423
2511
  return FALLBACK_VERSION;
2424
2512
  }
2425
- var MARKFORGE_VERSION = readVersionFromPackageJson(
2426
- // __dirname points to dist/ after build; walk up to find the package root
2427
- typeof __dirname !== "undefined" ? __dirname : process.cwd()
2428
- );
2429
- function getMarkforgeVersion(fromDir = process.cwd()) {
2513
+ function getPackageDir() {
2514
+ if (typeof __dirname !== "undefined") {
2515
+ return __dirname;
2516
+ }
2517
+ try {
2518
+ return path7.dirname(fileURLToPath2(import.meta.url));
2519
+ } catch {
2520
+ return process.cwd();
2521
+ }
2522
+ }
2523
+ var MARKFORGE_VERSION = readVersionFromPackageJson(getPackageDir());
2524
+ function getMarkforgeVersion(fromDir = getPackageDir()) {
2430
2525
  return readVersionFromPackageJson(fromDir);
2431
2526
  }
2432
2527
  export {
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ try {
3
+ if (typeof globalThis !== "undefined" && (!globalThis.localStorage || typeof globalThis.localStorage.getItem !== "function")) {
4
+ Object.defineProperty(globalThis, "localStorage", {
5
+ value: { getItem: () => null, setItem: () => {}, removeItem: () => {}, clear: () => {}, key: () => null, length: 0 },
6
+ configurable: true, writable: true,
7
+ });
8
+ }
9
+ } catch {}
10
+ import {
11
+ DEFAULT_CONFIG,
12
+ loadConfig
13
+ } from "./chunk-IYGPJIK5.mjs";
14
+ import "./chunk-YZHGBG4N.mjs";
15
+ export {
16
+ DEFAULT_CONFIG,
17
+ loadConfig
18
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masumdev/markforge",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Modern, high-performance Markdown & MDX multi-format document publishing engine and CLI (DOCX, PDF, HTML, and Images) with embedded HTML/CSS, image inliner, and Ink terminal UI.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",