circuit-json-to-kicad 0.0.39 → 0.0.41
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.ts +15 -0
- package/dist/index.js +128 -25
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -255,6 +255,21 @@ interface KicadLibraryConverterOptions {
|
|
|
255
255
|
* Return null if no metadata is available.
|
|
256
256
|
*/
|
|
257
257
|
getComponentKicadMetadata?: (filePath: string, componentName: string) => Promise<KicadFootprintMetadata | null>;
|
|
258
|
+
/**
|
|
259
|
+
* Whether to generate files for KiCad PCM (Plugin and Content Manager).
|
|
260
|
+
* When true:
|
|
261
|
+
* - Footprint references in symbols will be prefixed with "PCM_"
|
|
262
|
+
* - 3D model paths will use ${KICAD_3RD_PARTY} variable instead of relative paths
|
|
263
|
+
* Default: false
|
|
264
|
+
*/
|
|
265
|
+
isPcm?: boolean;
|
|
266
|
+
/**
|
|
267
|
+
* The KiCad PCM package identifier (e.g., "com_tscircuit_author_package-name").
|
|
268
|
+
* Required when useKicadPcmPaths is true.
|
|
269
|
+
* Used to construct 3D model paths like:
|
|
270
|
+
* ${KICAD9_3RD_PARTY}/3dmodels/<kicadPcmPackageId>/<library>.3dshapes/<model>.step
|
|
271
|
+
*/
|
|
272
|
+
kicadPcmPackageId?: string;
|
|
258
273
|
}
|
|
259
274
|
interface KicadLibraryConverterOutput {
|
|
260
275
|
/**
|
package/dist/index.js
CHANGED
|
@@ -101,6 +101,50 @@ function extractReferencePrefix(name) {
|
|
|
101
101
|
const match = name.match(/^([A-Za-z]+)/);
|
|
102
102
|
return match?.[1]?.toUpperCase() ?? "U";
|
|
103
103
|
}
|
|
104
|
+
var referencePrefixByFtype = {
|
|
105
|
+
simple_resistor: "R",
|
|
106
|
+
simple_capacitor: "C",
|
|
107
|
+
simple_inductor: "L",
|
|
108
|
+
simple_diode: "D",
|
|
109
|
+
simple_led: "D",
|
|
110
|
+
simple_chip: "U",
|
|
111
|
+
simple_transistor: "Q",
|
|
112
|
+
simple_mosfet: "Q",
|
|
113
|
+
simple_fuse: "F",
|
|
114
|
+
simple_switch: "SW",
|
|
115
|
+
simple_push_button: "SW",
|
|
116
|
+
simple_potentiometer: "RV",
|
|
117
|
+
simple_crystal: "Y",
|
|
118
|
+
simple_resonator: "Y",
|
|
119
|
+
simple_pin_header: "J",
|
|
120
|
+
simple_pinout: "J",
|
|
121
|
+
simple_test_point: "TP",
|
|
122
|
+
simple_battery: "BT"
|
|
123
|
+
};
|
|
124
|
+
var referenceDesignatorPattern = /^[A-Za-z]+\\d+$/;
|
|
125
|
+
function isReferenceDesignator(value) {
|
|
126
|
+
if (!value) return false;
|
|
127
|
+
return referenceDesignatorPattern.test(value.trim());
|
|
128
|
+
}
|
|
129
|
+
function getReferencePrefixForComponent(sourceComponent) {
|
|
130
|
+
const name = sourceComponent?.name;
|
|
131
|
+
if (isReferenceDesignator(name)) {
|
|
132
|
+
return extractReferencePrefix(name);
|
|
133
|
+
}
|
|
134
|
+
const ftype = sourceComponent?.ftype;
|
|
135
|
+
if (ftype && referencePrefixByFtype[ftype]) {
|
|
136
|
+
return referencePrefixByFtype[ftype];
|
|
137
|
+
}
|
|
138
|
+
return extractReferencePrefix(name);
|
|
139
|
+
}
|
|
140
|
+
function getReferenceDesignator(sourceComponent) {
|
|
141
|
+
const name = sourceComponent?.name;
|
|
142
|
+
if (isReferenceDesignator(name)) {
|
|
143
|
+
return name.trim();
|
|
144
|
+
}
|
|
145
|
+
const prefix = getReferencePrefixForComponent(sourceComponent);
|
|
146
|
+
return `${prefix}?`;
|
|
147
|
+
}
|
|
104
148
|
|
|
105
149
|
// lib/schematic/getLibraryId.ts
|
|
106
150
|
import { symbols } from "schematic-symbols";
|
|
@@ -127,7 +171,7 @@ function getLibraryId(sourceComp, schematicComp, cadComponent) {
|
|
|
127
171
|
sourceComp,
|
|
128
172
|
cadComponent
|
|
129
173
|
);
|
|
130
|
-
const refPrefix =
|
|
174
|
+
const refPrefix = getReferencePrefixForComponent(sourceComp);
|
|
131
175
|
return `Device:${refPrefix}_${ergonomicName}`;
|
|
132
176
|
}
|
|
133
177
|
|
|
@@ -197,7 +241,8 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
|
|
|
197
241
|
description: this.getDescription(sourceComp),
|
|
198
242
|
keywords: this.getKeywords(sourceComp),
|
|
199
243
|
fpFilters: this.getFpFilters(sourceComp),
|
|
200
|
-
footprintRef: footprintName ? `tscircuit:${footprintName}` : ""
|
|
244
|
+
footprintRef: footprintName ? `tscircuit:${footprintName}` : "",
|
|
245
|
+
referencePrefix: getReferencePrefixForComponent(sourceComp)
|
|
201
246
|
});
|
|
202
247
|
}
|
|
203
248
|
/**
|
|
@@ -220,7 +265,8 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
|
|
|
220
265
|
schematicComponent: void 0,
|
|
221
266
|
description: isPower ? "Power net label" : isGround ? "Ground net label" : "Net symbol",
|
|
222
267
|
keywords: isPower ? "power net" : isGround ? "ground net" : "net",
|
|
223
|
-
fpFilters: ""
|
|
268
|
+
fpFilters: "",
|
|
269
|
+
referencePrefix: libId.split(":")[1]?.[0] || "U"
|
|
224
270
|
});
|
|
225
271
|
}
|
|
226
272
|
/**
|
|
@@ -280,7 +326,8 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
|
|
|
280
326
|
description,
|
|
281
327
|
keywords,
|
|
282
328
|
fpFilters,
|
|
283
|
-
footprintRef = ""
|
|
329
|
+
footprintRef = "",
|
|
330
|
+
referencePrefix
|
|
284
331
|
}) {
|
|
285
332
|
const symbol = new SchematicSymbol({
|
|
286
333
|
libraryId: libId,
|
|
@@ -300,7 +347,8 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
|
|
|
300
347
|
description,
|
|
301
348
|
keywords,
|
|
302
349
|
fpFilters,
|
|
303
|
-
footprintRef
|
|
350
|
+
footprintRef,
|
|
351
|
+
referencePrefix
|
|
304
352
|
});
|
|
305
353
|
const drawingSymbol = this.createDrawingSubsymbol({
|
|
306
354
|
libId,
|
|
@@ -327,9 +375,10 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
|
|
|
327
375
|
description,
|
|
328
376
|
keywords,
|
|
329
377
|
fpFilters,
|
|
330
|
-
footprintRef = ""
|
|
378
|
+
footprintRef = "",
|
|
379
|
+
referencePrefix
|
|
331
380
|
}) {
|
|
332
|
-
const refPrefix = libId.split(":")[1]?.[0] || "U";
|
|
381
|
+
const refPrefix = referencePrefix || libId.split(":")[1]?.[0] || "U";
|
|
333
382
|
const properties = [
|
|
334
383
|
{
|
|
335
384
|
key: "Reference",
|
|
@@ -794,43 +843,44 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
|
|
|
794
843
|
*/
|
|
795
844
|
getComponentMetadata(sourceComp) {
|
|
796
845
|
const name = sourceComp.name || "?";
|
|
846
|
+
const reference = getReferenceDesignator(sourceComp);
|
|
797
847
|
if (sourceComp.ftype === "simple_resistor") {
|
|
798
848
|
return {
|
|
799
|
-
reference
|
|
849
|
+
reference,
|
|
800
850
|
value: sourceComp.display_resistance || "R",
|
|
801
851
|
description: "Resistor"
|
|
802
852
|
};
|
|
803
853
|
}
|
|
804
854
|
if (sourceComp.ftype === "simple_capacitor") {
|
|
805
855
|
return {
|
|
806
|
-
reference
|
|
856
|
+
reference,
|
|
807
857
|
value: sourceComp.display_capacitance || "C",
|
|
808
858
|
description: "Capacitor"
|
|
809
859
|
};
|
|
810
860
|
}
|
|
811
861
|
if (sourceComp.ftype === "simple_inductor") {
|
|
812
862
|
return {
|
|
813
|
-
reference
|
|
863
|
+
reference,
|
|
814
864
|
value: sourceComp.display_inductance || "L",
|
|
815
865
|
description: "Inductor"
|
|
816
866
|
};
|
|
817
867
|
}
|
|
818
868
|
if (sourceComp.ftype === "simple_diode") {
|
|
819
869
|
return {
|
|
820
|
-
reference
|
|
870
|
+
reference,
|
|
821
871
|
value: "D",
|
|
822
872
|
description: "Diode"
|
|
823
873
|
};
|
|
824
874
|
}
|
|
825
875
|
if (sourceComp.ftype === "simple_chip") {
|
|
826
876
|
return {
|
|
827
|
-
reference
|
|
877
|
+
reference,
|
|
828
878
|
value: name,
|
|
829
879
|
description: "Integrated Circuit"
|
|
830
880
|
};
|
|
831
881
|
}
|
|
832
882
|
return {
|
|
833
|
-
reference
|
|
883
|
+
reference,
|
|
834
884
|
value: name,
|
|
835
885
|
description: "Component"
|
|
836
886
|
};
|
|
@@ -2937,8 +2987,15 @@ var CircuitJsonToKicadLibraryConverter = class {
|
|
|
2937
2987
|
|
|
2938
2988
|
// lib/kicad-library/kicad-library-converter-utils/renameKicadFootprint.ts
|
|
2939
2989
|
import { parseKicadMod } from "kicadts";
|
|
2990
|
+
var KICAD_3RD_PARTY_PLACEHOLDER = "${KICAD_3RD_PARTY}";
|
|
2940
2991
|
function renameKicadFootprint(params) {
|
|
2941
|
-
const {
|
|
2992
|
+
const {
|
|
2993
|
+
kicadFootprint,
|
|
2994
|
+
newKicadFootprintName,
|
|
2995
|
+
kicadLibraryName,
|
|
2996
|
+
isPcm,
|
|
2997
|
+
kicadPcmPackageId
|
|
2998
|
+
} = params;
|
|
2942
2999
|
const footprint = parseKicadMod(kicadFootprint.kicadModString);
|
|
2943
3000
|
footprint.libraryLink = newKicadFootprintName;
|
|
2944
3001
|
for (const model of footprint.models) {
|
|
@@ -2946,7 +3003,11 @@ function renameKicadFootprint(params) {
|
|
|
2946
3003
|
const usesProjectPath = currentPath.includes("${KIPRJMOD}/") || /3dmodels[\\/]/.test(currentPath);
|
|
2947
3004
|
if (usesProjectPath) {
|
|
2948
3005
|
const filename = currentPath.split(/[\\/]/).pop() ?? "";
|
|
2949
|
-
|
|
3006
|
+
if (isPcm && kicadPcmPackageId) {
|
|
3007
|
+
model.path = `${KICAD_3RD_PARTY_PLACEHOLDER}/3dmodels/${kicadPcmPackageId}/${kicadLibraryName}.3dshapes/${filename}`;
|
|
3008
|
+
} else {
|
|
3009
|
+
model.path = `../../3dmodels/${kicadLibraryName}.3dshapes/${filename}`;
|
|
3010
|
+
}
|
|
2950
3011
|
}
|
|
2951
3012
|
}
|
|
2952
3013
|
return {
|
|
@@ -3077,6 +3138,8 @@ function applyKicadFootprintMetadata(kicadModString, metadata, footprintName) {
|
|
|
3077
3138
|
}
|
|
3078
3139
|
|
|
3079
3140
|
// lib/kicad-library/stages/ClassifyKicadFootprintsStage.ts
|
|
3141
|
+
import { parseKicadMod as parseKicadMod2 } from "kicadts";
|
|
3142
|
+
var KICAD_3RD_PARTY_PLACEHOLDER2 = "${KICAD_3RD_PARTY}";
|
|
3080
3143
|
function classifyKicadFootprints(ctx) {
|
|
3081
3144
|
for (const extractedKicadComponent of ctx.extractedKicadComponents) {
|
|
3082
3145
|
classifyFootprintsForComponent({
|
|
@@ -3101,7 +3164,9 @@ function classifyFootprintsForComponent({
|
|
|
3101
3164
|
let renamedFootprint = renameKicadFootprint({
|
|
3102
3165
|
kicadFootprint,
|
|
3103
3166
|
newKicadFootprintName: tscircuitComponentName,
|
|
3104
|
-
kicadLibraryName: ctx.kicadLibraryName
|
|
3167
|
+
kicadLibraryName: ctx.kicadLibraryName,
|
|
3168
|
+
isPcm: ctx.isPcm,
|
|
3169
|
+
kicadPcmPackageId: ctx.kicadPcmPackageId
|
|
3105
3170
|
});
|
|
3106
3171
|
if (metadata) {
|
|
3107
3172
|
renamedFootprint = {
|
|
@@ -3139,9 +3204,37 @@ function addBuiltinFootprint({
|
|
|
3139
3204
|
(fp) => fp.footprintName === kicadFootprint.footprintName
|
|
3140
3205
|
);
|
|
3141
3206
|
if (!alreadyExists) {
|
|
3142
|
-
ctx.
|
|
3207
|
+
if (ctx.isPcm && ctx.kicadPcmPackageId) {
|
|
3208
|
+
const updatedFootprint = updateBuiltinFootprintModelPaths({
|
|
3209
|
+
kicadFootprint,
|
|
3210
|
+
kicadPcmPackageId: ctx.kicadPcmPackageId
|
|
3211
|
+
});
|
|
3212
|
+
ctx.builtinKicadFootprints.push(updatedFootprint);
|
|
3213
|
+
} else {
|
|
3214
|
+
ctx.builtinKicadFootprints.push(kicadFootprint);
|
|
3215
|
+
}
|
|
3143
3216
|
}
|
|
3144
3217
|
}
|
|
3218
|
+
function updateBuiltinFootprintModelPaths({
|
|
3219
|
+
kicadFootprint,
|
|
3220
|
+
kicadPcmPackageId
|
|
3221
|
+
}) {
|
|
3222
|
+
const footprint = parseKicadMod2(kicadFootprint.kicadModString);
|
|
3223
|
+
for (const model of footprint.models) {
|
|
3224
|
+
const currentPath = model.path;
|
|
3225
|
+
const usesProjectPath = currentPath.includes("${KIPRJMOD}/") || /3dmodels[\\/]/.test(currentPath);
|
|
3226
|
+
if (usesProjectPath) {
|
|
3227
|
+
const filename = currentPath.split(/[\\/]/).pop() ?? "";
|
|
3228
|
+
model.path = `${KICAD_3RD_PARTY_PLACEHOLDER2}/3dmodels/${kicadPcmPackageId}/tscircuit_builtin.3dshapes/${filename}`;
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
return {
|
|
3232
|
+
footprintName: kicadFootprint.footprintName,
|
|
3233
|
+
kicadModString: footprint.getString(),
|
|
3234
|
+
model3dSourcePaths: kicadFootprint.model3dSourcePaths,
|
|
3235
|
+
isBuiltin: kicadFootprint.isBuiltin
|
|
3236
|
+
};
|
|
3237
|
+
}
|
|
3145
3238
|
function componentHasCustomFootprint(extractedKicadComponent) {
|
|
3146
3239
|
return extractedKicadComponent.kicadFootprints.some((fp) => !fp.isBuiltin);
|
|
3147
3240
|
}
|
|
@@ -3165,24 +3258,26 @@ function renameKicadSymbol(params) {
|
|
|
3165
3258
|
|
|
3166
3259
|
// lib/kicad-library/kicad-library-converter-utils/updateKicadSymbolFootprint.ts
|
|
3167
3260
|
function updateKicadSymbolFootprint(params) {
|
|
3168
|
-
const { kicadSymbol, kicadLibraryName, kicadFootprintName } = params;
|
|
3261
|
+
const { kicadSymbol, kicadLibraryName, kicadFootprintName, isPcm } = params;
|
|
3169
3262
|
const properties = kicadSymbol.symbol.properties ?? [];
|
|
3263
|
+
const effectiveKicadLibraryName = isPcm ? `PCM_${kicadLibraryName}` : kicadLibraryName;
|
|
3170
3264
|
for (const prop of properties) {
|
|
3171
3265
|
if (prop.key === "Footprint") {
|
|
3172
|
-
prop.value = `${
|
|
3266
|
+
prop.value = `${effectiveKicadLibraryName}:${kicadFootprintName}`;
|
|
3173
3267
|
}
|
|
3174
3268
|
}
|
|
3175
3269
|
}
|
|
3176
3270
|
|
|
3177
3271
|
// lib/kicad-library/kicad-library-converter-utils/updateBuiltinKicadSymbolFootprint.ts
|
|
3178
|
-
function updateBuiltinKicadSymbolFootprint(kicadSymbol) {
|
|
3272
|
+
function updateBuiltinKicadSymbolFootprint(kicadSymbol, options) {
|
|
3179
3273
|
const symbol = kicadSymbol.symbol;
|
|
3180
3274
|
const properties = symbol.properties ?? [];
|
|
3275
|
+
const libraryName = options?.isPcm ? "PCM_tscircuit_builtin" : "tscircuit_builtin";
|
|
3181
3276
|
for (const prop of properties) {
|
|
3182
3277
|
if (prop.key === "Footprint" && prop.value) {
|
|
3183
3278
|
const parts = prop.value.split(":");
|
|
3184
3279
|
const footprintName = parts.length > 1 ? parts[1] : parts[0];
|
|
3185
|
-
prop.value =
|
|
3280
|
+
prop.value = `${libraryName}:${footprintName}`;
|
|
3186
3281
|
}
|
|
3187
3282
|
}
|
|
3188
3283
|
return { symbolName: kicadSymbol.symbolName, symbol };
|
|
@@ -3218,7 +3313,8 @@ function classifySymbolsForComponent({
|
|
|
3218
3313
|
updateKicadSymbolFootprint({
|
|
3219
3314
|
kicadSymbol: renamedSymbol,
|
|
3220
3315
|
kicadLibraryName: ctx.kicadLibraryName,
|
|
3221
|
-
kicadFootprintName: tscircuitComponentName
|
|
3316
|
+
kicadFootprintName: tscircuitComponentName,
|
|
3317
|
+
isPcm: ctx.isPcm
|
|
3222
3318
|
});
|
|
3223
3319
|
}
|
|
3224
3320
|
addUserSymbol({ ctx, kicadSymbol: renamedSymbol });
|
|
@@ -3234,11 +3330,14 @@ function classifySymbolsForComponent({
|
|
|
3234
3330
|
updateKicadSymbolFootprint({
|
|
3235
3331
|
kicadSymbol: renamedSymbol,
|
|
3236
3332
|
kicadLibraryName: ctx.kicadLibraryName,
|
|
3237
|
-
kicadFootprintName: tscircuitComponentName
|
|
3333
|
+
kicadFootprintName: tscircuitComponentName,
|
|
3334
|
+
isPcm: ctx.isPcm
|
|
3238
3335
|
});
|
|
3239
3336
|
addUserSymbol({ ctx, kicadSymbol: renamedSymbol });
|
|
3240
3337
|
} else {
|
|
3241
|
-
const updatedSymbol = updateBuiltinKicadSymbolFootprint(kicadSymbol
|
|
3338
|
+
const updatedSymbol = updateBuiltinKicadSymbolFootprint(kicadSymbol, {
|
|
3339
|
+
isPcm: ctx.isPcm
|
|
3340
|
+
});
|
|
3242
3341
|
addBuiltinSymbol({ ctx, kicadSymbol: updatedSymbol });
|
|
3243
3342
|
}
|
|
3244
3343
|
}
|
|
@@ -3361,7 +3460,9 @@ var KicadLibraryConverter = class {
|
|
|
3361
3460
|
this.ctx = createKicadLibraryConverterContext({
|
|
3362
3461
|
kicadLibraryName: options.kicadLibraryName ?? "tscircuit_library",
|
|
3363
3462
|
includeBuiltins: options.includeBuiltins ?? true,
|
|
3364
|
-
getComponentKicadMetadata: options.getComponentKicadMetadata
|
|
3463
|
+
getComponentKicadMetadata: options.getComponentKicadMetadata,
|
|
3464
|
+
isPcm: options.isPcm ?? false,
|
|
3465
|
+
kicadPcmPackageId: options.kicadPcmPackageId
|
|
3365
3466
|
});
|
|
3366
3467
|
}
|
|
3367
3468
|
async run() {
|
|
@@ -3487,6 +3588,8 @@ function createKicadLibraryConverterContext(params) {
|
|
|
3487
3588
|
kicadLibraryName: params.kicadLibraryName,
|
|
3488
3589
|
includeBuiltins: params.includeBuiltins,
|
|
3489
3590
|
getComponentKicadMetadata: params.getComponentKicadMetadata,
|
|
3591
|
+
isPcm: params.isPcm,
|
|
3592
|
+
kicadPcmPackageId: params.kicadPcmPackageId,
|
|
3490
3593
|
footprintMetadataMap: /* @__PURE__ */ new Map(),
|
|
3491
3594
|
builtTscircuitComponents: [],
|
|
3492
3595
|
extractedKicadComponents: [],
|