create-vidra-app 0.1.7 → 0.1.9
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 +8 -2
- package/dist/cli.js +73 -25
- package/dist/index.js +11 -12
- package/package.json +2 -2
- package/templates/react-vite/README.md +5 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# create-vidra-app
|
|
2
2
|
|
|
3
|
-
Scaffold a new [Vidra](https://
|
|
3
|
+
Scaffold a new [Vidra](https://vidra.build) application — a
|
|
4
4
|
**React UI + .NET MAUI native host**, shipped from a single codebase.
|
|
5
5
|
|
|
6
6
|
> **Alpha.** APIs and templates may change between 0.x releases.
|
|
@@ -41,7 +41,13 @@ npx vidra build --target macos # build + package a macOS .dmg
|
|
|
41
41
|
|
|
42
42
|
If the MAUI workload is missing, `create-vidra-app` will detect it after
|
|
43
43
|
scaffolding and offer to install it for you. You can re-check at any time with
|
|
44
|
-
`npm run doctor`.
|
|
44
|
+
`npm run doctor`.
|
|
45
|
+
|
|
46
|
+
## Links
|
|
47
|
+
|
|
48
|
+
- Website: [vidra.build](https://vidra.build)
|
|
49
|
+
- GitHub: [rzamfiriu/vidra](https://github.com/rzamfiriu/vidra)
|
|
50
|
+
- npm: [create-vidra-app](https://www.npmjs.com/package/create-vidra-app)
|
|
45
51
|
|
|
46
52
|
## License
|
|
47
53
|
|
package/dist/cli.js
CHANGED
|
@@ -29,7 +29,7 @@ var parseArgs = (argv) => {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
// src/exec.ts
|
|
32
|
-
import { execSync } from "child_process";
|
|
32
|
+
import { execSync, spawn } from "child_process";
|
|
33
33
|
|
|
34
34
|
// src/theme.ts
|
|
35
35
|
import chalk from "chalk";
|
|
@@ -527,7 +527,7 @@ var runDoctor = async () => {
|
|
|
527
527
|
console.log(
|
|
528
528
|
footer(
|
|
529
529
|
`${dim("all checks passed \u2014 you're ready to run")} ${lime(
|
|
530
|
-
"
|
|
530
|
+
"npm run dev"
|
|
531
531
|
)}${dim(".")}`
|
|
532
532
|
)
|
|
533
533
|
);
|
|
@@ -539,7 +539,7 @@ var runDoctor = async () => {
|
|
|
539
539
|
footer(
|
|
540
540
|
`${dim(
|
|
541
541
|
`${n} issue${n === 1 ? "" : "s"} found. apply the ${n === 1 ? "fix" : "fixes"} above, then re-run`
|
|
542
|
-
)} ${lime("
|
|
542
|
+
)} ${lime("npm run doctor")}${dim(".")}`
|
|
543
543
|
)
|
|
544
544
|
);
|
|
545
545
|
console.log();
|
|
@@ -942,7 +942,7 @@ var stepPackage = async (project, target, bundlePath) => {
|
|
|
942
942
|
// src/commands/dev.ts
|
|
943
943
|
import path6 from "path";
|
|
944
944
|
import fs5 from "fs-extra";
|
|
945
|
-
import { execFileSync as execFileSync4, spawn } from "child_process";
|
|
945
|
+
import { execFileSync as execFileSync4, spawn as spawn2 } from "child_process";
|
|
946
946
|
import { request } from "http";
|
|
947
947
|
var POLL_INTERVAL_MS = 500;
|
|
948
948
|
var POLL_TIMEOUT_MS = 3e4;
|
|
@@ -1065,14 +1065,18 @@ var DevSession = class {
|
|
|
1065
1065
|
}
|
|
1066
1066
|
startVite() {
|
|
1067
1067
|
console.log(taggedRow("active", "ui", dim("starting dev server\u2026")));
|
|
1068
|
-
const vite =
|
|
1068
|
+
const vite = spawn2(NPM_COMMAND, ["run", "dev"], {
|
|
1069
1069
|
cwd: this.project.uiDir,
|
|
1070
1070
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1071
1071
|
shell: process.platform === "win32"
|
|
1072
1072
|
});
|
|
1073
1073
|
return this.registerChild(vite, "ui", "Vite dev server");
|
|
1074
1074
|
}
|
|
1075
|
-
|
|
1075
|
+
// Builds the MAUI host as a discrete step (a plain `dotnet build`, never
|
|
1076
|
+
// MSBuild's `-t:Run`) so the per-OS launch paths can spawn the produced
|
|
1077
|
+
// binary directly. `-t:Run` shells out in ways that break for both locally
|
|
1078
|
+
// signed mac apps and unpackaged Windows apps (see the call sites).
|
|
1079
|
+
buildHostSync() {
|
|
1076
1080
|
console.log(
|
|
1077
1081
|
taggedRow(
|
|
1078
1082
|
"active",
|
|
@@ -1107,6 +1111,9 @@ var DevSession = class {
|
|
|
1107
1111
|
}
|
|
1108
1112
|
process.exit(1);
|
|
1109
1113
|
}
|
|
1114
|
+
}
|
|
1115
|
+
launchMacosHost() {
|
|
1116
|
+
this.buildHostSync();
|
|
1110
1117
|
const appBundle = findMacAppBundle(
|
|
1111
1118
|
this.project.hostDir,
|
|
1112
1119
|
this.target.framework,
|
|
@@ -1141,33 +1148,49 @@ var DevSession = class {
|
|
|
1141
1148
|
console.log(
|
|
1142
1149
|
taggedRow("done", "host", `${dim("launched")} ${value(path6.basename(appBundle))}`)
|
|
1143
1150
|
);
|
|
1144
|
-
const host =
|
|
1151
|
+
const host = spawn2(binary, [], {
|
|
1145
1152
|
cwd: this.project.root,
|
|
1146
1153
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1147
1154
|
env: { ...process.env, VIDRA_DEV_URL: this.viteUrl }
|
|
1148
1155
|
});
|
|
1149
1156
|
return this.registerChild(host, "host", path6.basename(binary));
|
|
1150
1157
|
}
|
|
1158
|
+
// Build first, then spawn the produced .exe directly. A single
|
|
1159
|
+
// `dotnet build -t:Run` on an unpackaged MAUI Windows app
|
|
1160
|
+
// (`WindowsPackageType=None`) execs the binary before the WindowsAppSDK
|
|
1161
|
+
// native assets are laid out beside it, so the app can't resolve its deps and
|
|
1162
|
+
// dies with a bare `MSB3073 ... exited with code 3` (ERROR_PATH_NOT_FOUND —
|
|
1163
|
+
// "The system cannot find the path specified"). Building as a discrete step
|
|
1164
|
+
// and then launching the binary is the documented workaround.
|
|
1165
|
+
// See dotnet/maui#13942 and dotnet/maui#5975.
|
|
1151
1166
|
launchWindowsHost() {
|
|
1152
|
-
|
|
1153
|
-
const
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
"-c",
|
|
1159
|
-
this.buildConfig,
|
|
1160
|
-
"-f",
|
|
1161
|
-
this.target.framework,
|
|
1162
|
-
this.project.csprojPath
|
|
1163
|
-
],
|
|
1164
|
-
{
|
|
1165
|
-
cwd: this.project.root,
|
|
1166
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1167
|
-
env: { ...process.env, VIDRA_DEV_URL: this.viteUrl }
|
|
1168
|
-
}
|
|
1167
|
+
this.buildHostSync();
|
|
1168
|
+
const exe = findWindowsExecutable(
|
|
1169
|
+
this.project.hostDir,
|
|
1170
|
+
this.project.csprojPath,
|
|
1171
|
+
this.target.framework,
|
|
1172
|
+
this.buildConfig
|
|
1169
1173
|
);
|
|
1170
|
-
|
|
1174
|
+
if (!exe) {
|
|
1175
|
+
console.error(
|
|
1176
|
+
row({
|
|
1177
|
+
glyph: "error",
|
|
1178
|
+
detail: dim(
|
|
1179
|
+
`could not find the host .exe under ${path6.join(this.project.hostDir, "bin", this.buildConfig, this.target.framework)}`
|
|
1180
|
+
)
|
|
1181
|
+
})
|
|
1182
|
+
);
|
|
1183
|
+
process.exit(1);
|
|
1184
|
+
}
|
|
1185
|
+
console.log(
|
|
1186
|
+
taggedRow("done", "host", `${dim("launched")} ${value(path6.basename(exe))}`)
|
|
1187
|
+
);
|
|
1188
|
+
const host = spawn2(exe, [], {
|
|
1189
|
+
cwd: path6.dirname(exe),
|
|
1190
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1191
|
+
env: { ...process.env, VIDRA_DEV_URL: this.viteUrl }
|
|
1192
|
+
});
|
|
1193
|
+
return this.registerChild(host, "host", path6.basename(exe));
|
|
1171
1194
|
}
|
|
1172
1195
|
registerChild(child, tag2, label) {
|
|
1173
1196
|
this.children.push(child);
|
|
@@ -1314,6 +1337,31 @@ var findMacExecutable = (appBundle) => {
|
|
|
1314
1337
|
}
|
|
1315
1338
|
return null;
|
|
1316
1339
|
};
|
|
1340
|
+
var findWindowsExecutable = (hostDir, csprojPath, framework, buildConfig) => {
|
|
1341
|
+
const outputDir = path6.join(hostDir, "bin", buildConfig, framework);
|
|
1342
|
+
if (!fs5.existsSync(outputDir)) return null;
|
|
1343
|
+
const exeName = `${path6.basename(csprojPath, ".csproj")}.exe`.toLowerCase();
|
|
1344
|
+
return findFileRecursive(outputDir, (name) => name.toLowerCase() === exeName) ?? findFileRecursive(
|
|
1345
|
+
outputDir,
|
|
1346
|
+
(name) => name.toLowerCase().endsWith(".host.exe")
|
|
1347
|
+
) ?? findFileRecursive(outputDir, (name) => name.toLowerCase().endsWith(".exe"));
|
|
1348
|
+
};
|
|
1349
|
+
var findFileRecursive = (dir, match) => {
|
|
1350
|
+
if (!fs5.existsSync(dir)) return null;
|
|
1351
|
+
const entries = fs5.readdirSync(dir, { withFileTypes: true });
|
|
1352
|
+
for (const entry of entries) {
|
|
1353
|
+
if (entry.isFile() && match(entry.name)) {
|
|
1354
|
+
return path6.join(dir, entry.name);
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
for (const entry of entries) {
|
|
1358
|
+
if (entry.isDirectory()) {
|
|
1359
|
+
const found = findFileRecursive(path6.join(dir, entry.name), match);
|
|
1360
|
+
if (found) return found;
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
return null;
|
|
1364
|
+
};
|
|
1317
1365
|
var killChild = (child) => {
|
|
1318
1366
|
if (!child.pid || child.exitCode !== null) return;
|
|
1319
1367
|
if (process.platform === "win32") {
|
package/dist/index.js
CHANGED
|
@@ -44,7 +44,7 @@ var parseArgs = (argv) => {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
// src/exec.ts
|
|
47
|
-
import { execSync } from "child_process";
|
|
47
|
+
import { execSync, spawn } from "child_process";
|
|
48
48
|
|
|
49
49
|
// src/theme.ts
|
|
50
50
|
import chalk from "chalk";
|
|
@@ -107,14 +107,11 @@ var exec = (cmd, cwd) => {
|
|
|
107
107
|
process.exit(1);
|
|
108
108
|
}
|
|
109
109
|
};
|
|
110
|
-
var
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
};
|
|
110
|
+
var tryExecAsync = (cmd, cwd) => new Promise((resolve) => {
|
|
111
|
+
const child = spawn(cmd, { cwd, stdio: "ignore", shell: true });
|
|
112
|
+
child.on("error", () => resolve(false));
|
|
113
|
+
child.on("close", (code) => resolve(code === 0));
|
|
114
|
+
});
|
|
118
115
|
|
|
119
116
|
// src/scaffold.ts
|
|
120
117
|
import fs from "fs-extra";
|
|
@@ -335,7 +332,7 @@ var VIDRA_REPO_ROOT = path2.resolve(CLI_ROOT, "..", "..", "..");
|
|
|
335
332
|
var LOCAL_FEED_DIR = path2.join(VIDRA_REPO_ROOT, "dist", "packages");
|
|
336
333
|
var LOCAL_CLI_DIR = CLI_ROOT;
|
|
337
334
|
var LOCAL_SDK_DIR = path2.join(VIDRA_REPO_ROOT, "src", "sdk", "vidra-js");
|
|
338
|
-
var VIDRA_VERSION = "0.
|
|
335
|
+
var VIDRA_VERSION = "0.2.0";
|
|
339
336
|
var SDK_VERSION = "0.1.0";
|
|
340
337
|
var main = async () => {
|
|
341
338
|
console.log();
|
|
@@ -419,8 +416,10 @@ var main = async () => {
|
|
|
419
416
|
);
|
|
420
417
|
console.log(row({ glyph: "active", detail: dim("installing dependencies\u2026") }));
|
|
421
418
|
const uiDir = path2.join(root, "ui");
|
|
422
|
-
const rootNpmOk =
|
|
423
|
-
|
|
419
|
+
const [rootNpmOk, uiNpmOk] = await Promise.all([
|
|
420
|
+
tryExecAsync("npm install", root),
|
|
421
|
+
tryExecAsync("npm install", uiDir)
|
|
422
|
+
]);
|
|
424
423
|
const npmOk = rootNpmOk && uiNpmOk;
|
|
425
424
|
console.log();
|
|
426
425
|
console.log(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-vidra-app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Scaffold a new Vidra application (React + .NET MAUI)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"url": "git+https://github.com/rzamfiriu/vidra.git",
|
|
42
42
|
"directory": "src/cli/create-vidra-app"
|
|
43
43
|
},
|
|
44
|
-
"homepage": "https://
|
|
44
|
+
"homepage": "https://vidra.build",
|
|
45
45
|
"bugs": {
|
|
46
46
|
"url": "https://github.com/rzamfiriu/vidra/issues"
|
|
47
47
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# {{appTitle}}
|
|
2
2
|
|
|
3
|
-
A cross-platform application built with [Vidra](https://
|
|
3
|
+
A cross-platform application built with [Vidra](https://vidra.build) — React UI + .NET MAUI native host.
|
|
4
4
|
|
|
5
5
|
## Getting Started
|
|
6
6
|
|
|
@@ -69,3 +69,7 @@ npm run build
|
|
|
69
69
|
├── vite.config.ts
|
|
70
70
|
└── package.json
|
|
71
71
|
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
Built with [Vidra](https://vidra.build) — a C#/.NET native core with a web UI.
|