xs-dev 1.6.0 → 1.7.1--canary.98a7cea.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/build/package.json +3 -5
- package/build/src/commands/doctor.js +22 -77
- package/build/src/commands/init.js +15 -104
- package/build/src/toolbox/doctor/index.js +73 -0
- package/build/src/toolbox/init/index.js +108 -0
- package/build/types/src/toolbox/doctor/index.d.ts +14 -0
- package/build/types/src/toolbox/init/index.d.ts +12 -0
- package/package.json +3 -5
- package/scripts/fix-liblzma-arm64.mjs +0 -37
package/build/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xs-dev",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1--canary.98a7cea.0",
|
|
4
4
|
"description": "CLI for automating the setup and usage of Moddable XS tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "build/types/types.d.ts",
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"#src/": "./src/"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
|
-
"postinstall": "node scripts/fix-liblzma-arm64.mjs",
|
|
23
22
|
"xs-dev": "tsx src/cli.ts",
|
|
24
23
|
"xs-dev:debug": "DEBUG=* tsx --trace-deprecation src/cli.ts",
|
|
25
24
|
"format": "prettier --write **/*.{js,ts,json}",
|
|
@@ -45,8 +44,7 @@
|
|
|
45
44
|
"build",
|
|
46
45
|
"LICENSE",
|
|
47
46
|
"README.md",
|
|
48
|
-
"docs"
|
|
49
|
-
"scripts"
|
|
47
|
+
"docs"
|
|
50
48
|
],
|
|
51
49
|
"license": "MIT",
|
|
52
50
|
"repository": {
|
|
@@ -68,7 +66,7 @@
|
|
|
68
66
|
"windows-shortcuts": "^0.1.6"
|
|
69
67
|
},
|
|
70
68
|
"optionalDependencies": {
|
|
71
|
-
"node-liblzma": "^
|
|
69
|
+
"node-liblzma": "^4.0.1"
|
|
72
70
|
},
|
|
73
71
|
"devDependencies": {
|
|
74
72
|
"@astrojs/starlight": "^0.37.7",
|
|
@@ -1,19 +1,5 @@
|
|
|
1
|
-
import os from 'node:os';
|
|
2
|
-
import { existsSync, statSync } from 'node:fs';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
1
|
import { buildCommand } from '@stricli/core';
|
|
5
|
-
import {
|
|
6
|
-
import { DEVICE_ALIAS } from '../toolbox/prompt/devices.js';
|
|
7
|
-
import { getModdableVersion, moddableExists, } from '../toolbox/setup/moddable.js';
|
|
8
|
-
import { sourceEnvironment, which } from '../toolbox/system/exec.js';
|
|
9
|
-
import { detectPython, getPythonVersion } from '../toolbox/system/python.js';
|
|
10
|
-
import { unwrapOr } from '../toolbox/system/errors.js';
|
|
11
|
-
function isDir(path) {
|
|
12
|
-
return existsSync(path) && statSync(path).isDirectory();
|
|
13
|
-
}
|
|
14
|
-
function isFile(path) {
|
|
15
|
-
return existsSync(path) && statSync(path).isFile();
|
|
16
|
-
}
|
|
2
|
+
import { gatherEnvironmentInfo } from '../toolbox/doctor/index.js';
|
|
17
3
|
function printTable(rows, write) {
|
|
18
4
|
const labelWidth = Math.max(...rows.map((r) => r[0]?.length ?? 0)) + 2;
|
|
19
5
|
for (const [label, value] of rows) {
|
|
@@ -26,79 +12,38 @@ const command = buildCommand({
|
|
|
26
12
|
const write = (s) => {
|
|
27
13
|
proc.stdout.write(s);
|
|
28
14
|
};
|
|
29
|
-
await
|
|
30
|
-
|
|
31
|
-
if (moddableExists()) {
|
|
32
|
-
supportedDevices.push(DEVICE_ALIAS[os.type().toLowerCase()]);
|
|
33
|
-
}
|
|
34
|
-
if (typeof process.env.IDF_PATH === 'string' &&
|
|
35
|
-
isDir(process.env.IDF_PATH)) {
|
|
36
|
-
supportedDevices.push('esp32');
|
|
37
|
-
}
|
|
38
|
-
if (typeof process.env.ESP_BASE === 'string' &&
|
|
39
|
-
isDir(process.env.ESP_BASE) &&
|
|
40
|
-
isDir(join(process.env.ESP_BASE, 'toolchain')) &&
|
|
41
|
-
isDir(join(process.env.ESP_BASE, 'ESP8266_RTOS_SDK')) &&
|
|
42
|
-
isDir(join(process.env.ESP_BASE, 'esp8266-2.3.0'))) {
|
|
43
|
-
supportedDevices.push('esp8266');
|
|
44
|
-
}
|
|
45
|
-
if ((process.env.PATH ?? '').includes('binaryen') &&
|
|
46
|
-
isDir(process.env.EMSDK ?? '') &&
|
|
47
|
-
isFile(process.env.EMSDK_NODE ?? '') &&
|
|
48
|
-
isFile(process.env.EMSDK_PYTHON ?? '')) {
|
|
49
|
-
supportedDevices.push('wasm');
|
|
50
|
-
}
|
|
51
|
-
if (typeof process.env.PICO_SDK_PATH === 'string' &&
|
|
52
|
-
isDir(process.env.PICO_SDK_PATH) &&
|
|
53
|
-
which('picotool') !== null &&
|
|
54
|
-
isFile(process.env.PIOASM ?? '')) {
|
|
55
|
-
supportedDevices.push('pico');
|
|
56
|
-
}
|
|
57
|
-
if (typeof process.env.NRF_ROOT === 'string' &&
|
|
58
|
-
isDir(process.env.NRF_ROOT) &&
|
|
59
|
-
((typeof process.env.NRF_SDK_DIR === 'string' &&
|
|
60
|
-
isDir(process.env.NRF_SDK_DIR)) ||
|
|
61
|
-
(typeof process.env.NRF52_SDK_PATH === 'string' &&
|
|
62
|
-
isDir(process.env.NRF52_SDK_PATH)))) {
|
|
63
|
-
supportedDevices.push('nrf52');
|
|
64
|
-
}
|
|
65
|
-
if (typeof process.env.ZEPHYR_BASE === 'string' &&
|
|
66
|
-
isDir(process.env.ZEPHYR_BASE)) {
|
|
67
|
-
supportedDevices.push('zephyr');
|
|
68
|
-
}
|
|
69
|
-
const pythonVersion = unwrapOr(await getPythonVersion(), 'Unavailable');
|
|
70
|
-
const pythonPath = which(detectPython() ?? '') ?? 'n/a';
|
|
71
|
-
const moddableVersion = unwrapOr(await getModdableVersion(), 'Not found');
|
|
72
|
-
const moddablePath = process.env.MODDABLE ?? 'n/a';
|
|
73
|
-
info('xs-dev environment info:\n');
|
|
15
|
+
const info = await gatherEnvironmentInfo(currentVersion);
|
|
16
|
+
write('xs-dev environment info:\n');
|
|
74
17
|
printTable([
|
|
75
|
-
['CLI Version',
|
|
76
|
-
['OS',
|
|
77
|
-
['Arch',
|
|
78
|
-
['Shell',
|
|
18
|
+
['CLI Version', info.cliVersion],
|
|
19
|
+
['OS', info.osType],
|
|
20
|
+
['Arch', info.arch],
|
|
21
|
+
['Shell', info.shell],
|
|
22
|
+
['NodeJS Version', `${info.nodeVersion} (${info.nodePath})`],
|
|
23
|
+
['Python Version', `${info.pythonVersion} (${info.pythonPath})`],
|
|
79
24
|
[
|
|
80
|
-
'
|
|
81
|
-
`${
|
|
25
|
+
'Moddable SDK Version',
|
|
26
|
+
`${info.moddableVersion} (${info.moddablePath})`,
|
|
82
27
|
],
|
|
83
|
-
['Python Version', `${pythonVersion} (${pythonPath})`],
|
|
84
|
-
['Moddable SDK Version', `${moddableVersion} (${moddablePath})`],
|
|
85
28
|
[
|
|
86
29
|
'Supported target devices',
|
|
87
|
-
supportedDevices.length > 0
|
|
30
|
+
info.supportedDevices.length > 0
|
|
31
|
+
? info.supportedDevices.join(', ')
|
|
32
|
+
: 'None',
|
|
88
33
|
],
|
|
89
|
-
...(supportedDevices.includes('esp32')
|
|
34
|
+
...(info.supportedDevices.includes('esp32')
|
|
90
35
|
? [['ESP32 IDF Directory', String(process.env.IDF_PATH)]]
|
|
91
36
|
: []),
|
|
92
|
-
...(supportedDevices.includes('esp8266')
|
|
37
|
+
...(info.supportedDevices.includes('esp8266')
|
|
93
38
|
? [['ESP8266 Base Directory', String(process.env.ESP_BASE)]]
|
|
94
39
|
: []),
|
|
95
|
-
...(supportedDevices.includes('wasm')
|
|
40
|
+
...(info.supportedDevices.includes('wasm')
|
|
96
41
|
? [['Wasm EMSDK Directory', String(process.env.EMSDK)]]
|
|
97
42
|
: []),
|
|
98
|
-
...(supportedDevices.includes('pico')
|
|
43
|
+
...(info.supportedDevices.includes('pico')
|
|
99
44
|
? [['Pico SDK Directory', String(process.env.PICO_SDK_PATH)]]
|
|
100
45
|
: []),
|
|
101
|
-
...(supportedDevices.includes('nrf52')
|
|
46
|
+
...(info.supportedDevices.includes('nrf52')
|
|
102
47
|
? [
|
|
103
48
|
[
|
|
104
49
|
'NRF52 SDK Directory',
|
|
@@ -106,11 +51,11 @@ const command = buildCommand({
|
|
|
106
51
|
],
|
|
107
52
|
]
|
|
108
53
|
: []),
|
|
109
|
-
...(supportedDevices.includes('zephyr')
|
|
54
|
+
...(info.supportedDevices.includes('zephyr')
|
|
110
55
|
? [['Zephyr SDK Directory', String(process.env.ZEPHYR_BASE)]]
|
|
111
56
|
: []),
|
|
112
57
|
], write);
|
|
113
|
-
|
|
58
|
+
write(`\nIf this is related to an error when using the CLI, please create an issue at "https://github.com/hipsterbrown/xs-dev/issues/new" with the above info.\n`);
|
|
114
59
|
},
|
|
115
60
|
docs: {
|
|
116
61
|
brief: 'Display the current environment setup information, including valid target devices.',
|
|
@@ -120,4 +65,4 @@ const command = buildCommand({
|
|
|
120
65
|
},
|
|
121
66
|
});
|
|
122
67
|
export default command;
|
|
123
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
68
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9jdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL2RvY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBRTVDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDRCQUE0QixDQUFBO0FBRWxFLFNBQVMsVUFBVSxDQUFDLElBQWdCLEVBQUUsS0FBMEI7SUFDOUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDdEUsS0FBSyxNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ2xDLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxLQUFLLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQTtJQUNoRSxDQUFDO0FBQ0gsQ0FBQztBQUVELE1BQU0sT0FBTyxHQUFHLFlBQVksQ0FBQztJQUMzQixLQUFLLENBQUMsSUFBSTtRQUNSLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQTtRQUM5QyxNQUFNLEtBQUssR0FBRyxDQUFDLENBQVMsRUFBUSxFQUFFO1lBQ2hDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ3RCLENBQUMsQ0FBQTtRQUVELE1BQU0sSUFBSSxHQUFHLE1BQU0scUJBQXFCLENBQUMsY0FBYyxDQUFDLENBQUE7UUFFeEQsS0FBSyxDQUFDLDRCQUE0QixDQUFDLENBQUE7UUFDbkMsVUFBVSxD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
|
|
@@ -1,113 +1,24 @@
|
|
|
1
|
-
import { existsSync, statSync, mkdirSync, cpSync, readdirSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
1
|
import { buildCommand } from '@stricli/core';
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import * as output from '../lib/output.js';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { handleEvent } from '../lib/renderer.js';
|
|
4
|
+
import { createInteractivePrompter, createNonInteractivePrompter, isInteractive, } from '../lib/prompter.js';
|
|
5
|
+
import initProject from '../toolbox/init/index.js';
|
|
9
6
|
const command = buildCommand({
|
|
10
7
|
docs: {
|
|
11
8
|
brief: 'Scaffold a new Moddable XS project',
|
|
12
9
|
},
|
|
13
10
|
async func(flags, projectName) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
statSync(projectName).isDirectory()) {
|
|
19
|
-
output.warn(`Directory called ${projectName} already exists. Please pass the --overwrite flag to replace an existing project.`);
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
await sourceEnvironment();
|
|
23
|
-
if (example !== undefined || listExamples) {
|
|
24
|
-
// find example project
|
|
25
|
-
const exampleProjectPath = join(String(process.env.MODDABLE), 'examples');
|
|
26
|
-
const exampleChildren = existsSync(exampleProjectPath) &&
|
|
27
|
-
statSync(exampleProjectPath).isDirectory()
|
|
28
|
-
? readdirSync(exampleProjectPath).map((entry) => buildTree(join(exampleProjectPath, entry), entry))
|
|
29
|
-
: undefined;
|
|
30
|
-
const choices = exampleChildren !== undefined
|
|
31
|
-
? exampleChildren
|
|
32
|
-
.map((example) => collectChoicesFromTree(example))
|
|
33
|
-
.flat()
|
|
34
|
-
: [];
|
|
35
|
-
let selectedExample = choices.find((choice) => choice === example);
|
|
36
|
-
if (listExamples || selectedExample === undefined) {
|
|
37
|
-
const filteredChoices = choices.filter((choice) => choice.includes(String(example)));
|
|
38
|
-
selectedExample = await select({
|
|
39
|
-
message: 'Here are the available examples templates:',
|
|
40
|
-
choices: (filteredChoices.length > 0
|
|
41
|
-
? filteredChoices
|
|
42
|
-
: choices).map((c) => ({
|
|
43
|
-
name: c,
|
|
44
|
-
value: c,
|
|
45
|
-
})),
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
// copy files into new project directory
|
|
49
|
-
if (selectedExample !== '' && selectedExample !== undefined) {
|
|
50
|
-
const selectedExamplePath = join(exampleProjectPath, selectedExample);
|
|
51
|
-
output.info(`Generating project directory from ${selectedExample}`);
|
|
52
|
-
cpSync(selectedExamplePath, projectName, {
|
|
53
|
-
recursive: true,
|
|
54
|
-
force: overwrite,
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
output.warn('Please select an example template to use.');
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
output.info(`Generating Moddable project: ${projectName}`);
|
|
64
|
-
mkdirSync(projectName, { recursive: true });
|
|
65
|
-
const includes = [
|
|
66
|
-
io
|
|
67
|
-
? [
|
|
68
|
-
'"$(MODDABLE)/modules/io/manifest.json"',
|
|
69
|
-
'"$(MODDABLE)/examples/manifest_net.json"',
|
|
70
|
-
]
|
|
71
|
-
: '"$(MODDABLE)/examples/manifest_base.json"',
|
|
72
|
-
typescript && '"$(MODDABLE)/examples/manifest_typings.json"',
|
|
73
|
-
]
|
|
74
|
-
.filter(Boolean)
|
|
75
|
-
.flat()
|
|
76
|
-
.join(',\n\t');
|
|
77
|
-
const defines = asyncMain
|
|
78
|
-
? ',\n defines: {\n async_main: 1\n }'
|
|
79
|
-
: '';
|
|
80
|
-
const { createManifest, createMain, createPackageJSON, createTSConfig, } = await import('../toolbox/init/templates.js');
|
|
81
|
-
const fileTasks = [
|
|
82
|
-
createMain({
|
|
83
|
-
target: `${projectName}/main.${typescript ? 'ts' : 'js'}`,
|
|
84
|
-
legacy: manifest,
|
|
85
|
-
}),
|
|
86
|
-
];
|
|
87
|
-
if (manifest) {
|
|
88
|
-
fileTasks.push(createManifest({
|
|
89
|
-
target: `${projectName}/manifest.json`,
|
|
90
|
-
includes,
|
|
91
|
-
defines,
|
|
92
|
-
}));
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
fileTasks.push(createPackageJSON({
|
|
96
|
-
target: `${projectName}/package.json`,
|
|
97
|
-
projectName,
|
|
98
|
-
typescript,
|
|
99
|
-
io,
|
|
100
|
-
}));
|
|
101
|
-
}
|
|
102
|
-
if (typescript) {
|
|
103
|
-
fileTasks.push(createTSConfig({ target: `${projectName}/tsconfig.json` }));
|
|
104
|
-
}
|
|
105
|
-
await Promise.all(fileTasks);
|
|
106
|
-
}
|
|
107
|
-
this.process.stdout.write(`Run the project using: cd ${projectName} && xs-dev run\n`);
|
|
11
|
+
if (projectName === undefined) {
|
|
12
|
+
// output.warn equivalent — use process.stdout since no spinner yet
|
|
13
|
+
this.process.stdout.write('Name is required to generate project: xs-dev init my-project-name\n');
|
|
14
|
+
return;
|
|
108
15
|
}
|
|
109
|
-
|
|
110
|
-
|
|
16
|
+
const prompter = isInteractive()
|
|
17
|
+
? createInteractivePrompter()
|
|
18
|
+
: createNonInteractivePrompter();
|
|
19
|
+
const spinner = ora();
|
|
20
|
+
for await (const event of initProject(projectName, flags, prompter)) {
|
|
21
|
+
handleEvent(event, spinner);
|
|
111
22
|
}
|
|
112
23
|
},
|
|
113
24
|
parameters: {
|
|
@@ -162,4 +73,4 @@ const command = buildCommand({
|
|
|
162
73
|
},
|
|
163
74
|
});
|
|
164
75
|
export default command;
|
|
165
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
76
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy9pbml0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDNUMsT0FBTyxHQUFHLE1BQU0sS0FBSyxDQUFBO0FBRXJCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUNoRCxPQUFPLEVBQ0wseUJBQXlCLEVBQ3pCLDRCQUE0QixFQUM1QixhQUFhLEdBQ2QsTUFBTSxvQkFBb0IsQ0FBQTtBQUMzQixPQUFPLFdBQVcsTUFBTSwwQkFBMEIsQ0FBQTtBQUdsRCxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUM7SUFDM0IsSUFBSSxFQUFFO1FBQ0osS0FBSyxFQUFFLG9DQUFvQztLQUM1QztJQUNELEtBQUssQ0FBQyxJQUFJLENBQXFCLEtBQWtCLEVBQUUsV0FBbUI7UUFDcEUsSUFBSSxXQUFXLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDOUIsbUVBQW1FO1lBQ25FLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FDdkIscUVBQXFFLENBQ3RFLENBQUE7WUFDRCxPQUFNO1FBQ1IsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLGFBQWEsRUFBRTtZQUM5QixDQUFDLENBQUMseUJBQXlCLEVBQUU7WUFDN0IsQ0FBQyxDQUFDLDRCQUE0QixFQUFFLENBQUE7UUFFbEMsTUFBTSxPQUFPLEdBQUcsR0FBRyxFQUFFLENBQUE7UUFDckIsSUFBSSxLQUFLLEVBQUUsTUFBTSxLQUFLLElBQUksV0FBVyxDQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUNwRSxXQUFXLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBQzdCLENBQUM7SUFDSCxDQUFDO0lBQ0QsVUFBVSxFQUFFO1FBQ1YsVUFBVSxFQUFFO1lBQ1YsSUFBSSxFQUFFLE9BQU87WUFDYixVQUFVLEVBQUU7Z0JBQ1Y7b0JBQ0UsV0FBVyxFQUFFLGFBQWE7b0JBQzFCLEtBQUssRUFBRSxNQUFNO29CQUNiLEtBQUssRUFBRSx5Q0FBeUM7aUJBQ2pEO2FBQ0Y7U0FDRjtRQUNELEtBQUssRUFBRTtZQUNMLFVBQVUsRUFBRTtnQkFDVixJQUFJLEVBQUUsU0FBUztnQkFDZixLQUFLLEVBQ0gsc0VBQXNFO2dCQUN4RSxRQUFRLEVBQUUsSUFBSTthQUNmO1lBQ0QsRUFBRSxFQUFFO2dCQUNGLElBQUksRUFBRSxTQUFTO2dCQUNmLEtBQUssRUFDSCwwRUFBMEU7Z0JBQzVFLFFBQVEsRUFBRSxJQUFJO2FBQ2Y7WUFDRCxRQUFRLEVBQUU7Z0JBQ1IsSUFBSSxFQUFFLFNBQVM7Z0JBQ2YsS0FBSyxFQUNILDZGQUE2RjtnQkFDL0YsUUFBUSxFQUFFLElBQUk7YUFDZjtZQUNELE9BQU8sRUFBRTtnQkFDUCxJQUFJLEVBQUUsUUFBUTtnQkFDZCxLQUFLLEVBQ0gsc0lBQXNJO2dCQUN4SSxLQUFLLEVBQUUsTUFBTTtnQkFDYixRQUFRLEVBQUUsSUFBSTthQUNmO1lBQ0QsZUFBZSxFQUFFO2dCQUNmLElBQUksRUFBRSxTQUFTO2dCQUNmLEtBQUssRUFBRSxpREFBaUQ7Z0JBQ3hELFFBQVEsRUFBRSxJQUFJO2FBQ2Y7WUFDRCxTQUFTLEVBQUU7Z0JBQ1QsSUFBSSxFQUFFLFNBQVM7Z0JBQ2YsS0FBSyxFQUNILGlHQUFpRztnQkFDbkcsUUFBUSxFQUFFLElBQUk7YUFDZjtZQUNELFNBQVMsRUFBRTtnQkFDVCxJQUFJLEVBQUUsU0FBUztnQkFDZixLQUFLLEVBQ0gsMkVBQTJFO2dCQUM3RSxRQUFRLEVBQUUsSUFBSTthQUNmO1NBQ0Y7S0FDRjtDQUNGLENBQUMsQ0FBQTtBQUVGLGVBQWUsT0FBTyxDQUFBIn0=
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import { existsSync, statSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { DEVICE_ALIAS } from '../prompt/devices.js';
|
|
5
|
+
import { getModdableVersion, moddableExists } from '../setup/moddable.js';
|
|
6
|
+
import { sourceEnvironment, which } from '../system/exec.js';
|
|
7
|
+
import { detectPython, getPythonVersion } from '../system/python.js';
|
|
8
|
+
import { unwrapOr } from '../system/errors.js';
|
|
9
|
+
function isDir(path) {
|
|
10
|
+
return existsSync(path) && statSync(path).isDirectory();
|
|
11
|
+
}
|
|
12
|
+
function isFile(path) {
|
|
13
|
+
return existsSync(path) && statSync(path).isFile();
|
|
14
|
+
}
|
|
15
|
+
export async function gatherEnvironmentInfo(cliVersion) {
|
|
16
|
+
await sourceEnvironment();
|
|
17
|
+
const supportedDevices = [];
|
|
18
|
+
if (moddableExists()) {
|
|
19
|
+
supportedDevices.push(DEVICE_ALIAS[os.type().toLowerCase()]);
|
|
20
|
+
}
|
|
21
|
+
if (typeof process.env.IDF_PATH === 'string' && isDir(process.env.IDF_PATH)) {
|
|
22
|
+
supportedDevices.push('esp32');
|
|
23
|
+
}
|
|
24
|
+
if (typeof process.env.ESP_BASE === 'string' &&
|
|
25
|
+
isDir(process.env.ESP_BASE) &&
|
|
26
|
+
isDir(join(process.env.ESP_BASE, 'toolchain')) &&
|
|
27
|
+
isDir(join(process.env.ESP_BASE, 'ESP8266_RTOS_SDK')) &&
|
|
28
|
+
isDir(join(process.env.ESP_BASE, 'esp8266-2.3.0'))) {
|
|
29
|
+
supportedDevices.push('esp8266');
|
|
30
|
+
}
|
|
31
|
+
if ((process.env.PATH ?? '').includes('binaryen') &&
|
|
32
|
+
isDir(process.env.EMSDK ?? '') &&
|
|
33
|
+
isFile(process.env.EMSDK_NODE ?? '') &&
|
|
34
|
+
isFile(process.env.EMSDK_PYTHON ?? '')) {
|
|
35
|
+
supportedDevices.push('wasm');
|
|
36
|
+
}
|
|
37
|
+
if (typeof process.env.PICO_SDK_PATH === 'string' &&
|
|
38
|
+
isDir(process.env.PICO_SDK_PATH) &&
|
|
39
|
+
which('picotool') !== null &&
|
|
40
|
+
isFile(process.env.PIOASM ?? '')) {
|
|
41
|
+
supportedDevices.push('pico');
|
|
42
|
+
}
|
|
43
|
+
if (typeof process.env.NRF_ROOT === 'string' &&
|
|
44
|
+
isDir(process.env.NRF_ROOT) &&
|
|
45
|
+
((typeof process.env.NRF_SDK_DIR === 'string' &&
|
|
46
|
+
isDir(process.env.NRF_SDK_DIR)) ||
|
|
47
|
+
(typeof process.env.NRF52_SDK_PATH === 'string' &&
|
|
48
|
+
isDir(process.env.NRF52_SDK_PATH)))) {
|
|
49
|
+
supportedDevices.push('nrf52');
|
|
50
|
+
}
|
|
51
|
+
if (typeof process.env.ZEPHYR_BASE === 'string' &&
|
|
52
|
+
isDir(process.env.ZEPHYR_BASE)) {
|
|
53
|
+
supportedDevices.push('zephyr');
|
|
54
|
+
}
|
|
55
|
+
const pythonVersion = unwrapOr(await getPythonVersion(), 'Unavailable');
|
|
56
|
+
const pythonPath = which(detectPython() ?? '') ?? 'n/a';
|
|
57
|
+
const moddableVersion = unwrapOr(await getModdableVersion(), 'Not found');
|
|
58
|
+
const moddablePath = process.env.MODDABLE ?? 'n/a';
|
|
59
|
+
return {
|
|
60
|
+
cliVersion,
|
|
61
|
+
osType: os.type(),
|
|
62
|
+
arch: os.arch(),
|
|
63
|
+
shell: process.env.SHELL ?? 'Unknown',
|
|
64
|
+
nodeVersion: process.version,
|
|
65
|
+
nodePath: which('node') ?? 'path not found',
|
|
66
|
+
pythonVersion,
|
|
67
|
+
pythonPath,
|
|
68
|
+
moddableVersion,
|
|
69
|
+
moddablePath,
|
|
70
|
+
supportedDevices,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdG9vbGJveC9kb2N0b3IvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQ3hCLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQzlDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDaEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHNCQUFzQixDQUFBO0FBQ25ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxjQUFjLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQUN6RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsS0FBSyxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDNUQsT0FBTyxFQUFFLFlBQVksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBRXBFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUU5QyxTQUFTLEtBQUssQ0FBQyxJQUFZO0lBQ3pCLE9BQU8sVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtBQUN6RCxDQUFDO0FBRUQsU0FBUyxNQUFNLENBQUMsSUFBWTtJQUMxQixPQUFPLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUE7QUFDcEQsQ0FBQztBQWdCRCxNQUFNLENBQUMsS0FBSyxVQUFVLHFCQUFxQixDQUN6QyxVQUFrQjtJQUVsQixNQUFNLGlCQUFpQixFQUFFLENBQUE7SUFFekIsTUFBTSxnQkFBZ0IsR0FBYSxFQUFFLENBQUE7SUFFckMsSUFBSSxjQUFjLEVBQUUsRUFBRSxDQUFDO1FBQ3JCLGdCQUFnQixDQUFDLElBQUksQ0FDbkIsWUFBWSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQVksQ0FBVyxDQUMxRCxDQUFBO0lBQ0gsQ0FBQztJQUVELElBQUksT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztRQUM1RSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDaEMsQ0FBQztJQUNELElBQ0UsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxRQUFRO1FBQ3hDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQztRQUMzQixLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQzlDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztRQUNyRCxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLGVBQWUsQ0FBQyxDQUFDLEVBQ2xELENBQUM7UUFDRCxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDbEMsQ0FBQztJQUNELElBQ0UsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDO1FBQzdDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDOUIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQztRQUNwQyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLElBQUksRUFBRSxDQUFDLEVBQ3RDLENBQUM7UUFDRCxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDL0IsQ0FBQztJQUNELElBQ0UsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsS0FBSyxRQUFRO1FBQzdDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQztRQUNoQyxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssSUFBSTtRQUMxQixNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLEVBQ2hDLENBQUM7UUFDRCxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDL0IsQ0FBQztJQUNELElBQ0UsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxRQUFRO1FBQ3hDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQztRQUMzQixDQUFDLENBQUMsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsS0FBSyxRQUFRO1lBQzNDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQy9CLENBQUMsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsS0FBSyxRQUFRO2dCQUM3QyxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLEVBQ3ZDLENBQUM7UUFDRCxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDaEMsQ0FBQztJQUNELElBQ0UsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsS0FBSyxRQUFRO1FBQzNDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxFQUM5QixDQUFDO1FBQ0QsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQ2pDLENBQUM7SUFFRCxNQUFNLGFBQWEsR0FBRyxRQUFRLENBQUMsTUFBTSxnQkFBZ0IsRUFBRSxFQUFFLGFBQWEsQ0FBQyxDQUFBO0lBQ3ZFLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUMsSUFBSSxLQUFLLENBQUE7SUFDdkQsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDLE1BQU0sa0JBQWtCLEVBQUUsRUFBRSxXQUFXLENBQUMsQ0FBQTtJQUN6RSxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsSUFBSSxLQUFLLENBQUE7SUFFbEQsT0FBTztRQUNMLFVBQVU7UUFDVixNQUFNLEVBQUUsRUFBRSxDQUFDLElBQUksRUFBRTtRQUNqQixJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksRUFBRTtRQUNmLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssSUFBSSxTQUFTO1FBQ3JDLFdBQVcsRUFBRSxPQUFPLENBQUMsT0FBTztRQUM1QixRQUFRLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLGdCQUFnQjtRQUMzQyxhQUFhO1FBQ2IsVUFBVTtRQUNWLGVBQWU7UUFDZixZQUFZO1FBQ1osZ0JBQWdCO0tBQ2pCLENBQUE7QUFDSCxDQUFDIn0=
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { existsSync, statSync, readdirSync, mkdirSync, cpSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { collectChoicesFromTree } from '../prompt/choices.js';
|
|
4
|
+
import { buildTree } from '../prompt/tree.js';
|
|
5
|
+
import { sourceEnvironment } from '../system/exec.js';
|
|
6
|
+
export default async function* initProject(projectName, flags, prompter) {
|
|
7
|
+
const { typescript = false, io = true, manifest = false, example, 'list-examples': listExamples = false, overwrite = false, asyncMain = false, } = flags;
|
|
8
|
+
if (!overwrite &&
|
|
9
|
+
existsSync(projectName) &&
|
|
10
|
+
statSync(projectName).isDirectory()) {
|
|
11
|
+
yield {
|
|
12
|
+
type: 'warning',
|
|
13
|
+
message: `Directory called ${projectName} already exists. Please pass the --overwrite flag to replace an existing project.`,
|
|
14
|
+
};
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
await sourceEnvironment();
|
|
18
|
+
if (example !== undefined || listExamples) {
|
|
19
|
+
yield { type: 'step:start', message: 'Discovering example projects...' };
|
|
20
|
+
const exampleProjectPath = join(String(process.env.MODDABLE), 'examples');
|
|
21
|
+
const exampleChildren = existsSync(exampleProjectPath) &&
|
|
22
|
+
statSync(exampleProjectPath).isDirectory()
|
|
23
|
+
? readdirSync(exampleProjectPath).map((entry) => buildTree(join(exampleProjectPath, entry), entry))
|
|
24
|
+
: [];
|
|
25
|
+
const choices = exampleChildren
|
|
26
|
+
.map((ex) => collectChoicesFromTree(ex))
|
|
27
|
+
.flat();
|
|
28
|
+
let selectedExample = choices.find((choice) => choice === example);
|
|
29
|
+
if (listExamples || selectedExample === undefined) {
|
|
30
|
+
const filteredChoices = choices.filter((choice) => choice.includes(String(example)));
|
|
31
|
+
selectedExample = await prompter.select('Here are the available example templates:', (filteredChoices.length > 0 ? filteredChoices : choices).map((c) => ({
|
|
32
|
+
label: c,
|
|
33
|
+
value: c,
|
|
34
|
+
})));
|
|
35
|
+
}
|
|
36
|
+
if (selectedExample === '' || selectedExample === undefined) {
|
|
37
|
+
yield {
|
|
38
|
+
type: 'warning',
|
|
39
|
+
message: 'Please select an example template to use.',
|
|
40
|
+
};
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const selectedExamplePath = join(exampleProjectPath, selectedExample);
|
|
44
|
+
yield {
|
|
45
|
+
type: 'info',
|
|
46
|
+
message: `Generating project directory from ${selectedExample}`,
|
|
47
|
+
};
|
|
48
|
+
cpSync(selectedExamplePath, projectName, {
|
|
49
|
+
recursive: true,
|
|
50
|
+
force: overwrite,
|
|
51
|
+
});
|
|
52
|
+
yield { type: 'step:done' };
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
yield {
|
|
56
|
+
type: 'step:start',
|
|
57
|
+
message: `Generating Moddable project: ${projectName}`,
|
|
58
|
+
};
|
|
59
|
+
mkdirSync(projectName, { recursive: true });
|
|
60
|
+
const includes = [
|
|
61
|
+
io
|
|
62
|
+
? [
|
|
63
|
+
'"$(MODDABLE)/modules/io/manifest.json"',
|
|
64
|
+
'"$(MODDABLE)/examples/manifest_net.json"',
|
|
65
|
+
]
|
|
66
|
+
: '"$(MODDABLE)/examples/manifest_base.json"',
|
|
67
|
+
typescript ? '"$(MODDABLE)/examples/manifest_typings.json"' : undefined,
|
|
68
|
+
]
|
|
69
|
+
.filter(Boolean)
|
|
70
|
+
.flat()
|
|
71
|
+
.join(',\n\t');
|
|
72
|
+
const defines = asyncMain
|
|
73
|
+
? ',\n defines: {\n async_main: 1\n }'
|
|
74
|
+
: '';
|
|
75
|
+
const { createManifest, createMain, createPackageJSON, createTSConfig } = await import('./templates.js');
|
|
76
|
+
const fileTasks = [
|
|
77
|
+
createMain({
|
|
78
|
+
target: `${projectName}/main.${typescript ? 'ts' : 'js'}`,
|
|
79
|
+
legacy: manifest,
|
|
80
|
+
}),
|
|
81
|
+
];
|
|
82
|
+
if (manifest) {
|
|
83
|
+
fileTasks.push(createManifest({
|
|
84
|
+
target: `${projectName}/manifest.json`,
|
|
85
|
+
includes,
|
|
86
|
+
defines,
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
fileTasks.push(createPackageJSON({
|
|
91
|
+
target: `${projectName}/package.json`,
|
|
92
|
+
projectName,
|
|
93
|
+
typescript,
|
|
94
|
+
io,
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
if (typescript) {
|
|
98
|
+
fileTasks.push(createTSConfig({ target: `${projectName}/tsconfig.json` }));
|
|
99
|
+
}
|
|
100
|
+
await Promise.all(fileTasks);
|
|
101
|
+
yield { type: 'step:done' };
|
|
102
|
+
}
|
|
103
|
+
yield {
|
|
104
|
+
type: 'info',
|
|
105
|
+
message: `Run the project using: cd ${projectName} && xs-dev run`,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdG9vbGJveC9pbml0L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQzlFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFHaEMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sc0JBQXNCLENBQUE7QUFDN0QsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQzdDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBWXJELE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQyxXQUFXLENBQ3hDLFdBQW1CLEVBQ25CLEtBQWtCLEVBQ2xCLFFBQWtCO0lBRWxCLE1BQU0sRUFDSixVQUFVLEdBQUcsS0FBSyxFQUNsQixFQUFFLEdBQUcsSUFBSSxFQUNULFFBQVEsR0FBRyxLQUFLLEVBQ2hCLE9BQU8sRUFDUCxlQUFlLEVBQUUsWUFBWSxHQUFHLEtBQUssRUFDckMsU0FBUyxHQUFHLEtBQUssRUFDakIsU0FBUyxHQUFHLEtBQUssR0FDbEIsR0FBRyxLQUFLLENBQUE7SUFFVCxJQUNFLENBQUMsU0FBUztRQUNWLFVBQVUsQ0FBQyxXQUFXLENBQUM7UUFDdkIsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUNuQyxDQUFDO1FBQ0QsTUFBTTtZQUNKLElBQUksRUFBRSxTQUFTO1lBQ2YsT0FBTyxFQUFFLG9CQUFvQixXQUFXLG1GQUFtRjtTQUM1SCxDQUFBO1FBQ0QsT0FBTTtJQUNSLENBQUM7SUFFRCxNQUFNLGlCQUFpQixFQUFFLENBQUE7SUFFekIsSUFBSSxPQUFPLEtBQUssU0FBUyxJQUFJLFlBQVksRUFBRSxD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
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface EnvironmentInfo {
|
|
2
|
+
cliVersion: string;
|
|
3
|
+
osType: string;
|
|
4
|
+
arch: string;
|
|
5
|
+
shell: string;
|
|
6
|
+
nodeVersion: string;
|
|
7
|
+
nodePath: string;
|
|
8
|
+
pythonVersion: string;
|
|
9
|
+
pythonPath: string;
|
|
10
|
+
moddableVersion: string;
|
|
11
|
+
moddablePath: string;
|
|
12
|
+
supportedDevices: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare function gatherEnvironmentInfo(cliVersion: string): Promise<EnvironmentInfo>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Prompter } from '../../lib/prompter.js';
|
|
2
|
+
import type { OperationEvent } from '../../lib/events.js';
|
|
3
|
+
export interface InitOptions {
|
|
4
|
+
typescript?: boolean;
|
|
5
|
+
io?: boolean;
|
|
6
|
+
manifest?: boolean;
|
|
7
|
+
example?: string;
|
|
8
|
+
'list-examples'?: boolean;
|
|
9
|
+
overwrite?: boolean;
|
|
10
|
+
asyncMain?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export default function initProject(projectName: string, flags: InitOptions, prompter: Prompter): AsyncGenerator<OperationEvent>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xs-dev",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1--canary.98a7cea.0",
|
|
4
4
|
"description": "CLI for automating the setup and usage of Moddable XS tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "build/types/types.d.ts",
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"#src/": "./src/"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
|
-
"postinstall": "node scripts/fix-liblzma-arm64.mjs",
|
|
23
22
|
"xs-dev": "tsx src/cli.ts",
|
|
24
23
|
"xs-dev:debug": "DEBUG=* tsx --trace-deprecation src/cli.ts",
|
|
25
24
|
"format": "prettier --write **/*.{js,ts,json}",
|
|
@@ -45,8 +44,7 @@
|
|
|
45
44
|
"build",
|
|
46
45
|
"LICENSE",
|
|
47
46
|
"README.md",
|
|
48
|
-
"docs"
|
|
49
|
-
"scripts"
|
|
47
|
+
"docs"
|
|
50
48
|
],
|
|
51
49
|
"license": "MIT",
|
|
52
50
|
"repository": {
|
|
@@ -68,7 +66,7 @@
|
|
|
68
66
|
"windows-shortcuts": "^0.1.6"
|
|
69
67
|
},
|
|
70
68
|
"optionalDependencies": {
|
|
71
|
-
"node-liblzma": "^
|
|
69
|
+
"node-liblzma": "^4.0.1"
|
|
72
70
|
},
|
|
73
71
|
"devDependencies": {
|
|
74
72
|
"@astrojs/starlight": "^0.37.7",
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workaround for node-liblzma missing darwin-arm64 prebuild.
|
|
3
|
-
*
|
|
4
|
-
* The darwin-x64 prebuild is a universal binary (x86_64 + arm64 slices),
|
|
5
|
-
* so it works on Apple Silicon. node-gyp-build only looks in darwin-arm64/
|
|
6
|
-
* on arm64 hosts, so we copy the universal binary there.
|
|
7
|
-
*
|
|
8
|
-
* Track upstream fix: https://github.com/oorabona/node-liblzma
|
|
9
|
-
*/
|
|
10
|
-
'use strict'
|
|
11
|
-
|
|
12
|
-
import { existsSync, mkdirSync, copyFileSync } from 'node:fs'
|
|
13
|
-
import { join } from 'node:path'
|
|
14
|
-
import { platform, arch } from 'node:os'
|
|
15
|
-
import { debuglog } from 'node:util'
|
|
16
|
-
|
|
17
|
-
const debug = debuglog('xs-dev')
|
|
18
|
-
|
|
19
|
-
if (platform() === 'darwin' && arch() === 'arm64') {
|
|
20
|
-
try {
|
|
21
|
-
const pkg = require.resolve('node-liblzma')
|
|
22
|
-
const prebuildsDir = join(pkg, '..', '..', 'prebuilds')
|
|
23
|
-
const src = join(prebuildsDir, 'darwin-x64', 'node-liblzma.node')
|
|
24
|
-
const destDir = join(prebuildsDir, 'darwin-arm64')
|
|
25
|
-
const dest = join(destDir, 'node-liblzma.node')
|
|
26
|
-
|
|
27
|
-
if (existsSync(src) && !existsSync(dest)) {
|
|
28
|
-
mkdirSync(destDir, { recursive: true })
|
|
29
|
-
copyFileSync(src, dest)
|
|
30
|
-
debug(
|
|
31
|
-
'node-liblzma: copied universal darwin-x64 prebuild to darwin-arm64',
|
|
32
|
-
)
|
|
33
|
-
}
|
|
34
|
-
} catch {
|
|
35
|
-
// node-liblzma is optional — silently skip if not installed
|
|
36
|
-
}
|
|
37
|
-
}
|