zigbee-clusters 2.8.1 → 2.8.2
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/index.d.ts +647 -151
- package/package.json +1 -1
- package/scripts/generate-types.js +86 -19
package/package.json
CHANGED
|
@@ -179,6 +179,8 @@ function generateClusterInterface(cluster) {
|
|
|
179
179
|
lines.push(` readAttributes<K extends ${attrNames}>(attributeNames: K[], opts?: { timeout?: number }): Promise<Pick<${interfaceName}Attributes, K>>;`);
|
|
180
180
|
lines.push(` readAttributes(attributeNames: Array<keyof ${interfaceName}Attributes | number>, opts?: { timeout?: number }): Promise<Partial<${interfaceName}Attributes> & Record<number, unknown>>;`);
|
|
181
181
|
lines.push(` writeAttributes(attributes: Partial<${interfaceName}Attributes>, opts?: { timeout?: number }): Promise<unknown>;`);
|
|
182
|
+
lines.push(` on<K extends keyof ${interfaceName}Attributes & string>(eventName: \`attr.\${K}\`, listener: (value: ${interfaceName}Attributes[K]) => void): this;`);
|
|
183
|
+
lines.push(` once<K extends keyof ${interfaceName}Attributes & string>(eventName: \`attr.\${K}\`, listener: (value: ${interfaceName}Attributes[K]) => void): this;`);
|
|
182
184
|
}
|
|
183
185
|
|
|
184
186
|
// Add command methods
|
|
@@ -208,9 +210,14 @@ function generateClusterInterface(cluster) {
|
|
|
208
210
|
/**
|
|
209
211
|
* Generate the full index.d.ts file
|
|
210
212
|
* @param {object[]} clusters - Array of parsed cluster definitions
|
|
213
|
+
* @param {Array<{
|
|
214
|
+
* constantName: string;
|
|
215
|
+
* clusterId: number;
|
|
216
|
+
* clusterName: string;
|
|
217
|
+
* }>} clusterDefinitions - Array of CLUSTER definitions used to generate typed CLUSTER exports
|
|
211
218
|
* @returns {string} Complete TypeScript definitions file
|
|
212
219
|
*/
|
|
213
|
-
function generateTypesFile(clusters) {
|
|
220
|
+
function generateTypesFile(clusters, clusterDefinitions) {
|
|
214
221
|
const lines = [];
|
|
215
222
|
|
|
216
223
|
// Header
|
|
@@ -309,6 +316,42 @@ type ZCLNodeConstructorInput = {
|
|
|
309
316
|
lines.push('}');
|
|
310
317
|
lines.push('');
|
|
311
318
|
|
|
319
|
+
// Generate cluster type lookup maps for inference helpers
|
|
320
|
+
lines.push('/** Cluster type lookup by cluster NAME */');
|
|
321
|
+
lines.push('export interface ClusterTypeByName {');
|
|
322
|
+
for (const cluster of clusters) {
|
|
323
|
+
const interfaceName = toInterfaceName(cluster);
|
|
324
|
+
lines.push(` ${cluster.clusterName}: ${interfaceName};`);
|
|
325
|
+
}
|
|
326
|
+
lines.push('}');
|
|
327
|
+
lines.push('');
|
|
328
|
+
|
|
329
|
+
// Generate cluster attribute lookup maps for inference helpers
|
|
330
|
+
lines.push('/** Cluster attributes lookup by cluster NAME */');
|
|
331
|
+
lines.push('export interface ClusterAttributesByName {');
|
|
332
|
+
for (const cluster of clusters) {
|
|
333
|
+
const interfaceName = toInterfaceName(cluster);
|
|
334
|
+
const attributesInterfaceName = `${interfaceName}Attributes`;
|
|
335
|
+
const attributesType = cluster.attributes.length > 0 ? attributesInterfaceName : 'Record<string, unknown>';
|
|
336
|
+
lines.push(` ${cluster.clusterName}: ${attributesType};`);
|
|
337
|
+
}
|
|
338
|
+
lines.push('}');
|
|
339
|
+
lines.push('');
|
|
340
|
+
|
|
341
|
+
lines.push('/** Infer a typed cluster interface from a CLUSTER definition object. */');
|
|
342
|
+
lines.push('export type ClusterTypeFromDefinition<TDef extends { NAME: string; ID: number }> =');
|
|
343
|
+
lines.push(" TDef['NAME'] extends keyof ClusterTypeByName");
|
|
344
|
+
lines.push(" ? ClusterTypeByName[TDef['NAME']]");
|
|
345
|
+
lines.push(' : ZCLNodeCluster;');
|
|
346
|
+
lines.push('');
|
|
347
|
+
|
|
348
|
+
lines.push('/** Infer typed cluster attribute map from a CLUSTER definition object. */');
|
|
349
|
+
lines.push('export type ClusterAttributesFromDefinition<TDef extends { NAME: string; ID: number }> =');
|
|
350
|
+
lines.push(" TDef['NAME'] extends keyof ClusterAttributesByName");
|
|
351
|
+
lines.push(" ? ClusterAttributesByName[TDef['NAME']]");
|
|
352
|
+
lines.push(' : Record<string, unknown>;');
|
|
353
|
+
lines.push('');
|
|
354
|
+
|
|
312
355
|
// Generate endpoint type
|
|
313
356
|
lines.push(`export type ZCLNodeEndpoint = {
|
|
314
357
|
clusters: ClusterRegistry & {
|
|
@@ -327,30 +370,46 @@ export interface ZCLNode {
|
|
|
327
370
|
}
|
|
328
371
|
`);
|
|
329
372
|
|
|
330
|
-
//
|
|
331
|
-
lines.push(`
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
};
|
|
335
|
-
export const CLUSTER: {
|
|
336
|
-
[key: string]: { ID: number; NAME: string; ATTRIBUTES: unknown; COMMANDS: unknown };
|
|
337
|
-
};
|
|
338
|
-
export { ZCLNodeCluster };`);
|
|
373
|
+
// Runtime value exports
|
|
374
|
+
lines.push(`export const ZCLNode: {
|
|
375
|
+
new (node: ZCLNodeConstructorInput): ZCLNode;
|
|
376
|
+
};
|
|
339
377
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
lines.push(` export const ${exportName}: {`);
|
|
345
|
-
lines.push(` new (...args: any[]): ${interfaceName};`);
|
|
378
|
+
export const CLUSTER: {
|
|
379
|
+
`);
|
|
380
|
+
for (const def of clusterDefinitions) {
|
|
381
|
+
lines.push(` ${def.constantName}: {`);
|
|
346
382
|
lines.push(' ID: number;');
|
|
347
|
-
lines.push(
|
|
383
|
+
lines.push(` NAME: '${def.clusterName}';`);
|
|
348
384
|
lines.push(' ATTRIBUTES: unknown;');
|
|
349
385
|
lines.push(' COMMANDS: unknown;');
|
|
350
386
|
lines.push(' };');
|
|
351
387
|
}
|
|
388
|
+
lines.push('};');
|
|
352
389
|
|
|
353
|
-
|
|
390
|
+
// Export all cluster classes
|
|
391
|
+
for (const cluster of clusters) {
|
|
392
|
+
const interfaceName = toInterfaceName(cluster);
|
|
393
|
+
const exportName = cluster.exportName || interfaceName;
|
|
394
|
+
lines.push(`export const ${exportName}: {`);
|
|
395
|
+
lines.push(` new (...args: any[]): ${interfaceName};`);
|
|
396
|
+
lines.push(` ID: ${cluster.clusterId};`);
|
|
397
|
+
lines.push(` NAME: '${cluster.clusterName}';`);
|
|
398
|
+
lines.push(' ATTRIBUTES: unknown;');
|
|
399
|
+
lines.push(' COMMANDS: unknown;');
|
|
400
|
+
lines.push('};');
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
lines.push('');
|
|
404
|
+
lines.push('declare const _default: {');
|
|
405
|
+
lines.push(' ZCLNode: typeof ZCLNode;');
|
|
406
|
+
lines.push(' CLUSTER: typeof CLUSTER;');
|
|
407
|
+
for (const cluster of clusters) {
|
|
408
|
+
const exportName = cluster.exportName || toInterfaceName(cluster);
|
|
409
|
+
lines.push(` ${exportName}: typeof ${exportName};`);
|
|
410
|
+
}
|
|
411
|
+
lines.push('};');
|
|
412
|
+
lines.push('export default _default;');
|
|
354
413
|
|
|
355
414
|
return lines.join('\n');
|
|
356
415
|
}
|
|
@@ -381,8 +440,16 @@ function main() {
|
|
|
381
440
|
// Sort clusters alphabetically
|
|
382
441
|
clusters.sort((a, b) => a.clusterName.localeCompare(b.clusterName));
|
|
383
442
|
|
|
443
|
+
const clusterDefinitions = Object.entries(clustersModule.CLUSTER)
|
|
444
|
+
.map(([constantName, value]) => ({
|
|
445
|
+
constantName,
|
|
446
|
+
clusterId: value.ID,
|
|
447
|
+
clusterName: value.NAME,
|
|
448
|
+
}))
|
|
449
|
+
.sort((a, b) => a.constantName.localeCompare(b.constantName));
|
|
450
|
+
|
|
384
451
|
console.log(`\nGenerating ${OUTPUT_FILE}...`);
|
|
385
|
-
const output = generateTypesFile(clusters);
|
|
452
|
+
const output = generateTypesFile(clusters, clusterDefinitions);
|
|
386
453
|
fs.writeFileSync(OUTPUT_FILE, output);
|
|
387
454
|
|
|
388
455
|
console.log(`Done! Generated types for ${clusters.length} clusters.`);
|