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.
- package/README.md +35 -0
- package/dist/__tests__/cctUtil.test.js +18 -1
- package/dist/__tests__/cctUtil.test.js.map +1 -1
- package/dist/__tests__/lightControl.test.js +259 -0
- package/dist/__tests__/lightControl.test.js.map +1 -1
- package/dist/commands/__tests__/newCommands.test.d.ts +2 -0
- package/dist/commands/__tests__/newCommands.test.d.ts.map +1 -0
- package/dist/commands/__tests__/newCommands.test.js +195 -0
- package/dist/commands/__tests__/newCommands.test.js.map +1 -0
- package/dist/commands/daylightSimulation/graphSchedule.js +1 -1
- package/dist/commands/daylightSimulation/graphSchedule.js.map +1 -1
- package/dist/commands/deviceControl/effect.d.ts +5 -0
- package/dist/commands/deviceControl/effect.d.ts.map +1 -0
- package/dist/commands/deviceControl/effect.js +172 -0
- package/dist/commands/deviceControl/effect.js.map +1 -0
- package/dist/commands/deviceControl/fan.d.ts +5 -0
- package/dist/commands/deviceControl/fan.d.ts.map +1 -0
- package/dist/commands/deviceControl/fan.js +105 -0
- package/dist/commands/deviceControl/fan.js.map +1 -0
- package/dist/commands/deviceControl/firmware.d.ts +5 -0
- package/dist/commands/deviceControl/firmware.d.ts.map +1 -0
- package/dist/commands/deviceControl/firmware.js +68 -0
- package/dist/commands/deviceControl/firmware.js.map +1 -0
- package/dist/commands/deviceControl/group.d.ts +5 -0
- package/dist/commands/deviceControl/group.d.ts.map +1 -0
- package/dist/commands/deviceControl/group.js +101 -0
- package/dist/commands/deviceControl/group.js.map +1 -0
- package/dist/commands/deviceControl/info.d.ts +5 -0
- package/dist/commands/deviceControl/info.d.ts.map +1 -0
- package/dist/commands/deviceControl/info.js +57 -0
- package/dist/commands/deviceControl/info.js.map +1 -0
- package/dist/commands/deviceControl/preset.d.ts +5 -0
- package/dist/commands/deviceControl/preset.d.ts.map +1 -0
- package/dist/commands/deviceControl/preset.js +55 -0
- package/dist/commands/deviceControl/preset.js.map +1 -0
- package/dist/commands/deviceControl/quickshot.d.ts +5 -0
- package/dist/commands/deviceControl/quickshot.d.ts.map +1 -0
- package/dist/commands/deviceControl/quickshot.js +51 -0
- package/dist/commands/deviceControl/quickshot.js.map +1 -0
- package/dist/commands/deviceControl/scene.d.ts +5 -0
- package/dist/commands/deviceControl/scene.d.ts.map +1 -0
- package/dist/commands/deviceControl/scene.js +101 -0
- package/dist/commands/deviceControl/scene.js.map +1 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +17 -0
- package/dist/commands.js.map +1 -1
- package/dist/daylightSimulation/cctUtil.d.ts.map +1 -1
- package/dist/daylightSimulation/cctUtil.js +51 -23
- package/dist/daylightSimulation/cctUtil.js.map +1 -1
- package/dist/daylightSimulation/constants.d.ts +1 -0
- package/dist/daylightSimulation/constants.d.ts.map +1 -1
- package/dist/daylightSimulation/constants.js +1 -0
- package/dist/daylightSimulation/constants.js.map +1 -1
- package/dist/daylightSimulation/curves/realistic.d.ts +6 -6
- package/dist/daylightSimulation/curves/realistic.d.ts.map +1 -1
- package/dist/daylightSimulation/curves/realistic.js +6 -6
- package/dist/daylightSimulation/curves/realistic.js.map +1 -1
- package/dist/daylightSimulation/graphSchedule.d.ts +1 -1
- package/dist/daylightSimulation/graphSchedule.d.ts.map +1 -1
- package/dist/daylightSimulation/graphSchedule.js +27 -5
- package/dist/daylightSimulation/graphSchedule.js.map +1 -1
- package/dist/daylightSimulation/scheduleMaker.d.ts +2 -5
- package/dist/daylightSimulation/scheduleMaker.d.ts.map +1 -1
- package/dist/daylightSimulation/scheduleMaker.js.map +1 -1
- package/dist/daylightSimulation/textSchedule.d.ts.map +1 -1
- package/dist/daylightSimulation/textSchedule.js +2 -2
- package/dist/daylightSimulation/textSchedule.js.map +1 -1
- package/dist/daylightSimulation/types.d.ts +1 -0
- package/dist/daylightSimulation/types.d.ts.map +1 -1
- package/dist/daylightSimulation/types.js.map +1 -1
- package/dist/deviceControl/discovery.d.ts.map +1 -1
- package/dist/deviceControl/discovery.js +0 -2
- package/dist/deviceControl/discovery.js.map +1 -1
- package/dist/deviceControl/lightControl.d.ts +67 -78
- package/dist/deviceControl/lightControl.d.ts.map +1 -1
- package/dist/deviceControl/lightControl.js +292 -203
- package/dist/deviceControl/lightControl.js.map +1 -1
- package/dist/deviceControl/types.d.ts +18 -0
- package/dist/deviceControl/types.d.ts.map +1 -1
- package/dist/test/MockLightServer.d.ts.map +1 -1
- package/dist/test/MockLightServer.js +134 -12
- package/dist/test/MockLightServer.js.map +1 -1
- package/package.json +8 -7
- package/scripts/extract-api.ts +158 -0
- package/scripts/extract-usage.ts +199 -0
- 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
|
+
});
|
package/scripts/release.js
CHANGED
|
@@ -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 (
|
|
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 (
|
|
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)
|
|
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 (
|
|
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
|
}
|