@tscircuit/cli 0.1.1648 → 0.1.1650
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/cli/build/build.worker.js +287 -154
- package/dist/cli/main.js +1505 -1353
- package/dist/cli/snapshot/snapshot.worker.js +251 -94
- package/dist/lib/index.js +1 -1
- package/package.json +1 -1
|
@@ -2485,8 +2485,8 @@ export default {
|
|
|
2485
2485
|
import { parentPort } from "node:worker_threads";
|
|
2486
2486
|
|
|
2487
2487
|
// lib/shared/process-snapshot-file.ts
|
|
2488
|
-
import
|
|
2489
|
-
import
|
|
2488
|
+
import fs8 from "node:fs";
|
|
2489
|
+
import path7 from "node:path";
|
|
2490
2490
|
|
|
2491
2491
|
// node_modules/circuit-json-to-3d-png/dist/index.js
|
|
2492
2492
|
function normalizeDir(dir) {
|
|
@@ -2775,9 +2775,140 @@ function init(open, close) {
|
|
|
2775
2775
|
}
|
|
2776
2776
|
var kleur_default = $;
|
|
2777
2777
|
|
|
2778
|
+
// lib/shared/circuit-json-build-cache.ts
|
|
2779
|
+
import fs from "node:fs";
|
|
2780
|
+
import path from "node:path";
|
|
2781
|
+
import { createHash } from "node:crypto";
|
|
2782
|
+
var SOURCE_FILE_EXTENSIONS = new Set([
|
|
2783
|
+
".tsx",
|
|
2784
|
+
".ts",
|
|
2785
|
+
".jsx",
|
|
2786
|
+
".js",
|
|
2787
|
+
".json",
|
|
2788
|
+
".txt",
|
|
2789
|
+
".md",
|
|
2790
|
+
".obj",
|
|
2791
|
+
".kicad_mod",
|
|
2792
|
+
".kicad_pcb",
|
|
2793
|
+
".kicad_pro",
|
|
2794
|
+
".kicad_sch"
|
|
2795
|
+
]);
|
|
2796
|
+
var IGNORED_DIRECTORY_NAMES = new Set([
|
|
2797
|
+
"node_modules",
|
|
2798
|
+
"dist",
|
|
2799
|
+
"build",
|
|
2800
|
+
".git"
|
|
2801
|
+
]);
|
|
2802
|
+
var isPathInside = (childPath, parentPath) => {
|
|
2803
|
+
const relative = path.relative(parentPath, childPath);
|
|
2804
|
+
return relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
2805
|
+
};
|
|
2806
|
+
var findCircuitProjectDir = (filePath) => {
|
|
2807
|
+
const absoluteFilePath = path.resolve(filePath);
|
|
2808
|
+
let currentDir = path.dirname(absoluteFilePath);
|
|
2809
|
+
while (true) {
|
|
2810
|
+
if (fs.existsSync(path.join(currentDir, "package.json"))) {
|
|
2811
|
+
return currentDir;
|
|
2812
|
+
}
|
|
2813
|
+
const parentDir = path.dirname(currentDir);
|
|
2814
|
+
if (parentDir === currentDir)
|
|
2815
|
+
break;
|
|
2816
|
+
currentDir = parentDir;
|
|
2817
|
+
}
|
|
2818
|
+
const cwd = path.resolve(process.cwd());
|
|
2819
|
+
return isPathInside(absoluteFilePath, cwd) ? cwd : path.dirname(absoluteFilePath);
|
|
2820
|
+
};
|
|
2821
|
+
var getCircuitJsonOutputDirName = (relativePath) => {
|
|
2822
|
+
const normalizedRelativePath = relativePath.toLowerCase().replaceAll("\\", "/");
|
|
2823
|
+
if (normalizedRelativePath === "circuit.json" || normalizedRelativePath.endsWith("/circuit.json")) {
|
|
2824
|
+
return path.dirname(relativePath);
|
|
2825
|
+
}
|
|
2826
|
+
return relativePath.replace(/(\.board|\.circuit)?\.tsx$/, "").replace(/\.circuit\.json$/, "");
|
|
2827
|
+
};
|
|
2828
|
+
var getCircuitJsonBuildOutputPath = (filePath) => {
|
|
2829
|
+
const absoluteFilePath = path.resolve(filePath);
|
|
2830
|
+
const projectDir = findCircuitProjectDir(absoluteFilePath);
|
|
2831
|
+
const relativePath = path.relative(projectDir, absoluteFilePath);
|
|
2832
|
+
return path.join(projectDir, "dist", getCircuitJsonOutputDirName(relativePath), "circuit.json");
|
|
2833
|
+
};
|
|
2834
|
+
var getSourceFilePaths = (projectDir) => {
|
|
2835
|
+
const sourceFilePaths = [];
|
|
2836
|
+
const visit = (directoryPath) => {
|
|
2837
|
+
const entries = fs.readdirSync(directoryPath, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
2838
|
+
for (const entry of entries) {
|
|
2839
|
+
const entryPath = path.join(directoryPath, entry.name);
|
|
2840
|
+
if (entry.isDirectory()) {
|
|
2841
|
+
if (IGNORED_DIRECTORY_NAMES.has(entry.name) || entry.name.startsWith(".")) {
|
|
2842
|
+
continue;
|
|
2843
|
+
}
|
|
2844
|
+
visit(entryPath);
|
|
2845
|
+
continue;
|
|
2846
|
+
}
|
|
2847
|
+
if (!entry.isFile() || entry.name.endsWith(".circuit.json") || !SOURCE_FILE_EXTENSIONS.has(path.extname(entry.name).toLowerCase())) {
|
|
2848
|
+
continue;
|
|
2849
|
+
}
|
|
2850
|
+
sourceFilePaths.push(entryPath);
|
|
2851
|
+
}
|
|
2852
|
+
};
|
|
2853
|
+
visit(projectDir);
|
|
2854
|
+
return sourceFilePaths;
|
|
2855
|
+
};
|
|
2856
|
+
var getSourceFilesystemMd5Hash = (filePath) => {
|
|
2857
|
+
const projectDir = findCircuitProjectDir(filePath);
|
|
2858
|
+
const hash = createHash("md5");
|
|
2859
|
+
for (const sourceFilePath of getSourceFilePaths(projectDir)) {
|
|
2860
|
+
const relativePath = path.relative(projectDir, sourceFilePath).split(path.sep).join("/");
|
|
2861
|
+
const content = fs.readFileSync(sourceFilePath);
|
|
2862
|
+
hash.update(`${Buffer.byteLength(relativePath)}:`);
|
|
2863
|
+
hash.update(relativePath);
|
|
2864
|
+
hash.update(`${content.byteLength}:`);
|
|
2865
|
+
hash.update(content);
|
|
2866
|
+
}
|
|
2867
|
+
return hash.digest("hex");
|
|
2868
|
+
};
|
|
2869
|
+
var addSourceFilesystemHash = (circuitJson, sourceFilesystemMd5Hash) => {
|
|
2870
|
+
let foundProjectMetadata = false;
|
|
2871
|
+
const circuitJsonWithHash = circuitJson.map((element) => {
|
|
2872
|
+
if (element.type !== "source_project_metadata")
|
|
2873
|
+
return element;
|
|
2874
|
+
foundProjectMetadata = true;
|
|
2875
|
+
const metadataWithHash = {
|
|
2876
|
+
...element,
|
|
2877
|
+
source_filesystem_md5_hash: sourceFilesystemMd5Hash
|
|
2878
|
+
};
|
|
2879
|
+
return metadataWithHash;
|
|
2880
|
+
});
|
|
2881
|
+
if (!foundProjectMetadata) {
|
|
2882
|
+
const metadataWithHash = {
|
|
2883
|
+
type: "source_project_metadata",
|
|
2884
|
+
source_filesystem_md5_hash: sourceFilesystemMd5Hash
|
|
2885
|
+
};
|
|
2886
|
+
circuitJsonWithHash.push(metadataWithHash);
|
|
2887
|
+
}
|
|
2888
|
+
return circuitJsonWithHash;
|
|
2889
|
+
};
|
|
2890
|
+
var readCurrentCircuitJsonBuild = ({
|
|
2891
|
+
filePath,
|
|
2892
|
+
sourceFilesystemMd5Hash
|
|
2893
|
+
}) => {
|
|
2894
|
+
const outputPath = getCircuitJsonBuildOutputPath(filePath);
|
|
2895
|
+
try {
|
|
2896
|
+
const parsed = JSON.parse(fs.readFileSync(outputPath, "utf-8"));
|
|
2897
|
+
if (!Array.isArray(parsed))
|
|
2898
|
+
return null;
|
|
2899
|
+
const hasCurrentFilesystemHash = parsed.some((element) => element?.type === "source_project_metadata" && element.source_filesystem_md5_hash === sourceFilesystemMd5Hash);
|
|
2900
|
+
return hasCurrentFilesystemHash ? {
|
|
2901
|
+
circuitJson: parsed,
|
|
2902
|
+
outputPath
|
|
2903
|
+
} : null;
|
|
2904
|
+
} catch {
|
|
2905
|
+
return null;
|
|
2906
|
+
}
|
|
2907
|
+
};
|
|
2908
|
+
|
|
2778
2909
|
// lib/shared/generate-circuit-json.tsx
|
|
2779
|
-
import
|
|
2780
|
-
import
|
|
2910
|
+
import fs5 from "node:fs";
|
|
2911
|
+
import path5 from "node:path";
|
|
2781
2912
|
import { pathToFileURL } from "node:url";
|
|
2782
2913
|
import Debug from "debug";
|
|
2783
2914
|
|
|
@@ -2799,8 +2930,8 @@ var abbreviateStringifyObject = (obj) => {
|
|
|
2799
2930
|
var import_make_vfs = __toESM(require_dist(), 1);
|
|
2800
2931
|
|
|
2801
2932
|
// lib/shared/autorouter-diagnostics.ts
|
|
2802
|
-
import
|
|
2803
|
-
import
|
|
2933
|
+
import fs2 from "node:fs";
|
|
2934
|
+
import path2 from "node:path";
|
|
2804
2935
|
import { convertCircuitJsonToPcbSvg } from "circuit-to-svg";
|
|
2805
2936
|
|
|
2806
2937
|
// lib/shared/convert-svg-to-png.ts
|
|
@@ -2815,7 +2946,7 @@ var convertSvgToPngBuffer = (svg) => {
|
|
|
2815
2946
|
};
|
|
2816
2947
|
|
|
2817
2948
|
// lib/shared/autorouter-diagnostics.ts
|
|
2818
|
-
var DEFAULT_DEBUG_DIR =
|
|
2949
|
+
var DEFAULT_DEBUG_DIR = path2.join("dist", "autorouter-debug");
|
|
2819
2950
|
var PROGRESS_LOG_INTERVAL_MS = 1e4;
|
|
2820
2951
|
var CIRCUIT_JSON_ID_PATTERN = /\b(?:source|pcb|schematic|subcircuit|cad|simulation)_[a-z0-9_]*_\d+\b/gi;
|
|
2821
2952
|
var parseAutorouterTimeout = (duration) => {
|
|
@@ -3160,24 +3291,24 @@ class AutorouterDiagnostics {
|
|
|
3160
3291
|
return this.options.dumpSrj === "all" || this.options.dumpSrj === "failed" || this.options.dumpSrj === `phase:${routingPhaseIndex}`;
|
|
3161
3292
|
}
|
|
3162
3293
|
writeJson(fileName, value) {
|
|
3163
|
-
const debugDir =
|
|
3164
|
-
|
|
3165
|
-
const filePath =
|
|
3166
|
-
|
|
3294
|
+
const debugDir = path2.resolve(this.options.debugDir ?? DEFAULT_DEBUG_DIR);
|
|
3295
|
+
fs2.mkdirSync(debugDir, { recursive: true });
|
|
3296
|
+
const filePath = path2.join(debugDir, fileName);
|
|
3297
|
+
fs2.writeFileSync(filePath, JSON.stringify(value, null, 2));
|
|
3167
3298
|
this.logArtifact(filePath);
|
|
3168
3299
|
return filePath;
|
|
3169
3300
|
}
|
|
3170
3301
|
writePngSnapshot(fileName, circuitJson) {
|
|
3171
3302
|
const pcbSvg = convertCircuitJsonToPcbSvg(circuitJson);
|
|
3172
3303
|
const png = convertSvgToPngBuffer(pcbSvg);
|
|
3173
|
-
const debugDir =
|
|
3174
|
-
|
|
3175
|
-
const filePath =
|
|
3176
|
-
|
|
3304
|
+
const debugDir = path2.resolve(this.options.debugDir ?? DEFAULT_DEBUG_DIR);
|
|
3305
|
+
fs2.mkdirSync(debugDir, { recursive: true });
|
|
3306
|
+
const filePath = path2.join(debugDir, fileName);
|
|
3307
|
+
fs2.writeFileSync(filePath, png);
|
|
3177
3308
|
this.logArtifact(filePath);
|
|
3178
3309
|
}
|
|
3179
3310
|
logArtifact(filePath) {
|
|
3180
|
-
this.log(`Wrote debug artifact: ${
|
|
3311
|
+
this.log(`Wrote debug artifact: ${path2.relative(process.cwd(), filePath)}`);
|
|
3181
3312
|
}
|
|
3182
3313
|
getCircuitJsonWithCompletedPhaseTraces() {
|
|
3183
3314
|
const circuitJson = [...this.getCurrentCircuitJson()];
|
|
@@ -3323,12 +3454,12 @@ class AutorouterDiagnostics {
|
|
|
3323
3454
|
|
|
3324
3455
|
// lib/shared/importFromUserLand.ts
|
|
3325
3456
|
import { createRequire as createRequire2 } from "node:module";
|
|
3326
|
-
import
|
|
3327
|
-
import
|
|
3457
|
+
import fs3 from "node:fs";
|
|
3458
|
+
import path3 from "node:path";
|
|
3328
3459
|
async function importFromUserLand(moduleName) {
|
|
3329
|
-
const userModulePath =
|
|
3330
|
-
if (
|
|
3331
|
-
const userRequire = createRequire2(
|
|
3460
|
+
const userModulePath = path3.join(process.cwd(), "node_modules", moduleName);
|
|
3461
|
+
if (fs3.existsSync(userModulePath)) {
|
|
3462
|
+
const userRequire = createRequire2(path3.join(process.cwd(), "noop.js"));
|
|
3332
3463
|
try {
|
|
3333
3464
|
const resolvedUserPath = userRequire.resolve(moduleName);
|
|
3334
3465
|
return await import(resolvedUserPath);
|
|
@@ -3351,8 +3482,8 @@ async function importFromUserLand(moduleName) {
|
|
|
3351
3482
|
}
|
|
3352
3483
|
|
|
3353
3484
|
// lib/shared/register-static-asset-loaders.ts
|
|
3354
|
-
import
|
|
3355
|
-
import
|
|
3485
|
+
import fs4 from "node:fs";
|
|
3486
|
+
import path4 from "node:path";
|
|
3356
3487
|
var STATIC_ASSET_EXTENSIONS = [
|
|
3357
3488
|
".glb",
|
|
3358
3489
|
".gltf",
|
|
@@ -3377,15 +3508,15 @@ var TEXT_STATIC_ASSET_EXTENSIONS = new Set([
|
|
|
3377
3508
|
".kicad_sch"
|
|
3378
3509
|
]);
|
|
3379
3510
|
var readFileContentForStaticLoader = (filePath) => {
|
|
3380
|
-
const ext =
|
|
3511
|
+
const ext = path4.extname(filePath).toLowerCase();
|
|
3381
3512
|
if (TEXT_STATIC_ASSET_EXTENSIONS.has(ext)) {
|
|
3382
|
-
return
|
|
3513
|
+
return fs4.readFileSync(filePath, "utf-8");
|
|
3383
3514
|
}
|
|
3384
|
-
const buffer =
|
|
3515
|
+
const buffer = fs4.readFileSync(filePath);
|
|
3385
3516
|
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
3386
3517
|
};
|
|
3387
3518
|
var getStaticFileLoader = (filePath) => {
|
|
3388
|
-
const extWithDot =
|
|
3519
|
+
const extWithDot = path4.extname(filePath).toLowerCase();
|
|
3389
3520
|
const ext = extWithDot.replace(/^\./, "");
|
|
3390
3521
|
return activePlatformConfig?.staticFileLoaderMap?.[ext] ?? activePlatformConfig?.staticFileLoaderMap?.[extWithDot];
|
|
3391
3522
|
};
|
|
@@ -3399,12 +3530,12 @@ var normalizeStaticFileLoaderResult = (result) => {
|
|
|
3399
3530
|
};
|
|
3400
3531
|
};
|
|
3401
3532
|
var getBaseUrlFromTsConfig = () => {
|
|
3402
|
-
const tsconfigPath =
|
|
3533
|
+
const tsconfigPath = path4.join(process.cwd(), "tsconfig.json");
|
|
3403
3534
|
try {
|
|
3404
|
-
if (!
|
|
3535
|
+
if (!fs4.existsSync(tsconfigPath)) {
|
|
3405
3536
|
return null;
|
|
3406
3537
|
}
|
|
3407
|
-
const tsconfigContent =
|
|
3538
|
+
const tsconfigContent = fs4.readFileSync(tsconfigPath, "utf-8");
|
|
3408
3539
|
const tsconfig = JSON.parse(tsconfigContent);
|
|
3409
3540
|
if (tsconfig.compilerOptions?.baseUrl) {
|
|
3410
3541
|
return tsconfig.compilerOptions.baseUrl;
|
|
@@ -3431,8 +3562,8 @@ var registerStaticAssetLoaders = (platformConfig) => {
|
|
|
3431
3562
|
loader: "object"
|
|
3432
3563
|
};
|
|
3433
3564
|
}
|
|
3434
|
-
const baseDir = baseUrl ?
|
|
3435
|
-
const relativePath =
|
|
3565
|
+
const baseDir = baseUrl ? path4.resolve(process.cwd(), baseUrl) : process.cwd();
|
|
3566
|
+
const relativePath = path4.relative(baseDir, args.path).split(path4.sep).join("/");
|
|
3436
3567
|
const pathStr = `./${relativePath}`;
|
|
3437
3568
|
return {
|
|
3438
3569
|
exports: {
|
|
@@ -3472,9 +3603,11 @@ async function generateCircuitJson({
|
|
|
3472
3603
|
platformConfig,
|
|
3473
3604
|
injectedProps,
|
|
3474
3605
|
onAsyncEffectStatus,
|
|
3475
|
-
autorouterDiagnostics: autorouterDiagnosticsOptions
|
|
3606
|
+
autorouterDiagnostics: autorouterDiagnosticsOptions,
|
|
3607
|
+
sourceFilesystemMd5Hash
|
|
3476
3608
|
}) {
|
|
3477
3609
|
debug(`Generating circuit JSON for ${filePath}`);
|
|
3610
|
+
const currentSourceFilesystemMd5Hash = sourceFilesystemMd5Hash ?? getSourceFilesystemMd5Hash(filePath);
|
|
3478
3611
|
const React = await importFromUserLand("react");
|
|
3479
3612
|
globalThis.React = React;
|
|
3480
3613
|
registerStaticAssetLoaders(platformConfig);
|
|
@@ -3484,12 +3617,12 @@ async function generateCircuitJson({
|
|
|
3484
3617
|
});
|
|
3485
3618
|
const autorouterDiagnostics = new AutorouterDiagnostics(autorouterDiagnosticsOptions);
|
|
3486
3619
|
autorouterDiagnostics.attachToRootCircuit(runner);
|
|
3487
|
-
const absoluteFilePath =
|
|
3488
|
-
const projectDir =
|
|
3620
|
+
const absoluteFilePath = path5.isAbsolute(filePath) ? filePath : path5.resolve(process.cwd(), filePath);
|
|
3621
|
+
const projectDir = path5.dirname(absoluteFilePath);
|
|
3489
3622
|
const resolvedOutputDir = outputDir ?? projectDir;
|
|
3490
|
-
const relativeComponentPath =
|
|
3491
|
-
const baseFileName = outputFileName ||
|
|
3492
|
-
const outputPath =
|
|
3623
|
+
const relativeComponentPath = path5.relative(projectDir, absoluteFilePath);
|
|
3624
|
+
const baseFileName = outputFileName || path5.basename(absoluteFilePath).replace(/\.[^.]+$/, "");
|
|
3625
|
+
const outputPath = path5.join(resolvedOutputDir, `${baseFileName}.circuit.json`);
|
|
3493
3626
|
debug(`Project directory: ${projectDir}`);
|
|
3494
3627
|
debug(`Relative component path: ${relativeComponentPath}`);
|
|
3495
3628
|
debug(`Output path: ${outputPath}`);
|
|
@@ -3509,7 +3642,7 @@ async function generateCircuitJson({
|
|
|
3509
3642
|
return false;
|
|
3510
3643
|
if (normalizedFilePath.match(/^\.[^/]/))
|
|
3511
3644
|
return false;
|
|
3512
|
-
if (!ALLOWED_FILE_EXTENSIONS.includes(
|
|
3645
|
+
if (!ALLOWED_FILE_EXTENSIONS.includes(path5.extname(normalizedFilePath)))
|
|
3513
3646
|
return false;
|
|
3514
3647
|
return true;
|
|
3515
3648
|
},
|
|
@@ -3541,11 +3674,11 @@ async function generateCircuitJson({
|
|
|
3541
3674
|
runner.render();
|
|
3542
3675
|
}
|
|
3543
3676
|
runner.emit("renderComplete");
|
|
3544
|
-
const circuitJson = await runner.getCircuitJson();
|
|
3677
|
+
const circuitJson = addSourceFilesystemHash(await runner.getCircuitJson(), currentSourceFilesystemMd5Hash);
|
|
3545
3678
|
await autorouterDiagnostics.finalize(circuitJson);
|
|
3546
3679
|
if (saveToFile) {
|
|
3547
3680
|
debug(`Saving circuit JSON to ${outputPath}`);
|
|
3548
|
-
|
|
3681
|
+
fs5.writeFileSync(outputPath, JSON.stringify(circuitJson, null, 2));
|
|
3549
3682
|
}
|
|
3550
3683
|
return {
|
|
3551
3684
|
circuitJson,
|
|
@@ -3554,30 +3687,54 @@ async function generateCircuitJson({
|
|
|
3554
3687
|
};
|
|
3555
3688
|
}
|
|
3556
3689
|
|
|
3690
|
+
// lib/shared/get-or-generate-circuit-json.ts
|
|
3691
|
+
var getOrGenerateCircuitJson = async (options) => {
|
|
3692
|
+
const sourceFilesystemMd5Hash = getSourceFilesystemMd5Hash(options.filePath);
|
|
3693
|
+
const cachedBuild = readCurrentCircuitJsonBuild({
|
|
3694
|
+
filePath: options.filePath,
|
|
3695
|
+
sourceFilesystemMd5Hash
|
|
3696
|
+
});
|
|
3697
|
+
if (cachedBuild) {
|
|
3698
|
+
return {
|
|
3699
|
+
...cachedBuild,
|
|
3700
|
+
rootCircuit: undefined,
|
|
3701
|
+
cacheHit: true
|
|
3702
|
+
};
|
|
3703
|
+
}
|
|
3704
|
+
const generated = await generateCircuitJson({
|
|
3705
|
+
...options,
|
|
3706
|
+
sourceFilesystemMd5Hash
|
|
3707
|
+
});
|
|
3708
|
+
return {
|
|
3709
|
+
...generated,
|
|
3710
|
+
cacheHit: false
|
|
3711
|
+
};
|
|
3712
|
+
};
|
|
3713
|
+
|
|
3557
3714
|
// lib/shared/get-platform-config-with-cli-defaults.ts
|
|
3558
|
-
import { createHash } from "node:crypto";
|
|
3559
|
-
import
|
|
3560
|
-
import
|
|
3715
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
3716
|
+
import fs6 from "node:fs";
|
|
3717
|
+
import path6 from "node:path";
|
|
3561
3718
|
import { getPlatformConfig } from "@tscircuit/eval/platform-config";
|
|
3562
|
-
function createLocalCacheEngine(cacheDir =
|
|
3719
|
+
function createLocalCacheEngine(cacheDir = path6.join(process.cwd(), ".tscircuit", "cache")) {
|
|
3563
3720
|
return {
|
|
3564
3721
|
getItem: (key) => {
|
|
3565
3722
|
try {
|
|
3566
|
-
const hash =
|
|
3723
|
+
const hash = createHash2("md5").update(key).digest("hex");
|
|
3567
3724
|
const keyWithSafeCharacters = key.replace(/[^a-zA-Z0-9]/g, "_");
|
|
3568
|
-
const filePath =
|
|
3569
|
-
return
|
|
3725
|
+
const filePath = path6.join(cacheDir, `${keyWithSafeCharacters.slice(keyWithSafeCharacters.length - 10, keyWithSafeCharacters.length)}-${hash}.json`);
|
|
3726
|
+
return fs6.readFileSync(filePath, "utf-8");
|
|
3570
3727
|
} catch {
|
|
3571
3728
|
return null;
|
|
3572
3729
|
}
|
|
3573
3730
|
},
|
|
3574
3731
|
setItem: (key, value) => {
|
|
3575
3732
|
try {
|
|
3576
|
-
|
|
3577
|
-
const hash =
|
|
3733
|
+
fs6.mkdirSync(cacheDir, { recursive: true });
|
|
3734
|
+
const hash = createHash2("md5").update(key).digest("hex");
|
|
3578
3735
|
const keyWithSafeCharacters = key.replace(/[^a-zA-Z0-9]/g, "_");
|
|
3579
|
-
const filePath =
|
|
3580
|
-
|
|
3736
|
+
const filePath = path6.join(cacheDir, `${keyWithSafeCharacters.slice(keyWithSafeCharacters.length - 10, keyWithSafeCharacters.length)}-${hash}.json`);
|
|
3737
|
+
fs6.writeFileSync(filePath, value);
|
|
3581
3738
|
} catch {}
|
|
3582
3739
|
}
|
|
3583
3740
|
};
|
|
@@ -3593,15 +3750,15 @@ function getPlatformConfigWithCliDefaults(userConfig) {
|
|
|
3593
3750
|
loadFromUrl: async (url) => {
|
|
3594
3751
|
let fetchUrl = url;
|
|
3595
3752
|
if (url.startsWith("./") || url.startsWith("../")) {
|
|
3596
|
-
const absolutePath =
|
|
3753
|
+
const absolutePath = path6.resolve(process.cwd(), url);
|
|
3597
3754
|
fetchUrl = `file://${absolutePath}`;
|
|
3598
3755
|
} else if (url.startsWith("/")) {
|
|
3599
|
-
if (
|
|
3756
|
+
if (fs6.existsSync(url)) {
|
|
3600
3757
|
fetchUrl = `file://${url}`;
|
|
3601
3758
|
} else {
|
|
3602
3759
|
const relativePath = `.${url}`;
|
|
3603
|
-
const absolutePath =
|
|
3604
|
-
if (
|
|
3760
|
+
const absolutePath = path6.resolve(process.cwd(), relativePath);
|
|
3761
|
+
if (fs6.existsSync(absolutePath)) {
|
|
3605
3762
|
fetchUrl = `file://${absolutePath}`;
|
|
3606
3763
|
} else {
|
|
3607
3764
|
fetchUrl = `file://${url}`;
|
|
@@ -3674,7 +3831,7 @@ var getSimulationSvgAssetsFromCircuitJson = (circuitJson) => {
|
|
|
3674
3831
|
|
|
3675
3832
|
// lib/shared/compare-images.ts
|
|
3676
3833
|
import looksSame from "@tscircuit/image-utils/looks-same";
|
|
3677
|
-
import
|
|
3834
|
+
import fs7 from "node:fs/promises";
|
|
3678
3835
|
var compareAndCreateDiff = async (buffer1, buffer2, diffPath, createDiff = true) => {
|
|
3679
3836
|
const b1 = Buffer.from(buffer1);
|
|
3680
3837
|
const b2 = Buffer.from(buffer2);
|
|
@@ -3690,9 +3847,9 @@ var compareAndCreateDiff = async (buffer1, buffer2, diffPath, createDiff = true)
|
|
|
3690
3847
|
highlightColor: "#ff00ff",
|
|
3691
3848
|
tolerance: 2
|
|
3692
3849
|
});
|
|
3693
|
-
await
|
|
3850
|
+
await fs7.writeFile(diffPath, diffBuffer);
|
|
3694
3851
|
} else {
|
|
3695
|
-
await
|
|
3852
|
+
await fs7.writeFile(diffPath, buffer2);
|
|
3696
3853
|
}
|
|
3697
3854
|
}
|
|
3698
3855
|
return { equal };
|
|
@@ -3721,7 +3878,7 @@ var processSnapshotFile = async ({
|
|
|
3721
3878
|
cameraPreset,
|
|
3722
3879
|
pcbLayer
|
|
3723
3880
|
}) => {
|
|
3724
|
-
const relativeFilePath =
|
|
3881
|
+
const relativeFilePath = path7.relative(projectDir, file);
|
|
3725
3882
|
const successPaths = [];
|
|
3726
3883
|
const warningMessages = [];
|
|
3727
3884
|
const mismatches = [];
|
|
@@ -3732,11 +3889,11 @@ var processSnapshotFile = async ({
|
|
|
3732
3889
|
let simulationSvgAssets;
|
|
3733
3890
|
try {
|
|
3734
3891
|
if (isCircuitJsonFile(file)) {
|
|
3735
|
-
const parsed = JSON.parse(
|
|
3892
|
+
const parsed = JSON.parse(fs8.readFileSync(file, "utf-8"));
|
|
3736
3893
|
circuitJson = Array.isArray(parsed) ? parsed : [];
|
|
3737
3894
|
} else {
|
|
3738
3895
|
const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(platformConfig);
|
|
3739
|
-
const result = await
|
|
3896
|
+
const result = await getOrGenerateCircuitJson({
|
|
3740
3897
|
filePath: file,
|
|
3741
3898
|
platformConfig: platformConfigWithCliDefaults
|
|
3742
3899
|
});
|
|
@@ -3816,12 +3973,12 @@ var processSnapshotFile = async ({
|
|
|
3816
3973
|
} catch (error) {
|
|
3817
3974
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3818
3975
|
if (errorMessage.includes("No pcb_board found in circuit JSON")) {
|
|
3819
|
-
const fileDir =
|
|
3820
|
-
const relativeDir =
|
|
3821
|
-
const snapDir2 = snapshotsDirName ?
|
|
3822
|
-
const base2 =
|
|
3823
|
-
const snap3dPath =
|
|
3824
|
-
const existing3dSnapshot =
|
|
3976
|
+
const fileDir = path7.dirname(file);
|
|
3977
|
+
const relativeDir = path7.relative(projectDir, fileDir);
|
|
3978
|
+
const snapDir2 = snapshotsDirName ? path7.join(projectDir, snapshotsDirName, relativeDir) : path7.join(fileDir, "__snapshots__");
|
|
3979
|
+
const base2 = path7.basename(file).replace(/\.[^.]+$/, "");
|
|
3980
|
+
const snap3dPath = path7.join(snapDir2, `${base2}-3d.snap.png`);
|
|
3981
|
+
const existing3dSnapshot = fs8.existsSync(snap3dPath);
|
|
3825
3982
|
if (existing3dSnapshot) {
|
|
3826
3983
|
return {
|
|
3827
3984
|
ok: false,
|
|
@@ -3832,7 +3989,7 @@ var processSnapshotFile = async ({
|
|
|
3832
3989
|
errorMessage: kleur_default.red(`
|
|
3833
3990
|
❌ Failed to generate 3D snapshot for ${relativeFilePath}:
|
|
3834
3991
|
`) + kleur_default.red(` No pcb_board found in circuit JSON
|
|
3835
|
-
`) + kleur_default.red(` Existing snapshot: ${
|
|
3992
|
+
`) + kleur_default.red(` Existing snapshot: ${path7.relative(projectDir, snap3dPath)}
|
|
3836
3993
|
`)
|
|
3837
3994
|
};
|
|
3838
3995
|
}
|
|
@@ -3853,9 +4010,9 @@ var processSnapshotFile = async ({
|
|
|
3853
4010
|
}
|
|
3854
4011
|
}
|
|
3855
4012
|
}
|
|
3856
|
-
const snapDir = snapshotsDirName ?
|
|
3857
|
-
|
|
3858
|
-
const base =
|
|
4013
|
+
const snapDir = snapshotsDirName ? path7.join(projectDir, snapshotsDirName, path7.relative(projectDir, path7.dirname(file))) : path7.join(path7.dirname(file), "__snapshots__");
|
|
4014
|
+
fs8.mkdirSync(snapDir, { recursive: true });
|
|
4015
|
+
const base = path7.basename(file).replace(/\.[^.]+$/, "");
|
|
3859
4016
|
const snapshots = [];
|
|
3860
4017
|
if (!simulationOnly && (pcbOnly || !schematicOnly)) {
|
|
3861
4018
|
let pcbSnapshotType = "pcb";
|
|
@@ -3889,17 +4046,17 @@ var processSnapshotFile = async ({
|
|
|
3889
4046
|
for (const snapshot of snapshots) {
|
|
3890
4047
|
const { type } = snapshot;
|
|
3891
4048
|
const is3d = type === "3d";
|
|
3892
|
-
const snapPath =
|
|
3893
|
-
const existing =
|
|
4049
|
+
const snapPath = path7.join(snapDir, `${base}-${type}.snap.${is3d ? "png" : "svg"}`);
|
|
4050
|
+
const existing = fs8.existsSync(snapPath);
|
|
3894
4051
|
const newContentBuffer = snapshot.isBinary ? snapshot.content : Buffer.from(snapshot.content, "utf8");
|
|
3895
4052
|
const newContentForFile = snapshot.content;
|
|
3896
4053
|
if (!existing) {
|
|
3897
|
-
|
|
3898
|
-
successPaths.push(
|
|
4054
|
+
fs8.writeFileSync(snapPath, newContentForFile);
|
|
4055
|
+
successPaths.push(path7.relative(projectDir, snapPath));
|
|
3899
4056
|
didUpdate = true;
|
|
3900
4057
|
continue;
|
|
3901
4058
|
}
|
|
3902
|
-
const oldContentBuffer =
|
|
4059
|
+
const oldContentBuffer = fs8.readFileSync(snapPath);
|
|
3903
4060
|
let equal;
|
|
3904
4061
|
let diffPath;
|
|
3905
4062
|
if (createDiff) {
|
|
@@ -3911,16 +4068,16 @@ var processSnapshotFile = async ({
|
|
|
3911
4068
|
}
|
|
3912
4069
|
if (update) {
|
|
3913
4070
|
if (!forceUpdate && equal) {
|
|
3914
|
-
successPaths.push(
|
|
4071
|
+
successPaths.push(path7.relative(projectDir, snapPath));
|
|
3915
4072
|
} else {
|
|
3916
|
-
|
|
3917
|
-
successPaths.push(
|
|
4073
|
+
fs8.writeFileSync(snapPath, newContentForFile);
|
|
4074
|
+
successPaths.push(path7.relative(projectDir, snapPath));
|
|
3918
4075
|
didUpdate = true;
|
|
3919
4076
|
}
|
|
3920
4077
|
} else if (!equal) {
|
|
3921
4078
|
mismatches.push(diffPath ? `${snapPath} (diff: ${diffPath})` : snapPath);
|
|
3922
4079
|
} else {
|
|
3923
|
-
successPaths.push(
|
|
4080
|
+
successPaths.push(path7.relative(projectDir, snapPath));
|
|
3924
4081
|
}
|
|
3925
4082
|
}
|
|
3926
4083
|
return {
|
|
@@ -3933,8 +4090,8 @@ var processSnapshotFile = async ({
|
|
|
3933
4090
|
};
|
|
3934
4091
|
|
|
3935
4092
|
// lib/project-config/index.ts
|
|
3936
|
-
import * as
|
|
3937
|
-
import * as
|
|
4093
|
+
import * as fs9 from "node:fs";
|
|
4094
|
+
import * as path8 from "node:path";
|
|
3938
4095
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
3939
4096
|
|
|
3940
4097
|
// lib/project-config/project-config-schema.ts
|
|
@@ -4009,10 +4166,10 @@ var stripWrappingQuotes = (value) => {
|
|
|
4009
4166
|
var loadProjectEnv = (projectDir) => {
|
|
4010
4167
|
const initialEnvKeys = new Set(Object.keys(process.env));
|
|
4011
4168
|
for (const envFileName of ENV_FILENAMES) {
|
|
4012
|
-
const envPath =
|
|
4013
|
-
if (!
|
|
4169
|
+
const envPath = path8.join(projectDir, envFileName);
|
|
4170
|
+
if (!fs9.existsSync(envPath))
|
|
4014
4171
|
continue;
|
|
4015
|
-
const envContent =
|
|
4172
|
+
const envContent = fs9.readFileSync(envPath, "utf8");
|
|
4016
4173
|
for (const rawLine of envContent.split(/\r?\n/)) {
|
|
4017
4174
|
const line = rawLine.trim();
|
|
4018
4175
|
if (!line || line.startsWith("#"))
|
|
@@ -4030,12 +4187,12 @@ var loadProjectEnv = (projectDir) => {
|
|
|
4030
4187
|
}
|
|
4031
4188
|
};
|
|
4032
4189
|
var loadProjectConfigSync = (projectDir = process.cwd()) => {
|
|
4033
|
-
const configPath =
|
|
4034
|
-
if (!
|
|
4190
|
+
const configPath = path8.join(projectDir, CONFIG_FILENAME);
|
|
4191
|
+
if (!fs9.existsSync(configPath)) {
|
|
4035
4192
|
return null;
|
|
4036
4193
|
}
|
|
4037
4194
|
try {
|
|
4038
|
-
const configContent =
|
|
4195
|
+
const configContent = fs9.readFileSync(configPath, "utf8");
|
|
4039
4196
|
const parsedConfig = JSON.parse(configContent);
|
|
4040
4197
|
return projectConfigSchema.parse(parsedConfig);
|
|
4041
4198
|
} catch (error) {
|
|
@@ -4046,12 +4203,12 @@ var loadProjectConfigSync = (projectDir = process.cwd()) => {
|
|
|
4046
4203
|
var loadProjectConfigModule = async (projectDir) => {
|
|
4047
4204
|
loadProjectEnv(projectDir);
|
|
4048
4205
|
for (const configFileName of CONFIG_MODULE_FILENAMES) {
|
|
4049
|
-
const configPath =
|
|
4050
|
-
if (!
|
|
4206
|
+
const configPath = path8.join(projectDir, configFileName);
|
|
4207
|
+
if (!fs9.existsSync(configPath))
|
|
4051
4208
|
continue;
|
|
4052
4209
|
try {
|
|
4053
4210
|
const moduleUrl = pathToFileURL2(configPath);
|
|
4054
|
-
const stat =
|
|
4211
|
+
const stat = fs9.statSync(configPath);
|
|
4055
4212
|
moduleUrl.searchParams.set("tsci", String(stat.mtimeMs));
|
|
4056
4213
|
const importedModule = await import(moduleUrl.href);
|
|
4057
4214
|
const exportedConfig = importedModule.default ?? importedModule.config ?? importedModule;
|
|
@@ -4098,13 +4255,13 @@ var getSnapshotsDir = (projectDir = process.cwd()) => {
|
|
|
4098
4255
|
return config?.snapshotsDir;
|
|
4099
4256
|
};
|
|
4100
4257
|
var saveProjectConfig = (config, projectDir = process.cwd()) => {
|
|
4101
|
-
const configPath =
|
|
4258
|
+
const configPath = path8.join(projectDir, CONFIG_FILENAME);
|
|
4102
4259
|
try {
|
|
4103
4260
|
const configWithSchema = {
|
|
4104
4261
|
$schema: CONFIG_SCHEMA_URL,
|
|
4105
4262
|
...config ?? {}
|
|
4106
4263
|
};
|
|
4107
|
-
|
|
4264
|
+
fs9.writeFileSync(configPath, JSON.stringify(configWithSchema, null, 2));
|
|
4108
4265
|
return true;
|
|
4109
4266
|
} catch (error) {
|
|
4110
4267
|
console.error(`Error saving tscircuit config: ${error}`);
|
package/dist/lib/index.js
CHANGED
|
@@ -65811,7 +65811,7 @@ var getNodeHandler = (winterSpec, { port, middleware = [] }) => {
|
|
|
65811
65811
|
}));
|
|
65812
65812
|
};
|
|
65813
65813
|
// package.json
|
|
65814
|
-
var version = "0.1.
|
|
65814
|
+
var version = "0.1.1649";
|
|
65815
65815
|
var package_default = {
|
|
65816
65816
|
name: "@tscircuit/cli",
|
|
65817
65817
|
version,
|