amaran-light-cli 1.5.0 → 1.6.0

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 (86) hide show
  1. package/README.md +35 -0
  2. package/dist/__tests__/cctUtil.test.js +18 -1
  3. package/dist/__tests__/cctUtil.test.js.map +1 -1
  4. package/dist/__tests__/lightControl.test.js +259 -0
  5. package/dist/__tests__/lightControl.test.js.map +1 -1
  6. package/dist/commands/__tests__/newCommands.test.d.ts +2 -0
  7. package/dist/commands/__tests__/newCommands.test.d.ts.map +1 -0
  8. package/dist/commands/__tests__/newCommands.test.js +195 -0
  9. package/dist/commands/__tests__/newCommands.test.js.map +1 -0
  10. package/dist/commands/daylightSimulation/graphSchedule.js +1 -1
  11. package/dist/commands/daylightSimulation/graphSchedule.js.map +1 -1
  12. package/dist/commands/deviceControl/effect.d.ts +5 -0
  13. package/dist/commands/deviceControl/effect.d.ts.map +1 -0
  14. package/dist/commands/deviceControl/effect.js +172 -0
  15. package/dist/commands/deviceControl/effect.js.map +1 -0
  16. package/dist/commands/deviceControl/fan.d.ts +5 -0
  17. package/dist/commands/deviceControl/fan.d.ts.map +1 -0
  18. package/dist/commands/deviceControl/fan.js +105 -0
  19. package/dist/commands/deviceControl/fan.js.map +1 -0
  20. package/dist/commands/deviceControl/firmware.d.ts +5 -0
  21. package/dist/commands/deviceControl/firmware.d.ts.map +1 -0
  22. package/dist/commands/deviceControl/firmware.js +68 -0
  23. package/dist/commands/deviceControl/firmware.js.map +1 -0
  24. package/dist/commands/deviceControl/group.d.ts +5 -0
  25. package/dist/commands/deviceControl/group.d.ts.map +1 -0
  26. package/dist/commands/deviceControl/group.js +101 -0
  27. package/dist/commands/deviceControl/group.js.map +1 -0
  28. package/dist/commands/deviceControl/info.d.ts +5 -0
  29. package/dist/commands/deviceControl/info.d.ts.map +1 -0
  30. package/dist/commands/deviceControl/info.js +57 -0
  31. package/dist/commands/deviceControl/info.js.map +1 -0
  32. package/dist/commands/deviceControl/preset.d.ts +5 -0
  33. package/dist/commands/deviceControl/preset.d.ts.map +1 -0
  34. package/dist/commands/deviceControl/preset.js +55 -0
  35. package/dist/commands/deviceControl/preset.js.map +1 -0
  36. package/dist/commands/deviceControl/quickshot.d.ts +5 -0
  37. package/dist/commands/deviceControl/quickshot.d.ts.map +1 -0
  38. package/dist/commands/deviceControl/quickshot.js +51 -0
  39. package/dist/commands/deviceControl/quickshot.js.map +1 -0
  40. package/dist/commands/deviceControl/scene.d.ts +5 -0
  41. package/dist/commands/deviceControl/scene.d.ts.map +1 -0
  42. package/dist/commands/deviceControl/scene.js +101 -0
  43. package/dist/commands/deviceControl/scene.js.map +1 -0
  44. package/dist/commands.d.ts.map +1 -1
  45. package/dist/commands.js +17 -0
  46. package/dist/commands.js.map +1 -1
  47. package/dist/daylightSimulation/cctUtil.d.ts.map +1 -1
  48. package/dist/daylightSimulation/cctUtil.js +51 -23
  49. package/dist/daylightSimulation/cctUtil.js.map +1 -1
  50. package/dist/daylightSimulation/constants.d.ts +1 -0
  51. package/dist/daylightSimulation/constants.d.ts.map +1 -1
  52. package/dist/daylightSimulation/constants.js +1 -0
  53. package/dist/daylightSimulation/constants.js.map +1 -1
  54. package/dist/daylightSimulation/curves/realistic.d.ts +6 -6
  55. package/dist/daylightSimulation/curves/realistic.d.ts.map +1 -1
  56. package/dist/daylightSimulation/curves/realistic.js +6 -6
  57. package/dist/daylightSimulation/curves/realistic.js.map +1 -1
  58. package/dist/daylightSimulation/graphSchedule.d.ts +1 -1
  59. package/dist/daylightSimulation/graphSchedule.d.ts.map +1 -1
  60. package/dist/daylightSimulation/graphSchedule.js +27 -5
  61. package/dist/daylightSimulation/graphSchedule.js.map +1 -1
  62. package/dist/daylightSimulation/scheduleMaker.d.ts +2 -5
  63. package/dist/daylightSimulation/scheduleMaker.d.ts.map +1 -1
  64. package/dist/daylightSimulation/scheduleMaker.js.map +1 -1
  65. package/dist/daylightSimulation/textSchedule.d.ts.map +1 -1
  66. package/dist/daylightSimulation/textSchedule.js +2 -2
  67. package/dist/daylightSimulation/textSchedule.js.map +1 -1
  68. package/dist/daylightSimulation/types.d.ts +1 -0
  69. package/dist/daylightSimulation/types.d.ts.map +1 -1
  70. package/dist/daylightSimulation/types.js.map +1 -1
  71. package/dist/deviceControl/discovery.d.ts.map +1 -1
  72. package/dist/deviceControl/discovery.js +0 -2
  73. package/dist/deviceControl/discovery.js.map +1 -1
  74. package/dist/deviceControl/lightControl.d.ts +67 -78
  75. package/dist/deviceControl/lightControl.d.ts.map +1 -1
  76. package/dist/deviceControl/lightControl.js +292 -203
  77. package/dist/deviceControl/lightControl.js.map +1 -1
  78. package/dist/deviceControl/types.d.ts +18 -0
  79. package/dist/deviceControl/types.d.ts.map +1 -1
  80. package/dist/test/MockLightServer.d.ts.map +1 -1
  81. package/dist/test/MockLightServer.js +134 -12
  82. package/dist/test/MockLightServer.js.map +1 -1
  83. package/package.json +8 -7
  84. package/scripts/extract-api.ts +158 -0
  85. package/scripts/extract-usage.ts +199 -0
  86. package/scripts/release.js +9 -9
@@ -0,0 +1,199 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as cheerio from 'cheerio';
4
+
5
+ const HTML_PATH = path.resolve('docs/howto-extract.html');
6
+ const OUTPUT_PATH = path.resolve('docs/USAGE_GUIDE.md');
7
+
8
+ function extractCode(
9
+ $: cheerio.CheerioAPI,
10
+ codeContainer: cheerio.Cheerio<any>
11
+ ): { lang: string; code: string; title?: string } {
12
+ let lang = 'text';
13
+ const classes = codeContainer.attr('class') || '';
14
+ const langMatch = classes.match(/language-(\w+)/);
15
+ if (langMatch) {
16
+ lang = langMatch[1];
17
+ }
18
+
19
+ const title = codeContainer.find('.codeBlockTitle_Ktv7').text().trim();
20
+
21
+ let codeText = '';
22
+ // Check if it's structured with token-lines (Docusaurus)
23
+ const lines = codeContainer.find('.token-line');
24
+ if (lines.length) {
25
+ lines.each((_i, el) => {
26
+ codeText += `${$(el as any)
27
+ .text()
28
+ .trim()}\n`;
29
+ });
30
+ } else {
31
+ codeText = codeContainer.find('code').text().trim() || codeContainer.text().trim();
32
+ }
33
+
34
+ if (lang === 'json') {
35
+ try {
36
+ codeText = JSON.stringify(JSON.parse(codeText), null, 2);
37
+ } catch (_e) {
38
+ // Keep as is
39
+ }
40
+ }
41
+
42
+ return { lang, code: codeText.trim(), title: title || undefined };
43
+ }
44
+
45
+ function extractTable($: cheerio.CheerioAPI, table: cheerio.Cheerio<any>): string {
46
+ const headers: string[] = [];
47
+ table.find('thead th').each((_i, el) => {
48
+ headers.push(
49
+ $(el as any)
50
+ .text()
51
+ .trim()
52
+ );
53
+ });
54
+
55
+ const rows: string[][] = [];
56
+ table.find('tbody tr').each((_i, tr) => {
57
+ const row: string[] = [];
58
+ $(tr as any)
59
+ .find('td')
60
+ .each((_j, td) => {
61
+ row.push(
62
+ $(td as any)
63
+ .text()
64
+ .trim()
65
+ .replace(/\n/g, ' ')
66
+ );
67
+ });
68
+ rows.push(row);
69
+ });
70
+
71
+ if (headers.length === 0 && rows.length > 0) {
72
+ // Handle cases where there might not be <thead> but just <tr> in <tbody> as headers
73
+ // Not common in Docusaurus but good to have
74
+ return '';
75
+ }
76
+ if (headers.length === 0) return '';
77
+
78
+ let md = `| ${headers.join(' | ')} |\n`;
79
+ md += `| ${headers.map(() => '---').join(' | ')} |\n`;
80
+ rows.forEach((row) => {
81
+ md += `| ${row.join(' | ')} |\n`;
82
+ });
83
+
84
+ return md;
85
+ }
86
+
87
+ async function run() {
88
+ if (!fs.existsSync(HTML_PATH)) {
89
+ console.error(`Error: ${HTML_PATH} not found.`);
90
+ process.exit(1);
91
+ }
92
+
93
+ const html = fs.readFileSync(HTML_PATH, 'utf-8');
94
+ const $ = cheerio.load(html);
95
+
96
+ let markdown = '';
97
+ const seenContent = new Set<string>();
98
+
99
+ // Extract H1
100
+ const h1 = $('h1').first().text().trim();
101
+ if (h1) {
102
+ markdown += `# ${h1}\n\n`;
103
+ }
104
+
105
+ // Find the main article or content area
106
+ const content = $('article');
107
+
108
+ // We want to iterate through the content children
109
+ content
110
+ .find('.theme-doc-markdown')
111
+ .children()
112
+ .each((_i, el) => {
113
+ const $el = $(el as any);
114
+ const tagName = (el as any).tagName ? (el as any).tagName.toLowerCase() : '';
115
+
116
+ if (/^h[1-6]$/.test(tagName)) {
117
+ const level = tagName[1];
118
+ const text = $el.text().replace('​', '').trim(); // Remove zero-width spaces
119
+ if (text && !seenContent.has(`H${level}:${text}`)) {
120
+ markdown += `${'#'.repeat(parseInt(level, 10))} ${text}\n\n`;
121
+ seenContent.add(`H${level}:${text}`);
122
+ }
123
+ } else if (tagName === 'p' || tagName === 'blockquote' || tagName === 'b' || tagName === 'i') {
124
+ const text = $el.text().trim();
125
+ if (text && !seenContent.has(text)) {
126
+ if (tagName === 'blockquote' || tagName === 'b') {
127
+ markdown += `> ${text}\n\n`;
128
+ } else {
129
+ markdown += `${text}\n\n`;
130
+ }
131
+ seenContent.add(text);
132
+ }
133
+ } else if (tagName === 'ul' || tagName === 'ol') {
134
+ let listMd = '';
135
+ $el.children('li').each((j, li) => {
136
+ const prefix = tagName === 'ul' ? '*' : `${j + 1}.`;
137
+ const $li = $(li);
138
+ // Handle content of LI, which might contain nested ULs
139
+ let liText = '';
140
+ $li.contents().each((_k, node) => {
141
+ if ((node as any).type === 'text') {
142
+ liText += $(node as any)
143
+ .text()
144
+ .trim();
145
+ } else if (
146
+ (node as any).type === 'tag' &&
147
+ ((node as any).tagName === 'ul' || (node as any).tagName === 'ol')
148
+ ) {
149
+ // Skip nested lists here, we will handle them if we want deep nesting,
150
+ // but for now let's just avoid double printing.
151
+ // Actually, let's just get the text of the LI but excluding nested UL/OL for the prefix line
152
+ } else {
153
+ liText += $(node as any)
154
+ .text()
155
+ .trim();
156
+ }
157
+ });
158
+ listMd += `${prefix} ${liText.trim()}\n`;
159
+
160
+ // If there's a nested list, let's indent it
161
+ $li.children('ul, ol').each((_k, nested) => {
162
+ const $nested = $(nested as any);
163
+ const nestedTag = (nested as any).tagName ? (nested as any).tagName.toLowerCase() : '';
164
+ $nested.children('li').each((l, nli) => {
165
+ const nPrefix = nestedTag === 'ul' ? ' *' : ` ${l + 1}.`;
166
+ listMd += `${nPrefix} ${$(nli as any)
167
+ .text()
168
+ .trim()}\n`;
169
+ });
170
+ });
171
+ });
172
+ if (listMd && !seenContent.has(listMd)) {
173
+ markdown += `${listMd}\n`;
174
+ seenContent.add(listMd);
175
+ }
176
+ } else if (tagName === 'table') {
177
+ const tableMd = extractTable($, $el);
178
+ if (tableMd && !seenContent.has(tableMd)) {
179
+ markdown += `${tableMd}\n\n`;
180
+ seenContent.add(tableMd);
181
+ }
182
+ } else if ($el.hasClass('codeBlockContainer_Ckt0')) {
183
+ const { lang, code, title } = extractCode($, $el);
184
+ const codeBlock = `${title ? `**${title}**\n` : ''}\`\`\`${lang}\n${code}\n\`\`\`\n\n`;
185
+ if (code && !seenContent.has(codeBlock)) {
186
+ markdown += codeBlock;
187
+ seenContent.add(codeBlock);
188
+ }
189
+ }
190
+ });
191
+
192
+ fs.writeFileSync(OUTPUT_PATH, `${markdown.trim()}\n`);
193
+ console.log(`Successfully extracted Usage Guide to ${OUTPUT_PATH}`);
194
+ }
195
+
196
+ run().catch((err) => {
197
+ console.error(err);
198
+ process.exit(1);
199
+ });
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { execSync } from 'node:child_process';
3
3
  import fs from 'node:fs';
4
- import readline from 'node:readline';
5
4
  import path from 'node:path';
5
+ import readline from 'node:readline';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  const __filename = fileURLToPath(import.meta.url);
@@ -10,7 +10,7 @@ const __dirname = path.dirname(__filename);
10
10
 
11
11
  const rl = readline.createInterface({
12
12
  input: process.stdin,
13
- output: process.stdout
13
+ output: process.stdout,
14
14
  });
15
15
 
16
16
  const askQuestion = (question) => {
@@ -21,7 +21,7 @@ const runCommand = (command) => {
21
21
  console.log(`Running: ${command}`);
22
22
  try {
23
23
  execSync(command, { stdio: 'inherit' });
24
- } catch (error) {
24
+ } catch (_error) {
25
25
  console.error(`Error executing command: ${command}`);
26
26
  process.exit(1);
27
27
  }
@@ -30,16 +30,16 @@ const runCommand = (command) => {
30
30
  const updateChangelog = async (version, releaseNotes) => {
31
31
  const changelogPath = path.join(__dirname, '../docs/CHANGELOG.md');
32
32
  let changelog = '';
33
-
33
+
34
34
  try {
35
35
  changelog = fs.readFileSync(changelogPath, 'utf8');
36
- } catch (error) {
36
+ } catch (_error) {
37
37
  console.log('No existing CHANGELOG.md found, creating a new one.');
38
38
  }
39
39
 
40
40
  const today = new Date().toISOString().split('T')[0];
41
41
  const newEntry = `## [${version}] - ${today}\n\n${releaseNotes}\n\n`;
42
-
42
+
43
43
  fs.writeFileSync(changelogPath, newEntry + changelog);
44
44
  console.log('CHANGELOG.md has been updated');
45
45
  };
@@ -63,7 +63,7 @@ const main = async () => {
63
63
  // Ask for release notes
64
64
  console.log('\nEnter release notes (press Enter then Ctrl+D when done):');
65
65
  let releaseNotes = '';
66
-
66
+
67
67
  const lines = [];
68
68
  for await (const line of rl) {
69
69
  lines.push(line);
@@ -76,7 +76,7 @@ const main = async () => {
76
76
 
77
77
  // Update package.json version
78
78
  packageJson.version = newVersion;
79
- fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2) + '\n');
79
+ fs.writeFileSync('package.json', `${JSON.stringify(packageJson, null, 2)}\n`);
80
80
  console.log('Updated package.json version');
81
81
 
82
82
  // Update CHANGELOG.md
@@ -94,7 +94,7 @@ const main = async () => {
94
94
  try {
95
95
  runCommand(`gh release create v${newVersion} --notes "${releaseNotes}"`);
96
96
  console.log(`\nšŸŽ‰ Successfully created release v${newVersion} on GitHub!`);
97
- } catch (error) {
97
+ } catch (_error) {
98
98
  console.warn('\nGitHub CLI not found or failed to create release.');
99
99
  console.log('Please create the release manually at: https://github.com/theontho/amaran-cli/releases/new');
100
100
  }