easyeda 0.0.2 → 0.0.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.
Files changed (33) hide show
  1. package/dist/cli/main.cjs +17 -5
  2. package/dist/cli/main.cjs.map +1 -1
  3. package/dist/lib/index.cjs +1 -1
  4. package/dist/lib/index.cjs.map +1 -1
  5. package/package.json +10 -3
  6. package/ai-assist-docs/soup-reference.md +0 -1325
  7. package/bun.lockb +0 -0
  8. package/cli/main.ts +0 -67
  9. package/dist/index.cjs +0 -29196
  10. package/dist/index.cjs.map +0 -1
  11. package/dist/index.d.cts +0 -1553
  12. package/lib/convert-easyeda-json-to-tscircuit-soup-json.ts +0 -204
  13. package/lib/fetch-easyeda-json.ts +0 -66
  14. package/lib/index.ts +0 -2
  15. package/lib/math/arc-utils.ts +0 -170
  16. package/lib/schemas/easy-eda-json-schema.ts +0 -158
  17. package/lib/schemas/package-detail-shape-schema.ts +0 -251
  18. package/lib/schemas/single-letter-shape-schema.ts +0 -201
  19. package/renovate.json +0 -6
  20. package/scripts/get-easyeda-json.ts +0 -12
  21. package/tests/assets/a555-timer-dip.raweasy.json +0 -244
  22. package/tests/assets/a555-timer-smd.raweasy.json +0 -226
  23. package/tests/assets/esp32.raweasy.json +0 -333
  24. package/tests/assets/usb-c.raweasy.json +0 -263
  25. package/tests/convert-to-soup-tests/a555timer-smd.test.ts +0 -18
  26. package/tests/convert-to-soup-tests/convert-easyeda-to-tscircuit-soup.test.ts +0 -49
  27. package/tests/convert-to-soup-tests/convert-usb-c-to-soup.test.ts +0 -18
  28. package/tests/convert-to-soup-tests/esp32-to-soup.test.ts +0 -13
  29. package/tests/parse-tests/parse-555-timer-json.test.ts +0 -9
  30. package/tests/parse-tests/parse-esp32.test.ts +0 -9
  31. package/tests/parse-tests/parse-usb-c.test.ts +0 -9
  32. package/tests/parse-tests/single-letter-shape-schema.test.ts +0 -30
  33. package/tsconfig.json +0 -28
@@ -1,251 +0,0 @@
1
- import { z } from "zod"
2
-
3
- export const PointSchema = z
4
- .any()
5
- .transform((p) => {
6
- if (Array.isArray(p)) {
7
- const [x, y] = p
8
- return { x, y }
9
- } else if (typeof p === "object") {
10
- return p
11
- }
12
- throw new Error(`Invalid point: ${p}`)
13
- })
14
- .pipe(
15
- z.object({
16
- x: z.number(),
17
- y: z.number(),
18
- })
19
- )
20
-
21
- export const BaseShapeSchema = z.object({
22
- type: z.string(),
23
- id: z.string().optional(),
24
- layer: z.coerce.number().optional(),
25
- })
26
-
27
- export const TrackSchema = BaseShapeSchema.extend({
28
- type: z.literal("TRACK"),
29
- width: z.coerce.number(),
30
- points: z.array(PointSchema),
31
- })
32
-
33
- export const PadSchema = BaseShapeSchema.extend({
34
- type: z.literal("PAD"),
35
- shape: z.enum(["RECT", "ELLIPSE", "OVAL"]),
36
- center: z.object({
37
- x: z.number(),
38
- y: z.number(),
39
- }),
40
- width: z.number(),
41
- height: z.number(),
42
- layermask: z.number(),
43
- net: z.union([z.string(), z.number()]).optional(),
44
- number: z.number(),
45
- holeRadius: z.number(),
46
- points: z.array(PointSchema).optional(),
47
- rotation: z.number().optional(),
48
- plated: z.boolean(),
49
- })
50
-
51
- // TODO this should be in "arc sweep" format with the following fields:
52
- // start, end, radius, largeArc, sweepDirection
53
- export const ArcSchema = BaseShapeSchema.extend({
54
- type: z.literal("ARC"),
55
- width: z.number(),
56
- start: PointSchema,
57
- end: PointSchema,
58
- radiusX: z.number(),
59
- radiusY: z.number(),
60
- largeArc: z.boolean(),
61
- sweepDirection: z.enum(["CW", "CCW"]),
62
- })
63
-
64
- export const CircleSchema = BaseShapeSchema.extend({
65
- type: z.literal("CIRCLE"),
66
- center: PointSchema,
67
- radius: z.number(),
68
- width: z.number(),
69
- })
70
-
71
- export const SolidRegionSchema = BaseShapeSchema.extend({
72
- type: z.literal("SOLIDREGION"),
73
- layermask: z.number(),
74
- points: z.array(PointSchema),
75
- fillStyle: z.string(),
76
- })
77
-
78
- export const SVGNodeSchema = BaseShapeSchema.extend({
79
- type: z.literal("SVGNODE"),
80
- svgData: z.object({
81
- gId: z.string(),
82
- nodeName: z.string(),
83
- nodeType: z.number(),
84
- layerid: z.string(),
85
- attrs: z.record(z.string(), z.string()),
86
- childNodes: z.array(z.unknown()),
87
- }),
88
- })
89
-
90
- // e.g. "HOLE~3999.449~3004.213~1.378~gge152~0"
91
- export const HoleSchema = BaseShapeSchema.extend({
92
- type: z.literal("HOLE"),
93
- center: PointSchema,
94
- radius: z.number(),
95
- })
96
-
97
- export const PackageDetailShapeSchema = z.discriminatedUnion("type", [
98
- TrackSchema,
99
- PadSchema,
100
- ArcSchema,
101
- CircleSchema,
102
- SolidRegionSchema,
103
- SVGNodeSchema,
104
- HoleSchema,
105
- ])
106
-
107
- const pairs = <T>(arr: T[]): [T, T][] => {
108
- const pairs: [T, T][] = []
109
- for (let i = 0; i < arr.length; i += 2) {
110
- pairs.push([arr[i], arr[i + 1]])
111
- }
112
- return pairs
113
- }
114
-
115
- const parsePoints = (pointsStr: string): number[][] =>
116
- pairs(
117
- pointsStr
118
- .trim()
119
- .split(" ")
120
- .map((n) => Number(n))
121
- )
122
-
123
- export const ShapeItemSchema = z
124
- .object({
125
- type: z.string(),
126
- data: z.string(),
127
- })
128
- .transform((shape) => {
129
- const [firstParam, ...restParams] = shape.data.split("~")
130
- const lastParam = restParams.pop()
131
-
132
- switch (shape.type) {
133
- case "TRACK": {
134
- const [width, layer, _, pointsStr, id, _n] = shape.data.split("~")
135
- const points = parsePoints(pointsStr)
136
- return TrackSchema.parse({ type: "TRACK", width, layer, points, id })
137
- }
138
- case "PAD": {
139
- const [padShape, ...params] = shape.data.split("~")
140
- const [
141
- centerX,
142
- centerY,
143
- width,
144
- height,
145
- layermask,
146
- net,
147
- number,
148
- holeRadius,
149
- ...rest
150
- ] = params.map((p) => (isNaN(Number(p)) ? p : Number(p)))
151
- const center = { x: centerX, y: centerY }
152
- let points, rotation
153
- if (padShape === "RECT") {
154
- points = parsePoints(rest[0] as any)
155
- rotation = Number(rest[1])
156
- }
157
- return PadSchema.parse({
158
- type: "PAD",
159
- shape: padShape,
160
- center,
161
- width,
162
- height,
163
- layermask,
164
- net,
165
- number,
166
- holeRadius,
167
- points,
168
- rotation,
169
- plated: rest.includes("Y"),
170
- })
171
- }
172
- case "ARC": {
173
- const [width, layer, , arcData] = shape.data.split("~")
174
- // A rx ry x-axis-rotation large-arc-flag sweep-flag x y
175
- // A rx ry x-axis-rotation large-arc-flag sweep-flag dx dy
176
- const [
177
- ,
178
- startX,
179
- startY,
180
- radiusX,
181
- radiusY,
182
- xAxisRotation,
183
- largeArcFlag,
184
- sweepFlag,
185
- endX,
186
- endY,
187
- ] = arcData.match(
188
- /M ([\d.]+) ([\d.]+) A ([\d.]+) ([\d.]+) ([\d.]+) ([\d.]+) ([\d.]+) ([\d.]+) ([\d.]+)/
189
- )!
190
- const start: [number, number] = [Number(startX), Number(startY)]
191
- const end: [number, number] = [Number(endX), Number(endY)]
192
- return ArcSchema.parse({
193
- type: "ARC",
194
- width: Number(width),
195
- layer: Number(layer),
196
- start,
197
- end,
198
- radiusX: Number(radiusX),
199
- radiusY: Number(radiusY),
200
- largeArc: largeArcFlag === "1",
201
- sweepDirection: sweepFlag === "1" ? "CW" : "CCW",
202
- })
203
- }
204
- case "CIRCLE": {
205
- const [centerX, centerY, radius, width, layer, id] =
206
- shape.data.split("~")
207
- const center: [number, number] = [Number(centerX), Number(centerY)]
208
- return CircleSchema.parse({
209
- type: "CIRCLE",
210
- center,
211
- radius: Number(radius),
212
- width: Number(width),
213
- layer: Number(layer),
214
- id,
215
- })
216
- }
217
- case "HOLE": {
218
- const [centerX, centerY, radius, id] = shape.data.split("~")
219
- const center: [number, number] = [Number(centerX), Number(centerY)]
220
- return HoleSchema.parse({
221
- type: "HOLE",
222
- center,
223
- radius: Number(radius),
224
- id,
225
- })
226
- }
227
- case "SOLIDREGION": {
228
- const [layermask, , pathData, fillStyle, id] = shape.data.split("~")
229
- const points = pathData
230
- .match(/[ML] ?([\d.]+[ ,][\d.]+)/g)!
231
- .map((point) => point.slice(2).split(/[ ,]/).map(Number))
232
- return SolidRegionSchema.parse({
233
- type: "SOLIDREGION",
234
- layermask: Number(layermask),
235
- points,
236
- fillStyle,
237
- id,
238
- })
239
- }
240
- case "SVGNODE": {
241
- const svgData = JSON.parse(shape.data)
242
- return SVGNodeSchema.parse({ type: "SVGNODE", svgData })
243
- }
244
- default:
245
- throw new Error(`Unknown shape type: ${shape.type}`)
246
- return BaseShapeSchema.parse({ type: shape.type })
247
- }
248
- })
249
- .pipe(PackageDetailShapeSchema)
250
-
251
- export const ShapesArraySchema = z.array(ShapeItemSchema)
@@ -1,201 +0,0 @@
1
- import { z } from "zod"
2
-
3
- /**
4
- I'll break down the elements in the `dataStr.head.shape` array and explain what they represent. This array contains instructions for drawing the schematic symbol of the component.
5
- 1. `"R~365~275~2~2~70~50~#880000~1~0~none~gge1~0~"`
6
- This represents a rectangle:
7
- - Starting position: (365, 275)
8
- - Width: 70
9
- - Height: 50
10
- - Color: #880000 (dark red)
11
- - Line width: 1
12
- - Other parameters are for internal use
13
- 2. `"E~370~280~1.5~1.5~#880000~1~0~#880000~gge2~0"`
14
- This draws an ellipse:
15
- - Center: (370, 280)
16
- - Radius X: 1.5
17
- - Radius Y: 1.5
18
- - Color: #880000 (dark red)
19
- - Line width: 1
20
- 3-10. `"P~show~0~1~355~285~180~gge5~0^^355~285^^M355,285h10~#000000^^1~368.7~289~0~GND~start~~~#000000^^1~364.5~284~0~1~end~~~#000000^^0~362~285^^0~M 365 288 L 368 285 L 365 282"`
21
- These represent pins of the component. Each pin has:
22
- - Pin number
23
- - Position
24
- - Orientation
25
- - Label (e.g., GND, TRIG, OUT)
26
- - Color
27
- - Drawing instructions for the pin shape
28
- To parse this data:
29
- 1. Split the string by `~` to get individual parameters.
30
- 2. For rectangles (R), use parameters 2-7 for position, size, and color.
31
- 3. For ellipses (E), use parameters 2-5 for position and size, and 6 for color.
32
- 4. For pins (P), split further by `^^` to get different sections:
33
- - First section: general pin properties
34
- - Second section: pin position
35
- - Third section: line drawing instruction
36
- - Fourth and Fifth sections: label position and text
37
- - Sixth section: additional drawing instruction for pin shape
38
- This data structure allows for a compact representation of the schematic symbol, which can be rendered by CAD software to display the component in circuit diagrams.
39
- */
40
- // Examples
41
- // "R~365~275~2~2~70~50~#880000~1~0~none~gge1~0~",
42
- // "E~370~280~1.5~1.5~#880000~1~0~#880000~gge2~0",
43
- // "P~show~0~1~355~285~180~gge5~0^^355~285^^M355,285h10~#000000^^1~368.7~289~0~GND~start~~~#000000^^1~364.5~284~0~1~end~~~#000000^^0~362~285^^0~M 365 288 L 368 285 L 365 282",
44
- // "P~show~0~2~355~295~180~gge6~0^^355~295^^M355,295h10~#880000^^1~368.7~299~0~TRIG~start~~~#0000FF^^1~364.5~294~0~2~end~~~#0000FF^^0~362~295^^0~M 365 298 L 368 295 L 365 292",
45
- // "P~show~0~3~355~305~180~gge7~0^^355~305^^M355,305h10~#880000^^1~368.7~309~0~OUT~start~~~#0000FF^^1~364.5~304~0~3~end~~~#0000FF^^0~362~305^^0~M 365 308 L 368 305 L 365 302",
46
- // "P~show~0~4~355~315~180~gge8~0^^355~315^^M355,315h10~#880000^^1~368.7~319~0~RESET~start~~~#0000FF^^1~364.5~314~0~4~end~~~#0000FF^^0~362~315^^0~M 365 318 L 368 315 L 365 312",
47
- // "P~show~0~5~445~315~0~gge9~0^^445~315^^M445,315h-10~#880000^^1~431.3~319~0~CONT~end~~~#0000FF^^1~435.5~314~0~5~start~~~#0000FF^^0~438~315^^0~M 435 312 L 432 315 L 435 318",
48
- // "P~show~0~6~445~305~0~gge10~0^^445~305^^M445,305h-10~#880000^^1~431.3~309~0~THRES~end~~~#0000FF^^1~435.5~304~0~6~start~~~#0000FF^^0~438~305^^0~M 435 302 L 432 305 L 435 308",
49
- // "P~show~0~7~445~295~0~gge11~0^^445~295^^M445,295h-10~#880000^^1~431.3~299~0~DISCH~end~~~#0000FF^^1~435.5~294~0~7~start~~~#0000FF^^0~438~295^^0~M 435 292 L 432 295 L 435 298",
50
- // "P~show~0~8~445~285~0~gge12~0^^445~285^^M445,285h-10~#FF0000^^1~431.3~289~0~VCC~end~~~#FF0000^^1~435.5~284~0~8~start~~~#FF0000^^0~438~285^^0~M 435 282 L 432 285 L 435 288",
51
-
52
- const PointSchema = z.object({
53
- x: z.number(),
54
- y: z.number(),
55
- })
56
-
57
- const RectangleShapeOutputSchema = z.object({
58
- type: z.literal("RECTANGLE"),
59
- position: PointSchema,
60
- width: z.number(),
61
- height: z.number(),
62
- color: z.string(),
63
- lineWidth: z.number(),
64
- id: z.string(),
65
- })
66
-
67
- export const RectangleShapeSchema = z
68
- .string()
69
- .startsWith("R~")
70
- .transform((str): z.infer<typeof RectangleShapeOutputSchema> => {
71
- const [, x, y, , , width, height, color, lineWidth, , , id] = str.split("~")
72
- return {
73
- type: "RECTANGLE",
74
- position: { x: Number(x), y: Number(y) },
75
- width: Number(width),
76
- height: Number(height),
77
- color,
78
- lineWidth: Number(lineWidth),
79
- id,
80
- }
81
- })
82
- .pipe(RectangleShapeOutputSchema)
83
-
84
- const EllipseShapeOutputSchema = z.object({
85
- type: z.literal("ELLIPSE"),
86
- center: PointSchema,
87
- radiusX: z.number(),
88
- radiusY: z.number(),
89
- color: z.string(),
90
- lineWidth: z.number(),
91
- id: z.string(),
92
- })
93
-
94
- export const EllipseShapeSchema = z
95
- .string()
96
- .startsWith("E~")
97
- .transform((str): z.infer<typeof EllipseShapeOutputSchema> => {
98
- const [, x, y, radiusX, radiusY, color, lineWidth, , , id] = str.split("~")
99
- return {
100
- type: "ELLIPSE",
101
- center: { x: Number(x), y: Number(y) },
102
- radiusX: Number(radiusX),
103
- radiusY: Number(radiusY),
104
- color,
105
- lineWidth: Number(lineWidth),
106
- id,
107
- }
108
- })
109
- .pipe(EllipseShapeOutputSchema)
110
-
111
- // type PinDirection = 'left' | 'right';
112
-
113
- // interface Pin {
114
- // type: 'P';
115
- // visibility: string;
116
- // id: string;
117
- // pin: number;
118
- // x: number;
119
- // y: number;
120
- // rotation: number;
121
- // name: string;
122
- // color: string;
123
- // path: string;
124
- // arrow: string;
125
- // direction: PinDirection;
126
- // }
127
- const PinShapeOutputSchema = z.object({
128
- type: z.literal("PIN"),
129
- visibility: z.enum(["show", "hide"]),
130
- pinNumber: z.number(),
131
- x: z.number(),
132
- y: z.number(),
133
- rotation: z.number(),
134
- id: z.string(),
135
- label: z.string(),
136
- labelColor: z.string(),
137
- path: z.string(),
138
- arrow: z.string(),
139
- })
140
-
141
- function parsePin(pinString: string): z.infer<typeof PinShapeOutputSchema> {
142
- const parts = pinString.split("~")
143
- const [_, visibility, __, pinNumber, x, y, rotation, id] = parts
144
-
145
- const nameMatch = pinString.match(/~(\w+)~start~/)
146
- const label = nameMatch ? nameMatch[1] : ""
147
-
148
- // TODO: make sure colors are associated properly
149
- const colorMatch = pinString.match(/#[0-9A-F]{6}/)
150
- const labelColor = colorMatch ? colorMatch[0] : ""
151
-
152
- const pathMatch = pinString.match(/\^\^([^~]+)/)
153
- const path = pathMatch ? pathMatch[1] : ""
154
-
155
- const arrowMatch = pinString.match(/\^\^0~(.+)$/)
156
- const arrow = arrowMatch ? arrowMatch[1] : ""
157
-
158
- return {
159
- type: "PIN",
160
- visibility: visibility as "show" | "hide",
161
- id,
162
- pinNumber: parseInt(pinNumber),
163
- x: parseFloat(x),
164
- y: parseFloat(y),
165
- rotation: parseFloat(rotation),
166
- label,
167
- labelColor,
168
- path,
169
- arrow,
170
- }
171
- }
172
-
173
- export const PinShapeSchema = z
174
- .string()
175
- .startsWith("P~")
176
- .transform((str): z.infer<typeof PinShapeOutputSchema> => {
177
- return parsePin(str)
178
- })
179
- .pipe(PinShapeOutputSchema)
180
-
181
- export const SingleLetterShapeSchema = z
182
- .string()
183
- .transform((x) => {
184
- // We do some discrimination here for better errors
185
- if (x.startsWith("R~")) {
186
- return RectangleShapeSchema.parse(x)
187
- } else if (x.startsWith("E~")) {
188
- return EllipseShapeSchema.parse(x)
189
- } else if (x.startsWith("P~")) {
190
- return PinShapeSchema.parse(x)
191
- } else {
192
- throw new Error("Invalid shape type: " + x)
193
- }
194
- })
195
- .pipe(
196
- z.union([
197
- RectangleShapeOutputSchema,
198
- EllipseShapeOutputSchema,
199
- PinShapeOutputSchema,
200
- ])
201
- )
package/renovate.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
- "extends": [
4
- "config:recommended"
5
- ]
6
- }
@@ -1,12 +0,0 @@
1
- import { fetchEasyEDAComponent } from "../lib/fetch-easyeda-json"
2
- import * as fs from "node:fs"
3
-
4
- // "C46749" // NE555P - DIP8
5
- // const partNumber = "C5125085" - SSOP8
6
- const partNumber = "C95209" // esp32
7
-
8
- const outputFile = "./test.json"
9
-
10
- const easyEdaJson = await fetchEasyEDAComponent(partNumber)
11
-
12
- fs.writeFileSync(outputFile, JSON.stringify(easyEdaJson, null, " "))