@typecad/framework-arduino 0.1.0-alpha.1
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/LICENSE +21 -0
- package/README.md +192 -0
- package/dist/arduino/i2c-arduino.d.ts +47 -0
- package/dist/arduino/i2c-arduino.js +6 -0
- package/dist/arduino/index.d.ts +6 -0
- package/dist/arduino/index.js +8 -0
- package/dist/arduino/spi-arduino.d.ts +42 -0
- package/dist/arduino/spi-arduino.js +6 -0
- package/dist/arduino/stubs-uno.d.ts +9 -0
- package/dist/arduino/stubs-uno.js +65 -0
- package/dist/arduino/uart-arduino.d.ts +41 -0
- package/dist/arduino/uart-arduino.js +6 -0
- package/dist/arduino-class-map.d.ts +5 -0
- package/dist/arduino-class-map.js +21 -0
- package/dist/arduino-compile.d.ts +24 -0
- package/dist/arduino-compile.js +316 -0
- package/dist/arduino-libs.d.ts +6 -0
- package/dist/arduino-libs.js +11 -0
- package/dist/cli-metadata.d.ts +12 -0
- package/dist/cli-metadata.js +196 -0
- package/dist/cpp-parser.d.ts +47 -0
- package/dist/cpp-parser.js +292 -0
- package/dist/debug-codegen.d.ts +20 -0
- package/dist/debug-codegen.js +115 -0
- package/dist/displays/ili9341-spi.d.ts +6 -0
- package/dist/displays/ili9341-spi.js +28 -0
- package/dist/displays/ssd1309-i2c.d.ts +2 -0
- package/dist/displays/ssd1309-i2c.js +16 -0
- package/dist/displays/st7796-spi.d.ts +2 -0
- package/dist/displays/st7796-spi.js +20 -0
- package/dist/graphics/ili9341.d.ts +24 -0
- package/dist/graphics/ili9341.js +59 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +27 -0
- package/dist/lib-declaration.d.ts +35 -0
- package/dist/lib-declaration.js +399 -0
- package/dist/lib-discovery.d.ts +38 -0
- package/dist/lib-discovery.js +189 -0
- package/dist/profile.d.ts +8 -0
- package/dist/profile.js +584 -0
- package/dist/strategy.d.ts +174 -0
- package/dist/strategy.js +2032 -0
- package/package.json +73 -0
- package/src/arduino/i2c-arduino.ts +72 -0
- package/src/arduino/index.ts +18 -0
- package/src/arduino/spi-arduino.ts +63 -0
- package/src/arduino/stubs-uno.ts +80 -0
- package/src/arduino/uart-arduino.ts +59 -0
- package/src/arduino-class-map.ts +32 -0
- package/src/arduino-compile.ts +359 -0
- package/src/arduino-libs.ts +33 -0
- package/src/cli-metadata.ts +250 -0
- package/src/cpp-parser.ts +361 -0
- package/src/debug-codegen.ts +155 -0
- package/src/displays/ili9341-spi.ts +33 -0
- package/src/displays/ssd1309-i2c.ts +19 -0
- package/src/displays/st7796-spi.ts +23 -0
- package/src/graphics/ili9341.ts +80 -0
- package/src/index.ts +37 -0
- package/src/lib-declaration.ts +493 -0
- package/src/lib-discovery.ts +267 -0
- package/src/profile.ts +676 -0
- package/src/strategy.ts +2126 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @typecad/framework-arduino — Arduino framework strategy
|
|
3
|
+
//
|
|
4
|
+
// Provides the ArduinoStrategy implementation for Arduino framework code
|
|
5
|
+
// generation. This is the main entry point for the framework-arduino package.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
// Export the main strategy class
|
|
9
|
+
export { ArduinoStrategy } from './strategy.js';
|
|
10
|
+
|
|
11
|
+
// Export as FrameworkStrategy for consistency with framework package naming
|
|
12
|
+
export { ArduinoStrategy as FrameworkStrategy } from './strategy.js';
|
|
13
|
+
|
|
14
|
+
// Arduino compile/upload/monitor
|
|
15
|
+
export {
|
|
16
|
+
flattenGeneratedModulesIntoSketch,
|
|
17
|
+
compileArduinoSketch,
|
|
18
|
+
uploadArduinoSketch,
|
|
19
|
+
monitorArduinoSketch,
|
|
20
|
+
} from './arduino-compile.js';
|
|
21
|
+
|
|
22
|
+
// Toolchain object for the framework registry
|
|
23
|
+
import { flattenGeneratedModulesIntoSketch, compileArduinoSketch, uploadArduinoSketch, monitorArduinoSketch } from './arduino-compile.js';
|
|
24
|
+
export const Toolchain = {
|
|
25
|
+
prepare: flattenGeneratedModulesIntoSketch,
|
|
26
|
+
compile: (options: any) => compileArduinoSketch(options.sourcePath, options.buildTarget, {
|
|
27
|
+
extraFlags: options.extraFlags,
|
|
28
|
+
defines: options.defines,
|
|
29
|
+
}),
|
|
30
|
+
upload: (options: any) => uploadArduinoSketch(options.outputDir, options.buildTarget, options.port),
|
|
31
|
+
monitor: (options: any) => monitorArduinoSketch(options.port, options.baud),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Library discovery — consumed by the transpiler's dynamic module loader
|
|
35
|
+
export { isArduinoLibraryImport as isFrameworkLibraryImport, getArduinoLibraryHeaderName as getFrameworkLibraryHeaderName } from './arduino-libs.js';
|
|
36
|
+
export { tryGenerateArduinoLibDecl as tryGenerateLibDecl } from './arduino-libs.js';
|
|
37
|
+
export { buildArduinoClassNameMap as buildClassNameMap } from './arduino-class-map.js';
|
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @typecad/framework-arduino — Arduino Library Declaration Generator
|
|
3
|
+
//
|
|
4
|
+
// Generates TypeScript .d.ts declarations and usage documentation from
|
|
5
|
+
// parsed Arduino library C++ headers.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import { type ArduinoLibrary, isArduinoLibraryImport, findArduinoLibrary, findLibraryHeader } from "./lib-discovery.js";
|
|
11
|
+
import { type CppParseResult, parseCppClass } from "./cpp-parser.js";
|
|
12
|
+
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Public types
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Result of generating a .d.ts file for an Arduino library.
|
|
19
|
+
*/
|
|
20
|
+
export interface GeneratedArduinoLib {
|
|
21
|
+
/** Path to the generated .d.ts file */
|
|
22
|
+
declPath: string;
|
|
23
|
+
/** The actual header file name (e.g., "Microfire_SHT3x.h") */
|
|
24
|
+
headerName: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Project root detection
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Find the project root by looking for package.json or tsconfig.json.
|
|
33
|
+
*/
|
|
34
|
+
function findProjectRoot(fromFile: string): string | undefined {
|
|
35
|
+
let currentDir = path.dirname(path.resolve(fromFile));
|
|
36
|
+
|
|
37
|
+
while (currentDir !== path.dirname(currentDir)) {
|
|
38
|
+
if (fs.existsSync(path.join(currentDir, "package.json")) ||
|
|
39
|
+
fs.existsSync(path.join(currentDir, "tsconfig.json"))) {
|
|
40
|
+
return currentDir;
|
|
41
|
+
}
|
|
42
|
+
currentDir = path.dirname(currentDir);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Declaration generation
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Generate export-based declaration content for @types packages.
|
|
54
|
+
*/
|
|
55
|
+
function generateExportDeclaration(
|
|
56
|
+
parsed: CppParseResult,
|
|
57
|
+
moduleDocstring?: string,
|
|
58
|
+
): string {
|
|
59
|
+
const lines: string[] = [];
|
|
60
|
+
|
|
61
|
+
// Add header comment explaining auto-generation and manual editing
|
|
62
|
+
lines.push("/**");
|
|
63
|
+
if (moduleDocstring) {
|
|
64
|
+
lines.push(` * ${moduleDocstring}`);
|
|
65
|
+
}
|
|
66
|
+
lines.push(" *");
|
|
67
|
+
lines.push(" * Auto-generated by TypeCAD from Arduino library C++ headers.");
|
|
68
|
+
lines.push(" * Arduino peripheral types (TwoWire, HardwareSerial, etc.) are mapped to TypeCAD equivalents.");
|
|
69
|
+
lines.push(" *");
|
|
70
|
+
lines.push(" * You can manually edit this file to:");
|
|
71
|
+
lines.push(" * - Add missing methods or properties");
|
|
72
|
+
lines.push(" * - Fix incorrect type mappings");
|
|
73
|
+
lines.push(" * - Add JSDoc documentation");
|
|
74
|
+
lines.push(" *");
|
|
75
|
+
lines.push(" * To regenerate: delete this file and re-run TypeCAD transpile.");
|
|
76
|
+
lines.push(" */");
|
|
77
|
+
lines.push("");
|
|
78
|
+
|
|
79
|
+
// Export constants
|
|
80
|
+
for (const constant of parsed.constants) {
|
|
81
|
+
lines.push(`export declare const ${constant.name}: ${constant.type};`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (parsed.constants.length > 0 && parsed.classes.length > 0) {
|
|
85
|
+
lines.push("");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Export classes
|
|
89
|
+
for (const cppClass of parsed.classes) {
|
|
90
|
+
lines.push(`export declare class ${cppClass.name} {`);
|
|
91
|
+
|
|
92
|
+
// Add constructors
|
|
93
|
+
for (const ctor of cppClass.constructors) {
|
|
94
|
+
const params = ctor.parameters
|
|
95
|
+
.filter(p => p.name)
|
|
96
|
+
.map(p => `${p.name}: ${p.type}`)
|
|
97
|
+
.join(", ");
|
|
98
|
+
lines.push(` constructor(${params});`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Add public methods
|
|
102
|
+
const publicMethods = cppClass.methods.filter(m => m.isPublic);
|
|
103
|
+
for (const method of publicMethods) {
|
|
104
|
+
const params = method.parameters
|
|
105
|
+
.filter(p => p.name)
|
|
106
|
+
.map(p => `${p.name}: ${p.type}`)
|
|
107
|
+
.join(", ");
|
|
108
|
+
lines.push(` ${method.name}(${params}): ${method.returnType};`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
lines.push("}");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
lines.push("");
|
|
115
|
+
|
|
116
|
+
return lines.join("\n");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
// Public API
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Generate a .d.ts file for an Arduino library.
|
|
125
|
+
* Returns the path to the generated file and header info, or undefined if generation failed.
|
|
126
|
+
*/
|
|
127
|
+
export function generateArduinoLibDecl(
|
|
128
|
+
library: ArduinoLibrary,
|
|
129
|
+
fromFile: string
|
|
130
|
+
): GeneratedArduinoLib | undefined {
|
|
131
|
+
// Find the main header file
|
|
132
|
+
const headerPath = findLibraryHeader(library);
|
|
133
|
+
if (!headerPath) {
|
|
134
|
+
console.log(` No header file found for Arduino library '${library.name}'`);
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (!fs.existsSync(headerPath)) {
|
|
139
|
+
console.log(` Header file does not exist: ${headerPath}`);
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const content = fs.readFileSync(headerPath, "utf8");
|
|
144
|
+
const parsed = parseCppClass(content);
|
|
145
|
+
|
|
146
|
+
if (parsed.classes.length === 0 && parsed.constants.length === 0) {
|
|
147
|
+
console.log(` No class definitions found in '${library.name}' header`);
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Generate export-based declaration for @types
|
|
152
|
+
const declaration = generateExportDeclaration(
|
|
153
|
+
parsed,
|
|
154
|
+
`Arduino library: ${library.name}`
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
// Find project root
|
|
158
|
+
const projectRoot = findProjectRoot(fromFile);
|
|
159
|
+
if (!projectRoot) {
|
|
160
|
+
console.log(` Could not find project root for '${fromFile}'`);
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Place declarations in node_modules/@types/LibraryName/
|
|
165
|
+
// TypeScript automatically looks here for type declarations
|
|
166
|
+
const typeDir = path.join(projectRoot, "node_modules", "@types", library.name);
|
|
167
|
+
|
|
168
|
+
// Ensure output directory exists
|
|
169
|
+
if (!fs.existsSync(typeDir)) {
|
|
170
|
+
fs.mkdirSync(typeDir, { recursive: true });
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const declPath = path.join(typeDir, "index.d.ts");
|
|
174
|
+
|
|
175
|
+
// Write the declaration file
|
|
176
|
+
fs.writeFileSync(declPath, declaration, "utf8");
|
|
177
|
+
|
|
178
|
+
// Also write a minimal package.json for module resolution
|
|
179
|
+
const packageJson = {
|
|
180
|
+
name: `@types/${library.name}`,
|
|
181
|
+
version: "0.0.0",
|
|
182
|
+
main: "index.d.ts",
|
|
183
|
+
types: "index.d.ts"
|
|
184
|
+
};
|
|
185
|
+
fs.writeFileSync(
|
|
186
|
+
path.join(typeDir, "package.json"),
|
|
187
|
+
JSON.stringify(packageJson, null, 2),
|
|
188
|
+
"utf8"
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
// Extract the actual header file name from the path
|
|
192
|
+
const headerName = path.basename(headerPath);
|
|
193
|
+
|
|
194
|
+
// Generate usage documentation
|
|
195
|
+
const usageDoc = generateUsageDocumentation(parsed, library.name, library);
|
|
196
|
+
fs.writeFileSync(
|
|
197
|
+
path.join(typeDir, "USAGE.md"),
|
|
198
|
+
usageDoc,
|
|
199
|
+
"utf8"
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
return { declPath, headerName };
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Try to generate .d.ts for a missing Arduino library import.
|
|
207
|
+
* Returns the path to the generated declaration file, or undefined if not found.
|
|
208
|
+
*/
|
|
209
|
+
export function tryGenerateArduinoLibDecl(
|
|
210
|
+
moduleSpecifier: string,
|
|
211
|
+
fromFile: string
|
|
212
|
+
): string | undefined {
|
|
213
|
+
if (!isArduinoLibraryImport(moduleSpecifier)) {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const library = findArduinoLibrary(moduleSpecifier);
|
|
218
|
+
if (!library) {
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
console.log(`\n Found Arduino library '${library.name}' at: ${library.path}`);
|
|
223
|
+
|
|
224
|
+
const result = generateArduinoLibDecl(library, fromFile);
|
|
225
|
+
|
|
226
|
+
if (result) {
|
|
227
|
+
console.log(` Generated declaration: ${result.declPath}`);
|
|
228
|
+
console.log(` Review the generated types and adjust if needed.\n`);
|
|
229
|
+
return result.declPath;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return undefined;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Try to get the actual header file name for an Arduino library import.
|
|
237
|
+
* Returns the header file name (e.g., "Microfire_SHT3x.h") or undefined if not found.
|
|
238
|
+
*/
|
|
239
|
+
export function getArduinoLibraryHeaderName(moduleSpecifier: string): string | undefined {
|
|
240
|
+
if (!isArduinoLibraryImport(moduleSpecifier)) {
|
|
241
|
+
return undefined;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const library = findArduinoLibrary(moduleSpecifier);
|
|
245
|
+
if (!library) {
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const headerPath = findLibraryHeader(library);
|
|
250
|
+
if (!headerPath) {
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return path.basename(headerPath);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Get fully qualified class names for an Arduino library.
|
|
259
|
+
* Returns a map of simple class name to fully qualified name (e.g., "SHT3x" -> "Microfire::SHT3x").
|
|
260
|
+
*/
|
|
261
|
+
export function getArduinoLibraryClassNames(moduleSpecifier: string): Map<string, string> {
|
|
262
|
+
const result = new Map<string, string>();
|
|
263
|
+
|
|
264
|
+
if (!isArduinoLibraryImport(moduleSpecifier)) {
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const library = findArduinoLibrary(moduleSpecifier);
|
|
269
|
+
if (!library) {
|
|
270
|
+
return result;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const headerPath = findLibraryHeader(library);
|
|
274
|
+
if (!headerPath || !fs.existsSync(headerPath)) {
|
|
275
|
+
return result;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const content = fs.readFileSync(headerPath, "utf8");
|
|
279
|
+
const parsed = parseCppClass(content);
|
|
280
|
+
|
|
281
|
+
for (const cppClass of parsed.classes) {
|
|
282
|
+
result.set(cppClass.name, cppClass.fullName);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return result;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// ---------------------------------------------------------------------------
|
|
289
|
+
// Documentation generation
|
|
290
|
+
// ---------------------------------------------------------------------------
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Generate usage documentation for an Arduino library.
|
|
294
|
+
*/
|
|
295
|
+
export function generateUsageDocumentation(
|
|
296
|
+
parsed: CppParseResult,
|
|
297
|
+
libraryName: string,
|
|
298
|
+
library?: ArduinoLibrary
|
|
299
|
+
): string {
|
|
300
|
+
const lines: string[] = [];
|
|
301
|
+
|
|
302
|
+
lines.push(`# ${libraryName} - TypeCAD Usage Guide`);
|
|
303
|
+
lines.push("");
|
|
304
|
+
|
|
305
|
+
if (library?.sentence) {
|
|
306
|
+
lines.push(`> ${library.sentence}`);
|
|
307
|
+
lines.push("");
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (library?.author) {
|
|
311
|
+
lines.push(`**Author:** ${library.author}`);
|
|
312
|
+
lines.push("");
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
lines.push("## Overview");
|
|
316
|
+
lines.push("");
|
|
317
|
+
lines.push(`This library was auto-discovered from your Arduino installation and TypeCAD`);
|
|
318
|
+
lines.push(`has generated TypeScript type definitions for it.`);
|
|
319
|
+
lines.push("");
|
|
320
|
+
|
|
321
|
+
if (parsed.classes.length > 0) {
|
|
322
|
+
lines.push("## Classes");
|
|
323
|
+
lines.push("");
|
|
324
|
+
|
|
325
|
+
for (const cppClass of parsed.classes) {
|
|
326
|
+
lines.push(`### ${cppClass.name}`);
|
|
327
|
+
lines.push("");
|
|
328
|
+
|
|
329
|
+
// Show C++ fully qualified name if different
|
|
330
|
+
if (cppClass.fullName !== cppClass.name) {
|
|
331
|
+
lines.push(`**C++:** \`${cppClass.fullName}\``);
|
|
332
|
+
lines.push("");
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Constructor
|
|
336
|
+
if (cppClass.constructors.length > 0) {
|
|
337
|
+
lines.push("#### Constructor");
|
|
338
|
+
lines.push("");
|
|
339
|
+
lines.push("```typescript");
|
|
340
|
+
lines.push(`import { ${cppClass.name} } from '${libraryName}';`);
|
|
341
|
+
lines.push("");
|
|
342
|
+
|
|
343
|
+
for (const ctor of cppClass.constructors) {
|
|
344
|
+
const params = ctor.parameters
|
|
345
|
+
.filter(p => p.name)
|
|
346
|
+
.map(p => `${p.name}: ${p.type}`)
|
|
347
|
+
.join(", ");
|
|
348
|
+
lines.push(`const sensor = new ${cppClass.name}(${params});`);
|
|
349
|
+
}
|
|
350
|
+
lines.push("```");
|
|
351
|
+
lines.push("");
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Methods
|
|
355
|
+
if (cppClass.methods.length > 0) {
|
|
356
|
+
lines.push("#### Methods");
|
|
357
|
+
lines.push("");
|
|
358
|
+
lines.push("| Method | Parameters | Returns |");
|
|
359
|
+
lines.push("|--------|------------|---------|");
|
|
360
|
+
|
|
361
|
+
for (const method of cppClass.methods) {
|
|
362
|
+
const params = method.parameters
|
|
363
|
+
.filter(p => p.name)
|
|
364
|
+
.map(p => `${p.name}: ${p.type}`)
|
|
365
|
+
.join(", ");
|
|
366
|
+
lines.push(`| \`${method.name}()\` | ${params || "none"} | ${method.returnType} |`);
|
|
367
|
+
}
|
|
368
|
+
lines.push("");
|
|
369
|
+
|
|
370
|
+
// Usage examples
|
|
371
|
+
lines.push("#### Example Usage");
|
|
372
|
+
lines.push("");
|
|
373
|
+
lines.push("```typescript");
|
|
374
|
+
lines.push(`import { ${cppClass.name} } from '${libraryName}';`);
|
|
375
|
+
|
|
376
|
+
// Add peripheral imports if needed
|
|
377
|
+
const peripheralTypes = new Set<string>();
|
|
378
|
+
for (const method of cppClass.methods) {
|
|
379
|
+
for (const param of method.parameters) {
|
|
380
|
+
if (param.type === "I2C0" || param.type === "I2C1") {
|
|
381
|
+
peripheralTypes.add("I2C0");
|
|
382
|
+
} else if (param.type === "SPI0" || param.type === "SPI1") {
|
|
383
|
+
peripheralTypes.add("SPI0");
|
|
384
|
+
} else if (param.type === "UART0" || param.type === "UART1") {
|
|
385
|
+
peripheralTypes.add("UART0");
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
for (const ctor of cppClass.constructors) {
|
|
389
|
+
for (const param of ctor.parameters) {
|
|
390
|
+
if (param.type === "I2C0" || param.type === "I2C1") {
|
|
391
|
+
peripheralTypes.add("I2C0");
|
|
392
|
+
} else if (param.type === "SPI0" || param.type === "SPI1") {
|
|
393
|
+
peripheralTypes.add("SPI0");
|
|
394
|
+
} else if (param.type === "UART0" || param.type === "UART1") {
|
|
395
|
+
peripheralTypes.add("UART0");
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
if (peripheralTypes.size > 0) {
|
|
402
|
+
lines.push(`import { ${[...peripheralTypes].join(", ")} } from '@typecad/board';`);
|
|
403
|
+
}
|
|
404
|
+
lines.push("");
|
|
405
|
+
|
|
406
|
+
// Constructor example
|
|
407
|
+
if (cppClass.constructors.length > 0) {
|
|
408
|
+
const ctor = cppClass.constructors[0];
|
|
409
|
+
const args = ctor.parameters
|
|
410
|
+
.filter(p => p.name)
|
|
411
|
+
.map(p => {
|
|
412
|
+
// Provide example values for common types
|
|
413
|
+
if (p.type === "I2C0") return "I2C0";
|
|
414
|
+
if (p.type === "SPI0") return "SPI0";
|
|
415
|
+
if (p.type === "UART0") return "UART0";
|
|
416
|
+
if (p.type === "number") return "0x44";
|
|
417
|
+
if (p.type === "boolean") return "true";
|
|
418
|
+
if (p.type === "string") return '"example"';
|
|
419
|
+
return p.name;
|
|
420
|
+
})
|
|
421
|
+
.join(", ");
|
|
422
|
+
lines.push(`const device = new ${cppClass.name}(${args});`);
|
|
423
|
+
} else {
|
|
424
|
+
lines.push(`const device = new ${cppClass.name}();`);
|
|
425
|
+
}
|
|
426
|
+
lines.push("");
|
|
427
|
+
|
|
428
|
+
// Show common method calls
|
|
429
|
+
const beginMethod = cppClass.methods.find(m => m.name === "begin");
|
|
430
|
+
if (beginMethod) {
|
|
431
|
+
const args = beginMethod.parameters
|
|
432
|
+
.filter(p => p.name)
|
|
433
|
+
.map(p => {
|
|
434
|
+
if (p.type === "I2C0") return "I2C0";
|
|
435
|
+
if (p.type === "SPI0") return "SPI0";
|
|
436
|
+
if (p.type === "UART0") return "UART0";
|
|
437
|
+
if (p.type === "number") return "0x44";
|
|
438
|
+
if (p.type === "boolean") return "true";
|
|
439
|
+
return p.name;
|
|
440
|
+
})
|
|
441
|
+
.join(", ");
|
|
442
|
+
lines.push(`device.begin(${args});`);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const measureMethod = cppClass.methods.find(m => m.name === "measure" || m.name === "read");
|
|
446
|
+
if (measureMethod) {
|
|
447
|
+
lines.push(`device.${measureMethod.name}();`);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const connectedMethod = cppClass.methods.find(m => m.name === "connected" || m.name === "begin");
|
|
451
|
+
if (connectedMethod && connectedMethod.returnType === "boolean") {
|
|
452
|
+
lines.push("");
|
|
453
|
+
lines.push(`if (device.${connectedMethod.name}()) {`);
|
|
454
|
+
lines.push(` // Device is ready`);
|
|
455
|
+
lines.push(`}`);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
lines.push("```");
|
|
459
|
+
lines.push("");
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Type mappings section
|
|
465
|
+
lines.push("## Type Mappings");
|
|
466
|
+
lines.push("");
|
|
467
|
+
lines.push("TypeCAD automatically maps Arduino C++ types to TypeScript equivalents:");
|
|
468
|
+
lines.push("");
|
|
469
|
+
lines.push("| Arduino C++ | TypeCAD TypeScript |");
|
|
470
|
+
lines.push("|-------------|---------------------|");
|
|
471
|
+
lines.push("| `TwoWire` / `TwoWire*` | `I2C0` |");
|
|
472
|
+
lines.push("| `SPIClass` / `SPIClass*` | `SPI0` |");
|
|
473
|
+
lines.push("| `HardwareSerial` / `HardwareSerial*` | `UART0` |");
|
|
474
|
+
lines.push("| `int`, `uint8_t`, `uint16_t`, etc. | `number` |");
|
|
475
|
+
lines.push("| `float`, `double` | `number` |");
|
|
476
|
+
lines.push("| `bool` | `boolean` |");
|
|
477
|
+
lines.push("| `String`, `const char*` | `string` |");
|
|
478
|
+
lines.push("");
|
|
479
|
+
|
|
480
|
+
lines.push("## Editing Type Definitions");
|
|
481
|
+
lines.push("");
|
|
482
|
+
lines.push("The generated type definitions are best-effort. You can manually edit the");
|
|
483
|
+
lines.push(`\`node_modules/@types/${libraryName}/index.d.ts\` file to:`);
|
|
484
|
+
lines.push("");
|
|
485
|
+
lines.push("- Add missing methods or properties");
|
|
486
|
+
lines.push("- Fix incorrect type mappings");
|
|
487
|
+
lines.push("- Add JSDoc documentation");
|
|
488
|
+
lines.push("");
|
|
489
|
+
lines.push("To regenerate: delete the file and re-run TypeCAD transpile.");
|
|
490
|
+
lines.push("");
|
|
491
|
+
|
|
492
|
+
return lines.join("\n");
|
|
493
|
+
}
|