@flare-desktop/cli 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +76 -2
- package/bin/flare.js +4 -0
- package/package.json +42 -4
- package/src/cli.js +93 -0
- package/src/commands/build.js +37 -0
- package/src/commands/bundle.js +44 -0
- package/src/commands/completions.js +45 -0
- package/src/commands/dev.js +91 -0
- package/src/commands/doctor.js +88 -0
- package/src/commands/icon.js +31 -0
- package/src/commands/info.js +65 -0
- package/src/commands/init.js +108 -0
- package/src/commands/inspect.js +35 -0
- package/src/help.js +32 -0
- package/src/index.js +17 -0
- package/src/lib/args.js +65 -0
- package/src/lib/build.js +29 -0
- package/src/lib/cmake.js +102 -0
- package/src/lib/commands.js +15 -0
- package/src/lib/errors.js +7 -0
- package/src/lib/icons.js +127 -0
- package/src/lib/logger.js +19 -0
- package/src/lib/packaging/common.js +131 -0
- package/src/lib/packaging/index.js +228 -0
- package/src/lib/packaging/linux.js +283 -0
- package/src/lib/packaging/macos.js +84 -0
- package/src/lib/packaging/msi.js +143 -0
- package/src/lib/packaging/nsis.js +106 -0
- package/src/lib/packaging/staging.js +123 -0
- package/src/lib/packaging/tools.js +75 -0
- package/src/lib/png.js +288 -0
- package/src/lib/process.js +57 -0
- package/src/lib/project.js +285 -0
- package/src/schema.js +2 -0
- package/src/templates/project.js +284 -0
- package/src/version.js +6 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { SCHEMA_URL } from "../schema.js";
|
|
2
|
+
|
|
3
|
+
export function embeddedIdentifier(name) {
|
|
4
|
+
const segments = String(name).split("-").filter(Boolean);
|
|
5
|
+
return segments
|
|
6
|
+
.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
|
|
7
|
+
.join("");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function configTemplate({ name, identifier, version }) {
|
|
11
|
+
return {
|
|
12
|
+
$schema: SCHEMA_URL,
|
|
13
|
+
package: { productName: name, version },
|
|
14
|
+
app: {
|
|
15
|
+
identifier,
|
|
16
|
+
productName: name,
|
|
17
|
+
mainBinaryName: name,
|
|
18
|
+
version
|
|
19
|
+
},
|
|
20
|
+
build: {
|
|
21
|
+
frontendDist: "frontend",
|
|
22
|
+
devUrl: "",
|
|
23
|
+
beforeDevCommand: "",
|
|
24
|
+
afterDevCommand: "",
|
|
25
|
+
beforeBuildCommand: "",
|
|
26
|
+
afterBuildCommand: ""
|
|
27
|
+
},
|
|
28
|
+
bundle: {
|
|
29
|
+
active: true,
|
|
30
|
+
identifier,
|
|
31
|
+
icon: "icons/icon.png",
|
|
32
|
+
category: "DeveloperTool",
|
|
33
|
+
shortDescription: `${name} built with flare`,
|
|
34
|
+
targets: []
|
|
35
|
+
},
|
|
36
|
+
security: {
|
|
37
|
+
csp: "default-src 'self'",
|
|
38
|
+
freezePrototype: true
|
|
39
|
+
},
|
|
40
|
+
windows: [
|
|
41
|
+
{
|
|
42
|
+
label: "main",
|
|
43
|
+
title: name,
|
|
44
|
+
width: 960,
|
|
45
|
+
height: 640,
|
|
46
|
+
resizable: true,
|
|
47
|
+
center: true,
|
|
48
|
+
theme: "automatic"
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function packageJsonTemplate({ name, version, cliVersion }) {
|
|
55
|
+
return {
|
|
56
|
+
name,
|
|
57
|
+
version,
|
|
58
|
+
private: true,
|
|
59
|
+
type: "module",
|
|
60
|
+
scripts: {
|
|
61
|
+
dev: "flare dev",
|
|
62
|
+
build: "flare build",
|
|
63
|
+
bundle: "flare bundle",
|
|
64
|
+
icon: "flare icon icons/icon.png"
|
|
65
|
+
},
|
|
66
|
+
devDependencies: {
|
|
67
|
+
"@flare-desktop/cli": `^${cliVersion}`
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function cmakeTemplate({ name, version, coreVersion }) {
|
|
73
|
+
return `cmake_minimum_required(VERSION 3.24)
|
|
74
|
+
|
|
75
|
+
project(${name} VERSION ${version} LANGUAGES CXX)
|
|
76
|
+
|
|
77
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
78
|
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
79
|
+
|
|
80
|
+
include(FetchContent)
|
|
81
|
+
|
|
82
|
+
FetchContent_Declare(
|
|
83
|
+
flare
|
|
84
|
+
GIT_REPOSITORY https://github.com/flare-desktop/flare.git
|
|
85
|
+
GIT_TAG v${coreVersion}
|
|
86
|
+
GIT_SHALLOW TRUE)
|
|
87
|
+
FetchContent_MakeAvailable(flare)
|
|
88
|
+
|
|
89
|
+
add_executable(${name} source/main.cpp)
|
|
90
|
+
target_link_libraries(${name} PRIVATE flare::core flare::assets)
|
|
91
|
+
|
|
92
|
+
set(FLARE_FRONTEND_DIR "frontend" CACHE PATH "Frontend directory")
|
|
93
|
+
file(TO_CMAKE_PATH "\${FLARE_FRONTEND_DIR}" FLARE_FRONTEND_DIR)
|
|
94
|
+
target_compile_definitions(${name} PRIVATE FLARE_FRONTEND_DIR="\${FLARE_FRONTEND_DIR}")
|
|
95
|
+
FlareEmbedFrontend(${name} "\${FLARE_FRONTEND_DIR}")
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function sourceTemplate({ name, identifier, version }) {
|
|
100
|
+
const embedded = embeddedIdentifier(name);
|
|
101
|
+
return `#include <flare/config/config.h>
|
|
102
|
+
#include <flare/core/application.h>
|
|
103
|
+
#include <flare/log/log.h>
|
|
104
|
+
|
|
105
|
+
#include <${name}-frontend.h>
|
|
106
|
+
|
|
107
|
+
#include <cstdlib>
|
|
108
|
+
#include <string>
|
|
109
|
+
|
|
110
|
+
#ifndef FLARE_FRONTEND_DIR
|
|
111
|
+
#define FLARE_FRONTEND_DIR "frontend"
|
|
112
|
+
#endif
|
|
113
|
+
|
|
114
|
+
int main() {
|
|
115
|
+
const bool development = std::getenv("FLARE_DEV") != nullptr;
|
|
116
|
+
|
|
117
|
+
Flare::ApplicationOptions options;
|
|
118
|
+
options.config = Flare::Config::Defaults("${identifier}", "${version}");
|
|
119
|
+
options.config.app.productName = "${name}";
|
|
120
|
+
options.config.windows.front().title = "${name}";
|
|
121
|
+
options.development = development;
|
|
122
|
+
|
|
123
|
+
std::string error;
|
|
124
|
+
Flare::ConfigLoader loader(
|
|
125
|
+
Flare::ConfigMergeOptions{"flare.config.json", development ? "development" : "production", "", {}});
|
|
126
|
+
if (const auto loaded = loader.Load(error); loaded.has_value()) {
|
|
127
|
+
options.config = *loaded;
|
|
128
|
+
} else {
|
|
129
|
+
Flare::LogWarn("using the built-in configuration: {}", error);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const char* devUrl = std::getenv("FLARE_DEV_URL");
|
|
133
|
+
if (devUrl != nullptr) options.devUrl = devUrl;
|
|
134
|
+
if (development && options.devUrl.empty()) options.frontendDirectory = FLARE_FRONTEND_DIR;
|
|
135
|
+
|
|
136
|
+
Flare::Application application(options);
|
|
137
|
+
if (!development) Flare::Embedded::Insert${embedded}(application.Assets());
|
|
138
|
+
|
|
139
|
+
application.RegisterCommand("greet", [](const Flare::InvokeRequest& request) {
|
|
140
|
+
const std::string name =
|
|
141
|
+
request.payload.contains("name") ? request.payload["name"].get<std::string>() : "world";
|
|
142
|
+
return Flare::JSON("hello, " + name);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
application.CreateWindow(application.Config().MainWindow());
|
|
146
|
+
Flare::LogInfo("${name} started");
|
|
147
|
+
application.Run();
|
|
148
|
+
return EXIT_SUCCESS;
|
|
149
|
+
}
|
|
150
|
+
`;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function indexHtmlTemplate(name) {
|
|
154
|
+
return `<!doctype html>
|
|
155
|
+
<html lang="en">
|
|
156
|
+
<head>
|
|
157
|
+
<meta charset="utf-8">
|
|
158
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
159
|
+
<title>${name}</title>
|
|
160
|
+
<link rel="stylesheet" href="style.css">
|
|
161
|
+
</head>
|
|
162
|
+
<body>
|
|
163
|
+
<main>
|
|
164
|
+
<h1>${name}</h1>
|
|
165
|
+
<p>the frontend runs in the system webview, the backend in C++.</p>
|
|
166
|
+
<button id="greet">call the backend</button>
|
|
167
|
+
<pre id="output"></pre>
|
|
168
|
+
</main>
|
|
169
|
+
<script type="module" src="main.js"></script>
|
|
170
|
+
</body>
|
|
171
|
+
</html>
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function styleTemplate() {
|
|
176
|
+
return `:root {
|
|
177
|
+
color-scheme: light dark;
|
|
178
|
+
--background: #f4f1ec;
|
|
179
|
+
--foreground: #2c2328;
|
|
180
|
+
--accent: #d8a7b1;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
@media (prefers-color-scheme: dark) {
|
|
184
|
+
:root {
|
|
185
|
+
--background: #201918;
|
|
186
|
+
--foreground: #f4f1ec;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
* {
|
|
191
|
+
box-sizing: border-box;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
body {
|
|
195
|
+
margin: 0;
|
|
196
|
+
min-height: 100vh;
|
|
197
|
+
display: grid;
|
|
198
|
+
place-items: center;
|
|
199
|
+
background: var(--background);
|
|
200
|
+
color: var(--foreground);
|
|
201
|
+
font-family: system-ui, sans-serif;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
main {
|
|
205
|
+
text-align: center;
|
|
206
|
+
padding: 2rem;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
h1 {
|
|
210
|
+
margin: 0 0 0.5rem;
|
|
211
|
+
letter-spacing: -0.02em;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
p {
|
|
215
|
+
margin: 0 0 1.5rem;
|
|
216
|
+
opacity: 0.7;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
button {
|
|
220
|
+
padding: 0.65rem 1.3rem;
|
|
221
|
+
border: 0;
|
|
222
|
+
border-radius: 0.6rem;
|
|
223
|
+
background: var(--accent);
|
|
224
|
+
color: #201918;
|
|
225
|
+
font-weight: 600;
|
|
226
|
+
cursor: pointer;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
pre {
|
|
230
|
+
margin-top: 1rem;
|
|
231
|
+
opacity: 0.8;
|
|
232
|
+
}
|
|
233
|
+
`;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export function scriptTemplate() {
|
|
237
|
+
return `import { app, invoke } from "/core.js";
|
|
238
|
+
|
|
239
|
+
const output = document.querySelector("#output");
|
|
240
|
+
|
|
241
|
+
document.querySelector("#greet").addEventListener("click", async () => {
|
|
242
|
+
const message = await invoke("greet", { name: "flare" });
|
|
243
|
+
const version = await app.version();
|
|
244
|
+
output.textContent = \`\${message} (\${version})\`;
|
|
245
|
+
});
|
|
246
|
+
`;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export function gitignoreTemplate() {
|
|
250
|
+
return "build/\ntarget/\nnode_modules/\n.DS_Store\n";
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export function readmeTemplate(name) {
|
|
254
|
+
return `# ${name}
|
|
255
|
+
|
|
256
|
+
A desktop application built with [flare](https://github.com/flare-desktop/flare).
|
|
257
|
+
|
|
258
|
+
## Development
|
|
259
|
+
|
|
260
|
+
\`\`\`bash
|
|
261
|
+
npm install
|
|
262
|
+
npm run dev
|
|
263
|
+
\`\`\`
|
|
264
|
+
|
|
265
|
+
## Build
|
|
266
|
+
|
|
267
|
+
\`\`\`bash
|
|
268
|
+
npm run build
|
|
269
|
+
npm run bundle
|
|
270
|
+
\`\`\`
|
|
271
|
+
|
|
272
|
+
\`npm run dev\` builds the C++ core and serves \`frontend/\` in the system webview.
|
|
273
|
+
\`npm run build\` compiles the frontend into the executable and produces a release build.
|
|
274
|
+
\`npm run bundle\` assembles the configured bundle targets under \`target/bundle\`.
|
|
275
|
+
|
|
276
|
+
## Icons
|
|
277
|
+
|
|
278
|
+
\`\`\`bash
|
|
279
|
+
npm run icon
|
|
280
|
+
\`\`\`
|
|
281
|
+
|
|
282
|
+
The command reads \`icons/icon.png\` and writes the png, ico and icns sets next to it.
|
|
283
|
+
`;
|
|
284
|
+
}
|